diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..5c2c35f Binary files /dev/null and b/.DS_Store differ diff --git a/Classes/.DS_Store b/Classes/.DS_Store new file mode 100755 index 0000000..9c39779 Binary files /dev/null and b/Classes/.DS_Store differ diff --git a/Classes/CoreSurface/CoreSurface.h b/Classes/CoreSurface/CoreSurface.h new file mode 100755 index 0000000..3ca8f77 --- /dev/null +++ b/Classes/CoreSurface/CoreSurface.h @@ -0,0 +1,50 @@ +#ifndef CORESURFACE_H +#define CORESURFACE_H + +#include + +#define kCoreSurfaceLockTypeGimmeVRAM 3 + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void * CoreSurfaceBufferRef; +typedef void * CoreSurfaceAcceleratorRef; + +/* Keys for the CoreSurfaceBufferCreate dictionary. */ +extern CFStringRef kCoreSurfaceBufferGlobal; /* CFBoolean */ +extern CFStringRef kCoreSurfaceBufferMemoryRegion; /* CFStringRef */ +extern CFStringRef kCoreSurfaceBufferPitch; /* CFNumberRef */ +extern CFStringRef kCoreSurfaceBufferWidth; /* CFNumberRef */ +extern CFStringRef kCoreSurfaceBufferHeight; /* CFNumberRef */ +extern CFStringRef kCoreSurfaceBufferPixelFormat; /* CFNumberRef (fourCC) */ +extern CFStringRef kCoreSurfaceBufferAllocSize; /* CFNumberRef */ +extern CFStringRef kCoreSurfaceBufferClientAddress; /* CFNumberRef */ + +CoreSurfaceBufferRef CoreSurfaceBufferLookup(long lookup); +CoreSurfaceBufferRef CoreSurfaceBufferCreate(CFDictionaryRef dict); +unsigned int CoreSurfaceBufferGetHeight(CoreSurfaceBufferRef surface); +unsigned int CoreSurfaceBufferGetPixelFormatType(CoreSurfaceBufferRef surface); +unsigned int CoreSurfaceBufferGetID(CoreSurfaceBufferRef surface); +unsigned int CoreSurfaceBufferGetPlaneCount(CoreSurfaceBufferRef surface); + +/* lockType is one of kCoreSurfaceLockType*. */ +int CoreSurfaceBufferLock(CoreSurfaceBufferRef surface, unsigned int lockType); +int CoreSurfaceBufferUnlock(CoreSurfaceBufferRef surface); +int CoreSurfaceBufferWrapClientMemory(CoreSurfaceBufferRef surface); +void *CoreSurfaceBufferGetBaseAddress(CoreSurfaceBufferRef surface); + +/* Set type to 0. */ +int CoreSurfaceAcceleratorCreate(CFAllocatorRef allocator, int type, + CoreSurfaceAcceleratorRef *accel); +unsigned int CoreSurfaceAcceleratorTransferSurfaceWithSwap( + CoreSurfaceAcceleratorRef accelerator, CoreSurfaceBufferRef dest, + CoreSurfaceBufferRef src, CFDictionaryRef options); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/Classes/GraphicsServices/GSFont.h b/Classes/GraphicsServices/GSFont.h new file mode 100755 index 0000000..2e93391 --- /dev/null +++ b/Classes/GraphicsServices/GSFont.h @@ -0,0 +1,25 @@ +#ifndef GRAPHICSSERVICES_GSFONT_H_ +#define GRAPHICSSERVICES_GSFONT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + kGSFontItalicTrait = (1 << 0), + kGSFontBoldTrait = (1 << 1), + kGSFontExpandedTrait = (1 << 5), + kGSFontCondensedTrait = (1 << 6), + kGSFontMonoSpaceTrait = (1 << 10), + kGSFontVerticalTrait = (1 << 11), +}; typedef uint32_t GSFontSymbolicTraits; + +typedef struct __GSFont *GSFontRef; + +GSFontRef GSFontCreateWithName(const char *name, GSFontSymbolicTraits traits, float size); + +#ifdef __cplusplus +} +#endif + +#endif/*GRAPHICSSERVICES_GSFONT_H_*/ diff --git a/Classes/GraphicsServices/GSWindow.h b/Classes/GraphicsServices/GSWindow.h new file mode 100755 index 0000000..9d96697 --- /dev/null +++ b/Classes/GraphicsServices/GSWindow.h @@ -0,0 +1,51 @@ +/* iPhone Open SDK - Free Open Source Anti-Apple SDK + * Copyright (C) 2008 Jay Freeman (saurik) +*/ + +/* + * Redistribution and use in source and binary + * forms, with or without modification, are permitted + * provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the + * above copyright notice, this list of conditions + * and the following disclaimer. + * 2. Redistributions in binary form must reproduce the + * above copyright notice, this list of conditions + * and the following disclaimer in the documentation + * and/or other materials provided with the + * distribution. + * 3. The name of the author may not be used to endorse + * or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef GRAPHICSSERVICS_GSWINDOW_H_ +#define GRAPHICSSERVICS_GSWINDOW_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct __GSWindow *GSWindowRef; + +#ifdef __cplusplus +} +#endif + +#endif/*GRAPHICSSERVICS_GSWINDOW_H_*/ diff --git a/Classes/GraphicsServices/GraphicsServices.h b/Classes/GraphicsServices/GraphicsServices.h new file mode 100755 index 0000000..c4c349f --- /dev/null +++ b/Classes/GraphicsServices/GraphicsServices.h @@ -0,0 +1,191 @@ +/* iPhone Open SDK - Free Open Source Anti-Apple SDK + * Copyright (C) 2008 Jay Freeman (saurik) +*/ + +/* + * Redistribution and use in source and binary + * forms, with or without modification, are permitted + * provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the + * above copyright notice, this list of conditions + * and the following disclaimer. + * 2. Redistributions in binary form must reproduce the + * above copyright notice, this list of conditions + * and the following disclaimer in the documentation + * and/or other materials provided with the + * distribution. + * 3. The name of the author may not be used to endorse + * or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef GRAPHICSSERVICES_GRAPHICSSERVICS_H_ +#define GRAPHICSSERVICES_GRAPHICSSERVICS_H_ + +#include +#import +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct GSPathInfo { + /*0x00:13c*/ uint8_t x00; // key + /*0x01:13d*/ uint8_t x01; + /*0x02:13e*/ uint8_t x02; // 2=no + /*0x03:13f*/ uint8_t x03; + /*0x04:140*/ uint32_t x04; + /*0x08:144*/ uint32_t x08; + /*0x0c:148*/ CGPoint position; + /*0x14:14c*/ uint32_t x14; +}; + +struct GSEventRecord { + /*0x00:08*/ uint32_t type; + /*0x04:0c*/ uint32_t subType; + /*0x08:10*/ CGPoint locationOnScreen; + /*0x10:18*/ CGPoint locationInWindow; + /*0x18:20*/ uint64_t timestamp; //(GSCurrentEventTimestamp) + /*0x20:28*/ uint32_t zero; + /*0x24:2c*/ uint32_t modifierFlags; + /*0x28:30*/ uint16_t eventNumber; + /*0x2a:32*/ uint16_t x2a; + /*0x2c:34*/ uint32_t size; +}; + +struct GSEventKeyInfo { + /*0x30:38*/ uint32_t type; + /*0x34:3c*/ uint16_t character; + /*0x38:3e*/ uint16_t characterSet; + /*0x3a:40*/ uint8_t keyRepeating; +}; + +struct GSEventHandInfo { + /*0x30:38:00:5c*/ uint32_t type; + /*0x34:3c:04:60*/ uint16_t x34; + /*0x38:3e:06:64*/ uint16_t x38; + /*0x3a:40:08:68*/ CGPoint x3a; + /*0x40:48:10:70*/ uint32_t x40; //handInfoScale scales +}; + +struct GSEventApplicationInfo { + /*0x30:00*/ uint32_t pid; + /*0x34:04*/ uint32_t x34; + /*0x38:08*/ char name[]; +}; + +struct GSEventRecordInfo { + /*0x30:38:00:5c*/ struct GSEventHandInfo handInfo; + /*0x44:4c:14:74*/ uint32_t x44; + /*0x48:50:18:78*/ uint32_t x48; //handInfoScale scales + /*0x4c:54:1c:7c*/ uint32_t x4c; + /*0x50:58:20*/ uint8_t x50; + /*0x51:59:21*/ uint8_t pathPositions; + /*0x52:5a:22*/ uint16_t x52; + /*0x54:5c:24*/ struct GSPathInfo pathInfo[]; +}; + +/*struct __GSEvent { + struct CFRuntimeBase base_; + struct GSEventRecord record_; +};*/ + +typedef struct __GSEvent *GSEventRef; + +#define GSEventTypeKeyDown 0x000d + +#define GSEventTypeAccelerometer 0x0017 +#define GSEventTypeProximityStateChanged 0x0018 +#define GSEventTypeDeviceOrientationChanged 0x0032 +// 0x03c:loc_0018ac preferences + +#define GSEventTypeMenuButtonDown 0x03e8 +#define GSEventTypeMenuButtonUp 0x03e9 +#define GSEventTypeRingerChanged0 0x03f4 +#define GSEventTypeRingerChanged1 0x03f5 +#define GSEventTypeLockDevice 0x03f6 +#define GSEventTypeStatusBarMouseDown 0x03f7 +#define GSEventTypeStatusBarMouseDragged 0x03f8 +#define GSEventTypeStatusBarMouseUp 0x03f9 +#define GSEventTypeLockButtonDown 0x03f2 +#define GSEventTypeLockButtonUp 0x03f3 +#define GSEventTypeHeadsetButtonDown 0x03fa +#define GSEventTypeHeadsetButtonUp 0x03fb + +#define GSEventTypeVibrateForDuration 0x044c +#define GSEventTypeSetBacklightFactor 0x044e +#define GSEventTypeSetBacklightLevel 0x044f + +#define GSEventTypeApplicationStarted 0x07d0 +#define GSEventTypeAnotherApplicationFinishedLauncing 0x07d2 +#define GSEventTypeApplicationTerminateWithStatus 0x07d3 +#define GSEventTypeApplicationSuspended 0x07d4 +// 0x07d5:loc_000550 internal url +// 0x07d6:loc_000a20 external url +#define GSEventTypeApplicationExited 0x07d7 +#define GSEventTypeApplicationShowHideSettings 0x07d8 +#define GSEventTypeQuitTopApplication 0x07d9 +#define GSEventTypeOtherApplicationWillSuspend 0x07da +#define GSEventTypeApplicationSuspendedSettingsUpdated 0x07db + +#define GSEventTypeResetIdleTimer 0x0898 +#define GSEventTypeResetIdleDuration 0x0899 +#define GSEventTypeDumpUIHierarchy 0x09c4 +#define GSEventTypeDumpScreenContents 0x09c5 +#define GSEventTypeProcessScriptEvent 0x0a8c + +#define GSEventTypeMouse 0x0bb9 + +#define GSEventTypeAccessoryAvailabilityChanged 0x0fa0 +#define GSEventTypeAccessoryKeyStateChanged 0x0fa1 +#define GSEventTypeAccessory 0x0fa2 + +#define GSEventTypeOutOfLineDataRequest 0x1388 +#define GSEventTypeUrgentMemoryWarning 0x1770 +#define GSEventTypeOutOfLineDataResponse 0x10001 + +#define GSMouseEventTypeDown 0x1 +#define GSMouseEventTypeDragged 0x2 +#define GSMouseEventTypeUp 0x6 +#define GSMouseEventTypeCancel 0x8 + +#define _PurpleSystemEventPortName "PurpleSystemEventPort" + +mach_port_name_t GSCopyPurpleSystemEventPort(void); +uint64_t GSCurrentEventTimestamp(void); +struct GSEventHandInfo GSEventGetHandInfo(GSEventRef event); +struct CGRect GSEventGetLocationInWindow(GSEventRef event); +struct GSPathInfo GSEventGetPathInfoAtIndex(GSEventRef event, unsigned index); +mach_port_name_t GSGetPurpleNamedPort(CFStringRef name); +void GSSendEvent(struct GSEventRecord *record, mach_port_name_t port); +void GSSendSystemEvent(struct GSEventRecord *record); +struct GSEventRecord *_GSEventGetGSEventRecord(GSEventRef event); + +CFArrayRef GSSystemGetCapability(CFStringRef type); +extern CFStringRef const kGSDisplayIdentifiersCapability; + +#ifdef __cplusplus +} +#endif + +#endif//GRAPHICSSERVICES_GRAPHICSSERVICS_H_ diff --git a/Classes/OptionsController.h b/Classes/OptionsController.h new file mode 100755 index 0000000..2fcdcf1 --- /dev/null +++ b/Classes/OptionsController.h @@ -0,0 +1,23 @@ +#import + + +@interface OptionsController : UIViewController +{ + IBOutlet UISegmentedControl* segmentedSkin; + IBOutlet UISwitch* switchScaling; + IBOutlet UISwitch* switchAutosave; + IBOutlet UISwitch* switchSmoothScaling; + IBOutlet UISwitch* switchFramerate; + IBOutlet UISwitch* switchCompatibility; + IBOutlet UISwitch* switchSpeedHack; + NSMutableArray* optionsArray; +} + +- (void)optionChanged:(id)sender; +- (NSString*)getDocumentsDirectory; +- (void)getOptions; +- (int)getCurrentSkin; +- (int)getCurrentScaling; +- (int)getCurrentSmoothScaling; + +@end diff --git a/Classes/OptionsController.m b/Classes/OptionsController.m new file mode 100755 index 0000000..ed8b80d --- /dev/null +++ b/Classes/OptionsController.m @@ -0,0 +1,199 @@ +#import "SOApplication.h" + +unsigned long gp2x_fps_debug = 0; +int __autosave = 0; +int __transparency = 0; +int __speedhack = 0; + +@implementation OptionsController + +/* +// The designated initializer. Override to perform setup that is required before the view is loaded. +- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { + if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) { + // Custom initialization + } + return self; +} +*/ + +/* +// Implement loadView to create a view hierarchy programmatically, without using a nib. +- (void)loadView { +} +*/ + +/* +// Implement viewDidLoad to do additional setup after loading the view, typically from a nib. +- (void)viewDidLoad { + [super viewDidLoad]; +} +*/ + +/* +// Override to allow orientations other than the default portrait orientation. +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { + // Return YES for supported orientations + return (interfaceOrientation == UIInterfaceOrientationPortrait); +} +*/ + +-(void)awakeFromNib +{ + self.navigationItem.hidesBackButton = YES; + + [self getOptions]; +} + +- (void)didReceiveMemoryWarning { + [super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview + // Release anything that's not essential, such as cached data +} + + +- (void)dealloc { + [super dealloc]; +} + +- (void)optionChanged:(id)sender +{ + [optionsArray removeAllObjects]; + [optionsArray addObject:[NSDictionary dictionaryWithObjectsAndKeys: + [NSString stringWithFormat:@"%d", segmentedSkin.selectedSegmentIndex], @"skin", + [NSString stringWithFormat:@"%d", [switchScaling isOn]], @"scaling", + [NSString stringWithFormat:@"%d", [switchAutosave isOn]], @"autosave", + [NSString stringWithFormat:@"%d", [switchCompatibility isOn]], @"compatibility", + [NSString stringWithFormat:@"%d", [switchFramerate isOn]], @"framerate", + [NSString stringWithFormat:@"%d", [switchSpeedHack isOn]], @"speedhack", + [NSString stringWithFormat:@"%d", [switchSmoothScaling isOn]], @"smoothscaling", + nil]]; + + [segmentedSkin setSelectedSegmentIndex:[[[optionsArray objectAtIndex:0] objectForKey:@"skin"] intValue]]; + [switchScaling setOn:[[[optionsArray objectAtIndex:0] objectForKey:@"scaling"] intValue] animated:NO]; + [switchAutosave setOn:[[[optionsArray objectAtIndex:0] objectForKey:@"autosave"] intValue] animated:NO]; + [switchCompatibility setOn:[[[optionsArray objectAtIndex:0] objectForKey:@"compatibility"] intValue] animated:NO]; + [switchFramerate setOn:[[[optionsArray objectAtIndex:0] objectForKey:@"framerate"] intValue] animated:NO]; + [switchSpeedHack setOn:[[[optionsArray objectAtIndex:0] objectForKey:@"speedhack"] intValue] animated:NO]; + [switchSmoothScaling setOn:[[[optionsArray objectAtIndex:0] objectForKey:@"smoothscaling"] intValue] animated:NO]; + + gp2x_fps_debug = [switchFramerate isOn]; + __autosave = [switchAutosave isOn]; + __transparency = [switchCompatibility isOn]; + __speedhack = [switchSpeedHack isOn]; + + NSString *path=[[self getDocumentsDirectory] stringByAppendingPathComponent:@"options.bin"]; + NSData *plistData; + + NSString *error; + + + + plistData = [NSPropertyListSerialization dataFromPropertyList:optionsArray + + format:NSPropertyListBinaryFormat_v1_0 + + errorDescription:&error]; + + if(plistData) + + { + + NSLog(@"No error creating plist data."); + + [plistData writeToFile:path atomically:NO]; + + } + else + { + + NSLog(error); + + [error release]; + + } +} + +- (int)getCurrentSkin +{ + return segmentedSkin.selectedSegmentIndex; +} + +- (int)getCurrentScaling +{ + return [switchScaling isOn]; +} + +- (int)getCurrentSmoothScaling +{ + return [switchSmoothScaling isOn]; +} + +- (NSString*)getDocumentsDirectory +{ +#ifdef APPSTORE_BUILD + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); + NSString *documentsDirectory = [paths objectAtIndex: 0]; + return documentsDirectory; +#else + return @"/Applications/snes4iphone.app"; +#endif +} + +- (void)getOptions +{ + NSString *path=[[self getDocumentsDirectory] stringByAppendingPathComponent:@"options.bin"]; + + NSData *plistData; + id plist; + NSString *error; + + NSPropertyListFormat format; + + plistData = [NSData dataWithContentsOfFile:path]; + + + + plist = [NSPropertyListSerialization propertyListFromData:plistData + + mutabilityOption:NSPropertyListImmutable + + format:&format + + errorDescription:&error]; + + if(!plist) + { + + NSLog(error); + + [error release]; + + optionsArray = [[NSMutableArray alloc] init]; + + [segmentedSkin setSelectedSegmentIndex:0]; + [switchScaling setOn:1 animated:NO]; + [switchAutosave setOn:0 animated:NO]; + [switchSmoothScaling setOn:0 animated:NO]; + [switchFramerate setOn:0 animated:NO]; + [switchCompatibility setOn:0 animated:NO]; + [switchSpeedHack setOn:0 animated:NO]; + + [self optionChanged:self]; + } + else + { + optionsArray = [[NSMutableArray alloc] initWithArray:plist]; + + [segmentedSkin setSelectedSegmentIndex:[[[optionsArray objectAtIndex:0] objectForKey:@"skin"] intValue]]; + [switchScaling setOn:[[[optionsArray objectAtIndex:0] objectForKey:@"scaling"] intValue] animated:NO]; + [switchAutosave setOn:[[[optionsArray objectAtIndex:0] objectForKey:@"autosave"] intValue] animated:NO]; + [switchSmoothScaling setOn:[[[optionsArray objectAtIndex:0] objectForKey:@"smoothscaling"] intValue] animated:NO]; + [switchCompatibility setOn:[[[optionsArray objectAtIndex:0] objectForKey:@"compatibility"] intValue] animated:NO]; + [switchFramerate setOn:[[[optionsArray objectAtIndex:0] objectForKey:@"framerate"] intValue] animated:NO]; + [switchSpeedHack setOn:[[[optionsArray objectAtIndex:0] objectForKey:@"speedhack"] intValue] animated:NO]; + + [self optionChanged:self]; + } +} + +@end diff --git a/Classes/RecentController.h b/Classes/RecentController.h new file mode 100755 index 0000000..9636c4d --- /dev/null +++ b/Classes/RecentController.h @@ -0,0 +1,19 @@ +#import + +@interface RecentController : UIViewController < UITableViewDataSource, UITableViewDelegate > { + IBOutlet UITableView * tableview; + IBOutlet UITabBar * tabBar; + IBOutlet UITextField * textBookmark; + IBOutlet UIWindow * window; + NSMutableArray * recentArray; +#ifdef WITH_ADS + AltAds* altAds; +#endif + NSUInteger adNotReceived; +} + +- (void)getRecent; +- (void)addRecent:(NSString*)thisPath; +- (NSString*)getDocumentsDirectory; + +@end diff --git a/Classes/RecentController.m b/Classes/RecentController.m new file mode 100755 index 0000000..12b47e5 --- /dev/null +++ b/Classes/RecentController.m @@ -0,0 +1,256 @@ +#import "SOApplication.h" + + +@implementation RecentController + +- (void)dealloc { + [ super dealloc ]; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + self.navigationItem.hidesBackButton = YES; +} + +-(void)awakeFromNib +{ + self.navigationItem.hidesBackButton = YES; + + // always put any sort of initializations in here. They will only be called once. + adNotReceived = 0; + + [self getRecent]; +} + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + self.navigationItem.hidesBackButton = YES; +} + +- (void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; +} + +- (void)viewWillDisappear:(BOOL)animated { +} + +- (void)viewDidDisappear:(BOOL)animated { +} + +- (void)didReceiveMemoryWarning { + [super didReceiveMemoryWarning]; +} + +- (NSString*)getDocumentsDirectory +{ +#ifdef APPSTORE_BUILD + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); + NSString *documentsDirectory = [paths objectAtIndex: 0]; + return documentsDirectory; +#else + return @"/Applications/snes4iphone.app"; +#endif +} + +- (void)addRecent:(NSString*)thisPath { + if(thisPath) + { + [recentArray addObject:[NSDictionary dictionaryWithObjectsAndKeys: + thisPath, @"path", + nil]]; + if([recentArray count] > 7) + { + [recentArray removeObjectAtIndex:1]; + } + [tableview reloadData]; + + } + else + { + return; + } + + NSString *path=[[self getDocumentsDirectory] stringByAppendingPathComponent:@"recent.bin"]; + NSData *plistData; + + NSString *error; + + + + plistData = [NSPropertyListSerialization dataFromPropertyList:recentArray + + format:NSPropertyListBinaryFormat_v1_0 + + errorDescription:&error]; + + if(plistData) + + { + + NSLog(@"No error creating plist data."); + + [plistData writeToFile:path atomically:NO]; + + } + else + { + + NSLog(error); + + [error release]; + + } +} + +- (void)getRecent { + NSString *path=[[self getDocumentsDirectory] stringByAppendingPathComponent:@"recent.bin"]; + + NSData *plistData; + id plist; + NSString *error; + + NSPropertyListFormat format; + + plistData = [NSData dataWithContentsOfFile:path]; + + + + plist = [NSPropertyListSerialization propertyListFromData:plistData + + mutabilityOption:NSPropertyListImmutable + + format:&format + + errorDescription:&error]; + + if(!plist) + { + + NSLog(error); + + [error release]; + + recentArray = [[NSMutableArray alloc] init]; + } + else + { + recentArray = [[NSMutableArray alloc] initWithArray:plist]; + } +} + +// *** Tablesource stuffs. +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + // Number of sections is the number of region dictionaries +#ifdef WITH_ADS + if(recentArray==nil) { + return 1; + } else { + return 2; + } +#else + return 1; +#endif +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + if(recentArray==nil) { + return 1; + } + +#ifdef WITH_ADS + if(section < 1) + { + return 1; + } +#endif + return [recentArray count]; +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { +#ifdef WITH_ADS + if(indexPath.section < 1) { + return 55.0; // this is the height of the ad + } +#endif + return 44.0; // this is the generic cell height +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + UITableViewCell *cell; +#ifdef WITH_ADS + if(indexPath.section < 1) + { + cell = [tableview dequeueReusableCellWithIdentifier:@"adCell"]; + /* + if(cell != nil) + { + [cell release]; + cell = nil; + } + */ + if(cell == nil) + { + cell = [[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:@"adCell"]; + // Request an ad for this table view cell + altAds = [SOApp.delegate getAdViewWithIndex:2]; + [cell.contentView addSubview:altAds]; + } + else + { + altAds = [SOApp.delegate getAdViewWithIndex:2]; + [cell.contentView addSubview:altAds]; + } + + cell.text = @""; + } + else +#endif + { + cell = [tableview dequeueReusableCellWithIdentifier:@"cell"]; + if (cell == nil) + { + cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:@"cell"] autorelease]; + UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 44)]; + label.numberOfLines = 1; + label.adjustsFontSizeToFitWidth = YES; + label.minimumFontSize = 9.0f; + label.lineBreakMode = UILineBreakModeMiddleTruncation; + label.tag = 1; + [cell.contentView addSubview:label]; + [label release]; + } + cell.accessoryType = UITableViewCellAccessoryNone; + if([[[recentArray objectAtIndex:indexPath.row] objectForKey:@"path"] compare:@""] != NSOrderedSame) + { + UILabel* tempLabel = (UILabel *)[cell viewWithTag:1]; + tempLabel.text = [[[recentArray objectAtIndex:indexPath.row] objectForKey:@"path"] lastPathComponent]; + } + } + + // Set up the cell + return cell; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { +#ifdef WITH_ADS + if( indexPath.section < 1 ) + { + return; + } +#endif + + [tableview deselectRowAtIndexPath:indexPath animated:YES]; + + char *cListingsPath; + if([[[recentArray objectAtIndex:indexPath.row] objectForKey:@"path"] compare:@""] != NSOrderedSame ) + { + cListingsPath = (char*)[[[recentArray objectAtIndex:indexPath.row] objectForKey:@"path"] UTF8String]; + } + + + [SOApp.nowPlayingView startEmu:cListingsPath]; + [SOApp.delegate switchToNowPlaying]; + //[tabBar didMoveToWindowNowPlaying]; +} + +@end \ No newline at end of file diff --git a/Classes/RomController.h b/Classes/RomController.h new file mode 100755 index 0000000..08bd90d --- /dev/null +++ b/Classes/RomController.h @@ -0,0 +1,24 @@ +#import + +extern void *app_Thread_Start(void *args); + +@interface RomController : UIViewController < UITableViewDataSource, UITableViewDelegate > { + NSMutableArray* arrayOfCharacters; + NSMutableDictionary* objectsForCharacters; + IBOutlet UITableView* tableview; + IBOutlet UIWindow* window; + IBOutlet UITabBar* tabBar; + IBOutlet UISearchBar* searchBar; +#ifdef WITH_ADS + AltAds* altAds; +#endif + NSUInteger adNotReceived; + NSString* currentPath; + NSArray* alphabetIndex; +} + +- (void)refreshData:(NSString*)path; +- (void)initRootData; +- (void)startRootData:(float)secs; + +@end diff --git a/Classes/RomController.m b/Classes/RomController.m new file mode 100755 index 0000000..7126733 --- /dev/null +++ b/Classes/RomController.m @@ -0,0 +1,405 @@ +#import "SOApplication.h" +#import + +/* Globals */ +int tArgc; +char** tArgv; +pthread_t main_tid; +volatile int __emulation_run = 0; +volatile int __emulation_saving = 0; +volatile int __emulation_paused = 0; + +#ifdef WITH_ADS +static const int section_offset = 1; +#else +static const int section_offset = 0; +#endif + +@implementation RomController + +- (void)awakeFromNib { + self.navigationItem.hidesBackButton = YES; + self.navigationItem.prompt = @"www.zodttd.com"; + + adNotReceived = 0; + arrayOfCharacters = [[NSMutableArray alloc] init]; + objectsForCharacters = [[NSMutableDictionary alloc] init]; + + alphabetIndex = [[NSArray arrayWithArray: + [@"A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|#" + componentsSeparatedByString:@"|"]] retain]; +} + +- (void)startRootData:(float)secs +{ + //[NSThread detachNewThreadSelector:@selector(initRootData) toTarget:self withObject:nil]; + + NSTimer* timer = [NSTimer scheduledTimerWithTimeInterval:secs + target:self + selector:@selector(initRootData) + userInfo:nil + repeats:NO]; +} + +- (void)initRootData +{ + //NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + + currentPath = [[NSString alloc] initWithCString:get_documents_path("")]; // initWithString:@"/var/mobile/Media/ROMs/GBA/"]; + [ self refreshData:currentPath ]; + + //[pool release]; +} + +- (void)refreshData:(NSString*)path +{ + NSString* prevPath; + [arrayOfCharacters removeAllObjects]; + [objectsForCharacters removeAllObjects]; + prevPath = [[NSString alloc] initWithString:path]; + [currentPath release]; + if([[prevPath substringWithRange:NSMakeRange([prevPath length]-1,1)] compare:@"/"] == NSOrderedSame) + { + currentPath = [[NSString alloc] initWithFormat:@"%@",prevPath]; + } + else + { + currentPath = [[NSString alloc] initWithFormat:@"%@/",prevPath]; + } + + int i; + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSArray* dirContents = [fileManager directoryContentsAtPath: currentPath]; + NSInteger entries = [dirContents count]; + int characterLUT[27]; + NSMutableArray* arrayOfIndexedFiles[27]; + + for(i = 0; i < 27; i++) + { + characterLUT[i] = 0; + arrayOfIndexedFiles[i] = [[NSMutableArray alloc] init]; + } + + for ( i = 0; i < entries; i++ ) + { + if( + ([[dirContents objectAtIndex: i] length] < 4) || + ( + [[[dirContents objectAtIndex: i ] substringWithRange:NSMakeRange([[dirContents objectAtIndex: i ] length]-4,4)] caseInsensitiveCompare:@".bin"] != NSOrderedSame && + [[[dirContents objectAtIndex: i ] substringWithRange:NSMakeRange([[dirContents objectAtIndex: i ] length]-4,4)] caseInsensitiveCompare:@".zip"] != NSOrderedSame && + [[[dirContents objectAtIndex: i ] substringWithRange:NSMakeRange([[dirContents objectAtIndex: i ] length]-4,4)] caseInsensitiveCompare:@".swc"] != NSOrderedSame && + [[[dirContents objectAtIndex: i ] substringWithRange:NSMakeRange([[dirContents objectAtIndex: i ] length]-4,4)] caseInsensitiveCompare:@".smc"] != NSOrderedSame + ) + ) + { + // Do nothing currently. + } + else + { + NSString* objectTitle = [dirContents objectAtIndex: i ]; + NSString* objectIndexer = [[objectTitle substringWithRange:NSMakeRange(0,1)] uppercaseString]; + NSUInteger objectIndex = [objectIndexer rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:@"ABCDEFGHIJKLMNOPQRSTUVWXYZ"]].location; + + if(objectIndex == NSNotFound) + { + objectIndex = 26; + } + else + { + char* objectLetter = [objectIndexer UTF8String]; + objectIndex = objectLetter[0] - 'A'; + if(objectIndex > 25) + { + objectIndex = 25; + } + } + + if(characterLUT[objectIndex] == 0) + { + characterLUT[objectIndex] = 1; + } + + [arrayOfIndexedFiles[objectIndex] addObject:[dirContents objectAtIndex:i]]; + } + } + + for(i = 0; i < 27; i++) + { + if(characterLUT[i] == 1) + { + NSString* characters = [NSString stringWithString:@"ABCDEFGHIJKLMNOPQRSTUVWXYZ#"]; + NSString* characterIndex = [characters substringWithRange:NSMakeRange(i,1)]; + [arrayOfCharacters addObject:characterIndex]; + [objectsForCharacters setObject:arrayOfIndexedFiles[i] forKey:characterIndex]; + } + [arrayOfIndexedFiles[i] release]; + } + + [tableview reloadData]; + + self.navigationItem.prompt = currentPath; + + [prevPath release]; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + UITableViewCell* cell; + NSMutableDictionary* objects; + + objects = objectsForCharacters; + +#ifdef WITH_ADS + if(indexPath.section < 1) + { + cell = [tableview dequeueReusableCellWithIdentifier:@"adCell"]; + /* + if(cell != nil) + { + [cell release]; + cell = nil; + } + */ + if(cell == nil) + { + cell = [[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:@"adCell"]; + // Request an ad for this table view cell + altAds = [SOApp.delegate getAdViewWithIndex:2]; + [cell.contentView addSubview:altAds]; + } + else + { + altAds = [SOApp.delegate getAdViewWithIndex:2]; + [cell.contentView addSubview:altAds]; + } + + cell.accessoryType = UITableViewCellAccessoryNone; + cell.text = @""; + } + else +#endif + { + cell = [tableview dequeueReusableCellWithIdentifier:@"labelCell"]; + if (cell == nil) + { + cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:@"labelCell"] autorelease]; + UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 44)]; + label.numberOfLines = 1; + label.adjustsFontSizeToFitWidth = YES; + label.minimumFontSize = 9.0f; + label.tag = 1; + label.lineBreakMode = UILineBreakModeMiddleTruncation; + [cell.contentView addSubview:label]; + [label release]; + } + + cell.accessoryType = UITableViewCellAccessoryNone; + + if([arrayOfCharacters count] <= 0) + { + cell.text = @""; + return cell; + } + + UILabel* tempLabel = (UILabel *)[cell viewWithTag:1]; + tempLabel.text = [[objects objectForKey:[arrayOfCharacters objectAtIndex:indexPath.section-section_offset]] objectAtIndex:indexPath.row]; + } + // Set up the cell + return cell; +} + + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ +#ifdef WITH_ADS + if( indexPath.section < 1 ) + { + return; + } +#endif + + if([arrayOfCharacters count] <= 0) + { + return; + } + + NSMutableDictionary* objects; + + [tableview deselectRowAtIndexPath:indexPath animated:YES]; + + objects = objectsForCharacters; + + NSMutableString *listingsPath = [[NSMutableString alloc] initWithCString:get_documents_path("")]; + if([[listingsPath substringWithRange:NSMakeRange([listingsPath length]-1,1)] compare:@"/"] == NSOrderedSame) + { + [listingsPath appendString:[[objects objectForKey:[arrayOfCharacters objectAtIndex:indexPath.section-section_offset]] objectAtIndex:indexPath.row]]; + } + else + { + [listingsPath stringByAppendingPathComponent:[[objects objectForKey:[arrayOfCharacters objectAtIndex:indexPath.section-section_offset]] objectAtIndex:indexPath.row]]; + } + + [SOApp.recentView addRecent:listingsPath]; + + char *cListingsPath = (char*)[listingsPath UTF8String]; + [SOApp.nowPlayingView startEmu:cListingsPath]; + + [SOApp.delegate switchToNowPlaying]; + + [listingsPath release]; +} + +// Override if you support editing the list +/* +- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { + + if (editingStyle == UITableViewCellEditingStyleDelete) { + // Delete the row from the data source + [tableview deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES]; + } + if (editingStyle == UITableViewCellEditingStyleInsert) { + // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view + } +} +*/ + + +// Override if you support conditional editing of the list +/* +- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { + // Return NO if you do not want the specified item to be editable. + return YES; +} +*/ + +// Override if you support rearranging the list +/* +- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath { +} +*/ + +// Override if you support conditional rearranging of the list +/* +- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath { + // Return NO if you do not want the item to be re-orderable. + return YES; +} +*/ + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; +} + +- (void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; +} + +- (void)viewWillDisappear:(BOOL)animated { +} + +- (void)viewDidDisappear:(BOOL)animated { +} + + +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { + // Return YES for supported orientations + return NO; //YES; //(interfaceOrientation == UIInterfaceOrientationPortrait); +} + + +- (void)didReceiveMemoryWarning { + [super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview + // Release anything that's not essential, such as cached data +} + + +- (void)dealloc { + [currentPath release]; + [arrayOfCharacters release]; + [objectsForCharacters release]; + [alphabetIndex release]; + [super dealloc]; +} + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { +#ifdef WITH_ADS + if([arrayOfCharacters count] <= 0) + { + return 1; + } + return [arrayOfCharacters count] + 1; +#else + if([arrayOfCharacters count] <= 0) + { + return 1; + } + return [arrayOfCharacters count]; +#endif +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { +#ifdef WITH_ADS + if(section < 1) + { + return 1; + } +#endif + + if([arrayOfCharacters count] <= 0) + { + return 0; + } + + NSMutableDictionary* objects; + + objects = objectsForCharacters; + + return [[objects objectForKey:[arrayOfCharacters objectAtIndex:section-section_offset]] count]; +} + + +- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section +{ +#ifdef WITH_ADS + if(section < 1) + { + return @""; + } +#endif + + if([arrayOfCharacters count] <= 0) + return @""; + + return [arrayOfCharacters objectAtIndex:section-section_offset]; +} + +- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView +{ + return alphabetIndex; +} + + +- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index { + NSInteger count = 0; + + for(NSString *character in arrayOfCharacters) + { + if([character isEqualToString:title]) + return count; + count++; + } + + return 0; // in case of some eror donot crash d application +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { +#ifdef WITH_ADS + if(indexPath.section < 1) { + return 55.0; // this is the height of the ad + } +#endif + return 44.0; // this is the generic cell height +} + +@end + diff --git a/Classes/SOApplication.h b/Classes/SOApplication.h new file mode 100755 index 0000000..4c82b90 --- /dev/null +++ b/Classes/SOApplication.h @@ -0,0 +1,30 @@ +#import +#import +#import "CoreSurface/CoreSurface.h" +#import "helpers.h" +#import "TabBar.h" +#import "AltAds.h" +#import "RomController.h" +#import "ShoutOutAppDelegate.h" +#import "NowPlayingController.h" +#import "SaveStatesController.h" +#import "RecentController.h" +#import "OptionsController.h" + +#define SOApp ((SOApplication *)[UIApplication sharedApplication]) +@interface SOApplication : UIApplication +{ + IBOutlet RomController * romView; + IBOutlet NowPlayingController * nowPlayingView; + IBOutlet SaveStatesController * saveStatesView; + IBOutlet RecentController * recentView; + IBOutlet OptionsController * optionsView; +} + +@property(assign) RomController * romView; +@property(assign) NowPlayingController * nowPlayingView; +@property(assign) SaveStatesController * saveStatesView; +@property(assign) RecentController * recentView; +@property(assign) OptionsController * optionsView; + +@end diff --git a/Classes/SOApplication.m b/Classes/SOApplication.m new file mode 100755 index 0000000..3aef900 --- /dev/null +++ b/Classes/SOApplication.m @@ -0,0 +1,9 @@ +#import "SOApplication.h" + +@implementation SOApplication +@synthesize romView; +@synthesize nowPlayingView; +@synthesize saveStatesView; +@synthesize recentView; +@synthesize optionsView; +@end diff --git a/Classes/SaveStatesController.h b/Classes/SaveStatesController.h new file mode 100755 index 0000000..c67f37c --- /dev/null +++ b/Classes/SaveStatesController.h @@ -0,0 +1,22 @@ +#import + +@interface SaveStatesController : UIViewController < UITableViewDataSource, UITableViewDelegate > { + NSMutableArray* arrayOfCharacters; + NSMutableDictionary* objectsForCharacters; + IBOutlet UITableView* tableview; + IBOutlet UIWindow* window; + IBOutlet UITabBar* tabBar; + IBOutlet UISearchBar* searchBar; +#ifdef WITH_ADS + AltAds* altAds; +#endif + NSUInteger adNotReceived; + NSString* currentPath; + NSArray* alphabetIndex; +} + +- (void)refreshData:(NSString*)path; +- (void)initSaveData; +- (void)startSaveData:(float)secs; + +@end diff --git a/Classes/SaveStatesController.m b/Classes/SaveStatesController.m new file mode 100755 index 0000000..5aac5f9 --- /dev/null +++ b/Classes/SaveStatesController.m @@ -0,0 +1,387 @@ +#import "SOApplication.h" + +#ifdef WITH_ADS +static const int section_offset = 1; +#else +static const int section_offset = 0; +#endif + +@implementation SaveStatesController + +- (void)awakeFromNib { + self.navigationItem.hidesBackButton = YES; + self.navigationItem.prompt = @"www.zodttd.com"; + + adNotReceived = 0; + arrayOfCharacters = [[NSMutableArray alloc] init]; + objectsForCharacters = [[NSMutableDictionary alloc] init]; + + alphabetIndex = [[NSArray arrayWithArray: + [@"A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z|#" + componentsSeparatedByString:@"|"]] retain]; +} + +- (void)startSaveData:(float)secs +{ + //[NSThread detachNewThreadSelector:@selector(initRootData) toTarget:self withObject:nil]; + + NSTimer* timer = [NSTimer scheduledTimerWithTimeInterval:secs + target:self + selector:@selector(initSaveData) + userInfo:nil + repeats:NO]; +} + +- (void)initSaveData +{ + //NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + + currentPath = [[NSString alloc] initWithCString:get_documents_path("")]; + [ self refreshData:currentPath ]; + + //[pool release]; +} + +- (void)refreshData:(NSString*)path +{ + NSString* prevPath; + [arrayOfCharacters removeAllObjects]; + [objectsForCharacters removeAllObjects]; + prevPath = [[NSString alloc] initWithString:path]; + [currentPath release]; + if([[prevPath substringWithRange:NSMakeRange([prevPath length]-1,1)] compare:@"/"] == NSOrderedSame) + { + currentPath = [[NSString alloc] initWithFormat:@"%@",prevPath]; + } + else + { + currentPath = [[NSString alloc] initWithFormat:@"%@/",prevPath]; + } + + int i; + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSArray* dirContents = [fileManager directoryContentsAtPath: currentPath]; + NSInteger entries = [dirContents count]; + int characterLUT[27]; + NSMutableArray* arrayOfIndexedFiles[27]; + + for(i = 0; i < 27; i++) + { + characterLUT[i] = 0; + arrayOfIndexedFiles[i] = [[NSMutableArray alloc] init]; + } + + for ( i = 0; i < entries; i++ ) + { + if(([[dirContents objectAtIndex: i] length] < 4) || + [[[dirContents objectAtIndex: i ] substringWithRange:NSMakeRange([[dirContents objectAtIndex: i ] length]-3,3)] caseInsensitiveCompare:@".sv"] != NSOrderedSame) + { + // Do nothing currently. + } + else + { + NSString* objectTitle = [dirContents objectAtIndex: i ]; + NSString* objectIndexer = [[objectTitle substringWithRange:NSMakeRange(0,1)] uppercaseString]; + NSUInteger objectIndex = [objectIndexer rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:@"ABCDEFGHIJKLMNOPQRSTUVWXYZ"]].location; + + if(objectIndex == NSNotFound) + { + objectIndex = 26; + } + else + { + char* objectLetter = [objectIndexer UTF8String]; + objectIndex = objectLetter[0] - 'A'; + if(objectIndex > 25) + { + objectIndex = 25; + } + } + + if(characterLUT[objectIndex] == 0) + { + characterLUT[objectIndex] = 1; + } + + [arrayOfIndexedFiles[objectIndex] addObject:[dirContents objectAtIndex:i]]; + } + } + + for(i = 0; i < 27; i++) + { + if(characterLUT[i] == 1) + { + NSString* characters = [NSString stringWithString:@"ABCDEFGHIJKLMNOPQRSTUVWXYZ#"]; + NSString* characterIndex = [characters substringWithRange:NSMakeRange(i,1)]; + [arrayOfCharacters addObject:characterIndex]; + [objectsForCharacters setObject:arrayOfIndexedFiles[i] forKey:characterIndex]; + } + [arrayOfIndexedFiles[i] release]; + } + + [tableview reloadData]; + + self.navigationItem.prompt = currentPath; + + [prevPath release]; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + UITableViewCell* cell; + NSMutableDictionary* objects; + + objects = objectsForCharacters; + +#ifdef WITH_ADS + if(indexPath.section < 1) + { + cell = [tableview dequeueReusableCellWithIdentifier:@"adCell"]; + /* + if(cell != nil) + { + [cell release]; + cell = nil; + } + */ + if(cell == nil) + { + cell = [[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:@"adCell"]; + // Request an ad for this table view cell + altAds = [SOApp.delegate getAdViewWithIndex:2]; + [cell.contentView addSubview:altAds]; + } + else + { + altAds = [SOApp.delegate getAdViewWithIndex:2]; + [cell.contentView addSubview:altAds]; + } + + cell.accessoryType = UITableViewCellAccessoryNone; + cell.text = @""; + } + else +#endif + { + cell = [tableview dequeueReusableCellWithIdentifier:@"labelCell"]; + if (cell == nil) + { + cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:@"labelCell"] autorelease]; + UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 44)]; + label.numberOfLines = 1; + label.adjustsFontSizeToFitWidth = YES; + label.minimumFontSize = 9.0f; + label.lineBreakMode = UILineBreakModeMiddleTruncation; + label.tag = 1; + [cell.contentView addSubview:label]; + [label release]; + } + + cell.accessoryType = UITableViewCellAccessoryNone; + + if([arrayOfCharacters count] <= 0) + { + cell.text = @""; + return cell; + } + + UILabel* tempLabel = (UILabel *)[cell viewWithTag:1]; + tempLabel.text = [[objects objectForKey:[arrayOfCharacters objectAtIndex:indexPath.section-section_offset]] objectAtIndex:indexPath.row]; + } + // Set up the cell + return cell; +} + + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ +#ifdef WITH_ADS + if( indexPath.section < 1 ) + { + return; + } +#endif + + if([arrayOfCharacters count] <= 0) + { + return; + } + + NSMutableDictionary* objects; + + [tableview deselectRowAtIndexPath:indexPath animated:YES]; + + objects = objectsForCharacters; + + NSMutableString *listingsPath = [[NSMutableString alloc] initWithCString:get_documents_path("")]; + if([[listingsPath substringWithRange:NSMakeRange([listingsPath length]-1,1)] compare:@"/"] == NSOrderedSame) + { + [listingsPath appendString:[[objects objectForKey:[arrayOfCharacters objectAtIndex:indexPath.section-section_offset]] objectAtIndex:indexPath.row]]; + } + else + { + [listingsPath stringByAppendingPathComponent:[[objects objectForKey:[arrayOfCharacters objectAtIndex:indexPath.section-section_offset]] objectAtIndex:indexPath.row]]; + } + + [SOApp.recentView addRecent:listingsPath]; + + char *cListingsPath = (char*)[listingsPath UTF8String]; + [SOApp.nowPlayingView startEmu:cListingsPath]; + + [SOApp.delegate switchToNowPlaying]; + + [listingsPath release]; +} + +// Override if you support editing the list +/* +- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { + + if (editingStyle == UITableViewCellEditingStyleDelete) { + // Delete the row from the data source + [tableview deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES]; + } + if (editingStyle == UITableViewCellEditingStyleInsert) { + // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view + } +} +*/ + + +// Override if you support conditional editing of the list +/* +- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { + // Return NO if you do not want the specified item to be editable. + return YES; +} +*/ + +// Override if you support rearranging the list +/* +- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath { +} +*/ + +// Override if you support conditional rearranging of the list +/* +- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath { + // Return NO if you do not want the item to be re-orderable. + return YES; +} +*/ + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; +} + +- (void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; +} + +- (void)viewWillDisappear:(BOOL)animated { +} + +- (void)viewDidDisappear:(BOOL)animated { +} + + +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { + // Return YES for supported orientations + return NO; //YES; //(interfaceOrientation == UIInterfaceOrientationPortrait); +} + + +- (void)didReceiveMemoryWarning { + [super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview + // Release anything that's not essential, such as cached data +} + + +- (void)dealloc { + [currentPath release]; + [arrayOfCharacters release]; + [objectsForCharacters release]; + [alphabetIndex release]; + [super dealloc]; +} + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { +#ifdef WITH_ADS + if([arrayOfCharacters count] <= 0) + { + return 1; + } + return [arrayOfCharacters count] + 1; +#else + if([arrayOfCharacters count] <= 0) + { + return 1; + } + return [arrayOfCharacters count]; +#endif +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { +#ifdef WITH_ADS + if(section < 1) + { + return 1; + } +#endif + + if([arrayOfCharacters count] <= 0) + { + return 0; + } + + NSMutableDictionary* objects; + + objects = objectsForCharacters; + + return [[objects objectForKey:[arrayOfCharacters objectAtIndex:section-section_offset]] count]; +} + + +- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section +{ +#ifdef WITH_ADS + if(section < 1) + { + return @""; + } +#endif + if([arrayOfCharacters count] <= 0) + return @""; + + return [arrayOfCharacters objectAtIndex:section-section_offset]; +} + +- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView +{ + return alphabetIndex; +} + + +- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index { + NSInteger count = 0; + + for(NSString *character in arrayOfCharacters) + { + if([character isEqualToString:title]) + return count; + count++; + } + + return 0; // in case of some eror donot crash d application +} + +- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { +#ifdef WITH_ADS + if(indexPath.section < 1) { + return 55.0; // this is the height of the ad + } +#endif + return 44.0; // this is the generic cell height +} + +@end diff --git a/Classes/ShoutOutAppDelegate.h b/Classes/ShoutOutAppDelegate.h new file mode 100755 index 0000000..327b5cf --- /dev/null +++ b/Classes/ShoutOutAppDelegate.h @@ -0,0 +1,38 @@ +// +// snes4iphone +// +// Created by Spookysoft on 9/6/08. +// Copyright Spookysoft 2008. All rights reserved. +// + +#import + +#define NUMBER_OF_AD_PAGES 4 + +@interface ShoutOutAppDelegate : NSObject { + + IBOutlet UIWindow* window; + IBOutlet UINavigationController* navigationController; + IBOutlet UITabBar* tabBar; +#ifdef WITH_ADS + AltAds* altAds[NUMBER_OF_AD_PAGES]; +#endif +} + +- (void)switchToBrowse; +- (void)switchToSaveStates; +//- (void)switchToBookmarks; +- (void)switchToNowPlaying; +- (void)switchToRecent; +- (void)switchToOptions; +#ifdef WITH_ADS +- (AltAds*)getAdViewWithIndex:(int)index; +- (void)pauseAdViews; +- (void)unpauseAdViews; +#endif + +@property (nonatomic, retain) UIWindow *window; +@property (nonatomic, retain) UINavigationController *navigationController; + +@end + diff --git a/Classes/ShoutOutAppDelegate.m b/Classes/ShoutOutAppDelegate.m new file mode 100755 index 0000000..1dfb291 --- /dev/null +++ b/Classes/ShoutOutAppDelegate.m @@ -0,0 +1,200 @@ +// +// snes4iphone +// +// Created by Spookysoft on 9/6/08. +// Copyright Spookysoft 2008. All rights reserved. +// + +#import "SOApplication.h" + +extern unsigned long gp2x_pad_status; + +@implementation ShoutOutAppDelegate + +@synthesize window; +@synthesize navigationController; + + +- (id)init { + if (self = [super init]) { + // + } + return self; +} + + +- (void)applicationDidFinishLaunching:(UIApplication *)application { + int i; + + [[UIApplication sharedApplication] setStatusBarHidden:NO animated:NO]; + [[UIApplication sharedApplication] setIdleTimerDisabled:YES]; + application.delegate = self; + +#ifdef WITH_ADS + //MainScreenWindow = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + //Blocked = [AltAds isAdBlockingEnabled]; + for(i = 0; i < NUMBER_OF_AD_PAGES; i++) + { + altAds[i] = [[AltAds alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 55.0f) andWindow:nil]; + } +#endif + + CGRect frame = window.frame; + frame.origin.y = window.frame.origin.y+window.frame.size.height-49; + frame.size.height = 49; + tabBar.frame = frame; + [window addSubview:tabBar]; + CGRect navFrame = [navigationController view].frame; + navFrame.origin.y = 20; + navFrame.size.height = 460 - 49; + [navigationController view].frame = navFrame; + +// tabBar.selectedItem = 0; + // Configure and show the window + //[SOApp.nowPlayingView startEmu:"/var/mobile/Media/ROMs/GBA/Pokemon - Emerald Version (U) [f1] (Save Type).gba"]; + //[window addSubview:[SOApp.nowPlayingView view]]; + //[window makeKeyAndVisible]; + + [window addSubview:[navigationController view]]; + + [window makeKeyAndVisible]; + + [self switchToBrowse]; + + // Load ROMs + [SOApp.romView startRootData:2.0f]; + + // Load Saves + [SOApp.saveStatesView startSaveData:4.0f]; +} + +#ifdef WITH_ADS +- (AltAds*)getAdViewWithIndex:(int)index { + if(index < NUMBER_OF_AD_PAGES) + { + return altAds[index]; + } + return altAds[0]; +} + +- (void)pauseAdViews { + int i; + + for(i = 0; i < NUMBER_OF_AD_PAGES; i++) + { + [altAds[i] stopAdTimers]; + } +} + +- (void)unpauseAdViews { + int i; + + for(i = 0; i < NUMBER_OF_AD_PAGES; i++) + { + [altAds[i] RefreshAd]; + } +} +#endif + +#pragma mark TabBar Actions +- (void)switchToBrowse { + [[UIApplication sharedApplication] setStatusBarHidden:NO animated:NO]; + [tabBar setHidden:NO]; + CGRect navFrame = [navigationController view].frame; + navFrame.origin.y = 20; + navFrame.size.height = 460 - 49; + [navigationController view].frame = navFrame; + navigationController.navigationBarHidden = FALSE; + navigationController.navigationBar.hidden = FALSE; + + if ([[[self navigationController] viewControllers] containsObject:SOApp.romView]) { + [[self navigationController] popToViewController:SOApp.romView animated:NO]; + } else { + [[self navigationController] pushViewController:SOApp.romView animated:NO]; + } +} +- (void)switchToSaveStates { + [[UIApplication sharedApplication] setStatusBarHidden:NO animated:NO]; + [tabBar setHidden:NO]; + CGRect navFrame = [navigationController view].frame; + navFrame.origin.y = 20; + navFrame.size.height = 460 - 49; + [navigationController view].frame = navFrame; + navigationController.navigationBarHidden = FALSE; + navigationController.navigationBar.hidden = FALSE; + + if ([[[self navigationController] viewControllers] containsObject:SOApp.saveStatesView]) { + [[self navigationController] popToViewController:SOApp.saveStatesView animated:NO]; + } else { + [[self navigationController] pushViewController:SOApp.saveStatesView animated:NO]; + } +} +- (void)switchToNowPlaying { + [[UIApplication sharedApplication] setStatusBarHidden:YES animated:NO]; + [tabBar setHidden:YES]; + CGRect navFrame = [navigationController view].frame; + navFrame.origin.y = 0; + navFrame.size.height = 480; + [navigationController view].frame = navFrame; + navigationController.navigationBarHidden = TRUE; + navigationController.navigationBar.hidden = TRUE; + + gp2x_pad_status = 0; + + if ([[[self navigationController] viewControllers] containsObject:SOApp.nowPlayingView]) { + [[self navigationController] popToViewController:SOApp.nowPlayingView animated:NO]; + } else { + [[self navigationController] pushViewController:SOApp.nowPlayingView animated:NO]; + } +} +- (void)switchToRecent { + [[UIApplication sharedApplication] setStatusBarHidden:NO animated:NO]; + [tabBar setHidden:NO]; + CGRect navFrame = [navigationController view].frame; + navFrame.origin.y = 20; + navFrame.size.height = 460 - 49; + [navigationController view].frame = navFrame; + navigationController.navigationBarHidden = FALSE; + navigationController.navigationBar.hidden = FALSE; + + if ([[[self navigationController] viewControllers] containsObject:SOApp.recentView]) { + [[self navigationController] popToViewController:SOApp.recentView animated:NO]; + } else { + [[self navigationController] pushViewController:SOApp.recentView animated:NO]; + } +} +- (void)switchToOptions { + [[UIApplication sharedApplication] setStatusBarHidden:NO animated:NO]; + [tabBar setHidden:NO]; + CGRect navFrame = [navigationController view].frame; + navFrame.origin.y = 20; + navFrame.size.height = 460 - 49; + [navigationController view].frame = navFrame; + navigationController.navigationBarHidden = FALSE; + navigationController.navigationBar.hidden = FALSE; + + if ([[[self navigationController] viewControllers] containsObject:SOApp.optionsView]) { + [[self navigationController] popToViewController:SOApp.optionsView animated:NO]; + } else { + [[self navigationController] pushViewController:SOApp.optionsView animated:NO]; + } +} + +- (void)applicationWillTerminate:(UIApplication *)application { +} + +- (void)dealloc { +#ifdef WITH_ADS + int i; + for(i = 0; i < NUMBER_OF_AD_PAGES; i++) + { + [altAds[i] release]; + } +#endif + + [ navigationController release ]; + [ window release ]; + [ super dealloc ]; +} + +@end diff --git a/Classes/TabBar.h b/Classes/TabBar.h new file mode 100755 index 0000000..b2a98b7 --- /dev/null +++ b/Classes/TabBar.h @@ -0,0 +1,7 @@ +@interface TabBar : UITabBar {} +-(void)resetButton; +-(void)didMoveToWindow; +//-(void)didMoveToWindowNowPlaying; +//-(void)didMoveToWindowBookmarks; +-(void)didMoveToWindowSaveStates; +@end diff --git a/Classes/TabBar.m b/Classes/TabBar.m new file mode 100755 index 0000000..6c3f935 --- /dev/null +++ b/Classes/TabBar.m @@ -0,0 +1,69 @@ +#import "SOApplication.h" + +BOOL blocking = NO; + +@implementation TabBar + +-(void)resetButton +{ + blocking = YES; + + [self setSelectedItem:[self.items objectAtIndex:0]]; +} + +- (void)didMoveToWindow +{ + [self setSelectedItem:[self.items objectAtIndex:0]]; +} + +/* +- (void)didMoveToWindowNowPlaying +{ + [self setSelectedItem:[self.items objectAtIndex:3]]; +} +*/ + +/* +- (void)didMoveToWindowBookmarks +{ + [self setSelectedItem:[self.items objectAtIndex:1]]; +} +*/ + +- (void)didMoveToWindowSaveStates +{ + [self setSelectedItem:[self.items objectAtIndex:2]]; +} + +- (void)setSelectedItem:(id)item { + [super setSelectedItem:item]; + int itemIndex = [self.items indexOfObject:self.selectedItem]; + + if (!blocking) + { + if (itemIndex == 0) + { + [SOApp.delegate switchToBrowse]; + } + else if (itemIndex == 1) + { + [SOApp.delegate switchToRecent]; + } + else if (itemIndex == 2) + { + [SOApp.delegate switchToSaveStates]; + } + else + { + [SOApp.delegate switchToOptions]; + } + } + blocking = NO; +} + +- (void)dealloc { + [super dealloc]; +} + + +@end diff --git a/Classes/helpers.h b/Classes/helpers.h new file mode 100755 index 0000000..571bc51 --- /dev/null +++ b/Classes/helpers.h @@ -0,0 +1,3 @@ + +extern const char* get_resource_path(char* file); +extern const char* get_documents_path(char* file); diff --git a/Classes/helpers.m b/Classes/helpers.m new file mode 100755 index 0000000..8235479 --- /dev/null +++ b/Classes/helpers.m @@ -0,0 +1,27 @@ +#import + +const char* get_resource_path(char* file) +{ + static char resource_path[1024]; +#ifdef APPSTORE_BUILD + const char* path = [[[NSBundle mainBundle] resourcePath] UTF8String]; + sprintf(resource_path, "%s/%s", path, file); +#else + sprintf(resource_path, "/Applications/snes4iphone.app/%s", file); +#endif + return resource_path; +} + +const char* get_documents_path(char* file) +{ + static char documents_path[1024]; +#ifdef APPSTORE_BUILD + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); + NSString *documentsDirectory = [paths objectAtIndex: 0]; + const char* path = [documentsDirectory UTF8String]; + sprintf(documents_path, "%s/%s", path, file); +#else + sprintf(documents_path, "/var/mobile/Media/ROMs/SNES/%s", file); +#endif + return documents_path; +} diff --git a/MainWindow.xib b/MainWindow.xib new file mode 100755 index 0000000..2222b3d --- /dev/null +++ b/MainWindow.xib @@ -0,0 +1,1578 @@ + + + + 512 + 9L30 + 677 + 949.54 + 353.00 + + YES + + + + + + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + + 1316 + + {320, 480} + + + 1 + MSAxIDEAA + + NO + + + + + + 1 + NO + + + 2 + + + + 256 + {{0, -44}, {0, 44}} + NO + YES + YES + 1 + + YES + + + + YES + + + + + + 274 + + YES + + + 274 + {320, 387} + + + NO + YES + NO + NO + 1 + 0 + YES + 4.400000e+01 + 2.700000e+01 + 2.700000e+01 + + + {320, 387} + + + 1 + MCAwIDAAA + + NO + + + + Save States + + + + 1 + NO + + + + + + 274 + + YES + + + 274 + {320, 387} + + + NO + YES + NO + NO + 1 + 0 + YES + 4.400000e+01 + 2.700000e+01 + 2.700000e+01 + + + {320, 387} + + + NO + + + + snes4iphone + + + + 1 + NO + + + + + + 274 + + YES + + + 274 + {320, 387} + + + NO + YES + NO + NO + 1 + 0 + YES + 4.400000e+01 + 2.700000e+01 + 2.700000e+01 + + + {320, 387} + + NO + + + Recent + + + + 1 + NO + + + + + + 274 + {{0, -49}, {320, 485}} + + + NO + + + + 1 + NO + + + + + + 274 + + YES + + + 292 + {{18, 124}, {141, 21}} + + NO + YES + NO + Autosave + + 1 + MSAxIDEAA + + 1 + + + + 1 + 1.000000e+01 + + + + 292 + {{18, 82}, {141, 21}} + + NO + YES + NO + Scaling + + 1 + MSAxIDEAA + + + + 1 + 1.000000e+01 + + + + 292 + {{18, 166}, {189, 21}} + + NO + YES + NO + Smooth Scaling + + 1 + MSAxIDEAA + + + + 1 + 1.000000e+01 + + + + 292 + {{20, 37}, {141, 21}} + + NO + YES + NO + Skin + + 1 + MSAxIDEAA + + + + 1 + 1.000000e+01 + + + + 292 + {{18, 208}, {144, 21}} + + NO + YES + NO + Framerate Counter + + 1 + MSAxIDEAA + + + + 1 + 1.000000e+01 + + + + 292 + {{105, 37}, {207, 30}} + + NO + NO + 2 + 5 + 0 + + YES + 1 + 2 + 3 + 4 + 5 + + + YES + + + + + + + + YES + + + + + + + + YES + {0, 0} + {0, 0} + {0, 0} + {0, 0} + {0, 0} + + + YES + + + + + + + + + + 292 + {{218, 82}, {94, 27}} + + NO + YES + YES + 0 + 0 + YES + + + + 292 + {{218, 124}, {94, 27}} + + NO + YES + YES + 0 + 0 + + + + 292 + {{218, 166}, {94, 27}} + + NO + YES + YES + 0 + 0 + + + + 292 + {{218, 208}, {94, 27}} + + NO + YES + YES + 0 + 0 + + + + 292 + {{18, 248}, {146, 21}} + + NO + YES + NO + Transparencies On + + 1 + MSAxIDEAA + + + + 1 + 1.000000e+01 + + + + 292 + {{218, 248}, {94, 27}} + + NO + YES + YES + 0 + 0 + + + + 292 + {{18, 290}, {144, 21}} + + NO + YES + NO + Speed Hacks + + 1 + MSAxIDEAA + + + + 1 + 1.000000e+01 + + + + 292 + {{218, 290}, {94, 27}} + + NO + YES + YES + 0 + 0 + + + {320, 367} + + + NO + + + + 1 + NO + + + 2 + + + + + 266 + {320, 49} + + 3 + MCAwAA + + NO + + YES + + Browse + + NSImage + genres.png + + + + + Recent + + + + + Saves + + + + + Options + + + + + + + + 290 + {{0, 172}, {320, 44}} + NO + 3 + YES + + + + + 290 + {{598, 126}, {320, 44}} + NO + 3 + YES + + + + + + YES + + + delegate + + + + 4 + + + + window + + + + 5 + + + + navigationController + + + + 15 + + + + tabBar + + + + 49 + + + + nowPlayingView + + + + 113 + + + + tabBar + + + + 144 + + + + delegate + + + + 167 + + + + tableview + + + + 168 + + + + dataSource + + + + 170 + + + + recentView + + + + 173 + + + + delegate + + + + 183 + + + + dataSource + + + + 184 + + + + tableview + + + + 185 + + + + saveStatesView + + + + 225 + + + + optionsView + + + + 351 + + + + optionChanged: + + + 13 + + 364 + + + + optionChanged: + + + 13 + + 365 + + + + optionChanged: + + + 13 + + 366 + + + + optionChanged: + + + 13 + + 367 + + + + optionChanged: + + + 13 + + 368 + + + + segmentedSkin + + + + 369 + + + + switchScaling + + + + 370 + + + + switchAutosave + + + + 371 + + + + switchFramerate + + + + 373 + + + + screenView + + + + 375 + + + + delegate + + + + 380 + + + + searchBar + + + + 381 + + + + delegate + + + + 386 + + + + dataSource + + + + 387 + + + + tableview + + + + 388 + + + + delegate + + + + 390 + + + + searchBar + + + + 391 + + + + romView + + + + 392 + + + + switchSmoothScaling + + + + 393 + + + + switchCompatibility + + + + 398 + + + + switchSpeedHack + + + + 399 + + + + optionChanged: + + + 13 + + 400 + + + + optionChanged: + + + 13 + + 401 + + + + + YES + + 0 + + YES + + + + + + 2 + + + YES + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + 3 + + + + + -2 + + + + + 9 + + + YES + + + + + + 11 + + + YES + + + + + 37 + + + YES + + + + + + + + + 104 + + + + + 94 + + + YES + + + + NowPlaying Controller + + + 152 + + + + + 153 + + + + + 162 + + + YES + + + + + Recent Controller + + + 163 + + + YES + + + + + + 164 + + + + + 166 + + + + + 176 + + + YES + + + + + SaveStates Controller + + + 177 + + + YES + + + + + + 178 + + + + + 180 + + + + + 224 + + + + + 95 + + + YES + + + + + 350 + + + YES + + + + + + 352 + + + YES + + + + + + + + + + + + + + + + + + + 353 + + + + + 354 + + + + + 355 + + + + + 356 + + + + + 357 + + + + + 358 + + + + + 359 + + + + + 360 + + + + + 361 + + + + + 362 + + + + + 363 + + + + + 376 + + + + + 382 + + + YES + + + + + Rom Controller + + + 383 + + + + + 384 + + + YES + + + + + + 385 + + + + + 389 + + + + + 394 + + + + + 395 + + + + + 396 + + + + + 397 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 104.CustomClassName + 104.IBPluginDependency + 11.IBPluginDependency + 152.IBPluginDependency + 153.IBPluginDependency + 162.CustomClassName + 162.IBEditorWindowLastContentRect + 162.IBPluginDependency + 163.IBPluginDependency + 164.IBPluginDependency + 166.IBPluginDependency + 176.CustomClassName + 176.IBEditorWindowLastContentRect + 176.IBPluginDependency + 177.IBPluginDependency + 178.IBPluginDependency + 180.IBPluginDependency + 2.IBAttributePlaceholdersKey + 2.IBEditorWindowLastContentRect + 2.IBPluginDependency + 224.IBPluginDependency + 3.CustomClassName + 3.IBPluginDependency + 350.CustomClassName + 350.IBEditorWindowLastContentRect + 350.IBPluginDependency + 352.IBPluginDependency + 353.IBPluginDependency + 354.IBPluginDependency + 355.IBPluginDependency + 356.IBPluginDependency + 357.IBPluginDependency + 358.IBPluginDependency + 359.IBPluginDependency + 360.IBPluginDependency + 361.IBPluginDependency + 362.IBPluginDependency + 363.IBPluginDependency + 37.CustomClassName + 37.IBEditorWindowLastContentRect + 37.IBPluginDependency + 376.IBPluginDependency + 382.CustomClassName + 382.IBEditorWindowLastContentRect + 382.IBPluginDependency + 383.IBPluginDependency + 384.IBPluginDependency + 385.IBPluginDependency + 389.IBPluginDependency + 394.IBPluginDependency + 395.IBPluginDependency + 396.IBPluginDependency + 397.IBPluginDependency + 9.IBEditorWindowLastContentRect + 9.IBPluginDependency + 94.CustomClassName + 94.IBEditorWindowLastContentRect + 94.IBPluginDependency + 95.IBPluginDependency + + + YES + SOApplication + UIResponder + AdViewController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + RecentController + {{965, 593}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + SaveStatesController + {{421, 187}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + YES + + YES + + + YES + + + {{823, 144}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + ShoutOutAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + OptionsController + {{634, 241}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + TabBar + {{119, 266}, {320, 49}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + RomController + {{421, 187}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{1166, -4}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + NowPlayingController + {{1162, 218}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 401 + + + + YES + + NSObject + + IBUserSource + + + + + NowPlayingController + UIViewController + + YES + + YES + setSaveState: + volumeChanged: + + + YES + id + id + + + + YES + + YES + ButtonCIRCLE + ButtonCROSS + ButtonDOWN + ButtonDOWNLEFT + ButtonDOWNRIGHT + ButtonEXIT + ButtonL1 + ButtonL2 + ButtonLEFT + ButtonR1 + ButtonR2 + ButtonRIGHT + ButtonSELECT + ButtonSQUARE + ButtonSTART + ButtonTRIANGLE + ButtonUP + ButtonUPLEFT + ButtonUPRIGHT + screenView + tabBar + window + + + YES + UIButton + UIButton + UIButton + UIButton + UIButton + UIButton + UIButton + UIButton + UIButton + UIButton + UIButton + UIButton + UIButton + UIButton + UIButton + UIButton + UIButton + UIButton + UIButton + UIView + UITabBar + UIWindow + + + + IBProjectSource + NowPlayingController.h + + + + OptionsController + UIViewController + + optionChanged: + id + + + YES + + YES + segmentedSkin + switchAutosave + switchCompatibility + switchFramerate + switchScaling + switchSmoothScaling + switchSpeedHack + + + YES + UISegmentedControl + UISwitch + UISwitch + UISwitch + UISwitch + UISwitch + UISwitch + + + + IBProjectSource + Classes/OptionsController.h + + + + RecentController + UIViewController + + YES + + YES + tabBar + tableview + textBookmark + window + + + YES + UITabBar + UITableView + UITextField + UIWindow + + + + IBProjectSource + Classes/RecentController.h + + + + RomController + UIViewController + + YES + + YES + searchBar + tabBar + tableview + window + + + YES + UISearchBar + UITabBar + UITableView + UIWindow + + + + IBProjectSource + Classes/RomController.h + + + + SOApplication + UIApplication + + YES + + YES + nowPlayingView + optionsView + recentView + romView + saveStatesView + + + YES + NowPlayingController + OptionsController + RecentController + RomController + SaveStatesController + + + + IBProjectSource + Classes/SOApplication.h + + + + SaveStatesController + UIViewController + + YES + + YES + searchBar + tabBar + tableview + window + + + YES + UISearchBar + UITabBar + UITableView + UIWindow + + + + IBProjectSource + Classes/SaveStatesController.h + + + + ShoutOutAppDelegate + NSObject + + YES + + YES + navigationController + tabBar + window + + + YES + UINavigationController + UITabBar + UIWindow + + + + IBProjectSource + Classes/ShoutOutAppDelegate.h + + + + TabBar + UITabBar + + IBProjectSource + Classes/TabBar.h + + + + + 0 + app.xcodeproj + 3 + 3.0 + + diff --git a/NowPlayingController.h b/NowPlayingController.h new file mode 100755 index 0000000..77deb1c --- /dev/null +++ b/NowPlayingController.h @@ -0,0 +1,237 @@ +// +// NowPlayingController.h +// ShoutOut +// +// Created by ME on 9/13/08. +// Copyright 2008 __MyCompanyName__. All rights reserved. +// + +#import +//#import +//#import +#import +#import +#import + +#import +#import +#import +#import + +struct myGSPathPoint { + char unk0; + char unk1; + char unk2; + char unk3; + char unk4; + char unk5; + char status; + char unk7; + char unk8; + char unk9; + char unk10; + char unk11; + char unk12; + char unk13; + char unk14; + char unk15; + float x; + float y; +}; + +typedef struct { + char unk0; + char unk1; + char unk2; + char unk3; + char unk4; + char unk5; + char unk6; + char unk7; + + char unk8; + char unk9; + char unk10; + char unk11; + char unk12; + char unk13; + char unk14; + char unk15; + + char unk16; + char unk17; + char unk18; + char unk19; + char unk20; + char unk21; + char unk22; + char unk23; + + char unk24; + char unk25; + char unk26; + char unk27; + char unk28; + char unk29; + char unk30; + char unk31; + + char unk32; + char unk33; + char unk34; + char unk35; + char unk36; + char unk37; + char unk38; + char unk39; + + char unk40; + char unk41; + char unk42; + char unk43; + char unk44; + char unk45; + char unk46; + char unk47; + + char unk48; + char unk49; + char unk50; + char unk51; + char unk52; + char unk53; + char unk54; + char unk55; + + char type; + char unk57; + char unk58; + char unk59; + char unk60; + char unk61; + char fingerCount; + char unk62; + char unk63; + char unk64; + char unk65; + char unk66; + char unk67; + char unk68; + char unk69; + char unk70; + char unk71; + char unk72; + char unk73; + char unk74; + char unk75; + char unk76; + char unk77; + char unk78; + char unk79; + char unk80; + char unk81; + char unk82; + char unk83; + char unk84; + char unk85; + char unk86; + struct myGSPathPoint points[100]; +} myGSEvent; + +@interface ScreenView : UIView +{ + CoreSurfaceBufferRef _screenSurface; + CALayer * screenLayer; + NSTimer * timer; +} + +- (id)initWithFrame:(CGRect)frame; +- (void)drawRect:(CGRect)rect; +- (CoreSurfaceBufferRef)getSurface; +- (void)updateScreen; +- (void)dummy; + +@end + +@interface NowPlayingController : UIViewController +{ + //IBOutlet UISlider * volumeSlider; + IBOutlet UIView * screenView; + IBOutlet UITabBar * tabBar; + IBOutlet UIWindow * window; + IBOutlet UIButton * ButtonL1; + IBOutlet UIButton * ButtonL2; + IBOutlet UIButton * ButtonR1; + IBOutlet UIButton * ButtonR2; + IBOutlet UIButton * ButtonUP; + IBOutlet UIButton * ButtonDOWN; + IBOutlet UIButton * ButtonLEFT; + IBOutlet UIButton * ButtonRIGHT; + IBOutlet UIButton * ButtonSTART; + IBOutlet UIButton * ButtonSELECT; + IBOutlet UIButton * ButtonUPLEFT; + IBOutlet UIButton * ButtonUPRIGHT; + IBOutlet UIButton * ButtonDOWNLEFT; + IBOutlet UIButton * ButtonDOWNRIGHT; + //IBOutlet UIButton * ButtonSAVE; + //IBOutlet UIButton * ButtonBOOKMARK; + IBOutlet UIButton * ButtonTRIANGLE; + IBOutlet UIButton * ButtonSQUARE; + IBOutlet UIButton * ButtonCIRCLE; + IBOutlet UIButton * ButtonCROSS; + IBOutlet UIButton * ButtonEXIT; + NSString * currentId; + NSString * currentTunein; + NSString * currentTitle; + NSString * currentPath; + NSString * currentFile; + NSString * currentDir; + //ScreenView * screenView; + UIImageView * controllerImageView; + CGRect A; + CGRect B; + CGRect AB; + CGRect Up; + CGRect Left; + CGRect Down; + CGRect Right; + CGRect UpLeft; + CGRect DownLeft; + CGRect UpRight; + CGRect DownRight; + CGRect Select; + CGRect Start; + CGRect LPad; + CGRect RPad; + CGRect LPad2; + CGRect RPad2; + CGRect Menu; + CGRect ButtonUp; + CGRect ButtonLeft; + CGRect ButtonDown; + CGRect ButtonRight; + CGRect ButtonUpLeft; + CGRect ButtonDownLeft; + CGRect ButtonUpRight; + CGRect ButtonDownRight; + + CGPoint fingers[5]; + int numFingers; + + CoreSurfaceBufferRef _screenSurface; + CALayer * screenLayer; + NSTimer * timer; +} + +- (void)getControllerCoords:(int)orientation; +- (void)fixRects; +- (void)volumeChanged:(id)sender; +//- (void)setBookmark:(id)sender; +- (void)setSaveState:(id)sender; +- (void)startEmu:(char*)path; +- (void)runSound; +- (void)runProgram; +- (void)runMenu; +- (void)runMainMenu; + +@end diff --git a/NowPlayingController.m b/NowPlayingController.m new file mode 100755 index 0000000..834d765 --- /dev/null +++ b/NowPlayingController.m @@ -0,0 +1,1099 @@ +// +// NowPlayingController.m +// ShoutOut +// +// Created by ME on 9/13/08. +// Copyright 2008 __MyCompanyName__. All rights reserved. +// + +#import "SOApplication.h" +#import + +#define IPHONE_MENU_DISABLED 0 +#define IPHONE_MENU_MAIN 1 +#define IPHONE_MENU_SAVE_CURRENT 2 +#define IPHONE_MENU_SAVE_NEW 3 +#define IPHONE_MENU_QUIT_LOAD 4 +#define IPHONE_MENU_QUIT 5 +#define IPHONE_MENU_MAIN_LOAD 6 + +char romfile[1024]; +char* ourArgs[255]; +int ourArgsCnt = 0; +unsigned short* screenbuffer; +int iphone_touches = 0; +int iphone_menu = IPHONE_MENU_DISABLED; +long long iphone_last_upd_ticks = 0; +int iphone_controller_opacity = 100; +int iphone_is_landscape = 0; +int iphone_soundon = 0; +pthread_t sound_tid; +static unsigned long newtouches[10]; +static unsigned long oldtouches[10]; + +enum { GP2X_UP=0x1, GP2X_LEFT=0x4, GP2X_DOWN=0x10, GP2X_RIGHT=0x40, + GP2X_START=1<<8, GP2X_SELECT=1<<9, GP2X_L=1<<10, GP2X_R=1<<11, + GP2X_A=1<<12, GP2X_B=1<<13, GP2X_X=1<<14, GP2X_Y=1<<15, + GP2X_VOL_UP=1<<23, GP2X_VOL_DOWN=1<<22, GP2X_PUSH=1<<27 }; + +extern float __audioVolume; +extern volatile unsigned short BaseAddress[240*160]; +extern unsigned long gp2x_pad_status; +extern volatile int __emulation_run; +extern volatile int __emulation_saving; +extern volatile int __emulation_paused; +extern int tArgc; +extern char** tArgv; +extern pthread_t main_tid; +extern unsigned char gamepak_filename[512]; +extern char test_print_buffer[128]; +extern unsigned short* videobuffer; +extern unsigned char *vrambuffer; + +extern void save_state(char *savestate_filename, unsigned short *screen_capture); +extern void set_save_state(void); +extern int iphone_main(char* filename); + +static ScreenView *sharedInstance = nil; + +void updateScreen() +{ + //usleep(100); + //sched_yield(); + [sharedInstance performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:NO]; +} + +void* app_Thread_Start(void* args) +{ + __emulation_run = 1; + iphone_main(ourArgs[1]); +/* if(tArgv) + { + int i; + for(i = 0; i < tArgc; i++) + { + if(tArgv[i] != NULL) free(tArgv[i]); + } + free(tArgv); + tArgv = NULL; + } +*/ + __emulation_run = 0; + __emulation_saving = 0; + return NULL; +} + +@implementation ScreenView +- (id)initWithFrame:(CGRect)frame { + if ((self = [super initWithFrame:frame])!=nil) { + CFMutableDictionaryRef dict; + int w = 256; //rect.size.width; + int h = 224; //rect.size.height; + + int pitch = w * 2, allocSize = 2 * w * h; + char *pixelFormat = "565L"; + + self.opaque = YES; + self.clearsContextBeforeDrawing = NO; + self.userInteractionEnabled = NO; + self.multipleTouchEnabled = NO; + self.contentMode = UIViewContentModeTopLeft; + + if([SOApp.optionsView getCurrentSmoothScaling]) + { + [[self layer] setMagnificationFilter:kCAFilterLinear]; + [[self layer] setMinificationFilter:kCAFilterLinear]; + } + else + { + [[self layer] setMagnificationFilter:kCAFilterNearest]; + [[self layer] setMinificationFilter:kCAFilterNearest]; + } + dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, + &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFDictionarySetValue(dict, kCoreSurfaceBufferGlobal, kCFBooleanTrue); + CFDictionarySetValue(dict, kCoreSurfaceBufferMemoryRegion, + @"IOSurfaceMemoryRegion"); + CFDictionarySetValue(dict, kCoreSurfaceBufferPitch, + CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &pitch)); + CFDictionarySetValue(dict, kCoreSurfaceBufferWidth, + CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &w)); + CFDictionarySetValue(dict, kCoreSurfaceBufferHeight, + CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &h)); + CFDictionarySetValue(dict, kCoreSurfaceBufferPixelFormat, + CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, pixelFormat)); + CFDictionarySetValue(dict, kCoreSurfaceBufferAllocSize, + CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &allocSize)); + + _screenSurface = CoreSurfaceBufferCreate(dict); + CoreSurfaceBufferLock(_screenSurface, 3); + + //CALayer* screenLayer = [CALayer layer]; + screenLayer = [[CALayer layer] retain]; + /* + CGAffineTransform affineTransform = CGAffineTransformIdentity; + affineTransform = CGAffineTransformConcat( affineTransform, CGAffineTransformMakeRotation(90)); + self.transform = affineTransform; + */ + if(!iphone_is_landscape) + { + if([SOApp.optionsView getCurrentScaling]) + { + screenLayer.frame = CGRectMake(23.0f, 0.0f, 274.0f, 240.0f); + [ screenLayer setOpaque: YES ]; + } + else + { + screenLayer.frame = CGRectMake(32.0f, 8.0f, 258.0f, 226.0f); + [ screenLayer setOpaque: YES ]; + } + } + else + { + if([SOApp.optionsView getCurrentScaling]) + { + CGAffineTransform transform = CGAffineTransformMakeRotation(3.0 * M_PI / 2.0f); // = CGAffineTransformMakeTranslation(1.0, 1.0); + [screenLayer setAffineTransform:transform]; + screenLayer.frame = CGRectMake(0.0f, 58.0f, 320.0f, 365.0f); + //[screenLayer setCenter:CGPointMake(240.0f,160.0f)]; + [ screenLayer setOpaque:YES ]; + } + else + { + CGAffineTransform transform = CGAffineTransformMakeRotation(3.0 * M_PI / 2.0f); // = CGAffineTransformMakeTranslation(1.0, 1.0); + [screenLayer setAffineTransform:transform]; + screenLayer.frame = CGRectMake(48.0f, 112.0f, 224.0f, 256.0f); + //[screenLayer setCenter:CGPointMake(240.0f,160.0f)]; + [ screenLayer setOpaque:YES ]; + } + } + if([SOApp.optionsView getCurrentSmoothScaling]) + { + [screenLayer setMagnificationFilter:kCAFilterLinear]; + [screenLayer setMinificationFilter:kCAFilterLinear]; + } + else + { + [screenLayer setMagnificationFilter:kCAFilterNearest]; + [screenLayer setMinificationFilter:kCAFilterNearest]; + } + screenLayer.contents = (id)_screenSurface; + [[self layer] addSublayer:screenLayer]; + + /* + screenLayer = [CALayer layer]; + screenLayer.doubleSided = NO; + screenLayer.bounds = rect; + screenLayer.contents = (id)_screenSurface; + screenLayer.anchorPoint = CGPointMake(0, 0); // set anchor point to top-left + [self.layer addSublayer: screenLayer]; + */ + CoreSurfaceBufferUnlock(_screenSurface); + + screenbuffer = CoreSurfaceBufferGetBaseAddress(_screenSurface); + //[NSThread setThreadPriority:0.0]; + //[NSThread detachNewThreadSelector:@selector(updateScreen) toTarget:self withObject:nil]; + + iphone_last_upd_ticks = 0; + /* + timer = [NSTimer scheduledTimerWithTimeInterval:(1.0f / 50.0f) + target:self + selector:@selector(setNeedsDisplay) + userInfo:nil + repeats:YES]; + */ + } + + sharedInstance = self; + + return self; +} + +- (void)dealloc +{ + //[timer invalidate]; + [ screenLayer release ]; + [ super dealloc ]; +} + +- (CoreSurfaceBufferRef)getSurface +{ + return _screenSurface; +} + + +- (void)drawRect:(CGRect)rect +{ + if(screenbuffer && vrambuffer) + { + memcpy(screenbuffer, vrambuffer, 256*224*2); + } +} + +- (void)dummy +{ + +} + +- (void)updateScreen +{ + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + + //[NSThread setThreadPriority:0.9]; +/* + struct sched_param param; + param.sched_priority = 46; + if(pthread_setschedparam(pthread_self(), SCHED_RR, ¶m) != 0) + { + fprintf(stderr, "Error setting pthread priority\n"); + } +*/ +/* + struct sched_param param; + param.sched_priority = -47; + if(pthread_setschedparam(pthread_self(), SCHED_OTHER, ¶m) != 0) + { + fprintf(stderr, "Error setting pthread priority\n"); + } +*/ + while(__emulation_run) + { + [self performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:YES]; + //usleep(16666); + //sched_yield(); + } + [pool release]; +} + +@end + +@implementation NowPlayingController + +- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex +{ + // the user clicked one of the OK/Cancel buttons + if(__emulation_run) + { + if(iphone_menu == IPHONE_MENU_MAIN) + { + if(buttonIndex == 0) + { + iphone_menu = IPHONE_MENU_SAVE_CURRENT; + } + else if(buttonIndex == 1) + { + iphone_menu = IPHONE_MENU_SAVE_NEW; + } + else if(buttonIndex == 2) + { + iphone_menu = IPHONE_MENU_QUIT_LOAD; + } + else + { + iphone_menu = IPHONE_MENU_DISABLED; + } + } + + if(iphone_menu == IPHONE_MENU_QUIT_LOAD) + { + iphone_menu = IPHONE_MENU_QUIT; + UIActionSheet *alert = [[UIActionSheet alloc] initWithTitle:@"Save your state before quitting? You can overwrite a currently loaded savestate, save to a new file, or cancel." delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:@"Save [Currently Loaded] State",@"Save State To New File",@"Don't Save",@"Cancel", nil]; + [alert showInView:screenView]; + [alert release]; + return; + } + + if(iphone_menu == IPHONE_MENU_QUIT) + { + if (buttonIndex == 0) + { + [SOApp.delegate switchToBrowse]; + [tabBar didMoveToWindow]; + __emulation_saving = 2; + __emulation_run = 0; + while(__emulation_saving) + { + usleep(16666); + //sched_yield(); + } + //pthread_join(main_tid, NULL); + [screenView removeFromSuperview]; + [screenView release]; + //[controllerImageView removeFromSuperview]; + //[controllerImageView release]; + __emulation_run = 0; + __emulation_saving = 0; +#ifdef WITH_ADS + [SOApp.delegate unpauseAdViews]; +#endif + [SOApp.saveStatesView startSaveData:0.1f]; + [SOApp.delegate switchToSaveStates]; + [tabBar didMoveToWindowSaveStates]; + } + else if (buttonIndex == 1) + { + [SOApp.delegate switchToBrowse]; + [tabBar didMoveToWindow]; + + __emulation_saving = 1; + __emulation_run = 0; + while(__emulation_saving) + { + usleep(1000000); + sched_yield(); + } + //pthread_join(main_tid, NULL); + [screenView removeFromSuperview]; + [screenView release]; + //[controllerImageView removeFromSuperview]; + //[controllerImageView release]; + __emulation_run = 0; + __emulation_saving = 0; +#ifdef WITH_ADS + [SOApp.delegate unpauseAdViews]; +#endif + [SOApp.saveStatesView startSaveData:0.1f]; + [SOApp.delegate switchToSaveStates]; + [tabBar didMoveToWindowSaveStates]; + } + else if (buttonIndex == 2) + { + [SOApp.delegate switchToBrowse]; + [tabBar didMoveToWindow]; + + __emulation_saving = 0; + __emulation_run = 0; + //pthread_join(main_tid, NULL); + [screenView removeFromSuperview]; + [screenView release]; + //[controllerImageView removeFromSuperview]; + //[controllerImageView release]; + __emulation_run = 0; + __emulation_saving = 0; +#ifdef WITH_ADS + [SOApp.delegate unpauseAdViews]; +#endif + } + iphone_menu = IPHONE_MENU_DISABLED; + } + else if(iphone_menu == IPHONE_MENU_SAVE_CURRENT) + { + __emulation_saving = 2; + iphone_menu = IPHONE_MENU_DISABLED; + } + else if(iphone_menu == IPHONE_MENU_SAVE_NEW) + { + __emulation_saving = 1; + iphone_menu = IPHONE_MENU_DISABLED; + } + else + { + iphone_menu = IPHONE_MENU_DISABLED; + } + } + else + { + if (buttonIndex == 0) + { + iphone_is_landscape = 0; + iphone_soundon = 1; + [ self getControllerCoords:0 ]; + [ self fixRects ]; + numFingers = 0; + __emulation_run = 1; + screenView = [ [ScreenView alloc] initWithFrame: CGRectMake(0, 0, 320, 480)]; + [self.view addSubview: screenView]; + /* + controllerImageView = [ [ UIImageView alloc ] initWithImage:[UIImage imageNamed:[NSString stringWithFormat:@"controller_hs%d.png", [SOApp.optionsView getCurrentSkin]]]]; + controllerImageView.frame = CGRectMake(0.0f, 240.0f, 320.0f, 240.0f); // Set the frame in which the UIImage should be drawn in. + controllerImageView.userInteractionEnabled = NO; + controllerImageView.multipleTouchEnabled = NO; + controllerImageView.clearsContextBeforeDrawing = NO; + [controllerImageView setOpaque:YES]; + [controllerImageView setAlpha:((float)iphone_controller_opacity / 100.0f)]; + [self.view addSubview: controllerImageView]; // Draw the image in self.view. + */ + } + else if (buttonIndex == 1) + { + iphone_is_landscape = 0; + iphone_soundon = 0; + [ self getControllerCoords:0 ]; + [ self fixRects ]; + numFingers = 0; + __emulation_run = 1; + screenView = [ [ScreenView alloc] initWithFrame: CGRectMake(0, 0, 320, 480)]; + [self.view addSubview: screenView]; + /* + controllerImageView = [ [ UIImageView alloc ] initWithImage:[UIImage imageNamed:[NSString stringWithFormat:@"controller_hs%d.png", [SOApp.optionsView getCurrentSkin]]]]; + controllerImageView.frame = CGRectMake(0.0f, 240.0f, 320.0f, 240.0f); // Set the frame in which the UIImage should be drawn in. + controllerImageView.userInteractionEnabled = NO; + controllerImageView.multipleTouchEnabled = NO; + controllerImageView.clearsContextBeforeDrawing = NO; + [controllerImageView setOpaque:YES]; + [controllerImageView setAlpha:((float)iphone_controller_opacity / 100.0f)]; + [self.view addSubview: controllerImageView]; // Draw the image in self.view. + */ + } + else if (buttonIndex == 2) + { + iphone_is_landscape = 1; + iphone_soundon = 1; + [ self getControllerCoords:1 ]; + [ self fixRects ]; + numFingers = 0; + __emulation_run = 1; + screenView = [ [ScreenView alloc] initWithFrame: CGRectMake(0, 0, 320, 480)]; + [self.view addSubview: screenView]; + /* + controllerImageView = [ [ UIImageView alloc ] initWithImage:[UIImage imageNamed:[NSString stringWithFormat:@"controller_fs%d.png", [SOApp.optionsView getCurrentSkin]]]]; + controllerImageView.frame = CGRectMake(0.0f, 0.0f, 320.0f, 480.0f); // Set the frame in which the UIImage should be drawn in. + controllerImageView.userInteractionEnabled = NO; + controllerImageView.multipleTouchEnabled = NO; + controllerImageView.clearsContextBeforeDrawing = NO; + [controllerImageView setOpaque:YES]; + [controllerImageView setAlpha:((float)iphone_controller_opacity / 100.0f)]; + [self.view addSubview: controllerImageView]; // Draw the image in self.view. + */ + } + else + { + iphone_is_landscape = 1; + iphone_soundon = 0; + [ self getControllerCoords:1 ]; + [ self fixRects ]; + numFingers = 0; + __emulation_run = 1; + screenView = [ [ScreenView alloc] initWithFrame: CGRectMake(0, 0, 320, 480)]; + [self.view addSubview: screenView]; + /* + controllerImageView = [ [ UIImageView alloc ] initWithImage:[UIImage imageNamed:[NSString stringWithFormat:@"controller_fs%d.png", [SOApp.optionsView getCurrentSkin]]]]; + controllerImageView.frame = CGRectMake(0.0f, 0.0f, 320.0f, 480.0f); // Set the frame in which the UIImage should be drawn in. + [controllerImageView setOpaque:YES]; + [controllerImageView setAlpha:((float)iphone_controller_opacity / 100.0f)]; + controllerImageView.userInteractionEnabled = NO; + controllerImageView.multipleTouchEnabled = NO; + controllerImageView.clearsContextBeforeDrawing = NO; + [self.view addSubview: controllerImageView]; // Draw the image in self.view. + */ + } +#ifdef WITH_ADS + [SOApp.delegate pauseAdViews]; +#endif + pthread_create(&main_tid, NULL, app_Thread_Start, NULL); +/* + struct sched_param param; + param.sched_priority = 46; + if(pthread_setschedparam(main_tid, SCHED_RR, ¶m) != 0) + { + fprintf(stderr, "Error setting pthread priority\n"); + } +*/ + + struct sched_param param; + param.sched_priority = 46; + if(pthread_setschedparam(main_tid, SCHED_OTHER, ¶m) != 0) + { + fprintf(stderr, "Error setting pthread priority\n"); + } + + //[NSThread detachNewThreadSelector:@selector(runSound) toTarget:self withObject:nil]; + } +} + +- (void)runProgram +{ + __emulation_run = 1; + iphone_main(ourArgs[1]); + __emulation_run = 0; + __emulation_saving = 0; +} + +- (void)startEmu:(char*)path { + int i; + + iphone_menu = IPHONE_MENU_DISABLED; + + ourArgsCnt = 0; + /* faked executable path */ + ourArgs[ourArgsCnt]=get_resource_path("snes4iphone"); ourArgsCnt++; + + /* playgame */ + sprintf(romfile, "%s", path); + ourArgs[ourArgsCnt]=romfile; ourArgsCnt++; + + for (i=0; i= rect.origin.x) && \ + (point.y >= rect.origin.y) && \ + (point.x <= rect.origin.x + rect.size.width) && \ + (point.y <= rect.origin.y + rect.size.height)) ? 1 : 0) + +#if 1 +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event +{ + int touchstate[10]; + //Get all the touches. + int i; + NSSet *allTouches = [event allTouches]; + int touchcount = [allTouches count]; + + if(!__emulation_run) + { + return; + } + + for (i = 0; i < 10; i++) + { + touchstate[i] = 0; + oldtouches[i] = newtouches[i]; + } + + for (i = 0; i < touchcount; i++) + { + UITouch *touch = [[allTouches allObjects] objectAtIndex:i]; + + if( touch != nil && + ( touch.phase == UITouchPhaseBegan || + touch.phase == UITouchPhaseMoved || + touch.phase == UITouchPhaseStationary) ) + { + struct CGPoint point; + point = [touch locationInView:self.view]; + + touchstate[i] = 1; + + if (MyCGRectContainsPoint(Left, point)) + { + gp2x_pad_status |= GP2X_LEFT; + newtouches[i] = GP2X_LEFT; + } + else if (MyCGRectContainsPoint(Right, point)) + { + gp2x_pad_status |= GP2X_RIGHT; + newtouches[i] = GP2X_RIGHT; + } + else if (MyCGRectContainsPoint(Up, point)) + { + gp2x_pad_status |= GP2X_UP; + newtouches[i] = GP2X_UP; + } + else if (MyCGRectContainsPoint(Down, point)) + { + gp2x_pad_status |= GP2X_DOWN; + newtouches[i] = GP2X_DOWN; + } + else if (MyCGRectContainsPoint(ButtonLeft, point)) + { + gp2x_pad_status |= GP2X_A; + newtouches[i] = GP2X_A; + } + else if (MyCGRectContainsPoint(ButtonRight, point)) + { + gp2x_pad_status |= GP2X_B; + newtouches[i] = GP2X_B; + } + else if (MyCGRectContainsPoint(ButtonUp, point)) + { + gp2x_pad_status |= GP2X_Y; + newtouches[i] = GP2X_Y; + } + else if (MyCGRectContainsPoint(ButtonDown, point)) + { + gp2x_pad_status |= GP2X_X; + newtouches[i] = GP2X_X; + } + else if (MyCGRectContainsPoint(ButtonUpLeft, point)) + { + gp2x_pad_status |= GP2X_A | GP2X_Y; + newtouches[i] = GP2X_A | GP2X_Y; + } + else if (MyCGRectContainsPoint(ButtonDownLeft, point)) + { + gp2x_pad_status |= GP2X_X | GP2X_A; + newtouches[i] = GP2X_X | GP2X_A; + } + else if (MyCGRectContainsPoint(ButtonUpRight, point)) + { + gp2x_pad_status |= GP2X_B | GP2X_Y; + newtouches[i] = GP2X_B | GP2X_Y; + } + else if (MyCGRectContainsPoint(ButtonDownRight, point)) + { + gp2x_pad_status |= GP2X_X | GP2X_B; + newtouches[i] = GP2X_X | GP2X_B; + } + else if (MyCGRectContainsPoint(UpLeft, point)) + { + gp2x_pad_status |= GP2X_UP | GP2X_LEFT; + newtouches[i] = GP2X_UP | GP2X_LEFT; + } + else if (MyCGRectContainsPoint(DownLeft, point)) + { + gp2x_pad_status |= GP2X_DOWN | GP2X_LEFT; + newtouches[i] = GP2X_DOWN | GP2X_LEFT; + } + else if (MyCGRectContainsPoint(UpRight, point)) + { + gp2x_pad_status |= GP2X_UP | GP2X_RIGHT; + newtouches[i] = GP2X_UP | GP2X_RIGHT; + } + else if (MyCGRectContainsPoint(DownRight, point)) + { + gp2x_pad_status |= GP2X_DOWN | GP2X_RIGHT; + newtouches[i] = GP2X_DOWN | GP2X_RIGHT; + } + else if (MyCGRectContainsPoint(LPad, point)) + { + gp2x_pad_status |= GP2X_L; + newtouches[i] = GP2X_L; + } + else if (MyCGRectContainsPoint(RPad, point)) + { + gp2x_pad_status |= GP2X_R; + newtouches[i] = GP2X_R; + } + else if (MyCGRectContainsPoint(LPad2, point)) + { + gp2x_pad_status |= GP2X_VOL_DOWN; + newtouches[i] = GP2X_VOL_DOWN; + } + else if (MyCGRectContainsPoint(RPad2, point)) + { + gp2x_pad_status |= GP2X_VOL_UP; + newtouches[i] = GP2X_VOL_UP; + } + else if (MyCGRectContainsPoint(Select, point)) + { + gp2x_pad_status |= GP2X_SELECT; + newtouches[i] = GP2X_SELECT; + } + else if (MyCGRectContainsPoint(Start, point)) + { + gp2x_pad_status |= GP2X_START; + newtouches[i] = GP2X_START; + } + else if (MyCGRectContainsPoint(Menu, point)) + { + if(touch.phase == UITouchPhaseBegan || touch.phase == UITouchPhaseStationary) + { + if(__emulation_run) + { + [NSThread detachNewThreadSelector:@selector(runMenu) toTarget:self withObject:nil]; + } + else + { + [SOApp.delegate switchToBrowse]; + [tabBar didMoveToWindow]; + } + + //return; + } + } + + if(oldtouches[i] != newtouches[i]) + { + gp2x_pad_status &= ~(oldtouches[i]); + } + } + } + + for (i = 0; i < 10; i++) + { + if(touchstate[i] == 0) + { + gp2x_pad_status &= ~(newtouches[i]); + newtouches[i] = 0; + oldtouches[i] = 0; + } + } +} + +- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { + [self touchesBegan:touches withEvent:event]; +} + +- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { + [self touchesBegan:touches withEvent:event]; +} + +- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { + [self touchesBegan:touches withEvent:event]; +} +#endif +/* +- (void)view:(UIView *)view handleTapWithCount:(int)count event:(myGSEvent *)event { + //NSLog(@"handleTapWithCount: %d", count); + [self dumpEvent: event]; +} +*/ +/* +- (double)viewTouchPauseThreshold:(UIView *)view { + NSLog(@"TouchPause!"); + return 0.0; +} +*/ + +#if 0 +- (void)mouseEvent:(myGSEvent*)event { + int i; + int touchcount = event->fingerCount; + + gp2x_pad_status = 0; + + for (i = 0; i < touchcount; i++) + { + struct CGPoint point = CGPointMake(event->points[i].x, event->points[i].y); + + if (MyCGRectContainsPoint(Left, point)) { + gp2x_pad_status |= GP2X_LEFT; + } + else if (MyCGRectContainsPoint(Right, point)) { + gp2x_pad_status |= GP2X_RIGHT; + } + else if (MyCGRectContainsPoint(Up, point)) { + gp2x_pad_status |= GP2X_UP; + } + else if (MyCGRectContainsPoint(Down, point)) { + gp2x_pad_status |= GP2X_DOWN; + } + else if (MyCGRectContainsPoint(A, point)) { + gp2x_pad_status |= GP2X_B; + } + else if (MyCGRectContainsPoint(B, point)) { + gp2x_pad_status |= GP2X_X; + } + else if (MyCGRectContainsPoint(AB, point)) { + gp2x_pad_status |= GP2X_B | GP2X_X; + } + else if (MyCGRectContainsPoint(UpLeft, point)) { + gp2x_pad_status |= GP2X_UP | GP2X_LEFT; + } + else if (MyCGRectContainsPoint(DownLeft, point)) { + gp2x_pad_status |= GP2X_DOWN | GP2X_LEFT; + } + else if (MyCGRectContainsPoint(UpRight, point)) { + gp2x_pad_status |= GP2X_UP | GP2X_RIGHT; + } + else if (MyCGRectContainsPoint(DownRight, point)) { + gp2x_pad_status |= GP2X_DOWN | GP2X_RIGHT; + } + else if (MyCGRectContainsPoint(LPad, point)) { + gp2x_pad_status |= GP2X_L; + } + else if (MyCGRectContainsPoint(RPad, point)) { + gp2x_pad_status |= GP2X_R; + } + else if (MyCGRectContainsPoint(Select, point)) { + gp2x_pad_status |= GP2X_SELECT; + } + else if (MyCGRectContainsPoint(Start, point)) { + gp2x_pad_status |= GP2X_START; + } + else if (MyCGRectContainsPoint(Menu, point)) { + //if(touch.phase == UITouchPhaseBegan || touch.phase == UITouchPhaseStationary) + { + [SOApp.delegate switchToBrowse]; + [tabBar didMoveToWindow]; + if(__emulation_run) + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Save Game State" message:@"Save Game State?" delegate:self cancelButtonTitle:nil otherButtonTitles:@"Save Game!",@"Don't Save?", nil]; + [alert show]; + [alert release]; + } + } + } + } +} + +- (void)mouseDown:(myGSEvent*)event { + //NSLog(@"mouseDown:"); + [self mouseEvent: event]; +} + +- (void)mouseDragged:(myGSEvent*)event { + //NSLog(@"mouseDragged:"); + [self mouseEvent: event]; +} + +- (void)mouseEntered:(myGSEvent*)event { + //NSLog(@"mouseEntered:"); + [self mouseEvent: event]; +} + +- (void)mouseExited:(myGSEvent*)event { + //NSLog(@"mouseExited:"); + [self mouseEvent: event]; +} + +- (void)mouseMoved:(myGSEvent*)event { + //NSLog(@"mouseMoved:"); + [self mouseEvent: event]; +} + +- (void)mouseUp:(myGSEvent*)event { + [self mouseEvent: event]; +} +#endif + +/* +- (BOOL)isFirstResponder { + return YES; +} +*/ + +- (void)getControllerCoords:(int)orientation { + char string[256]; + FILE *fp; + + if(!orientation) + { + fp = fopen([[NSString stringWithFormat:@"%scontroller_hs%d.txt", get_resource_path("/"), [SOApp.optionsView getCurrentSkin]] UTF8String], "r"); + } + else + { + fp = fopen([[NSString stringWithFormat:@"%scontroller_fs%d.txt", get_resource_path("/"), [SOApp.optionsView getCurrentSkin]] UTF8String], "r"); + } + + if (fp) + { + int i = 0; + while(fgets(string, 256, fp) != NULL && i < 24) { + char* result = strtok(string, ","); + int coords[4]; + int i2 = 1; + while( result != NULL && i2 < 5 ) + { + coords[i2 - 1] = atoi(result); + result = strtok(NULL, ","); + i2++; + } + + switch(i) + { + case 0: DownLeft = CGRectMake( coords[0], coords[1], coords[2], coords[3] ); break; + case 1: Down = CGRectMake( coords[0], coords[1], coords[2], coords[3] ); break; + case 2: DownRight = CGRectMake( coords[0], coords[1], coords[2], coords[3] ); break; + case 3: Left = CGRectMake( coords[0], coords[1], coords[2], coords[3] ); break; + case 4: Right = CGRectMake( coords[0], coords[1], coords[2], coords[3] ); break; + case 5: UpLeft = CGRectMake( coords[0], coords[1], coords[2], coords[3] ); break; + case 6: Up = CGRectMake( coords[0], coords[1], coords[2], coords[3] ); break; + case 7: UpRight = CGRectMake( coords[0], coords[1], coords[2], coords[3] ); break; + case 8: Select = CGRectMake( coords[0], coords[1], coords[2], coords[3] ); break; + case 9: Start = CGRectMake( coords[0], coords[1], coords[2], coords[3] ); break; + case 10: LPad = CGRectMake( coords[0], coords[1], coords[2], coords[3] ); break; + case 11: RPad = CGRectMake( coords[0], coords[1], coords[2], coords[3] ); break; + case 12: Menu = CGRectMake( coords[0], coords[1], coords[2], coords[3] ); break; + case 13: ButtonDownLeft = CGRectMake( coords[0], coords[1], coords[2], coords[3] ); break; + case 14: ButtonDown = CGRectMake( coords[0], coords[1], coords[2], coords[3] ); break; + case 15: ButtonDownRight = CGRectMake( coords[0], coords[1], coords[2], coords[3] ); break; + case 16: ButtonLeft = CGRectMake( coords[0], coords[1], coords[2], coords[3] ); break; + case 17: ButtonRight = CGRectMake( coords[0], coords[1], coords[2], coords[3] ); break; + case 18: ButtonUpLeft = CGRectMake( coords[0], coords[1], coords[2], coords[3] ); break; + case 19: ButtonUp = CGRectMake( coords[0], coords[1], coords[2], coords[3] ); break; + case 20: ButtonUpRight = CGRectMake( coords[0], coords[1], coords[2], coords[3] ); break; + case 21: LPad2 = CGRectMake( coords[0], coords[1], coords[2], coords[3] ); break; + case 22: RPad2 = CGRectMake( coords[0], coords[1], coords[2], coords[3] ); break; + case 23: iphone_controller_opacity = coords[0]; break; + } + i++; + } + fclose(fp); + } +} + +/* + Implement loadView if you want to create a view hierarchy programmatically +- (void)loadView { +} + */ + +/* + If you need to do additional setup after loading the view, override viewDidLoad. +- (void)viewDidLoad { +} + */ + + +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { + // Return YES for supported orientations + return (interfaceOrientation == UIInterfaceOrientationPortrait); +} + + +- (void)didReceiveMemoryWarning { + [super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview + // Release anything that's not essential, such as cached data +} + + +- (void)dealloc { + [super dealloc]; +} + +- (void)volumeChanged:(id)sender +{ +#if 0 + __audioVolume = volumeSlider.value; +#endif +} + +- (void)setSaveState:(id)sender +{ +#if 0 + if(__emulation_run) + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Save Game State" message:@"Save Game State?" delegate:self cancelButtonTitle:@"Dont Save?" otherButtonTitles:@"Save Game!", nil]; + [alert show]; + [alert release]; + __emulation_saving = 1; + __emulation_run = 0; + pthread_join(main_tid, NULL); + [screenView release]; + } + [SOApp.delegate switchToBrowse]; + [tabBar didMoveToWindow]; +#endif +} + +@end diff --git a/PlayViewController.xib b/PlayViewController.xib new file mode 100755 index 0000000..38de15e --- /dev/null +++ b/PlayViewController.xib @@ -0,0 +1,266 @@ + + + + 512 + 9E17 + 670 + 949.33 + 352.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 268 + + YES + + + 292 + {{0, 44}, {320, 320}} + + NO + YES + YES + + + + 292 + {{11, 366}, {298, 23}} + + NO + YES + YES + 0 + 0 + 1.000000e+00 + + + + 292 + {{0, 386}, {320, 21}} + + NO + YES + NO + VOLUME + + 1 + MC42MTIyNDQ5IDAuNjEyMjQ0OSAwLjYxMjI0NDkAA + + + 1 + 1.000000e+01 + 1 + + + {320, 480} + + + 3 + MQA + + 2 + + + + + + + YES + + + webView + + + + 12 + + + + volumeChanged: + + + 13 + + 24 + + + + view + + + + 46 + + + + volumeSlider + + + + 47 + + + + + YES + + 0 + + YES + + + + + + 1 + + + YES + + + + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + -2 + + + + + 10 + + + + + 16 + + + + + 20 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 1.IBEditorWindowLastContentRect + 1.IBPluginDependency + 10.IBPluginDependency + 16.IBPluginDependency + 20.IBPluginDependency + + + YES + PlayViewController + UIResponder + {{722, 560}, {320, 480}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 47 + + + + YES + + PlayViewController + UIViewController + + YES + + YES + refreshClicked: + volumeChanged: + + + YES + id + id + + + + YES + + YES + volumeLabel + volumeSlider + webView + + + YES + UILabel + UISlider + UIWebView + + + + IBProjectSource + Classes/PlayViewController.h + + + + UIView + UIResponder + + IBUserSource + + + + + + 0 + ShoutOut.xcodeproj + 3 + + diff --git a/RootViewController.xib b/RootViewController.xib new file mode 100755 index 0000000..530fc7d --- /dev/null +++ b/RootViewController.xib @@ -0,0 +1,241 @@ + + + + 512 + 9J61 + 677 + 949.46 + 353.00 + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + + + IBFirstResponder + + + + 292 + {320, 460} + + + 3 + MQA + + NO + YES + NO + NO + 1 + 0 + YES + 4.400000e+01 + 2.200000e+01 + 2.200000e+01 + + + + 290 + {{598, 126}, {320, 44}} + NO + 3 + YES + + + + + + YES + + + view + + + + 5 + + + + dataSource + + + + 6 + + + + delegate + + + + 7 + + + + tableView + + + + 8 + + + + delegate + + + + 18 + + + + searchBar + + + + 19 + + + + + YES + + 0 + + YES + + + + + + -1 + + + RmlsZSdzIE93bmVyA + + + -2 + + + + + 3 + + + YES + + + + + 17 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 17.IBPluginDependency + 3.IBEditorWindowLastContentRect + 3.IBPluginDependency + + + YES + RootViewController + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{434, 121}, {320, 460}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + YES + + + YES + + + + + YES + + YES + + + YES + + + + 19 + + + + YES + + RootViewController + UITableViewController + + doneSearching_Clicked: + id + + + YES + + YES + searchBar + tabBar + tableView + window + + + YES + UISearchBar + UITabBar + UITableView + UIWindow + + + + IBProjectSource + Classes/RootViewController.h + + + + RootViewController + UITableViewController + + IBUserSource + + + + + + 0 + app.xcodeproj + 3 + 3.0 + + diff --git a/main.m b/main.m new file mode 100755 index 0000000..0dc1462 --- /dev/null +++ b/main.m @@ -0,0 +1,17 @@ +// +// snes4iphone +// +// Created by Spookysoft on 9/6/08. +// Copyright Spookysoft 2008. All rights reserved. +// + +#import + +int main(int argc, char *argv[]) { + + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + //UIApplicationUseLegacyEvents(1); + int retVal = UIApplicationMain(argc, argv, @"SOApplication", nil); + [pool release]; + return retVal; +} diff --git a/res/Default.png b/res/Default.png new file mode 100755 index 0000000..d90ff2a Binary files /dev/null and b/res/Default.png differ diff --git a/res/Info.plist b/res/Info.plist new file mode 100755 index 0000000..9fc1256 --- /dev/null +++ b/res/Info.plist @@ -0,0 +1,40 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + snes4iphone + CFBundleExecutable + snes4iphone + CFBundleIconFile + icon + CFBundleIdentifier + com.zodttd.snes4iphone + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + snes4iphone + CFBundlePackageType + APPL + CFBundleResourceSpecification + ResourceRules.plist + CFBundleSignature + ???? + CFBundleVersion + 1.0 + DTPlatformName + iphoneos + DTSDKName + iphoneos2.0 + LSRequiresIPhoneOS + + MinimumOSVersion + 2.0 + NSMainNibFile + MainWindow + UIStatusBarStyle + UIStatusBarStyleBlackOpaque + + diff --git a/res/MainWindow.nib b/res/MainWindow.nib new file mode 100755 index 0000000..1ce60a0 Binary files /dev/null and b/res/MainWindow.nib differ diff --git a/res/PkgInfo b/res/PkgInfo new file mode 100755 index 0000000..bd04210 --- /dev/null +++ b/res/PkgInfo @@ -0,0 +1 @@ +APPL???? \ No newline at end of file diff --git a/res/ResourceRules.plist b/res/ResourceRules.plist new file mode 100755 index 0000000..645fb23 Binary files /dev/null and b/res/ResourceRules.plist differ diff --git a/res/controller_fs0.png b/res/controller_fs0.png new file mode 100755 index 0000000..54555f8 Binary files /dev/null and b/res/controller_fs0.png differ diff --git a/res/controller_fs0.txt b/res/controller_fs0.txt new file mode 100755 index 0000000..c159d38 --- /dev/null +++ b/res/controller_fs0.txt @@ -0,0 +1,24 @@ +0,0,58,50 +0,55,70,86 +0,148,58,22 +71,0,69,96 +71,97,69,96 +155,0,60,49 +141,52,70,86 +146,149,73,50 +0,176,45,55 +0,250,45,55 +282,0,38,90 +282,388,38,90 +282,190,38,100 +0,312,58,30 +0,350,75,65 +0,430,60,53 +68,275,67,70 +71,416,65,65 +151,290,63,55 +126,352,89,59 +153,432,62,48 +282,108,38,57 +282,308,38,57 +25 diff --git a/res/controller_fs1.png b/res/controller_fs1.png new file mode 100755 index 0000000..54555f8 Binary files /dev/null and b/res/controller_fs1.png differ diff --git a/res/controller_fs1.txt b/res/controller_fs1.txt new file mode 100755 index 0000000..c159d38 --- /dev/null +++ b/res/controller_fs1.txt @@ -0,0 +1,24 @@ +0,0,58,50 +0,55,70,86 +0,148,58,22 +71,0,69,96 +71,97,69,96 +155,0,60,49 +141,52,70,86 +146,149,73,50 +0,176,45,55 +0,250,45,55 +282,0,38,90 +282,388,38,90 +282,190,38,100 +0,312,58,30 +0,350,75,65 +0,430,60,53 +68,275,67,70 +71,416,65,65 +151,290,63,55 +126,352,89,59 +153,432,62,48 +282,108,38,57 +282,308,38,57 +25 diff --git a/res/controller_fs2.png b/res/controller_fs2.png new file mode 100755 index 0000000..54555f8 Binary files /dev/null and b/res/controller_fs2.png differ diff --git a/res/controller_fs2.txt b/res/controller_fs2.txt new file mode 100755 index 0000000..c159d38 --- /dev/null +++ b/res/controller_fs2.txt @@ -0,0 +1,24 @@ +0,0,58,50 +0,55,70,86 +0,148,58,22 +71,0,69,96 +71,97,69,96 +155,0,60,49 +141,52,70,86 +146,149,73,50 +0,176,45,55 +0,250,45,55 +282,0,38,90 +282,388,38,90 +282,190,38,100 +0,312,58,30 +0,350,75,65 +0,430,60,53 +68,275,67,70 +71,416,65,65 +151,290,63,55 +126,352,89,59 +153,432,62,48 +282,108,38,57 +282,308,38,57 +25 diff --git a/res/controller_fs3.png b/res/controller_fs3.png new file mode 100755 index 0000000..54555f8 Binary files /dev/null and b/res/controller_fs3.png differ diff --git a/res/controller_fs3.txt b/res/controller_fs3.txt new file mode 100755 index 0000000..c159d38 --- /dev/null +++ b/res/controller_fs3.txt @@ -0,0 +1,24 @@ +0,0,58,50 +0,55,70,86 +0,148,58,22 +71,0,69,96 +71,97,69,96 +155,0,60,49 +141,52,70,86 +146,149,73,50 +0,176,45,55 +0,250,45,55 +282,0,38,90 +282,388,38,90 +282,190,38,100 +0,312,58,30 +0,350,75,65 +0,430,60,53 +68,275,67,70 +71,416,65,65 +151,290,63,55 +126,352,89,59 +153,432,62,48 +282,108,38,57 +282,308,38,57 +25 diff --git a/res/controller_fs4.png b/res/controller_fs4.png new file mode 100755 index 0000000..54555f8 Binary files /dev/null and b/res/controller_fs4.png differ diff --git a/res/controller_fs4.txt b/res/controller_fs4.txt new file mode 100755 index 0000000..c159d38 --- /dev/null +++ b/res/controller_fs4.txt @@ -0,0 +1,24 @@ +0,0,58,50 +0,55,70,86 +0,148,58,22 +71,0,69,96 +71,97,69,96 +155,0,60,49 +141,52,70,86 +146,149,73,50 +0,176,45,55 +0,250,45,55 +282,0,38,90 +282,388,38,90 +282,190,38,100 +0,312,58,30 +0,350,75,65 +0,430,60,53 +68,275,67,70 +71,416,65,65 +151,290,63,55 +126,352,89,59 +153,432,62,48 +282,108,38,57 +282,308,38,57 +25 diff --git a/res/controller_fs5.png b/res/controller_fs5.png new file mode 100755 index 0000000..54555f8 Binary files /dev/null and b/res/controller_fs5.png differ diff --git a/res/controller_fs5.txt b/res/controller_fs5.txt new file mode 100755 index 0000000..c159d38 --- /dev/null +++ b/res/controller_fs5.txt @@ -0,0 +1,24 @@ +0,0,58,50 +0,55,70,86 +0,148,58,22 +71,0,69,96 +71,97,69,96 +155,0,60,49 +141,52,70,86 +146,149,73,50 +0,176,45,55 +0,250,45,55 +282,0,38,90 +282,388,38,90 +282,190,38,100 +0,312,58,30 +0,350,75,65 +0,430,60,53 +68,275,67,70 +71,416,65,65 +151,290,63,55 +126,352,89,59 +153,432,62,48 +282,108,38,57 +282,308,38,57 +25 diff --git a/res/controller_hs0.png b/res/controller_hs0.png new file mode 100755 index 0000000..e4fd207 Binary files /dev/null and b/res/controller_hs0.png differ diff --git a/res/controller_hs0.txt b/res/controller_hs0.txt new file mode 100755 index 0000000..dbedc7f --- /dev/null +++ b/res/controller_hs0.txt @@ -0,0 +1,24 @@ +0,380,35,50 +36,380,65,50 +102,380,35,50 +0,330,70,49 +71,330,70,49 +0,280,35,49 +36,280,65,49 +102,280,35,49 +100,449,50,30 +165,449,50,30 +0,240,65,30 +254,240,65,30 +0,449,50,30 +160,390,50,50 +211,390,55,50 +267,390,50,50 +160,330,55,54 +260,330,59,54 +160,271,50,58 +211,271,55,58 +267,271,50,58 +70,240,70,30 +175,240,70,30 +100 diff --git a/res/controller_hs1.png b/res/controller_hs1.png new file mode 100755 index 0000000..7b6ffe9 Binary files /dev/null and b/res/controller_hs1.png differ diff --git a/res/controller_hs1.txt b/res/controller_hs1.txt new file mode 100755 index 0000000..dbedc7f --- /dev/null +++ b/res/controller_hs1.txt @@ -0,0 +1,24 @@ +0,380,35,50 +36,380,65,50 +102,380,35,50 +0,330,70,49 +71,330,70,49 +0,280,35,49 +36,280,65,49 +102,280,35,49 +100,449,50,30 +165,449,50,30 +0,240,65,30 +254,240,65,30 +0,449,50,30 +160,390,50,50 +211,390,55,50 +267,390,50,50 +160,330,55,54 +260,330,59,54 +160,271,50,58 +211,271,55,58 +267,271,50,58 +70,240,70,30 +175,240,70,30 +100 diff --git a/res/controller_hs2.png b/res/controller_hs2.png new file mode 100755 index 0000000..7b6ffe9 Binary files /dev/null and b/res/controller_hs2.png differ diff --git a/res/controller_hs2.txt b/res/controller_hs2.txt new file mode 100755 index 0000000..dbedc7f --- /dev/null +++ b/res/controller_hs2.txt @@ -0,0 +1,24 @@ +0,380,35,50 +36,380,65,50 +102,380,35,50 +0,330,70,49 +71,330,70,49 +0,280,35,49 +36,280,65,49 +102,280,35,49 +100,449,50,30 +165,449,50,30 +0,240,65,30 +254,240,65,30 +0,449,50,30 +160,390,50,50 +211,390,55,50 +267,390,50,50 +160,330,55,54 +260,330,59,54 +160,271,50,58 +211,271,55,58 +267,271,50,58 +70,240,70,30 +175,240,70,30 +100 diff --git a/res/controller_hs3.png b/res/controller_hs3.png new file mode 100755 index 0000000..7b6ffe9 Binary files /dev/null and b/res/controller_hs3.png differ diff --git a/res/controller_hs3.txt b/res/controller_hs3.txt new file mode 100755 index 0000000..dbedc7f --- /dev/null +++ b/res/controller_hs3.txt @@ -0,0 +1,24 @@ +0,380,35,50 +36,380,65,50 +102,380,35,50 +0,330,70,49 +71,330,70,49 +0,280,35,49 +36,280,65,49 +102,280,35,49 +100,449,50,30 +165,449,50,30 +0,240,65,30 +254,240,65,30 +0,449,50,30 +160,390,50,50 +211,390,55,50 +267,390,50,50 +160,330,55,54 +260,330,59,54 +160,271,50,58 +211,271,55,58 +267,271,50,58 +70,240,70,30 +175,240,70,30 +100 diff --git a/res/controller_hs4.png b/res/controller_hs4.png new file mode 100755 index 0000000..7b6ffe9 Binary files /dev/null and b/res/controller_hs4.png differ diff --git a/res/controller_hs4.txt b/res/controller_hs4.txt new file mode 100755 index 0000000..dbedc7f --- /dev/null +++ b/res/controller_hs4.txt @@ -0,0 +1,24 @@ +0,380,35,50 +36,380,65,50 +102,380,35,50 +0,330,70,49 +71,330,70,49 +0,280,35,49 +36,280,65,49 +102,280,35,49 +100,449,50,30 +165,449,50,30 +0,240,65,30 +254,240,65,30 +0,449,50,30 +160,390,50,50 +211,390,55,50 +267,390,50,50 +160,330,55,54 +260,330,59,54 +160,271,50,58 +211,271,55,58 +267,271,50,58 +70,240,70,30 +175,240,70,30 +100 diff --git a/res/controller_hs5.png b/res/controller_hs5.png new file mode 100755 index 0000000..7b6ffe9 Binary files /dev/null and b/res/controller_hs5.png differ diff --git a/res/controller_hs5.txt b/res/controller_hs5.txt new file mode 100755 index 0000000..dbedc7f --- /dev/null +++ b/res/controller_hs5.txt @@ -0,0 +1,24 @@ +0,380,35,50 +36,380,65,50 +102,380,35,50 +0,330,70,49 +71,330,70,49 +0,280,35,49 +36,280,65,49 +102,280,35,49 +100,449,50,30 +165,449,50,30 +0,240,65,30 +254,240,65,30 +0,449,50,30 +160,390,50,50 +211,390,55,50 +267,390,50,50 +160,330,55,54 +260,330,59,54 +160,271,50,58 +211,271,55,58 +267,271,50,58 +70,240,70,30 +175,240,70,30 +100 diff --git a/res/genres.png b/res/genres.png new file mode 100755 index 0000000..e0cb2f8 Binary files /dev/null and b/res/genres.png differ diff --git a/res/icon.png b/res/icon.png new file mode 100755 index 0000000..7d96808 Binary files /dev/null and b/res/icon.png differ diff --git a/res/nowplaying.png b/res/nowplaying.png new file mode 100755 index 0000000..2c7ddc4 Binary files /dev/null and b/res/nowplaying.png differ diff --git a/res/options.bin b/res/options.bin new file mode 100755 index 0000000..e69de29 diff --git a/res/recent.bin b/res/recent.bin new file mode 100755 index 0000000..e69de29 diff --git a/res/snesadvance.dat b/res/snesadvance.dat new file mode 100755 index 0000000..e66a250 --- /dev/null +++ b/res/snesadvance.dat @@ -0,0 +1,628 @@ +10000004|0|7E0147|0|1E|2A|18EC3|0|18EC3=EAEA,18E52=EAEA,18E70=EAEA,18E79=EAEA,185CC=EAEA,18612=EAEA,1865E=EAEA,186A5=EAEA,1871D=EAEA,18762=EAEA,184F1=EAEA,18531=EAEA,18560=EAEA,1858D=EAEA,656=42FC,18ED5=42D2,18EDC=EAEA,189F1=EAEA,18A0A=EAEA,18A44=EAEA,18A81=EAEA,18AC7=EAEA,18AF4=EAEA,18803=EAEA,1884A=EAEA,18896=EAEA,188DB=EAEA,188DD=EAEA,18955=EAEA,1899A=EAEA,18B20=EAEA,18B7E=EAEA,18BCA=EAEA,18C11=EAEA,18C89=EAEA,18CD0=EAEA,18D3C=EAEA,18D5A=EAEA,18D85=EAEA,15943=42FA,18EF7=42DB,18E00=42DB,18E2C=EAEA,15811=42FA,18DAE=EAEA,18DD7=80,189D3=EAEA,87=42FA,1534F=42F6 +FBF3C0FF|3x3 Eyes - Seima Korin Den (J)|4|40044804|0|0|0|0|214=42D8 +B3ABDDE6|7th Saga (U)|1320005|40800|0|0|0|0|3F2EB=42DA,FAC0=42F7 +68D7819A|7thsaga|5|C00|0|0|0|C +27FF5BA1|AAAHH! Real Monsters (U)|10000000|44C00|0|0|0|0|39F37=EAEA,39F5D=EAEA,39F68=EAEA,39F6D=EAEA,39F9C=EAEA,39FA4=EAEA,39FE9=EAEA,39FFE=EAEA,3A00A=EAEA,3A01A=EAEA,3A054=EAEA,3A067=EAEA,3A096=EAEA,3A0A7=EAEA,3A0B3=EAEA,3A0C3=EAEA,3A0F9=EAEA,3A10C=EAEA,3A13C=EAEA,3A16D=EAEA,3A18E=EAEA,3A1A1=EAEA,3A1A6=EAEA,3A214=EAEA,3A22A=EAEA,3A23D=EAEA,3A242=EAEA,3A2AE=EAEA,3A2BC=EAEA,3A2C7=EAEA,3A33A=EAEA,3A34F=EAEA,3A3A7=EAEA,3A3D6=EAEA,3A3F0=EAEA,3A3F8=EAEA,3A411=EAEA,3A425=EAEA,6CAF=429B,8A8C=42,EDD0=42D9,1A6D0E=DB +E0DC8AD7|ABC Monday Night Football (U)|4|0|0|0|0|0 +0DA18A10|Acrobat Mission (U)|0|0|0|0|0|0|5DE=42FB +EAC3358D|Act Raiser|4|0|0|0|0|A|3248=EAEA,1367C=EAEA,12868=EAEA,9296=421B,422=421B,1B017=421A +4901F718|Act Raiser 2 (U)|14000001|4040|0|0|0|0 +C752F5DF|Action Pachio (J)|4000000|44808|0|0|0|0|23C=42F6,2D9=42D4 +20143571|AD&D - Eye of the Beholder|8000004|40000|0|0|0|0|E81FD=EAEA,E8246=EAEA,E8271=EAEA,E828A=EAEA,E8420=EAEA,E844E=EAEA,E8459=EAEA,E845E=EAEA,E84C4=EAEA,E84D9=EAEA,E84ED=EAEA +779F89C6|Addams Family|0|0|0|0|0|0 +2E8034AB|Addams Family (U)|0|0|0|0|0|0|14E9=EAEA,7870=EAEA,789D=EAEA +153A00A7|Addams Family - Pugsley's Scave|0|44C40|0|0|0|0|14C5=EAEA,14CE=EAEA,532A2=EAEA +98B07DB8|Addams Family Values (U)|0|0|0|0|0|0|19071B=4280,82CD6=EAEA,1E00FB=EAEA,1E0249=EAEA,1E0260=EAEA,1E0270=EAEA,1E0288=EAEA,1E0293=EAEA,1E0298=EAEA +CFAB3BBA|Adventures of Dr Franken (U)|0|40C00|0|0|0|0|53D7=EAEA +1664AE48|Adventures of Kid Kleets (U)|0|0|0|0|0|0|7B74=EAEA,50DA6=EAEA,51A9C=EAEA,51AD6=EAEA,51AE5=EAEA,51B1B=EAEA,51B4D=EAEA,51B6D=EAEA,51B7E=EAEA +DC8F5734|Adventures of Rocky & Bullwinkl|0|0|0|0|0|0|F756F=EAEA +F194D00A|Aero Fighters (U)|0|0|0|0|0|0|FD=42D7,19D=428E,26D=42 +919F23CB|Aero the Acro-Bat (U)|0|40C00|0|0|0|0|E1C87=EAEA,E1CAC=EAEA +8C05ED51|Aero the Acro-Bat 2 (U)|0|0|0|0|0|0|1F9B44=EAEA,1F9B69=EAEA,1F9918=EAEA,1F99F2=EAEA,1F9A10=EAEA +54302A46|Aerobiz (U)|4|0|0|0|0|0|14EB=EAEA +EFAFAB12|Aerobiz Supersonic (U)|4|0|0|0|0|0|469F=EAEA,46CB=EAEA,46D6=EAEA,46DB=EAEA,1596=428B,EE024=DBF1 +6B452801|Air Cavalry (U)|10000000|4040|0|0|0|0 +05C0DA54|Air Strike Patrol (U)|4|0|0|0|0|0|781FD=EAEA,78246=EAEA,78271=EAEA,7828A=EAEA,78420=EAEA,7844E=EAEA,78459=EAEA,7845E=EAEA,784C4=EAEA,784D9=EAEA,784F3=EAEA,78513=EAEA,88B9A=EAEA,31D=DB,337=42D9,D1B=42,212E=42,215F=42,219C=42,3AFC=4219,3BC2=DB,3C30=42,3C62=42,3C88=42,3CC8=42,3D0B=42,40AD=42,40D5=42,4971=42,49A2=42,49C8=42,4C46=DB,10026=423A,187FA=4280,18818=42DD,CF9B3=DB6A +EEF47B5E|Akazukin Cha Cha (J)|5|840000|0|0|0|0|16047E=EAEA,160456=EAEA,30F7=42DC +0AA75FA8|Akumajo Dracula XX|0|0|0|0|0|0|CA=4284,2B02=EAEA,29A2=EAEA +124D8E4D|Aladdin|0|0|7E08EA|0|1E|5|BC89=DBE2 +46CA01A9|Albert Odyssey (J)|4|0|0|0|0|0 +1B6ADD7B|Albert Odyssey 2 (J)|4000005|0|0|0|0|0 +05798DA8|Alice in Wonderland (J)|8000001|4040|0|0|0|0 +7E28C2D4|Alien 3 (E) [T-Port]|0|0|0|0|0|0|F80A1=EAEA,F814E=EAEA,F8123=EAEA,F8166=EAEA,F80A6=EAEA,F81A8=EAEA,BAD8=42DB,A629=42F8,A5E5=42FB +98E2AC15|Alien 3 (U)|0|0|0|0|0|0|F80A1=EAEA,F814E=EAEA,F8123=EAEA,F8166=EAEA,F80A6=EAEA,F81A8=EAEA,A5E5=42FB,A629=42F8,BAD8=42DB +A31D1F58|Alien Vs. Predator (E) [!]|2|0|0|0|0|0|60626=EAEA,6062E=EAEA,6063F=EAEA,60644=EAEA,60653=EAEA,3FCE=421B,3FDC=421B +1803CF20|Alien Vs. Predator (U)|0|0|0|0|0|0|60626=EAEA,6062E=EAEA,6063F=EAEA,60644=EAEA,60653=EAEA,3FCE=421B,3FDC=421B +2D5876FF|Aliens Vs Predator (J)|0|0|0|0|0|0|60426=EAEA,6042E=EAEA,6043F=EAEA,60444=EAEA,60453=EAEA,4245=421B,4253=421B +EBEFBDE2|All-American Championship Footb|2|0|0|0|0|0|825=DB,16C9=DB69,2DF7=4282,4015=4215,40A9=DB,4173=4210,4260=DB,37580=EAEA,375F0=EAEA,3760B=EAEA,37627=EAEA,37691=EAEA,3769C=EAEA,376A1=EAEA,376CC=EAEA,376D2=EAEA,3787D=EAEA,37883=EAEA,37898=EAEA,378A3=EAEA,378B0=EAEA,378BD=EAEA,378CC=EAEA,37C48=EAEA,37C4E=EAEA,37C63=EAEA,37C8A=EAEA +61753981|American Battle Dome (J)|0|0|0|0|0|0|D807E=EAEA,DA11D=EAEA,DA164=EAEA,2BF9=42DC,3081=421B +EEA38AED|An American Tale - Fievel Goes |1|0|0|0|0|0|F236=EAEA +D5B09EEF|Ancient Magic - Bazoo! Mahou Se|4|0|0|0|0|0 +D1AE87BE|Andre Agassi Tennis (U)|0|0|0|0|0|0 +EA6AE8A9|Angelic Voice Fantasy (J)|10000005|4040|0|0|0|0 +CF0F14D2|Animaniacs|0|0|0|0|0|0|364C=EAEA,34EE=EAEA,139=4284,570=EAEA +83B40AF2|Another World (E)|10000002|0|0|0|0|0|658D=EAEA,65A0=EAEA,65B7=EAEA,65CC=EAEA,65D4=EAEA,65E1=EAEA,65E6=EAEA,65FB=EAEA,6605=EAEA,6617=EAEA,662A=EAEA,66B5=EAEA,66C5=EAEA,1D997=4251,234C9=DB6D +4CA1696F|Aqutallion (J)|4|0|0|0|0|0 +B6DBF57B|Arabian Nights - Sabaku no Seir|5|44000|0|0|0|0|114C=EAEA,1177=EAEA,1156=EAEA,573A=EAEA,58B3=EAEA,4FBA=EAEA,4F90=EAEA,5387=EAEA,538C=EAEA,4C45=42FB +C891B297|Arcana (U)|4|0|0|0|0|0|1C1A=EAEA,1C3D=EAEA,5128=EAEA,516C=EAEA,51FB=EAEA,5208=EAEA,52BA=EAEA,52D0=EAEA,52DD=EAEA,5303=EAEA,5330=EAEA,533B=EAEA,5340=EAEA,5372=EAEA,E8160=EAEA,3A6=42,8FA=423A,900=421A,300EC=423F,30564=423F,EA2B9=4219 +E1CCCE49|Archer MacLean's Dropzone (E) [|2|0|0|0|0|0|F840C=EAEA +C9067671|Arcus Spirits (J)|0|0|0|0|0|0 +51A5F489|Ardy Lightfoot (U)|0|44C00|0|0|0|0|D008F=EAEA,D04A7=EAEA,7D6A=EAEA +06388F71|Area 88 (J)|8000000|44400|0|0|0|0|61=EAEA,129=42FC,65C4=42D5 +395BADE3|Aretha (J)|10000004|40840840|0|0|0|0|2367D=42D9,103D=423B +FF63EC26|Aretha II - Ariel no Fushigi na|4|0|0|0|0|0|10C68=EAEA,10C7D=EAEA,10C90=EAEA,10CA8=EAEA,10CEE=EAEA,10DA3=EAEA,10C4C=EAEA,10AF1=EAEA,9052=EAEA,1112A=42D9,189C=423B,13204=4289,114DE=42DB,268E=42D5 +B50503A0|Arkanoid - Doh it Again (U)|10000000|4000|0|0|0|C|100F0=EAEA,5D=4282 +9FA74067|Art of Fighting (U)|1|0|0|0|0|0 +24FE792F|Asameshimae Nyanko (J)|8000000|40440C00|0|0|0|0 +6B54BE97|Ashita no Joe (J)|10000000|4040|0|0|0|0|94B1=EAEA,A802=EAEA,A81A=EAEA,A825=EAEA,A82A=EAEA,A870=EAEA,A8A4=EAEA,A8BC=EAEA,A8C7=EAEA,A8CC=EAEA,B75C=EAEA +A5F63557|Assault Suits Valken (J)|0|4000|0|0|0|0 +EF85860E|Asterix & Obelix (E) [f1]|10000002|0|0|0|0|32|1803A=EAEA,1804A=EAEA,1B8AE=42FA +5DDEDC28|Asterix (E) [!]|2|0|0|0|0|0|B42B=EAEA,7D5B=EAEA,7D9B=EAEA,A4C=42DB +E87BD7EC|Astral Bout (J)|0|0|0|0|0|0 +AC212C51|Astral Bout 2, Sougou Kakutougi|0|0|0|0|0|0 +3F09A8D9|Astral Bout 3, RINGS (J)|0|0|0|0|0|0 +19E09C6B|Atlas, The - Renaissance Voyage|4|44C00|0|0|0|0 +B0A02734|Axelay (J)|0|44400|0|0|0|0|609=42DB +F812B533|Axelay (U)|0|0|0|0|0|0|C45=42D3,12A2=4219,12AA=4239,12B1=4219,12F6=DB,1DE5=42BA,D370E=4215,127=DB0D +1B83C440|Bahamut Lagoon (J)|5|0|0|0|0|3007|3007E=EAEA,1A0072=42FA,1580B4=42FC,1A67FB=EAEAEAEA +726B6C5A|Barkley Shut Up and Jam (U)|0|0|0|0|0|0|163B3=EAEA,163D7=EAEA,14D40=EAEA,14C8E=EAEA +832A27C2|Bass Masters Classic (U)|0|0|0|0|0|0 +C5058634|Bass Masters Classic Pro Editio|0|0|0|0|0|0|8CE7=EAEA,8D13=EAEA,8EE4=EAEA,8F12=EAEA,8C09=EAEA +7DC5B7B3|Bassins' Black Bass Fishing wit|4|0|0|0|0|0|13AF=EAEA,13BB=EAEA,13BF=EAEA +6742D51C|Bastard!! - Ankoku no Hakaishin|0|0|0|0|0|0 +E87DFDF6|Batman Returns|0|0|32C|0|1E|0|10D=653A85984280 +99A1F158|Battle Dodgeball - Tokyu Gekito|4|0|0|0|0|0|8B3=DBC4 +43D3F2B2|Battle Dodgeball 2 (J)|1|0|0|0|0|0|713=42DC +190FF436|Battle Grand Prix (U)|0|0|0|0|0|0|1AAB9=EAEA +B72BF1F2|Battle Robot Retsuden (J)|5|44040|0|0|0|0|836A=4282,83AD=42BA,BF02A=425B,BF0D2=425B,BF16F=425B,BF18C=425B,BF19D=425B,2C3CEB=42 +3733B1B1|Battle Soccer - Field no Hasya|4|0|0|0|0|0 +92AFAB02|Battle Tycoon (V1.1) (J)|5|0|0|0|0|0 +56C7EB66|Battletech 3050 (J)|8000001|400000|0|0|0|0|166CB4=EAEA,166CE0=EAEA,166EB1=EAEA,166EDF=EAEA,166BD6=EAEA,696=42DC,101C=42DC,154362=42DC,15464C=42DC,154960=42DC,154D80=42DC,154E70=42DC,13D77B=42DC,13D822=42DC,141973=42DC,141BAE=42DC,78EB=42DC,7815=42DC,13E727=42DC +8B18AC01|Battletoads & Double Dragon - T|14000000|40000|0|0|0|0|753E=EAEA,7706=EAEA,FFA3=EAEA,A800B=EAEA,A801D=EAEA,A802F=EAEA,A803E=EAEA,A80BD=EAEA,BC9CD=EAEA,BC9E5=EAEA,178=42D8,377=428E,808D=4280,AAB5A=DB,AF2A6=421C,B544D=DBF1,B8106=427D,B8C9D=DBF2,B9568=DB,B9EBA=42DA,BB2B4=DB,BB685=DBF2,BC569=4210,BFE99=428D,BFFF4=428D +1783E3A2|Battletoads in Battlemaniacs (U|0|4000|0|0|0|0|E7E0A=EAEA,E7E1C=EAEA,E7E2E=EAEA,E7E3D=EAEA,E7FDC=EAEA,7B08=428D,A785F=42D9,ED1EF=421C +956E183C|Beauty and the Beast (U)|0|40C00|0|0|0|0|3A622=EAEA,3A59F=EAEA,3A5BC=EAEA,C0052=42FB +15CF4BD5|Beavis and Butthead (U)|0|0|0|0|0|0|52BF=EAEA,5456=EAEA,6272=42FC +BDA2E412|Bebe's Kids (U)|0|0|0|0|0|0|5D07=42 +4E8B2ECB|Biker Mice From Mars (U)|0|0|0|0|0|0|185B=EAEA,16FC=EAEA,1A7=DB,501=4211,5A0=DB,91A=42BA,131F2=423B,164A0=4290 +53D8410E|Bio Metal (U)|0|4A0F|0|0|0|0|231=42FB +4229F61D|Bishoujo Sailor Moon R (trans)|1|0|0|0|0|0|CF3A=019C,FF92=019C,CBF6=42FC,D468=DB0B +4AEE5ABB|Bishoujo Senshi Sailormoon R (|8000001|44800|0|0|0|0|1E00FF=EAEA,1E0104=EAEA,1E011D=EAEA,8BE7=42FC,9C8D=42D8 +31092C4D|Bisyoujyo Senshi Sailor Moon -|8000005|44800|0|0|0|0|1E00FF=EAEA,1E0104=EAEA,1E011D=EAEA,8BE7=42FC,9C8D=42D8 +AD2EFFC3|Blaze On (J)|0|0|7E1100|0|1E|0|4A0=DB +3B01D0A3|Blazeon (U)|0|0|0|0|0|5|4A0=42FC +4A62057D|Blues Brothers, The (E) [!]|2|40000|0|0|0|0|3EA=EAEA,418=EAEA,145F=EAEA,1C76=EAEA,343=42FA +82B97464|Blues Brothers, The (U)|0|40000|0|0|0|0|3F0=EAEA,41E=EAEA,349=42FA +18BBEE33|Bobby's World (U)|0|0|0|0|0|0 +597AA981|Bonkers|0|0|7E0406|0|1E|0|FED=42 +1899AAFF|Boogerman - A Pick and Flick Ad|1|0|0|0|0|0|67=42DB,26A0=42F9,37C8=421A,28=42DB +F3DDF35F|Bounty Sword (J)|10000005|4000|0|0|0|0|2F5AA=EAEA,2F5AE=EAEA,2F5BE=EAEA,2F5BA=42DA +AC443D87|Brain Lord (U)|5|0|0|0|0|0|3065=EAEA,3080=EAEA,1D8FF=42,F8FA=42 +718CB0DF|Brainies, The (U)|0|0|0|0|0|0|3065=EAEA,3080=EAEA +5CECE690|Bram Stoker's Dracula (U)|0|0|0|0|0|0|F8099=EAEA,F8146=EAEA,F811B=EAEA,F815E=EAEA,F809E=EAEA +74F70A0B|Brandish (U)|5|0|0|0|0|0|140555=EAEA,14071A=EAEA,140742=EAEA,140819=EAEA,140E74=EAEA,140E90=EAEA,140EA8=EAEA,14C11D=EAEA,815E=42,8175=42D8,817D=42,81C4=42,81D2=42D8,81DA=42,8210=DB,854E=42B9,152737=DB,152B1E=421F +BB89E67E|Brandish 2 - The Planet Buster|5|0|0|0|0|0|1BF89C=EAEA,290631=EAEA,290CBC=EAEA,290CD8=EAEA,2C8E1F=EAEA +E822065C|Brawl Brothers (U)|0|0|0|0|0|0|56D8=EAEA,5707=EAEA,5716=EAEA,51FF=EAEA,29462=EAEA,2E5C5=EAEA +C788B696|Breath of Fire (U)|1300004|0|0|0|0|0|32E=421B,9AB=42D9,A6957=42D9 +67CDACC5|Breath of Fire II (U)|5|0|0|0|0|0|FAF=421B,5E0D=42D7 +9EBFE809|Brett Hull Hockey '95|18000000|4C00|0|0|0|0|F88C=EAEA,F8C0=EAEA,FAEF=EAEA,FCA1=EAEA,FCB9=EAEA,FCC4=EAEA,FCC9=EAEA,FCF7=EAEA,FD18=EAEA,FD1F=EAEA,FD2F=EAEA,FD40=EAEA,FD58=EAEA,FDE1=EAEA,FDF9=EAEA,FE04=EAEA,FE09=EAEA,FE37=EAEA,FE58=EAEA,FE5F=EAEA,FE6F=EAEA,FE80=EAEA,FE98=EAEA,1D66FB=EAEA,1D672D=EAEA,1D694C=EAEA,1D6B16=EAEA,1D6B2E=EAEA,1D6B39=EAEA,1D6B3E=EAEA,1D6B6C=EAEA,1D6B8D=EAEA,1D6B94=EAEA,1D6BA4=EAEA,1D6BB5=EAEA,1D6BCD=EAEA,1D6C5A=EAEA,1D6C72=EAEA, +FBE35998|Brett Hull Hockey (U)|0|0|0|0|0|0 +8FE49F80|Brutal - Paws of Fury (U)|0|40000|0|0|0|0|F84DC=EAEA,F8275=EAEA,6DF4=42 +21CB8FD4|BS Kirby no Omotya Bako Basebal|0|0|0|0|0|0 +29B7CF34|BS Spriggan Powered - BS Versi|8000000|4040|0|0|0|0|8DF=42FB +267A5348|BS Super Famicom Wars (V1|2|0|0|0|0|0|B0D=EAEA,B18=EAEA,B46=EAEA,B51=EAEA,BB1=EAEA,BBC=EAEA,BC1=EAEA,BF3=EAEA,C02=EAEA,C4A=EAEA,C5C=EAEA,CE8=EAEA,CF6=EAEA,D16=EAEA,121=42,81558=421E +444A52C1|Bubsy Bobcat (U)|0|400000|0|0|0|0|75F8=EAEA,176=4297 +D0D172FA|Bubsy II (U)|1|0|0|0|0|0 +832C0CB6|Bugs Bunny in Rabbit Rampage (U|0|0|0|0|0|0|6DF1=42FC,7017=42FC,70A8=42FC,726E=42FC,7429=42FC,64E9=42FC,423=42FC +62D31295|Bushi Seiryuden (J)|4|0|0|0|0|0 +3266FD23|Bust-a-Move (U)|0|80444C00|0|0|0|0|28B1C=EAEA,28B34=EAEA,28B3F=EAEA,28B44=EAEA,2B8AA=EAEA,2B927=EAEA,2B96F=EAEA,2B979=EAEA,2B98B=EAEA,2B9B3=EAEA,2B9C9=EAEA,2B9F4=EAEA,2BA06=EAEA,2BA31=EAEA,2BA3E=EAEA,2BA50=EAEA,2FEF1=EAEA,2824A=423B,2824F=421B,638C8=DBF2,64556=DB +A95C1FFF|Cameltry (J)|0|0|0|0|0|0|3A=421B +F3B5CBB1|Cannon Fodder (E)|2|0|0|0|0|0|D286=EAEA,D376=EAEA,E8D01=EAEA,F953F=EAEA,B9CE4=4289,C6B15=DB,12421B=42B6 +B95FE0A0|Cannondale Cup (U)|4|0|0|0|0|0|3857C=EAEA +456AB5C8|Captain America & the Avengers |0|0|0|0|0|0|3478=EAEA,354D=EAEA,3C7C=42 +81DB73C7|Captain Commando (U)|1D|0|0|0|0|0|6FC=42DA +9FD460A4|Captain Novolin (US)|18000000|844C00|0|0|0|0|49=42DB,380F5=42FC,380FE=42FC,183=42DB,1B45=42FB,1B50=42FB,19F0=42F8,272A=42F8 +A3B745BC|Casper (U)|0|0|0|0|0|0|578CC=EAEA,578F1=EAEA,572A8=42FC +7C4887E1|Castlevania - Dracula X|10000018|0|1D48|1DB6|1E|0|CE=4284,2B12=EAEA,29B2=EAEA +4EE9EE99|Castlevania - Vampire's Kiss (E|2|0|0|0|0|0|CE=4284,28E=42BA,336=42BA,B09=42D9,B46=42BA,71BCD=421D,1CE665=4212,1D705E=DB62 +B76714F8|Castlevania IV|4000010|0|54E|0|1E|A|187=4286 +2905C3DD|Championship Pool (E)|2|0|0|0|0|0|410A=EAEA,412F=EAEA,40A0=EAEA,40EB=EAEA,40C5=EAEA +98EF8414|Championship Pool (U)|0|0|0|0|0|0|410A=EAEA,412F=EAEA,40A0=EAEA,40EB=EAEA,40C5=EAEA +6B953095|Championship Soccer '94 (U)|10000004|40C00|0|0|0|0|3DC2=EAEA,3EA4=EAEA,4AB=42D9,58DCB=42 +76E01CCB|Chaos Seed - Fuusui Kairoki (J|4000005|4040|0|0|0|0|AB37=EAEA,AB3C=EAEA,AB55=EAEA,AE1E=EAEA,9752=42D4,9845=42D4,982C=421A +BC671E15|Chessmaster, The (U)|0|0|0|0|0|0|2A50=EAEA +557FE962|Chester Cheetah - Wild Wild Que|0|0|0|0|0|0|73C=EAEA,743=EAEA,74A=EAEA,77C=EAEA,783=EAEA,78A=EAEA +9E1CF43F|Cho Mahou Tairyku Wozz (J) [T-E|4|0|0|0|0|0|64D7=42FB,61C2=429B,5C0CF=42FB +788E42C9|Choplifter 3 (E)|2|44800|0|0|0|0|1B99=42F5 +1D2EAE52|Choplifter 3 (U)(30545)|0|44800|0|0|0|0|1B99=42F5 +227E2D1F|Choplifter 3 (U)(54553)|0|44800|0|0|0|0|1B99=42F5 +AD26CC9E|Choplifter III - Rescue Surviv|0|44800|0|0|0|0|1B99=42F5 +B3258F38|Chou Mahou Tairiku WOZZ (J)|4|0|0|0|0|0|64D7=42FB,61C2=429B,5C0CF=42FB +A5DB02E9|Choujikuu Yousai Macross - Scra|10000001|40C00|7E0A7A|0|1E|0|63752=42BD,BBD53=4250 +2D206BF7|Chrono Trigger (U)|5|0|0|0|5|0|703E5=80,7042A=80,70478=80,704F8=80,705D9=80,704EE=EAEAEA,3AC5=A90200 +AE93B9CA|CHRONO~1|5|0|0|0|5|0|703E5=80,7042A=80,70478=80,704EE=EAEAEA,704FA=EAEAEA,705D9=80,31A12=80,31343=EAEA,30720=EAEAEA,307B8=EAEAEA,307C7=EAEA,28D7E=EAEAEA +E237EC45|Chuck Rock (U)|0|0|0|0|0|0|E00B9=EAEA,E0083=EAEA,E00D0=EAEA,E00F3=EAEA,E0111=EAEA +41FDBA82|Civilization (U)|5|4000|0|0|0|0|2F1=EAEA,309=EAEA,314=EAEA,319=EAEA +12F8A26C|Cliffhanger (U)|0|0|0|0|0|0|1193E=EAEA,40F=42DB +A27940C1|College Football USA '97 - The|4|0|0|0|0|0 +5E2C24F6|Combatribes, The (J)|0|44800|0|0|0|0|32D=42FC +9304044A|Combatribes, The (U)|0|44800|0|0|0|0|2D4=42FC,32D=42FC +8A24FBA8|Congo's Caper (U)|0|0|0|0|0|0|53F=42FC +84DA7CFE|Contra III - The Alien Wars|8000010|0|22A|0|14|5|16A=428A +44E60E58|Cool Spot (U) [!]|0|840000|0|0|0|0|9EE=42FB,7313=DB68,F3038=42F0 +4DFA05B3|Cybernator (U)|0|0|0|0|0|0|5F3=42FB +4A5263DB|Cyborg 009 (J)|10000000|40004008|0|0|0|0|E00BB=EAEA,E00E0=EAEA,E0105=EAEA,E010F=EAEA,E011B=EAEA,E0127=EAEA,CA572=42FB,CC17D=42FB,CB323=42DB,CB2E6=42DB,CA563=42DB,CAE35=42DB,CAEEF=42DB,CAA30=42DB,CABA1=42DB,CAC1C=42DB,CE5B2=42DB,CE5BC=42,CE6B6=42DB,C82E3=42DB,C82F2=42,C834C=42DB,C8E63=42DB,C8E70=42,C9282=42DB,CEABC=42DB,CEAC9=42,CEC1C=42DB,4D7C=42DB,2159=42 +5F02A044|Daffy Duck - The Marvin Mission|0|4000|0|0|0|0|20E=42FB +C5341764|Darius Twin (U)|0|0|7E13D8|0|1E|5|77=428E,17A=4210,E0D47=4211 +7B9793B1|Dark Half (J)|5|0|0|0|0|0|75C=EAEA,12FF3C=EAEA,13F845=EAEA,1AFABB=EAEA,2A0508=EAEA,2A058D=EAEA,1BF=42B9,164604=428C,198B77=423B,2B5E4B=421C,2B66EC=DB +46F1F4A9|Dark Kingdom (J)|4|0|0|0|0|0|7521=EAEA,7552=EAEA,7583=EAEA,75E5=EAEA,BFE24=EAEA,C0F21=EAEA,C0F39=EAEA,C0F44=EAEA,C0F49=EAEA,C7B8F=EAEA,FC74B=EAEA,1101BB=EAEA,22F13=42,29924=DB,4065B=42,40693=42,406CE=4280,41F43=42D9,45F24=42D9,46DF6=42D9,47628=42D7,B3240=DB,BFEA5=42,BFEED=42,BFF53=4210,C0133=42D9,100490=42D9,100577=42D9,105E71=42D9,105E88=42D9,105EE3=42D9,11FF48=423F +125A0C22|Dark Law - Meaning of Death (J)|5|0|0|0|0|0|BCBF=EAEA,BCC4=EAEA,BCCB=EAEA,BCD0=EAEA,BCE6=EAEA,BCEB=EAEA,BCF7=EAEA,BCFC=EAEA,BD01=EAEA,BD2E=EAEA,BD33=EAEA,BD3D=EAEA,BD44=EAEA,BD4B=EAEA,BD52=EAEA,BD59=EAEA,BD60=EAEA,BD9F=EAEA,BDA6=EAEA,BDAD=EAEA,BDB4=EAEA,BDBB=EAEA,BDC2=EAEA,BDCE=EAEA,BDD9=EAEA,BDE1=EAEA,BDE6=EAEA,BDFF=EAEA,B057E=EAEA,B0592=EAEA,1AB15F=EAEA,1D8572=EAEA,1D9F33=EAEA,20199C=EAEA,28C9CA=EAEA,2DC3CA=EAEA,3F2190=EAEA,2BA=421A,3B2=42D6,ABE=42,38636=42,38677=42,92049=42,9208A=42,A4444=42,11274B=42,13B52D=42D4 +A3558177|DBZ - Saiyan Den. (J) [T+Eng]|4|40000|0|0|0|17 +A567957C|Death and Return of Superman, T|0|0|0|0|0|0 +E8236AD2|Demon's Crest|0|0|7E1034|0|1E|A|1A1=DB +8EE7FAA5|Dennis the Menace (U)|0|0|0|0|0|0|7702=EAEA +5608C71F|Der Langrisser (J) (V1|2000004|24000000|0|0|0|0|1B035C=EAEA,1B0364=EAEA,1B036C=EAEA,1B0374=EAEA,1B004F=EAEA,2008=EAEA,2023=42DC,1607B=42D4,12DE9=42D4 +35F9EECC|Der Langrisser (V1.1) (J)|4|0|0|0|0|0|1B035C=EAEA,1B0364=EAEA,1B036C=EAEA,1B0374=EAEA,1B004F=EAEA,2008=EAEA,2023=42DC,1607B=42D4,12DE9=42D4 +006364DB|Diddy's Kong Quest (V1.0) (U)|5|0|0|0|0|0|8431=EAEA,8429=EAEA,8434=EAEA,842D=EAEA,8505=EAEA,8411=EAEA,850F=EAEA,8586=EAEA +2D3B9662|Donald Duck - Maui Mallard in C|0|0|0|0|0|0|1CB=EAEA +C946DCA0|Donkey Kong Country (V1.0) (U)|10000005|40C00|7E0215|0|A|FFFFFFF1|AB209=EAEA +3EAA5697|Donkey Kong Country (V1.1) (U)|10000005|40C00|7E0215|0|A|FFFFFFF1|AB209=EAEA +0E204FBD|Donkey Kong Country - Competiti|10000005|40C00|0|0|0|0|AB0F8=EAEA,AB10A=EAEA,AB11C=EAEA,AB12B=EAEA,AB1B9=EAEA,AB1F9=EAEA,AB20E=EAEA,AB51C=EAEA +4E2D90F4|Donkey Kong Country 2 - Version|10000005|40C00|0|0|A|FFFFFFF1|358246=EAEA,358414=EAEA,2E8093=EAEA,2E8455=EAEA,302401=EAEA,30A18D=EAEA,32035F=EAEA,358205=EAEA,35822F=EAEA,358241=EAEA,358250=EAEA,358426=EAEA,358431=EAEA,35843E=EAEA,358449=EAEA +448EEC19|Donkey Kong Country 3 - Dixie K|10000005|40C00|0|0|0|FFFFFFF1|32848C=EAEA,3B8A3A=EAEA +0551FE84|Donkey Kong Country 3 - Dixie K|10000007|40C00|0|0|0|0|32848C=EAEA,3B8A3A=EAEA +1889FEEF|Doom Troopers (U)|0|0|0|0|0|0|1AAB9=EAEA +CEEB7C32|Doomsday Warrior (U)|0|0|0|0|0|0|126=42DA +98A96AE8|Double Dragon V (U)|1|40000|0|0|0|FFFFFFFB|80C1=42D9,4D9D8=4299,4AEC7=42DB,4DAE4=4299,287C1=42FC,4DD20=42F2,4AD5D=42DB,4DE77=42F9,4AF05=42FB,4AEE6=42FB,49C4A=42F9,4821F=42F9 +63CE5132|Dr. Mario (J) (NP)|4|0|0|0|0|19|255C=EAEA,5C8=4218 +407C5C24|Dragon - Bruce Lee Story (U)|1|0|0|0|0|0|C569=EAEA,C56F=EAEA,C5B5=EAEA,C607=EAEA,C645=EAEA,C64A=EAEA,C667=EAEA,C680=EAEA,C68C=EAEA,C692=EAEA,C696=EAEA,C6BE=EAEA,C6C4=EAEA,C6C6=EAEA,1C0=421A +57A7072B|Dragon Ball Z - Hyper Dimension|4|840000|0|0|0|0|5872=EAEA,58ED=EAEA,59D5=EAEA,59ED=EAEA +8C7780BD|Dragon Ball Z - Super Butoden (|0|0|0|0|0|0|73B3=EAEA,73B7=EAEA,74AD=EAEA,80=EAEA,8C=EAEA +081FDE86|Dragon Ball Z - Super Butoden 2|8000000|40808040|0|0|0|0|B0=EAEA,2934=EAEA,2949=EAEA,295F=EAEA,2973=EAEA,298D=EAEA,29A9=EAEA,29E9=EAEA,2A8B=EAEA,2C35=EAEA,2C9D=EAEA,2CCD=EAEA,2CE4=EAEA,2CFE=EAEA,25C52=EAEA,31088=EAEA,310A3=EAEA,44A93=EAEA,44AA9=EAEA,16E26C=EAEA,1BFEBF=EAEA,1F8C0E=EAEA,194=4294,9228=429A,922E=42BA,55D57=42B4,571D8=42,152A67=421E,1896D7=DB +D531289B|Dragon Ball Z - Super Goku Den|4|40040800|0|0|0|0|1B809D=EAEA,147=42DC,670=42DC +67BD2296|Dragon Ball Z - Super Gokuuden|4|44040|0|0|0|28|1809D=EAEA,242=42DC,8E1=42DC +63D4E96A|Dragon Ball Z - Super Gokuuden|4|40040800|0|0|0|0|1B809D=EAEA,147=42DC,670=42DC +ADE7B968|Dragon Ball Z - Super Saiya Den|4|40000|0|0|0|20615|20615=EAEA,20620=EAEA,295E=421B,2D8=42BA,DC=4210,1035=EAEA +52FC7228|Dragon Knight 4 (J)|1000004|440800|0|0|0|0|105=42DC,113D=42DC,135=42DC +80C078FF|Dragon Quest 1 & 2 (T)|2230004|0|0|0|0|0|0=D87818FB,78FA=EAEA,7901=EAEA,7908=EAEA,790F=EAEA,5BD=42DC +13836BD2|Dragon Quest 3 (J)|5|0|0|0|0|0|1E119=EAEA,1E125=EAEA,1E131=EAEA,1DD93=EAEA,1DDC0=EAEA,1DDFF=EAEA,1DFC3=EAEA,27AA=DBE9 +BC955F3B|Dragon Quest 5 (J)|4|44804|0|0|0|0|127E20=EAEA,127E25=EAEA,127E20=EAEA,127E25=EAEA,15C37C=EAEA,15C0F8=EAEA,15C37C=EAEA,15C33E=EAEA,FD2D1=EAEA,15C100=EAEA,15C102=EAEA,15BEE1=EAEA,15C1A0=EAEA,360F9=EAEA,15C1A6=EAEA,127FA4=EAEA,127F9F=EAEA,23D6=EAEA,15BCA2=EAEA,1D407=EAEA,1D409=EAEA,1D40B=EAEA,1D410=EAEA,1D411=EAEA,1D4A1=EAEA,1D4AD=EAEA,1D46C=EAEA,15C195=EAEA,90396=EAEA,90351=EAEA,15C09B=42,C02=42,FD2D4=EAEA,FD2B2=EAEA,FD2B4=EAEA,FD2B8=EAEA,FD2BE=EAEA,FD2C1=EAEA,FD2C3=EAEA,15C049=EAEA +E1924A15|Dragon Quest 6 (J) [T-Eng0|10000005|440000|0|0|0|0|1F0F7=EAEA,1F0FB=EAEA,1F103=EAEA,1F107=EAEA,1F10F=EAEA,1F113=EAEA,1ED70=EAEA,1ED9D=EAEA,1EDDC=EAEA,1EFA0=EAEA,1EE51=EAEA,2223=4288 +B5AE1E89|Dragon Quest I & II|10000004|0|0|0|0|0|0=D87818FB,5BD=42DC,754B=EAEA,7584=EAEA,76D3=EAEA,7701=EAEA,78FA=EAEA,7901=EAEA,7908=EAEA,790F=EAEA,7943=EAEA,795B=EAEA,7966=EAEA,796B=EAEA,12A3D3=EAEA +33304519|Dragon Quest VI - Maboroshi no|10000005|440000|0|0|0|0|1F0F7=EAEA,1F0FB=EAEA,1F103=EAEA,1F107=EAEA,1F10F=EAEA,1F113=EAEA,1ED70=EAEA,1ED9D=EAEA,1EDDC=EAEA,1EFA0=EAEA,1EE51=EAEA,2223=4288 +81BF8718|Dragon's Earth (J)|8000000|404800|0|0|0|0|6E41=42D8 +24FFE7FD|Dragon's Lair (U)|0|0|0|0|0|0|4DF6=EAEA +AB5A9E40|Dream TV (U)|0|0|0|0|0|0|301=EAEA +EBCC121C|Dynamic Stadium (J)|0|0|0|0|0|0|7F=42FC +DD49911E|E.V.O. Search for Eden (U)|4|0|0|0|0|0|130406=EAEA,13031A=EAEA,130429=EAEA +DC9BB451|Earthbound (U)|5|0|0|0|0|FFFFFFF6|AB93=EAEA,281D=EAEA,83A2=800E1A8FF07F32CFF07F3080,A12D=80,1FFE7=EAA90000,3FDD6=EAA9000080,8762=42FB +3A4A47EB|Earthworm Jim|4000001|0|5114|0|32|0|30169=DB +393DE197|Earthworm Jim 2 (U)|1|0|0|0|0|0|EB99=EAEA,EBC5=EAEA,ED96=EAEA,EDC4=EAEA,EABB=EAEA,E2B4=EAEA,582A=42FC +F0AEAD80|Edo No Kiba (J)|14000001|44800|0|0|0|0|E00A8=EAEA,759=42FC +EEC5A5B1|Edono Kiba (J)|14000001|44800|0|0|0|0|E00A8=EAEA,759=42FC +41E9CD70|Eien no Filena (J)|4|0|0|0|0|0|14DB62=EAEA,14DB96=EAEA,14DBB1=EAEA,14DBB9=EAEA,14DCC4=EAEA,14DFFC=EAEA,14E00E=EAEA,14E02B=EAEA,14E036=EAEA,14E058=EAEA,14E067=EAEA,14E078=EAEA,14E084=EAEA,14E0C4=EAEA,14E0DB=EAEA,14E0E6=EAEA,11A=423B,11F=421B,137=42D7,2296=42D9,2408=42D7,681F=42D9,1276B=42BA,12D63=42BA,1577D4=4251 +F70F2A95|Energy Breaker (J)|4000004|0|0|0|0|0 +BDBF64B3|Energy Breaker (J) [T-Eng]|4|0|0|0|0|0|17F2E8=428A,1813F3=42,1B64E0=4270,1BA050=42D0,1BA3AE=42BA,1BEE5F=42,1C17A0=DB,30D24D=DBF6,30E115=4210,766E=EAEA,7930=EAEA,7985=EAEA,7A94=EAEA,7C2E=EAEA,7C46=EAEA,7C51=EAEA,7C56=EAEA,20C291=EAEA,20F33F=EAEA +634344A0|Esparks - Ijigen kara no Houmon|5|0|0|0|0|0|DC819=EAEA,DC827=EAEA,DC83D=EAEA,DC849=EAEA,DC857=EAEA,DC86D=EAEA,DC888=EAEA,DC8BB=EAEA,DCA08=EAEA,DCA3B=EAEA,DCA64=EAEA,DCA9D=EAEA,DCAAD=EAEA,DCAC2=EAEA,DCADE=EAEA,DCB1C=EAEA,DCB2F=EAEA,DCB55=EAEA,DCB81=EAEA,DCB90=EAEA,DCBA8=EAEA,DCBB9=EAEA,DCBD4=EAEA,DCBEC=EAEA,DCBF7=EAEA,DCBFC=EAEA,DCC3D=EAEA,9AFD=42D9,966DC=42,DE559=4251,ECBDA=42D1 +26849F90|ESPN Sunday Night NFL (U)|4|0|0|0|0|0|1EAE57=EAEA,1EAE7C=EAEA +D9665BBC|Estpolis Denki II (J)|8000004|4044C00|0|0|0|0|69350=42FC,86=42DC,19010=42FC,69F11=42FC +2C6EB470|Euro Football Champ (E)|2|0|0|0|0|0|54=428E +440A4250|Extra Innings (U)|4|0|0|0|0|0|407=EA +AA0E31DE|F-Zero (U)|4|0|0|0|0|0|7819=EAEA,7831=EAEA,783C=EAEA,7841=EAEA,619=425B +7049AAE8|F1 Pole Position (u)|4|0|0|0|0|0|298=EAEA +2CE70B92|Famicom Tantei Club Part II (J)|4|0|0|0|0|0|219=4218 +1E327BD9|Far East of Eden Zero (J)|2|0|0|0|0|0|3157=EAEA,3197=EAEA,31AE=EAEA,31CA=EAEA,34EE=EAEA,34FA=EAEA,3506=EAEA,3518=EAEA,37F9=EAEA,3816=EAEA,3857=EAEA,385D=EAEA,398B=EAEA,3997=EAEA,39CA=EAEA,3A17=EAEA,3A38=EAEA,6FB6B=EAEA,6FBB1=EAEA,1DA793=EAEA,297691=EAEA,3F2F31=EAEA,46FBA3=EAEA,49CAD3=EAEA,4A5170=EAEA,4B1786=EAEA,F25A=42,F2A7=DB,F732=42,F8CD=42,FADC=42,10381=42D9,164A58=DB,47F43D=421E,4AB668=DB +0ED3DCF2|Farland Story (J)|5|0|0|0|0|0|1D129A=EAEA,1D0192=EAEA,4153F=42FB,413B2=42FB,4C9=42FB,40C00=42DC,1D12C3=42DB +1CF58DE9|Farland Story 2 (J)|5|800|0|0|0|0|2D01F3=EAEA,2D0196=EAEA,390=42FB,2D021C=42DB +C67257D0|Fatal Fury (U)|0|0|0|0|0|0|37C=42D8 +A26EBFEF|Fatal Fury 2 (U)|1|0|0|0|0|0|578CC=EAEA,578F1=EAEA,572A8=42FC +93935BEE|Fatal Fury Special (U)|1|0|0|0|0|0|C2A=42FB +EDA70F8A|Feda - Emblem of Justice (J)|5|0|0|0|0|0|5057B=EAEA,503B0=EAEA,503EC=EAEA,50423=EAEA,50453=EAEA,5047C=EAEA,504B0=EAEA,E9E=42DC,23A8=42D4,1017C=42D8,218C7=42D1,10401=42D1,503B4=42D2,F62=42D4,90385=42D4,19DE=42D4,11E67=42D4 +7D36ECD7|Feda - The Emblem of Justice (J|5|0|0|0|0|0|5057B=EAEA,503B0=EAEA,503EC=EAEA,50423=EAEA,50453=EAEA,5047C=EAEA,504B0=EAEA,E9E=42DC,23A8=42D4,1017C=42D8,218C7=42D1,10401=42D1,503B4=42D2,F62=42D4,90385=42D4,19DE=42D4,11E67=42D4 +65D0A825|ff2|10000004|0|0|0|0|0|F24=42DC,F15=42DC,BED=42,10524=42,20033=EAEA,20063=EAEA,20077=EAEA,200AA=EAEA,20235=EAEA,202D6=EAEA,202FA=EAEA,20311=EAEA,20374=EAEA,20385=EAEA,203A1=EAEA,204AB=EAEA,20547=EAEA,2056F=EAEA,205C7=EAEA,205D8=EAEA,205FA=EAEA,20610=EAEA +CAA15E97|FF4 (J)|4|0|0|0|0|0|F24=42DC,F15=42DC,BED=42,10524=42,20033=EAEA,20063=EAEA,20077=EAEA,200AA=EAEA,20235=EAEA,202D6=EAEA,202FA=EAEA,20311=EAEA,20374=EAEA,20385=EAEA,203A1=EAEA,204AB=EAEA,20547=EAEA,2056F=EAEA,205C7=EAEA,205D8=EAEA,205FA=EAEA,20610=EAEA +D5CC300E|ff4e|4|0|0|0|0|0|F24=42DC,F15=42DC,BED=42,10524=42,20033=EAEA,20063=EAEA,20077=EAEA,200AA=EAEA,20235=EAEA,202D6=EAEA,202FA=EAEA,20311=EAEA,20374=EAEA,20385=EAEA,203A1=EAEA,204AB=EAEA,20547=EAEA,2056F=EAEA,205C7=EAEA,205D8=EAEA,205FA=EAEA,20610=EAEA +C1BC267D|FF5 (J)|10000005|0|0|0|0|0 +170778FA|ff6e|5|0|0|0|0|0 +250B44BA|FFMISTIC|10000004|40C00|0|0|0|0|68047=EAEA,68068=EAEA,6807A=EAEA,680CD=EAEA,680FD=EAEA,68114=EAEA,68121=EAEA,6819B=EAEA,681A3=EAEA,681B9=EAEA,681C1=EAEA,681CB=EAEA,681DC=EAEA,681E4=EAEA,68214=EAEA,6821C=EAEA,6822F=EAEA,6828C=EAEA,6839E=EAEA,683C7=EAEA,683DD=EAEA,68437=EAEA,684CA=EAEA,6855F=EAEA,685D0=EAEA,685D6=EAEA,685F0=EAEA +A27F1C7A|Final Fantasy 3 (V1.0) (U)|10000005|44C00|0|0|0|0|28236=42DC,B7A3=EAEA,568=42FC,B80A=EAEA,109B9=EAEA,50055=EAEA,500A6=EAEA,500D6=EAEA,500ED=EAEA,500FA=EAEA,501B8=EAEA,5027C=EAEA,50391=EAEA,503E1=EAEA,5044C=EAEA,50489=EAEA,504B0=EAEA,504CB=EAEA,504F2=EAEA,50521=EAEA,5059B=EAEA,505C5=EAEA,5064A=EAEA,50662=EAEA,506A4=EAEA,506B2=EAEA,71796=EAEA,83440=EAEA,25F824=EAEA,25F855=EAEA,25F8D0=EAEA,295AF6=EAEA,2E1889=EAEA +892E44BE|Final Fantasy 5|5|0|0|0|0|0 +17444605|Final Fantasy 5 (Translated)|10000005|0|0|0|0|0|387BB=42DC,4E45=42FC,422=EAEAEA +8D66F796|Final Fantasy 5 (Translated)|10000005|40C00|0|0|0|0|422=EAEAEA,10397=421A,11A88=42D5,1EA6C=421A,1F77A=421A,2A10D=423A,2A113=421A,4CE48=42,4F07A=DBFE,1BF7CC=DB,387BB=42DC,4E45=42FC +45EF5AC8|Final Fantasy 6 (J)|10000005|44C00|0|0|0|0|B6D8=421B,B6D8=EAEA,B73F=421B,B73F=EAEA,568=42FC +23084FCD|Final Fantasy II|0|0|0|0|0|FFFFFFE7|F24=42DC,F15=42DC,BED=42,10524=42,20033=EAEA,20063=EAEA,20077=EAEA,200AA=EAEA,20235=EAEA,202D6=EAEA,202FA=EAEA,20311=EAEA,20374=EAEA,20385=EAEA,203A1=EAEA,204AB=EAEA,20547=EAEA,2056F=EAEA,205C7=EAEA,205D8=EAEA,205FA=EAEA,20610=EAEA +D19F6CB5|Final Fantasy V (J) [T+Eng1|10000005|0|0|0|0|0|B7D8=EAEA,B7E0=EAEA,3FE4A=EAEA,3FE6E=EAEA,3FE81=EAEA,3FED2=EAEA,3FF02=EAEA,3FF19=EAEA,3FF26=EAEA,3FFA0=EAEA,3FFA8=EAEA,3FFB2=EAEA,3FFC3=EAEA,3FFCB=EAEA,3FFF3=EAEA,3FFFB=EAEA +87C13675|Final Fantasy V (J) [T+Eng1|10000006|0|0|0|0|0|387BB=42DC,4E45=42FC,422=EAEAEA +4CAB21DB|Final Fight|0|0|7E0D0A|0|1E|0|81F5=EAEA,8231=EAEA,FA=421C +8C37FF55|Final Fight 2 (U)|0|0|7E1019|0|1E|0|966=42DB +A916E708|Final Fight 3 (U)|1|0|0|0|0|0|66F3=42F4 +BC1AE3C2|Final Fight Guy (US)|0|0|0|0|0|0|8456=EAEA,8312=EAEA,836C=EAEA +25D214F4|Fire Emblem - Monsyo no Nazo (V|4|0|0|0|0|0|3969=EAEA,3977=EAEA,39CC=EAEA,39DD=EAEA,39F0=EAEA,3A24=EAEA,3A56=EAEA,3A5B=EAEA,3A8A=EAEA,3AA2=EAEA,3AAD=EAEA,3AB2=EAEA,3CA5=EAEA,3CBE=EAEA,1C9A35=EAEA +DC0D8CF9|Fire Emblem 4 - Seisen no Keifu|5|0|0|0|0|0 +BC6162AE|Fire Emblem 5 Trachia 776 (J) (|4|0|0|0|0|0 +FC519952|Fire Emblem 5 Trachia 776 (Rom|4|0|0|0|0|0 +E500C7BA|Fire Striker (U)|0|0|0|0|0|0|96=42D9 +1E6ACEBA|Flashback - The Quest for Ident|1|0|0|0|0|0|190098=EAEA,1900B0=EAEA,1900BB=EAEA,1900C0=EAEA,1900EE=EAEA,1900FD=EAEA,190497=EAEA,1904C6=EAEA,1904F5=EAEA,19052C=EAEA,190560=EAEA,190588=EAEA,80A2=42D9,8183=42,15974=42,15991=42,159CF=42,159EC=42,15B60=42,16220=42,1628E4=4259 +3E7B51E0|Flintstones, The (U)|0|0|0|0|0|0 +5FA4D051|Foreman For Real (U)|0|0|0|0|0|0|11791=42F2 +21239DDA|Frank Thomas' Big Hurt Basebal|4|0|0|0|0|0|44F4=42FC,44D9=42FC,39104=42FC,39159=42FC,1E445=42FC,1E4AC=42FC,1F4F7=42FC,1F6CC=42FC,12126=42FC +FFA8D1FF|Frantic Flea (U)|0|0|0|0|0|0|1A424=EAEA,1A547=EAEA,1A4EF=EAEA,1A3FB=EAEA,1A4C4=EAEA,1A399=EAEA,1A45E=EAEA,1A49B=EAEA,8138=42FB +2488B8F2|Frogger (U)|0|0|0|0|0|0|7F353=EAEA,7F378=EAEA,7ED2F=42FC +2B4CD5A3|Front Mission (J) (V1.0)|5|40800|0|0|0|0|2A0A1B=EAEA,258A=42FB +5847D80F|Front Mission - Gun Hazard (J)|18000005|840C00|0|0|0|0|2A005B=EAEA,2A07E2=EAEA,2A0664=EAEA,2A0659=EAEA,1006B=42F7,10093=42F7,59B=42FB,6FB=42D0 +FD3FDBAC|Front Mission 2 - Gun Hazard (J|18000005|840C00|0|0|0|0|2A005B=EAEA,2A07E2=EAEA,2A0664=EAEA,2A0659=EAEA,1006B=42F7,10093=42F7,59B=42FB,6FB=42D0 +AF5703EE|Fushigi no Dungeon 2 - Furai n|5|40000084|0|0|0|0|18133=428E +79114FD0|G Gundam|1320001|0|0|0|0|0|8B3=42DB +B344E9A0|Gaia Gensouki (J)|28176=421A,2A116=EA,2A865=EA,39D4F=EA,497BA=EA,581D4=EA,5D931=EA,6913F=EA,8D7E2=EA,8E471=EA,8E8AB=EA +6CD62399|Ganbare Goemon - Yukihime Kyusy|10000000|840000|0|0|0|0|C2=4280 +CA4C0219|Ganbare Goemon 2 (J)|4|0|0|0|0|0|3A5A=EAEA,DB=4284 +7E5929E8|Ganbare Goemon 3 (J)|4|0|0|0|0|0|F3=4280,249C3=EAEA,24865=EAEA,1B0=4230 +BB9D8E56|Ganbare Goemon 4 - KiraKira Dot|4|0|0|0|0|0|704=EAEA,70B=EAEA,712=EAEA,744=EAEA,74B=EAEA,752=EAEA +EE801A54|Gemfire|6|0|0|0|0|0|1583=42DB,14C2=42D9,1155=42D9,1290=42D9,1539=42D9,1274=42D9,1217=42D9 +C8E8853E|Genghis Khan II - Clan of the G|4|0|0|0|0|0|3778=EAEA,37A4=EAEA,37AF=EAEA,37B4=EAEA,4E4=DB,10E9=42BA,38C0=42D9,3CE2=42D9 +EA16B5A2|Ghoul Patrol (U)|0|40C04|0|0|0|0|CFF4=EAEA,D00C=EAEA,D017=EAEA,D01C=EAEA,D061=EAEA,D068=EAEA,D082=EAEA,D0BC=EAEA,D0D3=EAEA,D0E6=EAEA,D113=EAEA,D135=EAEA,EE890=EAEA,256=42BA +019309A2|Ginga Eiyu Densetsu (J)|0|44800|0|0|0|0|407=42FC +04EE98ED|Gokujyou Parodius (J)|0|840000|7E0BCE|0|23|0|346A=EAEA,330B=EAEA,12C=4280 +426881A3|Gon (J)|0|0|0|0|0|0 +CD973979|Gradius 3|4000000|0|20E|0|32|0|1C7=428A +1903EA89|Great Circus Mystery Starring M|1|0|0|0|0|0|19D9=4290,1A64=42D9,1DB5=428E +1F73C832|GT Racing (J)|4|0|0|0|0|0 +6F5C5DC0|Gun Force|0|40000|9004|0|1E|5 +8E0A7034|Hagane (U)|1|0|0|0|0|0|D1E3=EAEA,D36E=EAEA,D394=EAEA,D32B=EAEA,D2C5=EAEA,D292=EAEA,D297=EAEA,D256=EAEA,D25B=EAEA,D398=EAEA,D086=EAEA,D08E=EAEA,D092=EAEA,3238=421B +58752BAF|HAL's Hole in One Golf|0|40C00|0|0|0|0|4F41=EAEA,5DF7=EAEA,5E39=EAEA,844E=EAEA,8546=EAEA,865C=EAEA,8826=EAEA,89C8=EAEA,9A12=EAEA,9A20=EAEA,B2FE=EAEA,D08F=EAEA,D27A=EAEA,FDA8=EAEA,FE04=EAEA,5EB46=EAEA,5EBE4=EAEA +B78F76BF|Hanjuku Eiyuu - Aah Sekai yo Ha|4|0|0|0|0|0 +D191AD46|Hanjuku Eiyuu - Aah Sekai yo Ha|4|0|0|0|0|0 +D54E1452|Harvest Moon (E) [!]|6|0|7E0147|0|1E|2A|18EC3=EAEA,18E52=EAEA,18E70=EAEA,18E79=EAEA,185CC=EAEA,18612=EAEA,1865E=EAEA,186A5=EAEA,1871D=EAEA,18762=EAEA,184F1=EAEA,18531=EAEA,18560=EAEA,1858D=EAEA,656=42FC,18ED5=42D2,18EDC=EAEA,189F1=EAEA,18A0A=EAEA,18A44=EAEA,18A81=EAEA,18AC7=EAEA,18AF4=EAEA,18803=EAEA,1884A=EAEA,18896=EAEA,188DB=EAEA,188DD=EAEA,18955=EAEA,1899A=EAEA,18B20=EAEA,18B7E=EAEA,18BCA=EAEA,18C11=EAEA,18C89=EAEA,18CD0=EAEA,18D3C=EAEA,18D5A=EAEA,18D85=EAEA,15943=42FA,18EF7=42DB,18E00=42DB,18E2C=EAEA,15811=42FA,18DAE=EAEA,18DD7=80,189D3=EAEA,87=42FA,1534F=42F6 +F829129E|Harvest Moon (U)|4|0|7E0147|0|1E|2A|18EC3=EAEA,18E52=EAEA,18E70=EAEA,18E79=EAEA,185CC=EAEA,18612=EAEA,1865E=EAEA,186A5=EAEA,1871D=EAEA,18762=EAEA,184F1=EAEA,18531=EAEA,18560=EAEA,1858D=EAEA,656=42FC,18ED5=42D2,18EDC=EAEA,189F1=EAEA,18A0A=EAEA,18A44=EAEA,18A81=EAEA,18AC7=EAEA,18AF4=EAEA,18803=EAEA,1884A=EAEA,18896=EAEA,188DB=EAEA,188DD=EAEA,18955=EAEA,1899A=EAEA,18B20=EAEA,18B7E=EAEA,18BCA=EAEA,18C11=EAEA,18C89=EAEA,18CD0=EAEA,18D3C=EAEA,18D5A=EAEA,18D85=EAEA,15943=42FA,18EF7=42DB,18E00=42DB,18E2C=EAEA,15811=42FA,18DAE=EAEA,18DD7=80,189D3=EAEA,87=42FA,1534F=42F6 +DD792499|Hashire Hebereke (J)|4|0|0|0|0|0|902=421A,938=421A,946=421A,9C3=421A,BCB=42BA +46ACFC84|Holy Striker (J)|0|0|0|0|0|0 +07C494B1|Home Alone|0|0|0|0|0|0|1C1=EAEA,3D9=EAEA,3FB=EAEA,40D=EAEA,429=EAEA,443=EAEA,44E=EAEA,453=EAEA,48E=EAEA,499=EAEA,4AE=EAEA,4C5=EAEA,4DC=EAEA,4E9=EAEA,4F9=EAEA +D19165D9|Home Alone 2 - Lost in New York|10000000|4000|0|0|0|0|72630=EAEA,7263B=EAEA,72650=EAEA,72695=EAEA,7269A=EAEA,726AB=EAEA,726B0=EAEA,726D3=EAEA,726F0=EAEA,7270A=EAEA,72715=EAEA,7271A=EAEA,72752=EAEA,72763=EAEA,72771=EAEA,7282B=EAEA,72836=EAEA,7284D=EAEA,72879=EAEA,7289F=EAEA,7237A=42 +FA698C31|Home Improvement (U)|0|0|0|0|0|0|5FAE1=EAEA,64911=EAEA,6492B=EAEA,64936=EAEA,6493B=EAEA,64A15=EAEA,64A33=EAEA,64AE9=EAEA,64B04=EAEA,64B16=EAEA,64B29=EAEA,64B38=EAEA,64B48=EAEA,64B67=EAEA,64B79=EAEA,64B8C=EAEA,64B9B=EAEA,64BB8=EAEA,64BE0=EAEA,1D0E8=DB,414E4=42,6083D=4210,60EE3=DBFC +D2AF01D4|Humans, The|2|0|0|0|0|0|24F6=EAEA,2521=EAEA,252C=EAEA,2531=EAEA,256A=EAEA,2585=EAEA,2590=EAEA,C646=EAEA,C6FC=EAEA,CD78=EAEA,1F39=423A,1FA5=42 +C796E830|Hunt for Red October (U)|0|0|0|0|0|0 +7D179E21|Hyper V-Ball (U)|0|0|0|0|0|0|E5=EAEA,D1=EAEA,CE27=EAEA,305=423C +EE441564|Ignition Factor (U)|1|0|0|0|0|0|9639=42D9,96B9=4237,96C2=4217,C000=42D9,C137=42D9,F408=423B,F40D=421B,F42C=42DD,ABCFC=DB,F31C6=4230,F8713=421F +1C3848C0|Illusion of Gaia (U)|5|0|0|0|5|0|3C75E=EAEA,28051=EAEA,8359=42BA,281CE=42D9,86541=DB,A6B23=DB64,B1BD9=42,DF223=4212,122D21=42BD +9D104C99|Illusion of Time (E)|6|0|0|0|0|0|38F=EAEA,10BA8=EAEA,10BAF=EAEA,110B5=EAEA,1113B=EAEA,11146=EAEA,1114B=EAEA,11183=EAEA,111A7=EAEA,111BF=EAEA,111CA=EAEA,111CF=EAEA,111FC=EAEA,120AA=EAEA,1E21F=EAEA,219B1=EAEA,2D27E=EAEA,3125C=EAEA,46FB8=EAEA,4C5C8=EAEA,5E6E6=EAEA,90EE2=EAEA,99340=EAEA,C0ACB=EAEA,F20CA=EAEA,106D87=EAEA,113C93=EAEA,1512B0=EAEA,156523=EAEA,15889E=EAEA,177B32=EAEA,186AFA=EAEA,188AC7=EAEA,35C=42BA,101CE=42D9,6F223=4212,146541=DB,1552ED=DB64,1583CC=42,192154=42BD +2624F8BD|Imperium (U)|18000000|40404|0|0|0|0|B8426=EAEA,B842E=EAEA,B843F=EAEA,B8444=EAEA,3362=421B,3354=4219,33C2=42D3 +D0FF7E9F|Incantation (U)|0|0|0|0|0|0 +0B6209BA|Incredible Crash Dummies, The (|0|0|0|0|0|0 +36B5A429|Incredible Hulk, The (U)|0|0|0|0|0|0 +70DA6BB8|Indiana Jones - Trilogy (US)|10000000|40844000|0|0|0|0|2E9=423C,1FD23C=42FC,E3A=42F8,1FAD4F=42F8,1FD17E=42DC,1FD1B8=42DC,1FF77C=42DC,1FF794=42D1,1FD316=42D5,1FF763=42 +0A20E602|International Superstar Soccer|0|440404|0|0|0|0|4337=EAEA,41D7=EAEA,DE=4284 +49627238|International Superstar Soccer|0|40000|0|0|0|0|2ABC=EAEA,294D=EAEA,295B=EAEA,F9=4284 +CBA724BA|International Superstar Soccer|2|440404|0|0|0|0|4337=EAEA,41D7=EAEA,DE=4284 +CD2150C8|J.R.R|0|0|0|0|0|0|8EF3=EAEA,8EF9=EAEA,8F37=EAEA,8F5B=EAEA,8F6E=EAEA,83A1=EAEA,83BC=EAEA,F4=42DB,7C=42DB,C6=42DB,E2E=42,83C2=42D4,19D1=421A,188D=421A +66F00725|James Pond's Crazy Sports (E)|2|0|0|0|0|0|170B0=EAEA,F55C=EAEA +3E3073CE|Jetsons (U)|10000000|4040|0|0|0|0|E0048=EAEA,E03D6=EAEA,1ED=42F9 +3A2B6167|Joe & Mac (U) [!]|0|0|0|0|0|0|1622=42FC +3511EFB3|Jungle Book, The (U)|0|840000|0|0|0|0 +8A926D1A|Jurassic Park II - The Chaos Co|10000002|44800|0|0|0|0|1180F6=EAEA,11811D=EAEA,118125=EAEA,11814C=EAEA,118154=EAEA,11817B=EAEA,118183=EAEA,1181AA=EAEA,149A0F=EAEA,149A36=EAEA,118420=EAEA,118447=EAEA,1C32F1=EAEA,1C3481=EAEA,1C348E=EAEA,1C34C4=EAEA,1C394C=EAEA,1C56C8=EAEA,1C3D0A=EAEA,1C3D40=EAEA,1C5774=EAEA,1C6C5B=EAEA,1C6C97=EAEA,1C6CBE=EAEA,1C42E7=EAEA,1C5216=EAEA,1C524C=EAEA,1C533D=EAEA,1C4A43=EAEA,1C4A79=EAEA,1C371E=EAEA,1C3754=EAEA,1C75F6=EAEA,1C45AF=EAEA,1C45E5=EAEA,1C461B=EAEA,1C1D16=EAEA,1C25E7=EAEA,1499B5=EAEA,1499BD=EAEA,1499E4=EAEA,F03E2=EAEA,F0409=EAEA,1498F2=EAEA,149919=EAEA,118465=EAEA,11848C=EAEA,1C2086=EAEA,14998E=EAEA,149921=EAEA,149948=EAEA,149950=EAEA,149977=EAEA,149850=EAEA,149877=EAEA,14987F=EAEA,1498A6=EAEA,F042C=EAEA,F0453=EAEA,E27B6=EAEA,E27DD=EAEA,E2A99=EAEA,E2AC0=EAEA,E2F11=EAEA,E2B28=EAEA,E2B4F=EAEA,E2CDD=EAEA,E2F38=EAEA,F0CC5=EAEA,E2D04=EAEA,F0CEC=EAEA,149779=EAEA,1497A0=EAEA,F15D9=EAEA,F1600=EAEA,F1702=EAEA,F1729=EAEA,F1738=EAEA,F175E=EAEA,506=EAEA,52D=EAEA,E3298=EAEA,E32BF=EAEA,E2D89=EAEA,E2DB0=EAEA,E2EDD=EAEA,E2F04=EAEA,149530=EAEA,E2F45=EAEA,1180DF=42FC,118383=42FC,118345=42FC,1C00E0=42FB,1C6425=42DB,7D2=42FC +836EE990|Jurassic Park Part 2 -The Chao|0|440800|0|0|0|0|1180F6=EAEA,11811D=EAEA,118125=EAEA,11814C=EAEA,118154=EAEA,11817B=EAEA,118183=EAEA,1181AA=EAEA,149A0F=EAEA,149A36=EAEA,118420=EAEA,118447=EAEA,1C81BE=EAEA,1C81E5=EAEA,1C7322=EAEA,1C734B=EAEA,1C75E8=EAEA,1C32F1=EAEA,1C3489=EAEA,1C34BF=EAEA,1C3947=EAEA,1C56BA=EAEA,1C3D05=EAEA,1C3D3B=EAEA,1C6417=EAEA,1C5766=EAEA,1C57AE=EAEA,1C6C4D=EAEA,1C6C89=EAEA,1C6CB0=EAEA,1C42E2=EAEA,1C4318=EAEA,1C4357=EAEA,1C5208=EAEA,1C532F=EAEA,1C52B9=EAEA,1C4A35=EAEA,1C4A6B=EAEA,1C3719=EAEA,1C45AA=EAEA,1C45E0=EAEA,1C4616=EAEA,1C252C=EAEA,1C25E7=EAEA,1C2086=EAEA,14998E=EAEA,118465=EAEA,11848C=EAEA,1C72FB=EAEA,1C1D16=EAEA,1499B5=EAEA,1499BD=EAEA,1499E4=EAEA,F03E2=EAEA,F0409=EAEA,1498F2=EAEA,149919=EAEA,149921=EAEA,149948=EAEA,149950=EAEA,149977=EAEA,149850=EAEA,149877=EAEA,14987F=EAEA,1498A6=EAEA,F042C=EAEA,F0453=EAEA,E27F1=EAEA,E2818=EAEA,E2F4C=EAEA,E2F73=EAEA,E2AD4=EAEA,E2AFB=EAEA,E2B63=EAEA,E2B8A=EAEA,E2D18=EAEA,F0CC5=EAEA,E2D3F=EAEA,F0CEC=EAEA,149779=EAEA,1497A0=EAEA,F15D9=EAEA,F1600=EAEA,F1702=EAEA,F1729=EAEA,F1738=EAEA,F175E=EAEA,4FB=EAEA,5FC=EAEA,522=EAEA,6B0=EAEA,623=EAEA,6D7=EAEA,E32D3=EAEA,E32FA=EAEA,E2DC4=EAEA,E2DEB=EAEA,E2F18=EAEA,E2F3F=EAEA,149530=EAEA,149557=EAEA,1C6CF7=EAEA,1C6D1E=EAEA,1C6D45=EAEA,1180DF=42FC,118383=42FC,118345=42FC,1C00E0=42FB,7C7=42FC +1D151D45|Jyutei Senki (J)|5|0|0|0|0|0 +457F32B5|Jyutei Senki (J) [t-eng]|10000005|4040|0|0|0|0 +B2592EAE|Kablooey (U)|0|0|0|0|0|0 +AD324F9D|Kabuki Rocks (J)|4|0|0|0|0|0 +8BF2B589|Ken Griffey Jr's. Baseball (U)|4|40C00|0|0|0|0|1A15=EAEA,1A57=EAEA,1AD6=EAEA,1AE6=EAEA,253FB=EAEA,25525=EAEA,2555C=EAEA,25583=EAEA,2559E=EAEA,1E8B12=EAEA +BD6C8AB1|Kid Klown in Crazy Chase (U)|0|0|0|0|0|0 +252C1DA7|Killer Instinct (V1.0) (U)|10000001|0|0|0|0|0|1F2A0=EAEA,F2B4=42 +09E9A04E|Killer Instinct (V1.1) (U) [!]|10000001|44040|0|0|0|0|1F25B=EAEA,F26C=42 +DD505DF7|King of Dragons, The (U)|1|0|0|0|0|0|41F60=EAEA,420E3=EAEA +B41AECCC|King of the Monsters 2(J)|1000001|0|0|0|0|0|14026D=EAEA,140189=EAEA,14018E=EAEA,1B0=42DC +0B677A37|King of the Monsters 2(U)|1|0|0|0|0|0|140285=EAEA,14028A=EAEA,1401A6=EAEA,1401AB=EAEA,1EE=42DC +5C869CA5|Kinnikuman - Dirty Challenger |0|44C00|0|0|0|0|F54=42D7,4993=42DA,F62=42DA,F85=42FB +2A24FC9B|Kirby Bowl (J) [!]|10000004|44C00|0|0|0|0|2C32=EAEA,2C3D=EAEA,2C42=EAEA,2C74=EAEA,3805=EAEA,389E=EAEA,38B4=EAEA,38E4=EAEA,38F5=EAEA,3903=EAEA,1C5=42DD,47E=423A,484=421A,89A21=DB +21E658B8|Kirby's Avalanche (U) [!]|10000000|840000|0|0|0|0|FF1=EAEA,106E=EAEA,1010=EAEA,103C=EAEA,CF=42FC,2407B=42DB,5AA=42 +995CC0A3|Kirby's Dream Course|18000004|40C00|0|0|0|0|2A95=EAEA,3716=EAEA,3724=EAEA,36D5=EAEA,36BF=EAEA,3705=EAEA,474=42 +DF8153D9|Kirby's Dream Course (U)|18000004|40C00|0|0|0|0|2A95=EAEA,3716=EAEA,3724=EAEA,36D5=EAEA,36BF=EAEA,3705=EAEA,474=42 +134DB760|Kirby's Dream Course (U)|18000004|40C00|0|0|0|0|2A95=EAEA,3716=EAEA,3724=EAEA,36D5=EAEA,36BF=EAEA,3705=EAEA,474=42 +81079934|Kishin Korinden ONI (J)(44230)|8000005|0|0|0|0|0 +AAA82126|Knights of the Round (U)|0|40000|0|0|0|0|71=42 +4390D719|Lady Stalker - Kako Kara no Ch|5|800|0|0|0|0|26041D=EAEA,2603D0=EAEA,2603E7=EAEA,2603FA=EAEA,2603A5=EAEA,2C623=EAEA,1EE0=423C,1F0C=423C +D2554270|Lagoon (U)|4|0|0|0|0|0|14B=EAEA,20E=42D9,4E6=42DB,3BB=42DA,9B1=42D9 +91633D95|Last Action Hero (E)|2|0|0|0|0|0|6F2=42FA,D1DAB=42FB,D1DFD=42FB,D1DD6=42FB,D04A4=42FB,D1D8A=421A,37DB8=42DB,5F8=421B +8254A32E|Last Fighter Twin (J)|4000000|400808|0|0|0|0|1103=42D7,BB5=42D8 +42E3774E|Legend (U)|0|0|0|0|0|0|38022=EAEAEAEA,D9=42FC +82479D6A|Legend of the Mystical Ninja|16000000|840000|0|0|0|0|C2=4280 +777AAC2F|Legend of Zelda, The - A Link t|4|0|0|0|0|0|36=42,E7=EAEA,894=EAEA,8B6=EAEA,8C1=EAEA,8C6=EAEA,BF1B=EAEA,BF5F=EAEA,C15C=EAEA,1056E=EAEA +B28B2F77|Legend of Zelda, The - Zelda no|4|0|0|0|0|0|36=42,E7=EAEA,894=EAEA,8B6=EAEA,8C1=EAEA,8C6=EAEA,BF1B=EAEA,BF5F=EAEA,C15C=EAEA,1056E=EAEA +51E3D566|Lemmings (V1.1) (U) [!]|0|0|0|0|0|0|42058=423C,B58F=423C,A201=42FC +C68BE22A|Lennus II - Fuuin no Shito (J)|5|400800|0|0|0|0|CAA0=EAEA,CAA4=EAEA,CAB0=EAEA,CAB4=EAEA,A626=42DC +8A46ED37|Lion King, The (E)|3|0|0|0|0|0 +B916334C|Little Master - Niji Iro no Mas|4|0|0|0|0|0|B801=42FC,63D1=42 +1EAFB345|Live A Live (J) [T+Eng V1|5|0|0|0|0|0 +6AEF6D1E|Lodoss Tou Senki (J)|4|4040404|0|0|0|0|60030=EAEA,60060=EAEA,60074=EAEA,600A7=EAEA,60168=EAEA,6018A=EAEA,60328=EAEA,603CE=EAEA,603F2=EAEA,60476=EAEA,60487=EAEA,604A3=EAEA,605D4=EAEA,606B9=EAEA,606E5=EAEA,6077A=EAEA,607AD=EAEA,607C2=EAEA,CEDC6=EAEA,24B=4280,41E=42D9,46A=421B,484=42,4C0=42,40174=428E,413EA=42BA,6BEA9=DBFF,C3B58=421B +6838BE08|Lost Vikings, The (U)|0|0|0|0|5|0|28D83=EAEA,28DF6=EAEA,28E09=EAEA +5E1AA1A6|Lufia & The Fortress of Doom (U|4|440|0|0|0|0|E00=EAEA,800A=EAEA,A856=EAEA,E57=EAEA,E71=EAEA,ED5=EAEA,EF0=EAEA,1038=EAEA,109B=EAEA,10F5=EAEA,2581=42,852A=42DB,8089=42,BE5E=42DB,4FB3=42,91AF=42DB,9FD8=42DC,4191D=42 +20F2AC29|Lufia II - Rise of the Sinistra|0|0|0|0|0|0|86=EAEA,19010=42FC +FDB80165|Lufia II - Rise of the Sinistra|6|0|0|0|0|0 +DDF832E8|Macross (J)|0|4000|0|0|0|0|E611=EAEA,E61C=EAEA +A7D31544|Madden NFL '94 (E) [!]|3|0|0|0|0|0 +27325E4D|Magic Sword (U)|0|40000|0|0|0|0|4166=EAEA,4D8=42DB,44A4=42DB,4251=42DB,1E9=42DB,272=42DB,41E0=42DB,4B53=42DB,214=42DB +D721EEE0|Marchen Adventure Cotton 100% (|0|0|0|0|0|0|B4C=42F8,4E8FB=42F7,4E93F=4270 +7BC22342|Mario & Wario (J) [h3] (Joypad)|0|0|7E00AB|0|1E|11 +E51A3FCD|Mario is Missing (U)|10000000|40C00|0|0|0|0|255=EAEA +F64C5AA0|Mario no Super Picross (J)|14000005|40C00|0|0|0|0|E0209=EAEA,E0217=EAEA,E0259=EAEA,E0267=EAEA,E028E=EAEA,E029C=EAEA,E02B1=EAEA,E02BF=EAEA,E0480=EAEA,E0501=EAEA,F23A6=EAEA,91A=42D8,1A3C=42D8,4D9FF=DB +AAD84250|Mario Paint (JU) [h1] (Joystick|4|4044|7E0227|0|1E|0|3964=EAEA,69AB=EAEA,937D=EAEA,DC1C=EAEA,DC4E=EAEA,DD5C=EAEA,DD78=EAEA,DD83=EAEA,DD88=EAEA,C0AB1=EAEA,E6EEE=EAEA,EEEEE=EAEA,D812=42D9,E0FC=42D8,E54D=42D8,EE0A=42D7,E2EF=42DA,D391=42DB +480B043A|Mario's Early Years - Fun With|1|0|0|0|0|0 +8C0C37F4|Mario's Early Years - Fun With|1|0|0|0|0|0 +85A6B2A8|Mario's Early Years - Preschool|1|0|0|0|0|0 +5E7397E0|Mario's Time Machine (U)|0|0|0|0|0|0 +AC0F2C23|Marvel Super Heroes - War of th|3|0|0|0|0|0|30076=EAEA,300C0=EAEA +C0ACC92D|Mechwarrior 3050 (U)|8000001|4800|0|0|0|0|166DBE=EAEA,166DEA=EAEA,166FBB=EAEA,166FE9=EAEA,166CE0=EAEA,7723=42DC,764D=42DC +44A9DB5C|Mega lo Mania (E)|6|0|6E|0|32|28|2808B=EAEA,17B88=EAEA,280DB=EAEA,17B99=EAEA,17BA7=EAEA,EAE=4298,A8E=4296 +2D947536|Mega Man 7 (U)|4000001|40000|7|0|0|AB|AB=42FB +DED53C64|Mega Man X|4000018|40000|BB0|B6|1E|0|A4=42,38161=EAEAEAEA +6F98885D|Mega Man X (DarkCube IPS)|4000018|40000|BB0|B6|1E|0|A4=42,38161=EAEAEAEA +D47EB040|Mega Man X 2 (E)|4000018|40000|BB0|B6|1E|0|A4=42,38161=EAEAEAEA +FA0FE671|Mega Man X 3 (E)|4000018|40000|BB0|B6|1E|0|A4=42,38161=EAEAEAEA +FA9EE2CE|Mega Man's Soccer (U)|0|0|0|0|0|0|C42=42DC +68DD767A|Megaman Soccer|0|40C00|0|0|0|0 +A079C881|Metal Max Returns (J)|4|0|0|0|0|0|1B9=42F8 +0ADAA9DA|Metal Morph (U)|10000000|800|0|0|0|0|35E=EAEA,31D=EAEA,326=EAEA,332=EAEA,237=EAEA,33C=EAEA,48C9=42FB,2A21=42FB,C596=4298 +856B5F76|Michael Jordan - Chaos in the W|10000001|1000|0|0|0|0|2C749=EAEA,2C8CF=EAEA,19331=42FB,1518B=42DB +08806B5B|Mickey Mania - The Timeless Adv|0|40004C00|0|0|0|0|109A13=EAEA,109A16=EAEA,1099A8=EAEA,10992B=EAEA,109970=EAEA,1099F8=EAEA,109A04=EAEA,109932=EAEA,10F13E=42FC,1F21F9=42FC,1F4DAE=42FC,1F34EE=42FC,1F0197=42FC,1EDD41=42FB,1F4218=42FC,1DDAF0=42FC,1D5118=42FC,1F8002=42FC,1FD017=42FC,1F6C10=42,1E1847=42,10DA1F=42,1E7544=42,1F71F0=42,1FAB96=42DA,1D57B0=42,1D5242=42,1F632C=42,1D5336=42,1D542A=42,10D6F3=42,10D71D=42,1F7A8E=42,F4B4F=42,1D556A=42,1DC89C=42,1F47F6=42,1E9042=42,1DFC46=42,F53A7=42,1F65FB=42,1F80E8=42,10DC12=42,10D908=42,1D56D3=42,1E6288=DB6E,1F503B=42,1F2773=42,1F20AE=42,1F136F=42 +10874C70|Mickey Mouse - Magical Quest|4000018|0|17F2|1AF5|1E|0|BC89=DBE2 +364E68BB|Micro Machines (U)|0|0|0|0|0|0|F725=EAEA,6801C=EAEA,F76C=EAEA +1619B619|Micro Machines 2 - Turbo Tourna|2|0|0|0|0|0 +A56EB77A|Mighty Morphin Power Rangers (U|0|0|0|0|0|0|5604=EAEA,38E=42FC +E3EF6201|Mighty Morphin Power rangers -|0|0|0|0|0|0|668D=EAEA,2D8=42F9 +460B0A60|Mighty Morphin Power Rangers -|0|0|0|0|0|0|4090=EAEA,40B6=EAEA,1415BC=EAEA,1415D4=EAEA,1415DF=EAEA,1415E4=EAEA,141612=EAEA,141637=EAEA,1416DF=EAEA,1417C3=EAEA,141801=EAEA,AD=42 +67B5FB22|Milandra (J)|4|4000|0|0|0|0|8007E=EAEA,800C8=EAEA,80DC=42FB,6E30=42FA,6E4B=42FA,819D=42D4,2D6=4219 +DEF42945|Mortal Kombat (U)|0|0|0|0|0|0|C20F4=EAEA,2687=EAEA,C2ADD=42FC +4E6AF725|Mortal Kombat 3 (U)|1|0|0|0|0|0 +1C3D3B72|Mortal Kombat II (V1.0) (U)|1|0|0|0|0|0|872A=421B,FED1=42B9,3B866=42BA,3F1A0=421A,94820=DB,EF4B7=42BB,FE55D=429D,127E41=4293,12D02F=427F,13B7D4=4270,22BAC2=4288,48029=EAEA,48052=EAEA,48081=EAEA,480F0=EAEA,4810B=EAEA,48124=EAEA,4818B=EAEA,48196=EAEA,4819B=EAEA,481C3=EAEA,481C9=EAEA,48249=EAEA,4852A=EAEA,48541=EAEA,48570=EAEA,4857F=EAEA,485AC=EAEA,A367B=EAEA,A6E89=EAEA,27D7C2=EAEA,2D1294=EAEA +70BB5513|Mortal Kombat II (V1.1) (U)|1|0|0|0|0|0|86EA=EAEA,4FD5A=EAEA,5DE20=EAEA,5DE1F=EAEA,5DE21=EAEA,5DE22=EAEA,5DE23=EAEA,5DE25=EAEA,5DE27=EAEA,5DE28=EAEA,5DE2A=EAEA +1C1025E2|Mr. Do! (U)|4000000|40000|0|0|0|0|301FB=EAEA,30244=EAEA,3026F=EAEA,30288=EAEA,3041E=EAEA,3044C=EAEA,30457=EAEA,3045C=EAEA,304C2=EAEA,304D7=EAEA,304EB=EAEA,718=42BA +74D210D3|Ms. Pac-Man|0|0|0|0|0|0|185D5=EAEA,1873D=EAEA,18763=EAEA,1876E=EAEA,18773=EAEA,187A2=EAEA,187AA=EAEA,18822=EAEA,18837=EAEA,1884D=EAEA,1888F=EAEA,1889D=EAEA,188A5=EAEA,188F9=EAEA,1890E=EAEA,18924=EAEA,18966=EAEA,18974=EAEA,1897C=EAEA,18996=EAEA,189D7=EAEA,18A03=EAEA,18A1B=EAEA,18A28=EAEA,18A3B=EAEA,18A7D=EAEA,18A95=EAEA,18A9C=EAEA,18B24=EAEA,18B29=EAEA,18B37=EAEA,18B3C=EAEA,18B49=EAEA,18C02=EAEA,18C2C=EAEA,18C3A=EAEA,18C58=EAEA,18C7A=EAEA +0E984752|Mujintou Monogatari (J)|4|400800|0|0|0|0|209=423C +011907A4|Musya (U)|0|0|0|0|0|0|54AC=421B,54C8=421B +1DE544EB|Mystic Ark - 7th Saga 2 (J) [T-|5|4000|0|0|0|0|C04EA=EAEA,C04F0=EAEA,C0503=EAEA,C0507=EAEA,F252=42FA +68C8B643|NBA Give N Go (U)|0|0|0|0|0|0|2916=EAEA,2A76=EAEA +262CE76B|NBA Hang Time (U)|5|0|0|0|0|0|5C32F=EAEA,5C358=EAEA,5C3D2=EAEA,5C555=EAEA,5C527=EAEA +43F1C013|NBA Jam (U)|0|0|0|0|0|0 +1FBC1DDB|NBA Jam Tournament Edition (U)|4|0|0|0|0|0|4F2D5=EAEA +5115B8E5|NBA Live '97 (U)|4|40C00|0|0|0|0 +514BFCB5|NBA Live '98 (U)|4|40C00|0|0|0|0 +42212A77|NHL '94|0|840400|0|0|0|0|FF4B7=42F1,58A=42FB,E19C8=EAEA,F870A=9BDB +233FEC8C|Nickelodeon GUTS|0|0|0|0|0|0 +066FE797|Ninja Gaiden Trilogy (U)|0|0|0|0|0|0|2B02=EAEA,29A2=EAEA,4314D=42D7,CA=4284,5B2=4219,1BA=42D1 +5995CF46|Ninja Ryuukenden Tomoe (J)|0|84000000|0|0|0|0|5B2=4219,4B=42DA +3BC037B6|Ninja Warriors Again, The (J)|0|0|0|0|0|0|240=EAEA,4803=EAEA,C6=42D9,4705=EAEA +733764D7|Ninja Warriors, The (E)|2|0|0|0|0|0 +7537D8D7|Ninja Warriors, The (U)|0|0|0|0|0|0|240=EAEA,4742=EAEA,475A=EAEA,4765=EAEA,476A=EAEA,4798=EAEA,47E7=EAEA,47FA=EAEA,4863=EAEA,C6=42D9 +ACFDB7B8|Ogre Battle (U)|10000004|44444444|0|0|5|0|2AA9E=EAEA,2AB0B=EAEA,3E78E=EAEA,42D25=EAEA,60050=EAEA,60057=EAEA,600DE=EAEA,600F6=EAEA,60101=EAEA,60106=EAEA,60138=EAEA,60144=EAEA,60166=EAEA,6019C=EAEA,6727D=EAEA +5F40A869|Out of This World|0|0|0|0|0|0|658D=EAEA,65A0=EAEA,65B7=EAEA,65CC=EAEA,65D4=EAEA,65E1=EAEA,65E6=EAEA,65FB=EAEA,6605=EAEA,6617=EAEA,662A=EAEA,66B5=EAEA,66C5=EAEA,1D997=4251,234C9=DB6D +191B1A19|Pac-Attack|10000000|44C00|0|0|0|0 +44375368|Pac-In-Time|0|0|0|0|0|0 +9FC62BCC|Pac-Man 2 - The New Adventures|10000000|44C00|0|0|0|0|8297=EAEA,829E=EAEA,82A8=EAEA,82BE=EAEA,82CE=EAEA,82E5=EAEA,832B=EAEA,836B=EAEA,83D3=EAEA,83F5=EAEA,8400=EAEA,8405=EAEA,915D=EAEA,9166=EAEA,917C=EAEA,9190=EAEA,91B1=EAEA,A43D=EAEA,B379=EAEA,13E96=EAEA,1B670=EAEA,1EE81=EAEA,1EEB5=EAEA,1EEBF=EAEA,1EED7=EAEA,1EEDC=EAEA,1EEE6=EAEA,1EEFE=EAEA,1EF03=EAEA,1EF0D=EAEA,142284=EAEA,176F79=EAEA +26C38EEE|Pagemaster, The|0|40C00|0|0|0|0|F80B8=EAEA,F8135=EAEA,F81E0=EAEA,F824B=EAEA,F8270=EAEA,F8295=EAEA,F82C1=EAEA,F82C6=EAEA,F82EC=EAEA,F82F1=EAEA,F8325=EAEA,F8345=EAEA,F834A=EAEA,F8375=EAEA,F83A8=EAEA,F83FB=EAEA,F8425=EAEA,F8450=EAEA,F8464=EAEA,F848F=EAEA,F849A=EAEA,F849F=EAEA,1CFF87=EAEA,1CFFA0=EAEA +14D70786|Panel de Pon (J)|0|0|0|0|0|0|1180=EAEA,1185=EAEA,11CB=EAEA,11D0=EAEA,125A=EAEA,125F=EAEA,11E1=EAEA,11DC=EAEA,1275=EAEA,127A=EAEA +C85AA66A|Paper Boy 2 (U)|0|0|0|0|0|0|6552=EAEA,1731=42D9,6978=42D8 +876DFD97|Parodius Da!|4000000|840000|B8C|0|1E|5|11A=4280 +6FFA308C|Parodius Non-Sense Fantasy (E)|2|0|0|0|0|0 +8071E5DB|Peace Keepers (U)|1|0|0|0|0|0|DCD2=EAEA,807B=EAEA,80EE=DBEB +DC90A8AB|Phalanx (U)|0|0|0|0|0|0 +561AEB8F|Phalanx - The Enforce Fighter |0|4040|0|0|0|0|11D=EAEA,FEBD9=42FB,348=42DB +DEF45776|Pilotwings (E)|2|0|0|0|0|0|31F5=EAEA,38D8=EAEA,52B6=EAEA,579D=EAEA,57D2=EAEA,58A0=EAEA,6176=EAEA,6576=EAEA,65B2=EAEA,65CA=EAEA,72A7=EAEA,72BD=EAEA,72C8=EAEA,72CD=EAEA,A76A=EAEA,BD06=EAEA,CE61=EAEA,CFEF=EAEA,716F=4217,728D=42D4 +81107CE2|Pinball Dreams (U)|10000000|0|0|0|0|0|56EB=EAEA,575B=EAEA,578A=EAEA,57AE=EAEA,5685=42DB,1320=42FB,13A5=42FB,3237=42FB,D34=42,953=42B9,1C74=42FA,1E94=42D8 +822AD378|Pinball Fantasies (U)|0|0|0|0|0|0|B0339=EAEA,B0486=EAEA,B0492=EAEA,B0384=EAEA,B0390=EAEA,B03A9=EAEA,B03B5=EAEA,1458=42FB,14DD=42FB,3D8D=42FB +AF2A3DFE|Pipe Dream (J)|0|40800|0|0|0|F|103B8=42FB,164=42F9,F74=42 +7CA0CA4D|Pirates of Dark Water (U)|0|0|0|0|0|0|297D=42FC +2B0E7EA3|Pocky & Rocky (U) [!]|0|0|0|0|0|0|5252=EAEA,2299=EAEA,2421=EAEA,1CA=42DB +892C6765|Pokemon (PD)|4000000|900000|0|0|0|0|4326=EAEA,4353=EAEA,436B=EAEA,4376=EAEA,437B=EAEA,43A9=EAEA,43BA=EAEA,FA3=42,22BA=42D8,1BE60F=DB +D16810CD|Poko Nyan! - Henpokorin Adventu|0|44000|0|0|0|0|69A4=428E +EE13E32D|Pop 'N' Twinbee (J)|10000000|840000|0|0|0|0|118=4280 +2DF4AA0F|Populous (U)|0|40C00|0|0|0|0|390D=4280,14F0E=429C,181A8=DB,1F450=DB +0A0235C0|Populous 2 (J)|0|4040|0|0|0|0 +CB4F87BB|Prehistorik Man (U)|10000000|4F0000|0|0|0|0|1FA18=EAEA,1FA61=EAEA,48314=EAEA,7F68=42FC,4D4=EAEA,181E3=EAEA,1F9CA=EAEA,1F9E2=EAEA,1F9F3=EAEA,1FA0E=EAEA,1FA35=EAEA,1FC6C=EAEA,1FC71=EAEA,1FCA8=EAEA,333E8=EAEA,496E7=EAEA +320562C3|Prince of Persia (E)|2|0|0|0|0|0 +891BB2BB|Prince of Persia (U)|0|0|0|0|0|0|118C2=EAEA,118D3=EAEA,118DF=EAEA,1190B=EAEA,11999=EAEA,11921=EAEA,1A2C1=42DB,1A2CD=4299 +96BD588B|Puzzle Bobble (J)|0|40C00|0|0|0|0 +694CBFE4|Q-bert 3 (U)|0|0|0|0|0|0|7E56=EAEA,6822=42FC +642B656B|R-Type 3|0|0|0|0|0|0|7F37=428E,1DE49E=421B +583FDBFF|Radical Dreamers (SNES) (J) [T+|5|0|0|0|0|0|20F21=EAEA,CFE58=EAEA,CFE5F=EAEA,CFE7D=EAEA,CFEB0=EAEA,CFEE0=EAEA,CFEFB=EAEA,CFF08=EAEA,D0054=EAEA,D0084=EAEA,D00C9=EAEA,D023F=EAEA,D028D=EAEA,D03DB=EAEA,D03FA=EAEA,D040C=EAEA,D0416=EAEA,D0445=EAEA,D0467=EAEA,D050C=EAEA,D0563=EAEA,D05AF=EAEA,D05CB=EAEA,D05D2=EAEA,D05E2=EAEA,D0664=EAEA,D067B=EAEA,D09C2=EAEA,9E41=421A,A1AB=421A,A1BE=421A,A1EA=421A,A1FF=421A,B85B=42BA,F8050=42 +C352D27F|Raiden Densetsu (J) [!]|18000000|0|0|0|0|0|E29=42,E34=42FC,E3A=429A +02CE6C96|Raiden Trad|18000000|0|0|0|0|0|E29=42,E3A=429A +9C79C3B8|Ranma RPG - Anime [T+Eng1.00]|4|0|0|0|0|0|456B=42DB +053B2615|Ranma ½ Bun no 1 - Bakuretsu Ra|1|0|0|0|0|0|FFA0=EAEA,4B1=42FB +0C552B1F|Ranma ½ Bun no 1 - Chogi Ranbu|1|0|0|0|0|0|32F=42DB,40640=42FB,48AF2=DB03,45E5B=DB91 +9BE46820|Realm (E) [!]|2|0|0|0|0|0|85EF=EAEA,F8263=EAEA,F82AF=EAEA,F82D5=EAEA,85E1=42FC,958=42FC,228=42FC +C2413BDD|Rejoice - Aretha Oukoku no Kana|4|44800|0|0|0|0|A5831=EAEA,A55F3=EAEA,A55FB=EAEA,A5838=EAEA,A583C=EAEA,A5845=EAEA,A5849=EAEA,A582D=42DA,2D516=42DB,2DAE1=42DB,2D687=42DB,95F6=42DB,226=42DB,4F7=42DB,7C86=42DB,6E74=42DB,72A5=42DB,1425B=42DB,16DF=42DB,9252=42DB,CEFE=42DB,CEB5=42DB,6D06=42DB,AFB6=42DB,92BC=42DB +CA988F59|Rival Turf (U)|0|0|0|0|0|0|272=EAEA,A6E=EAEA,1A3B=EAEA,1A9F=EAEA,1BB3=EAEA,1BB9=EAEA,632F=EAEA,6343=EAEA,635B=EAEA,6368=EAEA,643A=EAEA,6432=EAEA,6441=EAEA,6456=EAEA,C435=EAEA,11B16=EAEA,F1444=EAEA +BB2B8E2E|Road Runner (E)|2|0|0|0|0|0|7DD3=EAEA,7DEB=EAEA,7DF6=EAEA,7DFB=EAEA,7E88=EAEA,7E8E=EAEA,28902=EAEA,2A605=EAEA,381FD=EAEA,9FE7E=EAEA,9FE84=EAEA,163B=DB +F5AB5D91|Robocop Versus The Terminator |14000000|4040|0|0|0|0|94E=42DB,6D=42DB,AE=42DB,141E=EAEA,5FF5=42D9 +7AD4AADC|Robotrek (U)|5|0|0|0|0|0|4800D=421A +7D06F473|Rock N' Roll Racing (U)|0|0|0|0|0|0|7994=EAEA,AD8F=EAEA,F617=EAEA,3D10=4284 +0ECDC493|Rockman & Forte (J) [T+Eng1.00-|4000001|40000|7|0|0|0|D=42FB +2DCD95B9|Rockman 7 - Syukumei no Taikets|0|0|0|0|0|0 +F0ECDD92|Roger Clemens' MVP Baseball (U)|0|44808|0|0|0|0|A2E5D=42,A2E68=42,A5F0C=42DA,9=42,A39CB=42DB,683E=42 +8033574A|Romance of the Three Kingdoms I|4|0|0|0|0|0|12C1=EAEA,3115=EAEA,19F3=42DB +9684526D|Romancing Saga (V1.1) (J)|8000004|84848484|0|0|0|0|20068=EAEA,20098=EAEA,200AC=EAEA,200DF=EAEA,201C3=EAEA,201CB=EAEA,201E1=EAEA,20248=EAEA,202F0=EAEA,20319=EAEA,20330=EAEA,20385=EAEA,2039D=EAEA,2043C=EAEA,204EA=EAEA,2055C=EAEA,20564=EAEA,20589=EAEA,2058F=EAEA,205A9=EAEA,2D4=42D9,962=DB,13D34=4280,CEFBF=4258 +54A585BC|Romancing Saga 2 (J)|5|0|0|0|0|0|370B=EAEA,556F=EAEA,5581=EAEA,321E5=EAEA,4004A=EAEA,4006A=EAEA,40081=EAEA,4008C=EAEA,40095=EAEA,400E6=EAEA,40116=EAEA,4012D=EAEA,4013A=EAEA,40232=EAEA,4023A=EAEA,40257=EAEA,403DA=EAEA,40403=EAEA,40419=EAEA,40501=EAEA,40593=EAEA,405E1=EAEA,40613=EAEA,40619=EAEA,40666=EAEA,4067F=EAEA,406EB=EAEA,40719=EAEA,4072E=EAEA,40779=EAEA,407A7=EAEA,407BC=EAEA,407EA=EAEA,407FF=EAEA,4082D=EAEA,40840=EAEA,4084C=EAEA,14315C=EAEA,32F=4296,572=4210,69A=42D9,3981=42B0,E76B=42D9,204AF=42D9,30176=4280,3AEA7=42DD,3B0CB=42DD,3B3D2=42DD,3DF0A=DB,3E2E3=DB,3E91F=4280,568B5=DB +5399BDDB|Romancing SaGa 3 (J) (V1.0)|5|4800|0|0|0|0|6063D=EAEA,60643=EAEA,609B0=EAEA,670=42DC,3EC170=42FA,1C42A=42D9,5F957=42FC +42C664C2|Romancing Saga 3 (V1|5|40444444|0|0|0|0|6063D=EAEA,60643=EAEA,609B0=EAEA,670=42DC,3EC170=42FA,1C42A=42D9,5F957=42FC +E0BD6C71|RPG Tukool - Super Dante|4|0|0|0|0|0|00C1=EAEA,B74C=EAEA,B757=EAEA,B762=EAEA,B761=EAEA,B74B=EAEA +E20870EE|RPG Tukool - Super Dante (J)|4|0|0|0|0|0 +5D8CB7AC|Rudra no Hihou (J)|5|0|0|0|0|0|23A5=EAEA,4AA=42FC +244280AE|Rudra no Hihou (J) [T+Eng|2|0|0|0|0|0|130906=EAEA,26187A=EAEA,2B0022=EAEA,2B00A5=EAEA,2B00C9=EAEA,2B031C=EAEA,2B033E=EAEA,2B0357=EAEA,2B0457=EAEA,2B094B=EAEA,2B0954=EAEA,2B095F=EAEA,2DC5B6=EAEA,4AA=42FC +8708E5BB|Run Saber (U)|0|0|0|0|0|0|525=421B,9AB=4290 +454D7DCD|Ryuuki Heidan Danzalv (J)|5|44800|0|0|0|0|F8335=42FB,F8345=421B,F73FE=421B,F8340=423B,F8DDA=42DB,88D3A=4215,8C04F=42FC +CD89020D|Sailor Moon (F)|3|0|0|0|0|0|1B7F8=42FC,1BE5A=42CF,936E=42FC +2E614A53|Samurai Shodown (U)|1|4040|0|0|0|0|10B4=42 +4C78D5EE|Sangokushi - Eiketsu Den (J)|5|4000|0|0|0|0|2C0BB0=EAEA,898D=42DC,1E29=42DB,850E=42DC,1E8F=42DB,87A4=42DC,8544=42DC,1D8C=42DC +98D7611E|Scooby Doo (U)|0|C00|0|0|0|0|DDF0D=EAEA,1017D6=EAEA,114DD0=EAEA,114DF2=EAEA,114DFD=EAEA,114E02=EAEA,114FE5=EAEA,114FF4=EAEA,115007=EAEA,115041=EAEA,11506F=EAEA,115077=EAEA,115097=EAEA,1150A2=EAEA,1B5B14=EAEA,1C988F=EAEA,C39=42DB,1A6874=4211 +8BFCB5A3|SD Gundam X (J)|4|44000|0|0|0|0|454F=EAEA,16E91=EAEA,16ECC=EAEA,16EDD=EAEA,16EEB=EAEA,16EF0=EAEA,16F1E=EAEA,2C5F1=EAEA,4D024=EAEA,975E1=EAEA,AE344=4219 +AAE842D2|SD The Great Battle (J)|1230000|0|0|0|0|0|181=EAEA,6A9C=DB6A +A5C0045E|Secret of Evermore (U)|14000005|0|0|0|0|0 +D0176B24|Secret of Mana (U)|5|4000|7E0604|0|64|A|79773=EAEA,B07B=42DC,694D=421B +EF968ED1|Secret of the Stars (U)|1320004|0|0|0|0|0|417=421B +A638BEF1|Seifuku Densetsu Pretty Fighter|1|0|0|0|0|0 +15320173|Seijuu Maden - Beasts & Blades|5|4040|0|0|0|0|800E2=EAEA,801A1=EAEA,30013=EAEA,183C3=42FB,30135=42DC,30118=42DC,30009=42D8 +D0AEA27C|Seijuu Maden - Beasts & Blades|5|4040|0|0|0|0|800E2=EAEA,801A1=EAEA,30013=EAEA,183C3=42FB,30135=42DC,30118=42DC,30009=42D8 +FE1389B5|Seijuu Maden - Beasts & Blades|5|4040|0|0|0|0|800E2=EAEA,801A1=EAEA,30013=EAEA,183C3=42FB,30135=42DC,30118=42DC,30009=42D8 +BEA407DC|Seijuu Maden - Beasts & Blades|5|0|0|0|0|0 +863ED0B8|Seiken Densetsu 3 (J)|5|0|0|0|0|0|5008A=EAEA,3D8350=42FC,3D84D2=421A,3D837E=42FC,4A22=42D2,3D8306=80,340B=4290,33E2=42F8 +7DBDE871|Seiken Densetsu 3 (J) (e101|5|40000|0|0|0|0|5008A=EAEA,3D8350=42FC,3D84D2=421A,3D837E=42FC,4A22=42D2,3D8306=80,340B=4290,33E2=42F8 +B1D82240|SF96soe|4|0|0|0|0|0|337=EAEA,35D=EAEA,365=EAEA,3D6=EAEA,3ED=EAEA,404=EAEA,57A=EAEA,5A3=EAEA,5C9=EAEA,607=EAEA,61E=EAEA,635=EAEA,7A9=EAEA,7D2=EAEA,7F8=EAEA,1D53=EAEA,1E4C=EAEA,1E74=EAEA,1ED1=EAEA,1EFD=EAEA,1F31=EAEA,202B=EAEA,20C0=EAEA,23F574=EAEA,2BA616=EAEA,32FC20=EAEA,4847E4=EAEA,6004FC=EAEA,60050C=EAEA,600524=EAEA,60052F=EAEA,600534=EAEA,600572=EAEA,60080F=EAEA,600858=EAEA,6042FC=EAEA,6044CB=EAEA,6044FC=EAEA,604B46=EAEA,604B6C=EAEA,604C98=EAEA,6050E0=EAEA,605106=EAEA,605112=EAEA,605131=EAEA,605168=EAEA,6051D3=EAEA,6051F9=EAEA,60528A=EAEA,6052B6=EAEA,6CFAAD=EAEA,7AE950=EAEA,7D84EF=EAEA,8038FE=EAEA,834595=EAEA,8A3975=EAEA,8B62E4=EAEA,8F04BD=EAEA,A00337=EAEA,A0035D=EAEA,A00365=EAEA,A003D6=EAEA,A003ED=EAEA,A00404=EAEA,A0057A=EAEA,A005A3=EAEA,A005C9=EAEA,A00607=EAEA,A0061E=EAEA,A00635=EAEA,A007A9=EAEA,A007D2=EAEA,A007F8=EAEA,A01D53=EAEA,A01E4C=EAEA,A01E74=EAEA,A01ED1=EAEA,A01EFD=EAEA,A01F31=EAEA,A0202B=EAEA,A020C0=EAEA,A61D40=EAEA,A9A0AD=EAEA,B1838F=EAEA,BB1907=EAEA,18B=421B,2DB=42DB,76E6=42D9,7702=4280,7E98=42D6,204A1D=42D1,218A6F=42,2211F6=42,2315F6=DB,24D6A7=42D3,24E908=DB,268D19=42,2A157A=42,2BA92D=4230,2BEC66=42,2C0543=42D2,2E4B9D=42,2F166E=421F,2FAE82=DBFB,4C5627=42B8,600065=42D9,6004A1=423B,6004A6=421B,615B3C=423B,615B41=421B,647412=423B,647417=421B,647428=423B,64742D=421B,6E44D4=DBF6,6E4507=DBF7,6E45D1=DBF6,6E460C=42,7B1A92=DB,7BDF2E=427F,7D9F44=DB,816505=DB,829ACC=DB,83C95D=421D,8478B7=DBFA,859D22=4231,A0018B=421B,A002DB=42DB,A076E6=42D9,A07702=4280,A07E98=42D6,A10B55=423A,A10B5B=421A,A10B85=423B,A10B8A=421B,A11231=42D9,A17DFA=423B,A17DFF=421B,A318D4=423B,A318D9=421B,A56D16=423B,A56D1B=421B,A56D67=42D9,A6053B=423B,A60540=421B,A60551=423B,A60556=421B,A7B388=DB,AF4AB4=DB,B8F4EF=42BE,BA988C=421E +36894CC3|Shadow, The (U)|0|40800|0|0|0|0|714D=EAEA,7174=EAEA,717E=EAEA,71A5=EAEA,128999=EAEA,1289C0=EAEA,1F85E2=EAEA,1F8609=EAEA,1F831F=EAEA,12803C=EAEA,128063=EAEA,12806D=EAEA,128094=EAEA,1F8355=EAEA,1F837C=EAEA,1F8386=EAEA,1F83AD=EAEA,1F8290=EAEA,1F82B7=EAEA,1F8346=EAEA,1F8663=EAEA,1F80B8=EAEA,7222=EAEA,7249=EAEA,7253=EAEA,727A=EAEA,12A104=EAEA,12A12B=EAEA,12A135=EAEA,12A15C=EAEA,1F868A=EAEA,12A40D=EAEA,12A434=EAEA,12A43E=EAEA,1F83FA=EAEA,12A465=EAEA,1F8421=EAEA,1F825E=EAEA,1F8285=EAEA,10055=42FB +85D4CDA1|Shadowrun (U)(17759)|4|0|0|0|0|0|E16B=EAEA,E4C5=EAEA,B065=42,EE67=42 +3F34DFF0|Shadowrun (U)(63540)|4|4040|0|0|0|0|E17C=EAEA,E4D6=EAEA,B065=42,EE92=42 +4C2BEA69|Shiki Eiyuuden - Jinryuu Denset|4|400C09|0|0|0|0|7094D=EAEA,70756=EAEA,E80EE=42FA,30542=42FA,188AE=42FA,73D7=42FA,28622=42FA,1866E=42DC,408B4=42D4,47355=42FA,18567=42D5,21554=42D4,2127A=42D3 +C0AECDCA|Shin Kidoesenki Gundam Wing - E|0|0|0|0|0|0|38211=EAEA,38133=EAEA,B9=42F9 +67E1756B|Silva Saga II - The Legend of L|4|0|0|0|0|0|2CD=42FB,6029C=42D9 +9D5FEB20|Sim Ant (U)(49046)|4|0|0|0|0|0|781=42FC,10061=4299 +A39FD8D8|Sim City (J)|10000004|40000|0|0|0|0|12DE=42FA +8AEDD3A1|Sim City (U)|10000004|40000|7E01ED|0|19|8|1315=42FA +7FA5B218|Sim Earth (U)|4|0|0|0|0|0|17BB8=EAEA +ED1C03C2|Simpsons, The - Bart's Nightmar|0|0|0|0|0|0|ABCC6=42FC +AC5116D9|Simpsons, The - Krusty's Super|0|0|0|0|0|0|2DAA=42FA +1594A363|Sky Blazer (U)(12134)|10000008|F40|7EF101|7EF141|1E|5|1BF9=42F7,746=42F5 +D05114C0|Slam Dunk - SD Heat Up!!|0|0|0|0|0|0|3C58=EAEA,3BCA=EAEA,162=428E,3F4C=EAEA +2D0B20D0|Smash TV|18000000|40000|B|0|1E|0|521=42DB,74A1A=42 +D68D1AB3|Snow White in Happily Ever Afte|0|0|0|0|0|0 +2A9966C0|Soccer Kid (E)|2|0|0|0|0|0|7BBC=42D9,E4437=DB +E1701707|Soldiers of Fortune (U)|0|0|0|0|0|0|A1318=EAEA,BDDB6=EAEA,D01A6=EAEA,D0201=EAEA,2F50=423C,C42A1=42,C42A9=42D8,C42BE=42,C42C6=42D8,C42E3=42,C42EB=42D8,C4630=42,C4639=42D7,C4650=42,C4659=42D7,D07E9=42,D07F2=42D7,D0818=42,D0821=42D7,D8815=42,D881E=42D7,D8835=42,D883E=42D7,D885F=42,D8868=42D7,127F56=42,127F5E=42D8,1481AB=42,1481B4=42D7,1486E3=42,1486EC=42D7,148721=42,14872A=42D7,14877F=42,148788=42D7,1489AE=DB +B907BB27|Solid Runner (J)|4|4800|0|0|0|0|40053=EAEA,5C89=EAEA,40055=EAEA,402C6=EAEA,9A=42F9 +24229A34|Sonic Blastman 2 (U)|1|0|0|0|0|0|9023=EAEA,3F9=42DF,814B=EAEA,8161=EAEA +80E548A2|Sonic the Hedgehog (Hack)|0|0|0|7E008F|1E|5|B03E1=EAEA,4456=42DC,2D2=42DC +CFE75BCB|Sonic Wings (J)|4000000|4000|0|0|0|0|544=42DA,3F1=42DB,265=42FB,1EBDD=4285 +5FE69828|Soul & Sword (J)|4|0|0|0|0|0 +31B965DB|Soul Blazer (U)|4|0|0|0|0|0|131C1=421B +5ABFBE21|Space Funky B.O.B. (J)|0|0|0|0|0|0|24C=42FB +11202781|Space Megaforce (U)|0|44040|0|0|0|0|146C=EAEA,148B=EAEA,14E3=EAEA,14B5=EAEA,123=42FC,B6C=42FC,417=42FC +40D11C94|Sparkster (U)|0|0|0|0|0|0|4598=EAEA,45B9=EAEA,45F3=EAEA,4666=EAEA,4686=EAEA,46CB=EAEA,46EE=80,4737=80,473F=EAEA,474D=EAEA,4765=EAEA,4781=EAEA,4790=EAEA,47A2=EAEA,47B1=EAEA,47C1=EAEA,47CC=EAEA,4840=EAEA,488A=EAEA,48A1=EAEA,48AD=EAEA,6E9B=4211,4844=EAEA +4E1DAFD0|Spawn (U)|1|0|0|0|0|0|C045E=EAEA,C04DF=EAEA,D35D6=EAEA,DE3F1=EAEA +CB0653D0|Speedy Gonzales (V1.1) (U)|0|0|0|0|0|0 +3DAEA8A1|Spell Craft (U)|0|4040|0|0|0|0|4303=EAEA,53B46=EAEA,CE8A9=EAEA,3BE5=42D9,74D5=42,E92A7=429D +7EF2BB0C|Spider-Man - Maximum Carnage (U|0|0|0|0|0|0|10AAF=EAEA,12D4B=42F5 +919C509D|Spider-Man - Separation Anxiety|0|0|0|0|0|0|1399B=42F5 +3F83F67C|Spriggan Powered (J)|8000000|4000|0|0|0|0|8F1=42FB +89D0F7DC|Star Kirby Super Deluxe|4|0|0|0|0|0|4D2F=EAEA,4D49=EAEA,4D66=EAEA,4DB1=EAEA,4DC6=EAEA,4E3E=EAEA,4E53=EAEA,4E98=EAEA,4FD8=EAEA,4FE0=EAEA,501E=EAEA,5027=EAEA,53B9=EAEA,53C4=EAEA,53E7=EAEA,53FD=EAEA,540B=EAEA,541B=EAEA,5425=EAEA,542D=EAEA,5458=EAEA,5463=EAEA,5468=EAEA,549A=EAEA,36E258=EAEA,3A007B=EAEA,4B93=42D9,18AD47=4218,1E228D=421D,2CDC70=428F,377365=4214 +6BA9E08D|Star Ocean (English Translation|4|0|0|0|0|0|137=EAEA,15D=EAEA,165=EAEA,1D6=EAEA,1ED=EAEA,204=EAEA,37A=EAEA,3A3=EAEA,3C9=EAEA,407=EAEA,41E=EAEA,435=EAEA,5A9=EAEA,5D2=EAEA,5F8=EAEA,1B53=EAEA,1C4C=EAEA,1C74=EAEA,1CD1=EAEA,1CFD=EAEA,1D31=EAEA,1E2B=EAEA,1EC0=EAEA,82FC=EAEA,830C=EAEA,8324=EAEA,832F=EAEA,8334=EAEA,8372=EAEA,860F=EAEA,8658=EAEA,C0FC=EAEA,C2CB=EAEA,C2FC=EAEA,C946=EAEA,C96C=EAEA,CA98=EAEA,CEE0=EAEA,CF06=EAEA,CF12=EAEA,CF31=EAEA,CF68=EAEA,CFD3=EAEA,CFF9=EAEA,D08A=EAEA,D0B6=EAEA,C1B40=EAEA,131EAD=EAEA,19F8AD=EAEA,23018F=EAEA,35E750=EAEA,361707=EAEA,3B82EF=EAEA,4036FE=EAEA,464395=EAEA,47F374=EAEA,543775=EAEA,5660E4=EAEA,57A416=EAEA,5E02BD=EAEA,DB=42DB,74E6=42D9,7502=4280,7C98=42D6,7E65=42D9,20955=423A,2095B=421A,27BFA=423B,27BFF=421B,8F212=423B,8F217=421B,8F228=423B,8F22D=421B,A6B16=423B,A6B1B=421B,A6B67=42D9,C0351=423B,F3188=DB,1CC2D4=DBF6,1CC307=DBF7,1CC3D1=DBF6,1CC40C=42,1E48B4=DB,3172EF=42BE,35168C=421E,369892=DB,37DD2E=427F,3B9D44=DB,40C81D=42D1,426305=DB,43886F=42,448FF6=42,4518CC=DB,4693F6=DB,47475D=421D,4876B7=DBFA,49D4A7=42D3,49E708=DB,4B1B22=4231,4D8B19=42,54937A=42,57A72D=4230,57EA66=42,588343=42D2,5CC99D=42,5E946E=421F,5FAC82=DBFB +3DBDFDBF|Star Ocean (J)|4|0|0|0|0|0 +75BFF780|Star Trek - Deep Space Nine - C|2|0|0|0|0|0|C549C=EAEA,FE61=42DC +2DB38D24|Star Trek Starfleet Academy|0|44000|0|0|0|0|38EB4=EAEA,100D9=4234,10B90=42D8 +BC3DCD9D|Street Fighter II - The World W|14000000|40C00|0|0|0|0|FB=42 +A45CADD6|Street Fighter II Turbo (U)|1320001|0|0|0|0|0|D8=42FB +7455A7CF|Street Fighter Zero 2 (J)|0|0|0|0|0|0 +52ADA404|Sunset Riders (US)|8000000|4000|0|0|0|0|C2C=EAEA,C39=EAEA,1923=423B,1998=42D7,CEC=42D9 +9A8618D6|Super Adventure Island (E)|2|0|0|0|0|0 +DCD46848|Super Adventure Island (U)|0|0|0|0|0|0|8C=42F7 +5615D5ED|Super BC Kid (E)|3|0|0|0|0|0|C6E1=42DC +63A8E2C6|Super Bomberman|1|0|0|0|0|0 +3BBAEB19|Super Bomberman 4 (J)|1|0|0|0|0|0|2A6=EAEA,2AA=EAEA,2B2=EAEA,32B=EAEA,34C=EAEA,2E0=EAEA,488=EAEA,48F=EAEA,4B2=EAEA,730=EAEA,656=EAEA,6AF=EAEA,6E9=EAEA,3C4=EAEA,3BD99=EAEA,F0AD=EAEA,43E12=42FB,F162=42FB,358=EAEA,18BB4=4290,43E65=42FB,18649=DB2A +06B1F0F5|Super Bomberman 5 (J)|5|0|0|0|0|0|BAE6=DBE2 +5688B581|Super Bonk (U)|1|0|0|0|0|0|C6E8=42DB +9526D1AA|Super Buster Brothers|0|0|0|0|0|8|2E8A=DB87 +C86872D3|Super Buster Brothers (V1|0|0|0|0|0|0|2E46=DB87 +B64FFB12|Super Castlevania IV (U)|10|0|54E|0|1E|A|187=4286 +09ED12A5|Super Double Dragon (U)|0|0|0|0|0|0|3866=42 +3E631524|Super Earth Defense Force (J)|10000000|40404|0|0|0|0|3017A=EAEA,30125=EAEA,30135=EAEA,3013B=EAEA,30187=EAEA,3018C=EAEA,529=421B +CA8FF946|Super Earth Defense Force (U)|10000000|0|0|0|0|0|30125=EAEA,30135=EAEA,3013B=EAEA,30187=EAEA,3018C=EAEA,51B=421B +D6EACBEA|Super Famicom Wars (J) (NP)|4|4024400|0|0|0|0|DD4=EAEA,DD9=EAEA,EBA=EAEA,E1C=EAEA,CDF=EAEA,CEA=EAEA,2F3=42FC +FF33E304|Super Famicom Wars (J) (NP)|5|0|0|0|0|0 +DB71BF4A|Super Fire Pro Wrestling (J)|10000000|40044000|0|0|0|0|64F9=42DB,C8D=42D8,113A=42D5 +6AABA901|Super Ghouls N Ghosts|14000010|4040|45E|0|32|A|1D1=EAEA,A6C4=DB6F +935EA22C|Super Goal! (U)|4|0|0|0|0|0|E0DF4=EAEA,2854=EAEA +7E8FE01A|Super Mario All Stars|4|44444444|0|0|0|0|41=EAEA,7D5=EAEA,827=EAEA,BB8=EAEA,BD0=EAEA,BDB=EAEA,BE0=EAEA,189B4=EAEA,1E4E3=EAEA,201B9=EAEA,68755=EAEA,6E439=EAEA,88470=EAEA,8963A=EAEA,A5F2C=EAEA,A5FDB=EAEA,1166CD=EAEA,12F39D=EAEA,393=425B,18522=425B,2C804=42BA,683B5=425B,696AC=42BA,891D7=DB61,89583=425B,A7A9D=42BA,F06DA=42,F06E1=DB,F06E9=42D9,10705F=4256,1070D0=4256,10711B=4256,107142=4256,10718D=4256,1072E7=42D9,107355=425B,1073CF=425B,107443=425B,107498=425B,107504=425B,107538=425B,107562=425B +8089624C|Super Mario All-Stars & World|10000004|40C00|0|0|0|0|819=EAEA,86B=EAEA,C09=EAEA,C21=EAEA,C2C=EAEA,C31=EAEA,189C1=EAEA,1E4E3=EAEA,201B9=EAEA,68755=EAEA,6E439=EAEA,88494=EAEA,89696=EAEA,A5F2C=EAEA,A5FDB=EAEA,1166CD=EAEA,12F39D=EAEA,180095=EAEA,1800AD=EAEA,1800B8=EAEA,1800BD=EAEA,3D0=425B,18522=425B,2C804=42BA,683B5=425B,696AC=42BA,89233=DB61,895DF=425B,A7A9D=42BA,1072E7=42D9,107355=425B,1073CF=425B,107443=425B,107498=425B,107505=425B,107539=425B,107563=425B,1801D4=4210,18041D=4279 +925637C7|Super Mario All-Stars (U)|4|0|0|0|0|0|181AC=42 +56410E5E|Super Mario Kart (E) [!]|7|0|0|0|0|0|960C=EAEA,9638=EAEA,1F508=EAEA,1F51E=EAEA,1F529=EAEA,1F52E=EAEA,1F55C=EAEA,3BB80=EAEA,61E37=EAEA,805E=42 +CD80DB86|Super Mario Kart (U)|5|820000|0|0|0|0|9625=EAEA,9651=EAEA,1F513=EAEA,1F529=EAEA,1F534=EAEA,1F539=EAEA,1F567=EAEA,3BB72=EAEA,61E37=EAEA,805E=42 +B19ED489|Super Mario World|C|0|96|1C|A|19|6D=42 +B47F5F20|Super Mario World (V1|6|0|0|0|0|0 +AD2CBF9C|Super Metroid (E) (M3)|10000006|4800|0|0|0|0|346=42DB,16529=421B,2D1=423B,1606E=423B +D63ED5F8|Super Metroid (U)|10000004|40400000|B06|0|32|0|346=42DB +6BCBBA10|Super Ninja Boy (U)|0|0|0|0|0|4FA|4FA=421C,23C70=421B,8276=421B +E2F92F84|Super Punch-Out!! (U)|4000004|0|0|0|0|0|4C42=42DB,3145=42DC,10B7=42DC +8B22C830|Super R-Type|4000000|0|1599|0|1E|0|1BE=42 +442C47CB|Super Soccer (E)|2|0|0|0|0|0 +4FD164D8|Super Soccer (U)|0|0|0|0|0|0|4DE=EAEA,179=42F8 +13FC69C5|Super Star Wars (U) [p1][!]|0|0|0|0|0|0|1904=EAEA,22C2=EAEA,1783=42DB +ACBCAE7C|Super Star Wars (u)(31438)|0|4000|0|0|0|0|1787=42DB +1E7EA62C|Super Star Wars - Empire Strike|10000000|4040|0|0|0|0|4D0=EAEA,53F=EAEA,55A=EAEA,573=EAEA,5D4=EAEA,5DA=EAEA,5FB=EAEA,62B=EAEA,636=EAEA,63B=EAEA,182EB=EAEA,182F1=EAEA,1830A=EAEA,1833B=EAEA,AD93E=EAEA,17A962=EAEA,17C0BB=EAEA +F16D5CE9|Super Street Fighter 2 - The Ne|1320001|0|0|0|0|0|DB=42FB +70F28A6D|Super SWIV (J) (32469)|0|0|0|0|0|0|15C9=EAEA +8D383776|Super Tennis (U) [!]|0|0|0|0|0|0|47B4=EAEA +C6B25E62|Super Turrican (U)|0|40400000|4C3|0|3C|18|6020E=EAEA,6021F=EAEA,6022E=EAEA,60241=EAEA,3C1=42DB,5EC86=42,53673=42 +5E550E27|Super Turrican 2 (U)(32515)|0|40400000|0|0|0|0|1FFB20=4299,1FFB2B=42DB,1FF548=DB07,1FF6D2=DB07,1FF55A=42DB,1FF6E4=43DB,1FAD29=DBDA,1FAC12=42DC,1FED44=DB9F,157C=DB4F +D74570D3|Syndicate (U)|0|0|0|0|0|0|F756F=EAEA +5DC6B9FE|T2 - The Arcade Game (U)|0|0|0|0|0|0|F80B8=EAEA,F81E8=EAEA,F81BA=EAEA,F8202=EAEA,F80B6=EAEA,F80C4=EAEA +AB57932F|tactics ogre (v1.2) (j)|4|4849004|0|0|0|0|78073=EAEA,780B2=EAEA,78333=EAEA,78381=EAEA,783A0=EAEA,219D=42FB,78191=EAEA,DF5EC=EAEA +DAF285A5|Tactics Ogre - Version 1.0 (J)|4|4849004|0|0|0|0|78073=EAEA,780B2=EAEA,78333=EAEA,78381=EAEA,783A0=EAEA,219D=42FB,78191=EAEA,DF5EC=EAEA +271E1D07|Tactics Ogre - Version 1.1 (J)|4|4849004|0|0|0|0|78073=EAEA,780B2=EAEA,78333=EAEA,78381=EAEA,783A0=EAEA,219D=42FB,78191=EAEA,DF5EC=EAEA +12F0A699|Tactics Ogre - Version 1.2 (J)|4|4849004|0|0|0|0|78073=EAEA,780B2=EAEA,78333=EAEA,78381=EAEA,783A0=EAEA,219D=42FB,78191=EAEA,DF5EC=EAEA +93F29DDE|Taekwon-Do (J) (M2)|0|440800|0|0|0|0|618C=42F8,626B=42D3 +8745A442|Tales of Phantasia (J)|5|0|0|0|0|0 +14612848|Tales of Phantasia (J) [T-Eng1|5|0|0|0|0|0 +E302D853|Tecmo Super Baseball (U)|4|0|0|0|0|0|A39E=EAEA,A3C7=EAEA,A400=EAEA,A471=EAEA,A48C=EAEA,A4AC=EAEA,A516=EAEA,A521=EAEA,A526=EAEA,A54F=EAEA,A555=EAEA,A65E=EAEA,A968=EAEA,A97F=EAEA,A9AE=EAEA,A9BD=EAEA,A9EA=EAEA,758B4=EAEA,F23B5=EAEA +8EF1411F|Tecmo Super Bowl 3 (U)|4|0|0|0|0|0|4E31=EAEA,4E49=EAEA,4E55=EAEA,4E5A=EAEA,4EB2=EAEA,4EEA=EAEA,4F16=EAEA,4FA5=EAEA,4FAA=EAEA,4FD4=EAEA,7E81C=EAEA,351=42D9,4B085=DB,52399=DB,544AA=42BE,1C1897=DB60,1FAEBE=421F +7E107C35|Tekkaman Blade (J)|0|4444|0|0|0|0|181=42FC +066687CA|Tekken 2 (PD)|0|44C00|0|0|0|0 +6E030B96|Tenshi no Uta - Shiroki Tsubas|5|400400|0|0|0|0|EECE=EAEA,1001A5=EAEA,2840=421B,10148=421A,283B=423B,429E=42D7 +D71E6C3B|Terminator, The (U)|10000000|0|0|0|0|0|10046=EAEA,100AB=EAEA,100DE=EAEA,101B6=EAEA,330=42,5681=42 +974523FF|Terranigma (E) [!]|7|0|0|0|0|0|6B8F3=EAEA,798CF=8003,6800D=421A,797CE=80 +6C852EF3|Tetris & Dr. Mario (U) [!]|0|0|0|0|0|0|6EA=EAEA,3B3E=EAEA,3B89=EAEA,3B9D=EAEA +6C128210|Tetris Attack (U)|0|0|0|0|0|0|148B=EAEA,1486=EAEA,14CC=EAEA,1556=EAEA,14DD=EAEA,155B=EAEA,1571=EAEA,1576=EAEA,20168=DBA4 +B8F5F846|Tetris Battle Gaiden (J)|0|0|0|0|0|A|C040=42DB +B3EF81F5|The Adventures of Batman & Robi|18000000|44000|0|0|0|0|1779=EAEA,161B=EAEA,F3=4288 +CA0E041C|Theme Park (E) [!]|2|0|0|0|0|0|41EDF=EAEA,70073=EAEA,702D5=EAEA,74110=EAEA,744A6=EAEA,36F=4210,3AD=42D9,74A7C=DB +41A933A6|Thunder Spirits (J)|0|4484|0|0|0|0|810=42DB +522FE837|Thunder Spirits (U)|0|4444|0|0|0|0|818=42DB +12AB22A7|Tick, The (U)|0|0|0|0|0|0|723=42F3 +AB48D27A|Tiny Toons Adventures - Buster|0|0|0|0|0|0 +F1F8F87A|Tiny Toons Adventures - Buster|0|0|0|0|0|0|1AAF=DBBF +5940BD99|TMNT 4 - Turtles in Time|1320000|0|7E040C|0|1E|14|162=4280 +5D98C75C|TMNT 4 - Turtles in Time (Alt)|1320000|0|7E040C|0|1E|14|162=4280 +E2FE5DBF|TMNT Tournament Fighters|0|0|0|0|5|0|22DF=EAEA,22E4=EAEA,525=EAEA,21B5=EAEA,21C3=EAEA,21D1=EAEA,16D=4284 +654E1BE4|Torneco no Daibouken (J)|4|400800|0|0|0|0|181BB=EAEA,1AB9F=EAEA,1ABA0=EAEA,1ABA2=EAEA,1AB5F=EAEA,1A924=EAEA,1A92C=EAEA,1A708=428B +85A21253|Torneco no Daibouken (V1|4|400800|0|0|0|0|181BB=EAEA,1AB9F=EAEA,1ABA0=EAEA,1ABA2=EAEA,1AB5F=EAEA,1A924=EAEA,1A92C=EAEA,1A708=428B +B5113CCB|Traverse Starlight & Prairie (J|5|0|0|0|0|0|1C3385=421B,104857=42DB,10476C=423B,104771=421B,10486D=42DB,19D2A=EAEA +3CCEED49|Treasure Hunter G (J)|4|4000|0|0|0|0|40055=EAEA,402C8=EAEA,83=421B,88=423B,95=42F9 +4C9E6827|Treasure Hunter G (J) [T+EngBet|8000004|44C00|0|0|0|0|40055=EAEA,402C8=EAEA,83=421B,88=423B,95=42F9 +40CA49AE|True Lies (U)|0|80408|0|0|0|0|3EB=42D7,8D0A=EAEA,8D11=EAEA,8D4B=EAEA,8D5F=EAEA,8D6C=EAEA,8D90=EAEA,8DA3=EAEA,8DAE=EAEA,8DD2=EAEA,8DDB=EAEA,2AC40=EAEA,41D30=EAEA,6726F=EAEA,7886F=EAEA +91867AF4|Twinbee - Rainbow Bell Adventu|4000004|40404|0|0|0|FFFFFFFB|2959=EAEA,2967=EAEA,2975=EAEA,2A81=EAEA,10C=4281 +231F0F67|U.N. Squadron (U)|8000000|44400|0|0|0|19|61=EAEA,64=EAEA,65=EAEA,129=42FC +B380BCD9|Uchuu no Kishi Tekkaman Blade |0|4444|0|0|0|0|181=42FC +272DFC4B|UFO Kamen Yakisoban (J)|0|800|0|0|0|0|7C7=EAEA,7CE=EAEA,7D5=EAEA,805=EAEA,80C=EAEA,813=EAEA,53DA=EAEA,ACE5=42FB,B25F=42,A1=42 +9277C9F7|Ultima VI - The False Prophet (|4|0|0|0|0|0|237A=4210 +E790F52F|Ultima VII - The Black Gate (U)|4|0|0|0|0|0|3FC=EAEA,436=EAEA,441=EAEA,446=EAEA,474=EAEA,49E=EAEA,4B1=EAEA,4BD=EAEA,4C8=EAEA,4D5=EAEA,4EA=EAEA,F329D=DBFE,93295=DB +F5BFE41E|Ultimate Mortal Kombat 3 (U)|1|40444040|0|0|0|0|4E9BD=EAEA,4EA1B=EAEA,4EA32=EAEA,4EA4E=EAEA,4EA66=EAEA,4EA72=EAEA,4EA77=EAEA,4EAA5=EAEA,4EAD2=EAEA,4EADF=EAEA,4EAF9=EAEA,4EB17=EAEA,4EB1D=EAEA,4EB47=EAEA,4EB74=EAEA,4F95A=EAEA,4F985=EAEA,4F9B3=EAEA,4F9E1=EAEA,4FA0F=EAEA,4FA45=EAEA,4FA5F=EAEA,4FA82=EAEA,4FA95=EAEA,4FAB8=EAEA,4FACB=EAEA,4FAEE=EAEA,4FB01=EAEA,4FB28=EAEA,1121C5=EAEA,876F=42,FDCA=42B9,4EC17=428D,84B91=DB,F92C9=42BB,33D253=428F,39F773=DBF0,3B9DAC=DBF0 +0B108549|Ultra Baseball Jitsumei Ban 2 |4|0|0|0|0|0|7AF=421C +393CCCA2|Umi Hara Kawa Se (J)|40C0004|0|0|0|0|0|F0=42 +3C3C63E6|Uncharted Waters - New Horizons|5|0|0|0|0|0|9E98=42D9,9F5F=42DB +B574C939|Undercover Cops (J)|1|0|0|0|0|0|1C0520=EAEA,1C011D=EAEA,1C04C6=EAEA,1C04E3=EAEA,1C02E2=EAEA,1C02FF=EAEA,1C00D0=EAEA,1C00ED=EAEA,8128=42 +59180F1C|Universal Soldier (U) (Beta)|0|44C00|0|0|0|0|4A68=EAEA,4423=42FB,43F1=42F7,43A4=42D9,6033=42D8 +B9BF7990|Urban Strike (U) [!]|0|0|0|0|0|0 +2D1004F1|Wario's Woods (U)|4|0|0|0|0|0|58195=EAEA,5824E=EAEA,32F=42DC +A47884D0|Warlock (U)|4000000|0|0|0|0|0|676E=EAEA,6786=EAEA,6791=EAEA,6796=EAEA,67DB=EAEA,67E2=EAEA,6804=EAEA,683D=EAEA,6854=EAEA,6867=EAEA,68E0=EAEA,68F7=EAEA,690A=EAEA,694C=EAEA,69ED=429B,E905=42D9,1680FA=DB6E +8B477300|WCW Super Brawl (U)|0|0|0|0|0|0|13FFD=42FC,BBD9=42DB +7379E3B3|Whirlo (E)|2|0|0|0|0|0|CD3=42DC +1637D1A5|Wings 2 (U)|0|0|0|0|0|0|78103=EAEA,78116=EAEA,78119=EAEA +D5CE2DB5|Wizard of Oz, The (U)|0|44800|0|0|0|0|150=42FC,5224=42 +B8A72553|Wizardry 1 2 3 (J) (NP)|4|0|0|0|0|0|1C008E=EAEA,1C00CB=EAEA,1C00E0=EAEA,1C0108=EAEA,1C05AC=EAEA,1C05E3=EAEA,1C05ED=EAEA,BD=DB,1BF=42BA,159750=4210 +D8FDDD76|Wizardry 5 (U)|4|0|0|0|0|0|18A=42BA,213=428C,66830=42,14C5=EAEA,15D4=EAEA,695E=EAEA,69D8=EAEA,6C5F=EAEA,4003C=EAEA,40046=EAEA,40056=EAEA,40070=EAEA,4009A=EAEA,400A8=EAEA,400B3=EAEA,400C4=EAEA,400DE=EAEA,400FC=EAEA,40117=EAEA,40144=EAEA,40164=EAEA,4016B=EAEA,4017F=EAEA,401B8=EAEA,401C5=EAEA,401CF=EAEA,401DF=EAEA,401F1=EAEA,4020D=EAEA,49C8F=EAEA,5004B=EAEA,50055=EAEA,50065=EAEA,5007F=EAEA,500B7=EAEA,500D1=EAEA,500E6=EAEA,50105=EAEA,5011B=EAEA,5017D=EAEA,50187=EAEA,50197=EAEA,501B1=EAEA,501BA=EAEA,501CB=EAEA,501DD=EAEA,501EA=EAEA,5023B=EAEA,50245=EAEA,50255=EAEA,5026F=EAEA,50289=EAEA,50298=EAEA,95CD3=EAEA,A8655=EAEA,B7A03=EAEA,BBE13=EAEA,DCCB1=EAEA +1703D522|Wizardry Gaiden IV - Taima no K|4|40040800|0|0|0|0|B0726=EAEA,B05C8=EAEA,523=42DC,B071F=42,60=4283 +13BFB3A0|Wolfchild (U)|4000000|804|0|0|0|0|F8099=EAEA,F8146=EAEA,F811B=EAEA,F815E=EAEA,F809E=EAEA,5F8=42FC,614=42FC +36079184|Wonder Project J [T+Eng1.04]|5|0|0|0|0|0|AB80=EAEA,2E4A2=EAEA,2E4A8=EAEA,2E4BB=EAEA,2E4BF=EAEA,8420=42DB +90D0FAC0|Worms (E)|10000002|0|0|0|0|0|150085=EAEA,150178=EAEA,19C3B7=EAEA,1B5A=423A,1B60=421A,7627=DB,794E=423A,7BD1=42D8,1B1013=DB +4F02A304|X-Men Mutant Apocalypse (J)|4000001|44000|0|0|0|0|AB=42FB +5E34822A|X-Men Mutant Apocalypse (U)|4000001|44800|0|0|0|0|AB=42FB +C7C12A57|Xardion|4|0|D02|0|1E|5|5E90=421B,5E9E=421B,5E82=421B +7448D45C|Yogi Bear (U)|0|0|0|0|0|0|1ED=EAEA,74C=EAEA,856=EAEA,1137=EAEA,1DB6=EAEA,1EFC=EAEA,1FAD=EAEA,279E=EAEA,57FA=EAEA,5849=EAEA,5861=EAEA,586C=EAEA,5871=EAEA,601BD=EAEA,E84A7=EAEA +EF15F4C3|Yoshi's Cookie (U)|0|0|0|0|0|0|2824F=421B +D138F224|Yoshi's Island (V1.0) (U)|0|40C00|0|0|0|0|42B=EAEA,443=EAEA,44E=EAEA,453=EAEA,E79FB=EAEA,FBEE4=EAEA,FD086=EAEA,1DD2A6=EAEA,4065=4297,441A=427B,650B=42BA,B8845=421B,B884A=423B,1CC4C8=DB,1DEAED=DB +59490CE8|Yoshi's Safari|0|0|0|0|0|0 +7EA1AFE8|Young Merlin|0|0|0|0|0|0 +64A91E64|Ys 3 - Wanderers from Ys|0|0|0|0|0|0|D8=42 +1ADD47F0|Ys 4 - Mask of the Sun (J) [T-E|4|0|0|0|0|0|14060C=EAEA,140631=EAEA,9CA=42DC,A3B=42DC +7B4CEBAF|Ys 4 - Mask of the Sun (J) [T-E|4|0|0|0|0|14060C|14060C=EAEA,140631=EAEA,9CA=42DC,A3B=42DC +CFE632B9|Ys V - Expert (J)|4|44800|0|0|0|0|886=EAEA,79D=EAEA,3B81=EAEA,86C=EAEA,5E06=42FB,A9C=42FB,5DCC=42DB +EC96D517|YUUYUU Hakusho (J)|0|0|0|0|0|0|E15=42FC +EEF45A93|YUUYUU Hakusho 2 - Kakutou no S|0|0|0|0|0|0|10F=42DC +5617A42E|YUUYUU Hakusho Final (J)|1|0|0|0|0|0|A71D=EAEA,A683=EAEA,AB=42DC +535CCCAC|YUUYUU Hakusho Tokubehuten (J)|0|0|0|0|0|0|7957=EAEA,781A=EAEA +5409D4F4|Zen Nihon GT Sensyuken (J)|1320000|0|0|0|0|0|8003B=EAEA,8012B=EAEA,80137=EAEA,15E=42FB +5397D5BC|Zero the Kamikaze Squirrel (U)|0|0|0|0|0|0|41B44=EAEA,41B69=EAEA,1F3=42DB,12EA=4214,2884A=42DB,496=421B,41F=421B +7CFC0C7C|Zombies Ate My Neighbors (U)|10000000|4040|0|0|0|0|4CCF=EAEA,9DC=42 diff --git a/src/.DS_Store b/src/.DS_Store new file mode 100755 index 0000000..f65b5d0 Binary files /dev/null and b/src/.DS_Store differ diff --git a/src/snes4iphone_src/.DS_Store b/src/snes4iphone_src/.DS_Store new file mode 100755 index 0000000..5008ddf Binary files /dev/null and b/src/snes4iphone_src/.DS_Store differ diff --git a/src/snes4iphone_src/2xsaiwin.cpp b/src/snes4iphone_src/2xsaiwin.cpp new file mode 100755 index 0000000..8e11516 --- /dev/null +++ b/src/snes4iphone_src/2xsaiwin.cpp @@ -0,0 +1,707 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +//#define MMX + +#if !defined(_SNESPPC) && !defined(__GIZ__) && !defined(__GP2X__) && !defined(__IPHONE__) +#include "snes9x/snes9x.h" +#include "snes9x/port.h" +#include "snes9x/gfx.h" +#else +#include "snes9x.h" +#include "port.h" +#include "gfx.h" +#endif + +#ifdef MMX +EXTERN_C void _2xSaILine (uint8 *srcPtr, uint8 *deltaPtr, uint32 srcPitch, uint32 width, + uint8 *dstPtr, uint32 dstPitch); +EXTERN_C void _2xSaISuperEagleLine (uint8 *srcPtr, uint8 *deltaPtr, uint32 srcPitch, uint32 width, + uint8 *dstPtr, uint32 dstPitch); +EXTERN_C int Init_2xSaIMMX (uint32 BitFormat); +#endif + +bool mmx_cpu = false; + +static uint32 colorMask = 0xF7DEF7DE; +static uint32 lowPixelMask = 0x08210821; +static uint32 qcolorMask = 0xE79CE79C; +static uint32 qlowpixelMask = 0x18631863; + + +int Init_2xSaI(uint32 BitFormat) +{ + if (BitFormat == 565) + { + colorMask = 0xF7DEF7DE; + lowPixelMask = 0x08210821; + qcolorMask = 0xE79CE79C; + qlowpixelMask = 0x18631863; + } + else + if (BitFormat == 555) + { + colorMask = 0x7BDE7BDE; + lowPixelMask = 0x04210421; + qcolorMask = 0x739C739C; + qlowpixelMask = 0x0C630C63; + } + else + { + return 0; + } +#ifdef MMX + Init_2xSaIMMX(BitFormat); +#endif + return 1; +} + +STATIC inline int GetResult1(uint32 A, uint32 B, uint32 C, uint32 D, uint32 E) +{ + int x = 0; + int y = 0; + int r = 0; + if (A == C) x+=1; else if (B == C) y+=1; + if (A == D) x+=1; else if (B == D) y+=1; + if (x <= 1) r+=1; + if (y <= 1) r-=1; + return r; +} + +STATIC inline int GetResult2(uint32 A, uint32 B, uint32 C, uint32 D, uint32 E) +{ + int x = 0; + int y = 0; + int r = 0; + if (A == C) x+=1; else if (B == C) y+=1; + if (A == D) x+=1; else if (B == D) y+=1; + if (x <= 1) r-=1; + if (y <= 1) r+=1; + return r; +} + + +STATIC inline int GetResult(uint32 A, uint32 B, uint32 C, uint32 D) +{ + int x = 0; + int y = 0; + int r = 0; + if (A == C) x+=1; else if (B == C) y+=1; + if (A == D) x+=1; else if (B == D) y+=1; + if (x <= 1) r+=1; + if (y <= 1) r-=1; + return r; +} + + +STATIC inline uint32 INTERPOLATE(uint32 A, uint32 B) +{ + if (A !=B) + { + return ( ((A & colorMask) >> 1) + ((B & colorMask) >> 1) + (A & B & lowPixelMask) ); + } + else return A; +} + + +STATIC inline uint32 Q_INTERPOLATE(uint32 A, uint32 B, uint32 C, uint32 D) +{ + register uint32 x = ((A & qcolorMask) >> 2) + + ((B & qcolorMask) >> 2) + + ((C & qcolorMask) >> 2) + + ((D & qcolorMask) >> 2); + register uint32 y = (A & qlowpixelMask) + + (B & qlowpixelMask) + + (C & qlowpixelMask) + + (D & qlowpixelMask); + y = (y>>2) & qlowpixelMask; + return x+y; +} + + + + +#define HOR +#define VER +void Super2xSaI(uint8 *srcPtr, uint32 srcPitch, + uint8 *deltaPtr, + uint8 *dstPtr, uint32 dstPitch, int width, int height) +{ + uint32 *dP; + uint16 *bP; + +#ifdef MMX_BLA //no MMX version yet + if (cpu_mmx && width != 512) + { + for (height; height; height-=1) + { + bP = (uint16 *) srcPtr; + xP = (uint16 *) deltaPtr; + dP = (uint32 *) dstPtr; + _2xSaISuperEagleLine ((uint8 *) bP, (uint8 *) xP, srcPitch, width, (uint8 *) dP, dstPitch); + dstPtr += dstPitch << 1; + srcPtr += srcPitch; + deltaPtr += srcPitch; + } + } + else + { +#endif + uint32 Nextline = srcPitch >> 1; + + for (height; height; height-=1) + { + bP = (uint16 *) srcPtr; + dP = (uint32 *) dstPtr; + for (uint32 finish = width; finish; finish -= 1 ) + { + uint32 color4, color5, color6; + uint32 color1, color2, color3; + uint32 colorA0, colorA1, colorA2, colorA3, + colorB0, colorB1, colorB2, colorB3, + colorS1, colorS2; + uint32 product1a, product1b, + product2a, product2b; + +//--------------------------------------- B1 B2 +// 4 5 6 S2 +// 1 2 3 S1 +// A1 A2 + + colorB0 = *(bP- Nextline - 1); + colorB1 = *(bP- Nextline); + colorB2 = *(bP- Nextline + 1); + colorB3 = *(bP- Nextline + 2); + + color4 = *(bP - 1); + color5 = *(bP); + color6 = *(bP + 1); + colorS2 = *(bP + 2); + + color1 = *(bP + Nextline - 1); + color2 = *(bP + Nextline); + color3 = *(bP + Nextline + 1); + colorS1 = *(bP + Nextline + 2); + + colorA0 = *(bP + Nextline + Nextline - 1); + colorA1 = *(bP + Nextline + Nextline); + colorA2 = *(bP + Nextline + Nextline + 1); + colorA3 = *(bP + Nextline + Nextline + 2); + + +//-------------------------------------- + if (color2 == color6 && color5 != color3) + { + product2b = product1b = color2; + } + else + if (color5 == color3 && color2 != color6) + { + product2b = product1b = color5; + } + else + if (color5 == color3 && color2 == color6 && color5 != color6) + { + register int r = 0; + + r += GetResult (color6, color5, color1, colorA1); + r += GetResult (color6, color5, color4, colorB1); + r += GetResult (color6, color5, colorA2, colorS1); + r += GetResult (color6, color5, colorB2, colorS2); + + if (r > 0) + product2b = product1b = color6; + else + if (r < 0) + product2b = product1b = color5; + else + { + product2b = product1b = INTERPOLATE (color5, color6); + } + + } + else + { + +#ifdef VER + if (color6 == color3 && color3 == colorA1 && color2 != colorA2 && color3 != colorA0) + product2b = Q_INTERPOLATE (color3, color3, color3, color2); + else + if (color5 == color2 && color2 == colorA2 && colorA1 != color3 && color2 != colorA3) + product2b = Q_INTERPOLATE (color2, color2, color2, color3); + else +#endif + product2b = INTERPOLATE (color2, color3); + +#ifdef VER + if (color6 == color3 && color6 == colorB1 && color5 != colorB2 && color6 != colorB0) + product1b = Q_INTERPOLATE (color6, color6, color6, color5); + else + if (color5 == color2 && color5 == colorB2 && colorB1 != color6 && color5 != colorB3) + product1b = Q_INTERPOLATE (color6, color5, color5, color5); + else +#endif + product1b = INTERPOLATE (color5, color6); + } + +#ifdef HOR + if (color5 == color3 && color2 != color6 && color4 == color5 && color5 != colorA2) + product2a = INTERPOLATE (color2, color5); + else + if (color5 == color1 && color6 == color5 && color4 != color2 && color5 != colorA0) + product2a = INTERPOLATE(color2, color5); + else +#endif + product2a = color2; + +#ifdef HOR + if (color2 == color6 && color5 != color3 && color1 == color2 && color2 != colorB2) + product1a = INTERPOLATE (color2, color5); + else + if (color4 == color2 && color3 == color2 && color1 != color5 && color2 != colorB0) + product1a = INTERPOLATE(color2, color5); + else +#endif + product1a = color5; + + + product1a = product1a | (product1b << 16); + product2a = product2a | (product2b << 16); + + *(dP) = product1a; + *(dP+(dstPitch>>2)) = product2a; + + bP += 1; + dP += 1; + }//end of for ( finish= width etc..) + + dstPtr += dstPitch << 1; + srcPtr += srcPitch; + deltaPtr += srcPitch; + }; //endof: for (height; height; height--) +#ifdef MMX_BLA + } +#endif +} + + + + + + +/*ONLY use with 640x480x16 or higher resolutions*/ +/*Only use this if 2*width * 2*height fits on the current screen*/ +void SuperEagle(uint8 *srcPtr, uint32 srcPitch, + uint8 *deltaPtr, + uint8 *dstPtr, uint32 dstPitch, int width, int height) +{ + uint32 *dP; + uint16 *bP; +#if !defined(_SNESPPC) && !defined(__GIZ__) && !defined(__GP2X__) && !defined(__IPHONE__) + uint16 *xP; +#endif + +#ifdef MMX + if (mmx_cpu && width != 512) + { + for (height; height; height-=1) + { + bP = (uint16 *) srcPtr; + xP = (uint16 *) deltaPtr; + dP = (uint32 *) dstPtr; + _2xSaISuperEagleLine ((uint8 *) bP, (uint8 *) xP, srcPitch, width, (uint8 *)dP, dstPitch); + dstPtr += dstPitch << 1; + srcPtr += srcPitch; + deltaPtr += srcPitch; + } + } + else + { +#endif + uint32 Nextline = srcPitch >> 1; + + for (height; height; height-=1) + { + bP = (uint16 *) srcPtr; + dP = (uint32 *) dstPtr; + for (uint32 finish = width; finish; finish -= 1 ) + { + + uint32 color4, color5, color6; + uint32 color1, color2, color3; + uint32 colorA0, colorA1, colorA2, colorA3, + colorB0, colorB1, colorB2, colorB3, + colorS1, colorS2; + uint32 product1a, product1b, + product2a, product2b; + + colorB0 = *(bP- Nextline - 1); + colorB1 = *(bP- Nextline); + colorB2 = *(bP- Nextline + 1); + colorB3 = *(bP- Nextline + 2); + + color4 = *(bP - 1); + color5 = *(bP); + color6 = *(bP + 1); + colorS2 = *(bP + 2); + + color1 = *(bP + Nextline - 1); + color2 = *(bP + Nextline); + color3 = *(bP + Nextline + 1); + colorS1 = *(bP + Nextline + 2); + + colorA0 = *(bP + Nextline + Nextline - 1); + colorA1 = *(bP + Nextline + Nextline); + colorA2 = *(bP + Nextline + Nextline + 1); + colorA3 = *(bP + Nextline + Nextline + 2); + + + //-------------------------------------- + if (color2 == color6 && color5 != color3) + { + product1b = product2a = color2; + if ((color1 == color2 && color6 == colorS2) || + (color2 == colorA1 && color6 == colorB2)) + { + product1a = INTERPOLATE (color2, color5); + product1a = INTERPOLATE (color2, product1a); + product2b = INTERPOLATE (color2, color3); + product2b = INTERPOLATE (color2, product2b); +// product1a = color2; +// product2b = color2; + } + else + { + product1a = INTERPOLATE (color5, color6); + product2b = INTERPOLATE (color2, color3); + } + } + else + if (color5 == color3 && color2 != color6) + { + product2b = product1a = color5; + if ((colorB1 == color5 && color3 == colorA2) || + (color4 == color5 && color3 == colorS1)) + { + product1b = INTERPOLATE (color5, color6); + product1b = INTERPOLATE (color5, product1b); + product2a = INTERPOLATE (color5, color2); + product2a = INTERPOLATE (color5, product2a); +// product1b = color5; +// product2a = color5; + } + else + { + product1b = INTERPOLATE (color5, color6); + product2a = INTERPOLATE (color2, color3); + } + } + else + if (color5 == color3 && color2 == color6 && color5 != color6) + { + register int r = 0; + + r += GetResult (color6, color5, color1, colorA1); + r += GetResult (color6, color5, color4, colorB1); + r += GetResult (color6, color5, colorA2, colorS1); + r += GetResult (color6, color5, colorB2, colorS2); + + if (r > 0) + { + product1b = product2a = color2; + product1a = product2b = INTERPOLATE (color5, color6); + } + else + if (r < 0) + { + product2b = product1a = color5; + product1b = product2a = INTERPOLATE (color5, color6); + } + else + { + product2b = product1a = color5; + product1b = product2a = color2; + } + } + else + { + + if ((color2 == color5) || (color3 == color6)) + { + product1a = color5; + product2a = color2; + product1b = color6; + product2b = color3; + + } + else + { + product1b = product1a = INTERPOLATE (color5, color6); + product1a = INTERPOLATE (color5, product1a); + product1b = INTERPOLATE (color6, product1b); + + product2a = product2b = INTERPOLATE (color2, color3); + product2a = INTERPOLATE (color2, product2a); + product2b = INTERPOLATE (color3, product2b); + } + } + + + product1a = product1a | (product1b << 16); + product2a = product2a | (product2b << 16); + + *(dP) = product1a; + *(dP+(dstPitch>>2)) = product2a; + + bP += 1; + dP += 1; + }//end of for ( finish= width etc..) + + dstPtr += dstPitch << 1; + srcPtr += srcPitch; + deltaPtr += srcPitch; + }; //endof: for (height; height; height--) +#ifdef MMX + } +#endif +} + + + +/*ONLY use with 640x480x16 or higher resolutions*/ +/*Only use this if 2*width * 2*height fits on the current screen*/ +void _2xSaI(uint8 *srcPtr, uint32 srcPitch, + uint8 *deltaPtr, + uint8 *dstPtr, uint32 dstPitch, int width, int height) +{ + uint32 *dP; + uint16 *bP; +#if !defined(_SNESPPC) && !defined(__GIZ__) && !defined(__GP2X__) && !defined(__IPHONE__) + uint16 *xP; +#endif + +#ifdef MMX + if (mmx_cpu && width != 512) + { + for (height; height; height-=1) + { + + bP = (uint16 *) srcPtr; + xP = (uint16 *) deltaPtr; + dP = (uint32 *) dstPtr; + _2xSaILine ((uint8 *) bP, (uint8 *) xP, srcPitch, width, (uint8 *)dP, dstPitch); + dstPtr += dstPitch << 1; + srcPtr += srcPitch; + deltaPtr += srcPitch; + } + } + else + { +#endif + uint32 Nextline = srcPitch >> 1; + + for (height; height; height-=1) + { + bP = (uint16 *) srcPtr; + dP = (uint32 *) dstPtr; + for (uint32 finish = width; finish; finish -= 1 ) + { + + + register uint32 colorA, colorB; + uint32 colorC, colorD, + colorE, colorF, colorG, colorH, + colorI, colorJ, colorK, colorL, + colorM, colorN, colorO, colorP; + uint32 product, product1, product2; + + +//--------------------------------------- +// Map of the pixels: I|E F|J +// G|A B|K +// H|C D|L +// M|N O|P + colorI = *(bP- Nextline - 1); + colorE = *(bP- Nextline); + colorF = *(bP- Nextline + 1); + colorJ = *(bP- Nextline + 2); + + colorG = *(bP - 1); + colorA = *(bP); + colorB = *(bP + 1); + colorK = *(bP + 2); + + colorH = *(bP + Nextline - 1); + colorC = *(bP + Nextline); + colorD = *(bP + Nextline + 1); + colorL = *(bP + Nextline + 2); + + colorM = *(bP + Nextline + Nextline - 1); + colorN = *(bP + Nextline + Nextline); + colorO = *(bP + Nextline + Nextline + 1); + colorP = *(bP + Nextline + Nextline + 2); + + if ((colorA == colorD) && (colorB != colorC)) + { + if ( ((colorA == colorE) && (colorB == colorL)) || + ((colorA == colorC) && (colorA == colorF) && (colorB != colorE) && (colorB == colorJ)) ) + { + product = colorA; + } + else + { + product = INTERPOLATE(colorA, colorB); + } + + if (((colorA == colorG) && (colorC == colorO)) || + ((colorA == colorB) && (colorA == colorH) && (colorG != colorC) && (colorC == colorM)) ) + { + product1 = colorA; + } + else + { + product1 = INTERPOLATE(colorA, colorC); + } + product2 = colorA; + } + else + if ((colorB == colorC) && (colorA != colorD)) + { + if (((colorB == colorF) && (colorA == colorH)) || + ((colorB == colorE) && (colorB == colorD) && (colorA != colorF) && (colorA == colorI)) ) + { + product = colorB; + } + else + { + product = INTERPOLATE(colorA, colorB); + } + + if (((colorC == colorH) && (colorA == colorF)) || + ((colorC == colorG) && (colorC == colorD) && (colorA != colorH) && (colorA == colorI)) ) + { + product1 = colorC; + } + else + { + product1 = INTERPOLATE(colorA, colorC); + } + product2 = colorB; + } + else + if ((colorA == colorD) && (colorB == colorC)) + { + if (colorA == colorB) + { + product = colorA; + product1 = colorA; + product2 = colorA; + } + else + { + register int r = 0; + product1 = INTERPOLATE(colorA, colorC); + product = INTERPOLATE(colorA, colorB); + + r += GetResult1 (colorA, colorB, colorG, colorE, colorI); + r += GetResult2 (colorB, colorA, colorK, colorF, colorJ); + r += GetResult2 (colorB, colorA, colorH, colorN, colorM); + r += GetResult1 (colorA, colorB, colorL, colorO, colorP); + + if (r > 0) + product2 = colorA; + else + if (r < 0) + product2 = colorB; + else + { + product2 = Q_INTERPOLATE(colorA, colorB, colorC, colorD); + } + } + } + else + { + product2 = Q_INTERPOLATE(colorA, colorB, colorC, colorD); + + if ((colorA == colorC) && (colorA == colorF) && (colorB != colorE) && (colorB == colorJ)) + { + product = colorA; + } + else + if ((colorB == colorE) && (colorB == colorD) && (colorA != colorF) && (colorA == colorI)) + { + product = colorB; + } + else + { + product = INTERPOLATE(colorA, colorB); + } + + if ((colorA == colorB) && (colorA == colorH) && (colorG != colorC) && (colorC == colorM)) + { + product1 = colorA; + } + else + if ((colorC == colorG) && (colorC == colorD) && (colorA != colorH) && (colorA == colorI)) + { + product1 = colorC; + } + else + { + product1 = INTERPOLATE(colorA, colorC); + } + } + product = colorA | (product << 16); + product1 = product1 | (product2 << 16); + *(dP) = product; + *(dP+(dstPitch>>2)) = product1; + + bP += 1; + dP += 1; + }//end of for ( finish= width etc..) + + dstPtr += dstPitch << 1; + srcPtr += srcPitch; + deltaPtr += srcPitch; + }; //endof: for (height; height; height--) +#ifdef MMX + } +#endif +} diff --git a/src/snes4iphone_src/3d.h b/src/snes4iphone_src/3d.h new file mode 100755 index 0000000..6585fa7 --- /dev/null +++ b/src/snes4iphone_src/3d.h @@ -0,0 +1,100 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#ifndef _3D_H_ +#define _3D_H_ + +#if defined(USE_OPENGL) +#include +#include + +#ifdef __linux__ +//#include +#endif + +typedef struct +{ + bool8 packed_pixels_extension_present; + bool8 draw_cube; + uint32 version; + // Texture format + GLint internal_format; + GLint format; + GLint type; + + GLint max_texture_size;// 256 or 512 + GLint texture_size; + uint32 num_textures; // 1 if max_texture_size == 256, 2 otherwise + GLuint textures [2]; +} OpenGLData; + +extern OpenGLData OpenGL; + +bool8 S9xOpenGLInit (); +bool8 S9xOpenGLInit2 (); +void S9xOpenGLPutImage (int width, int height); +void S9xOpenGLDeinit (); + +#endif + +#ifdef USE_GLIDE +//#include + +typedef struct +{ + bool8 voodoo_present; + GrVertex sq[4]; + GrTexInfo texture; + int32 texture_mem_size; + int32 texture_mem_start; + float x_offset, y_offset; + float x_scale, y_scale; + float voodoo_width; + float voodoo_height; +} GlideData; + +extern GlideData Glide; +bool8 S9xGlideEnable (bool8 enable); +void S9xGlideDeinit (); +bool8 S9xGlideInit (); +bool8 S9xVoodooInitialise (); +#endif + +#endif diff --git a/src/snes4iphone_src/65c816.h b/src/snes4iphone_src/65c816.h new file mode 100755 index 0000000..aa251dc --- /dev/null +++ b/src/snes4iphone_src/65c816.h @@ -0,0 +1,123 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#ifndef _65c816_h_ +#define _65c816_h_ + +#define AL A.B.l +#define AH A.B.h +#define XL X.B.l +#define XH X.B.h +#define YL Y.B.l +#define YH Y.B.h +#define SL S.B.l +#define SH S.B.h +#define DL D.B.l +#define DH D.B.h +#define PL P.B.l +#define PH P.B.h + +#define Carry 1 +#define Zero 2 +#define IRQ 4 +#define Decimal 8 +#define IndexFlag 16 +#define MemoryFlag 32 +#define Overflow 64 +#define Negative 128 +#define Emulation 256 + +#define ClearCarry() (ICPU._Carry = 0) +#define SetCarry() (ICPU._Carry = 1) +#define SetZero() (ICPU._Zero = 0) +#define ClearZero() (ICPU._Zero = 1) +#define SetIRQ() (Registers.PL |= IRQ) +#define ClearIRQ() (Registers.PL &= ~IRQ) +#define SetDecimal() (Registers.PL |= Decimal) +#define ClearDecimal() (Registers.PL &= ~Decimal) +#define SetIndex() (Registers.PL |= IndexFlag) +#define ClearIndex() (Registers.PL &= ~IndexFlag) +#define SetMemory() (Registers.PL |= MemoryFlag) +#define ClearMemory() (Registers.PL &= ~MemoryFlag) +#define SetOverflow() (ICPU._Overflow = 1) +#define ClearOverflow() (ICPU._Overflow = 0) +#define SetNegative() (ICPU._Negative = 0x80) +#define ClearNegative() (ICPU._Negative = 0) + +#define CheckZero() (ICPU._Zero == 0) +#define CheckCarry() (ICPU._Carry) +#define CheckIRQ() (Registers.PL & IRQ) +#define CheckDecimal() (Registers.PL & Decimal) +#define CheckIndex() (Registers.PL & IndexFlag) +#define CheckMemory() (Registers.PL & MemoryFlag) +#define CheckOverflow() (ICPU._Overflow) +#define CheckNegative() (ICPU._Negative & 0x80) +#define CheckEmulation() (Registers.P.W & Emulation) + +#define ClearFlags(f) (Registers.P.W &= ~(f)) +#define SetFlags(f) (Registers.P.W |= (f)) +#define CheckFlag(f) (Registers.PL & (f)) + +typedef union +{ +#ifdef LSB_FIRST + struct { uint8 l,h; } PACKING B; +#else + struct { uint8 h,l; } PACKING B; +#endif + uint16 W; +} ALIGN_BY_ONE pair; + +struct SRegisters{ + uint8 PB; + uint8 DB; + pair P; + pair A; + pair D; + pair X; + pair S; + pair Y; + uint16 PC; +} PACKING; + +#define Registers CPU.Regs +//EXTERN_C struct SRegisters Registers; + +#endif diff --git a/src/snes4iphone_src/DSP1_gp32.cpp b/src/snes4iphone_src/DSP1_gp32.cpp new file mode 100755 index 0000000..a38763e --- /dev/null +++ b/src/snes4iphone_src/DSP1_gp32.cpp @@ -0,0 +1,529 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#include "snes9x.h" +#include "dsp1.h" +#include "missing.h" +#include "memmap.h" +#include + +#include "dsp1emu_gp32.c" + +void S9xInitDSP1 () +{ + static bool8 init = FALSE; + + if (!init) + { + InitDSP (); + init = TRUE; + } +} + +void S9xResetDSP1 () +{ + S9xInitDSP1 (); + + DSP1.waiting4command = TRUE; + DSP1.in_count = 0; + DSP1.out_count = 0; + DSP1.in_index = 0; + DSP1.out_index = 0; + DSP1.first_parameter = TRUE; +} + +uint8 S9xGetDSP (uint16 address) +{ + uint8 t; + +#ifdef DEBUGGER + if (Settings.TraceDSP) + { + sprintf (String, "DSP read: 0x%04X", address); + S9xMessage (S9X_TRACE, S9X_TRACE_DSP1, String); + } +#endif + if ((address & 0xf000) == 0x6000 || + (address >= 0x8000 && address < 0xc000)) + { + if (DSP1.out_count) + { + if ((address & 1) == 0) + t = (uint8) DSP1.output [DSP1.out_index]; + else + { + t = (uint8) (DSP1.output [DSP1.out_index] >> 8); + DSP1.out_index++; + if (--DSP1.out_count == 0) + { + if (DSP1.command == 0x1a || DSP1.command == 0x0a) + { + DSPOp0A (); + DSP1.out_count = 4; + DSP1.out_index = 0; + DSP1.output [0] = Op0AA; + DSP1.output [1] = Op0AB; + DSP1.output [2] = Op0AC; + DSP1.output [3] = Op0AD; + } + } + DSP1.waiting4command = TRUE; + } + } + else + { + // Top Gear 3000 requires this value.... + t = 0xff; + } + } + else + t = 0x80; + + return (t); +} + +void S9xSetDSP (uint8 byte, uint16 address) +{ +#ifdef DEBUGGER + missing.unknowndsp_write = address; + if (Settings.TraceDSP) + { + sprintf (String, "DSP write: 0x%04X=0x%02X", address, byte); + S9xMessage (S9X_TRACE, S9X_TRACE_DSP1, String); + } +#endif + if ((address & 0xf000) == 0x6000 || + (address >= 0x8000 && address < 0xc000)) + { + if ((address & 1) == 0) + { + if (DSP1.waiting4command) + { + DSP1.command = byte; + DSP1.in_index = 0; + DSP1.waiting4command = FALSE; + DSP1.first_parameter = TRUE; + + // Mario Kart uses 0x00, 0x02, 0x06, 0x0c, 0x28, 0x0a + switch (byte) + { + case 0x00: DSP1.in_count = 2; break; + case 0x10: DSP1.in_count = 2; break; + case 0x04: DSP1.in_count = 2; break; + case 0x08: DSP1.in_count = 3; break; + case 0x18: DSP1.in_count = 4; break; + case 0x28: DSP1.in_count = 3; break; + case 0x0c: DSP1.in_count = 3; break; + case 0x1c: DSP1.in_count = 6; break; + case 0x02: DSP1.in_count = 7; break; + case 0x0a: DSP1.in_count = 1; break; + case 0x1a: DSP1.in_count = 1; break; + case 0x06: DSP1.in_count = 3; break; + case 0x0e: DSP1.in_count = 2; break; + case 0x01: DSP1.in_count = 4; break; + case 0x11: DSP1.in_count = 4; break; + case 0x21: DSP1.in_count = 4; break; + case 0x0d: DSP1.in_count = 3; break; + case 0x1d: DSP1.in_count = 3; break; + case 0x2d: DSP1.in_count = 3; break; + case 0x03: DSP1.in_count = 3; break; + case 0x13: DSP1.in_count = 3; break; + case 0x23: DSP1.in_count = 3; break; + case 0x0b: DSP1.in_count = 3; break; + case 0x1b: DSP1.in_count = 3; break; + case 0x2b: DSP1.in_count = 3; break; + case 0x14: DSP1.in_count = 6; break; +// case 0x80: DSP1.in_count = 2; break; + + default: + case 0x80: + DSP1.in_count = 0; + DSP1.waiting4command = TRUE; + DSP1.first_parameter = TRUE; + break; + } + } + else + { + DSP1.parameters [DSP1.in_index] = byte; + DSP1.first_parameter = FALSE; + } + } + else + { + if (DSP1.waiting4command || + (DSP1.first_parameter && byte == 0x80)) + { + DSP1.waiting4command = TRUE; + DSP1.first_parameter = FALSE; + } + else + if (DSP1.first_parameter) + { + } + else + { + if (DSP1.in_count) + { + DSP1.parameters [DSP1.in_index] |= (byte << 8); + if (--DSP1.in_count == 0) + { + // Actually execute the command + DSP1.waiting4command = TRUE; + DSP1.out_index = 0; + switch (DSP1.command) + { + case 0x00: // Multiple + Op00Multiplicand = (int16) DSP1.parameters [0]; + Op00Multiplier = (int16) DSP1.parameters [1]; + + DSPOp00 (); + + DSP1.out_count = 1; + DSP1.output [0] = Op00Result; + break; + + case 0x10: // Inverse + Op10Coefficient = (int16) DSP1.parameters [0]; + Op10Exponent = (int16) DSP1.parameters [1]; + + DSPOp10 (); + + DSP1.out_count = 2; + DSP1.output [0] = (uint16) (int16) Op10CoefficientR; + DSP1.output [1] = (uint16) (int16) Op10ExponentR; + break; + + case 0x04: // Sin and Cos of angle + Op04Angle = (int16) DSP1.parameters [0]; + Op04Radius = (uint16) DSP1.parameters [1]; + + DSPOp04 (); + + DSP1.out_count = 2; + DSP1.output [0] = (uint16) Op04Sin; + DSP1.output [1] = (uint16) Op04Cos; + break; + + case 0x08: // Radius + Op08X = (int16) DSP1.parameters [0]; + Op08Y = (int16) DSP1.parameters [1]; + Op08Z = (int16) DSP1.parameters [2]; + + DSPOp08 (); + + DSP1.out_count = 2; + DSP1.output [0] = (int16) Op08Ll; + DSP1.output [1] = (int16) Op08Lh; + break; + + case 0x18: // Range + + Op18X = (int16) DSP1.parameters [0]; + Op18Y = (int16) DSP1.parameters [1]; + Op18Z = (int16) DSP1.parameters [2]; + Op18R = (int16) DSP1.parameters [3]; + + DSPOp18 (); + + DSP1.out_count = 1; + DSP1.output [0] = Op18D; + break; + + case 0x28: // Distance (vector length) + Op28X = (int16) DSP1.parameters [0]; + Op28Y = (int16) DSP1.parameters [1]; + Op28Z = (int16) DSP1.parameters [2]; + + DSPOp28 (); + + DSP1.out_count = 1; + DSP1.output [0] = (uint16) Op28R; + break; + + case 0x0c: // Rotate (2D rotate) + Op0CA = (int16) DSP1.parameters [0]; + Op0CX1 = (int16) DSP1.parameters [1]; + Op0CY1 = (int16) DSP1.parameters [2]; + + DSPOp0C (); + + DSP1.out_count = 2; + DSP1.output [0] = (uint16) Op0CX2; + DSP1.output [1] = (uint16) Op0CY2; + break; + + case 0x1c: // Polar (3D rotate) + Op1CZ = DSP1.parameters [0]; + Op1CX = DSP1.parameters [1]; + Op1CY = DSP1.parameters [2]; + Op1CXBR = DSP1.parameters [3]; + Op1CYBR = DSP1.parameters [4]; + Op1CZBR = DSP1.parameters [5]; + + DSPOp1C (); + + DSP1.out_count = 3; + DSP1.output [0] = (uint16) Op1CXAR; + DSP1.output [1] = (uint16) Op1CYAR; + DSP1.output [2] = (uint16) Op1CZAR; + break; + + case 0x02: // Parameter (Projection) + Op02FX = DSP1.parameters [0]; + Op02FY = DSP1.parameters [1]; + Op02FZ = DSP1.parameters [2]; + Op02LFE = DSP1.parameters [3]; + Op02LES = DSP1.parameters [4]; + Op02AAS = DSP1.parameters [5]; + Op02AZS = DSP1.parameters [6]; + + DSPOp02 (); + + DSP1.out_count = 4; + DSP1.output [0] = Op02VOF; + DSP1.output [1] = Op02VVA; + DSP1.output [2] = Op02CX; + DSP1.output [3] = Op02CY; + break; + + case 0x1a: // Raster mode 7 matrix data + case 0x0a: + Op0AVS = DSP1.parameters [0]; + + DSPOp0A (); + + DSP1.out_count = 4; + DSP1.output [0] = Op0AA; + DSP1.output [1] = Op0AB; + DSP1.output [2] = Op0AC; + DSP1.output [3] = Op0AD; + break; + + case 0x06: // Project object + Op06X = (int16) DSP1.parameters [0]; + Op06Y = (int16) DSP1.parameters [1]; + Op06Z = (int16) DSP1.parameters [2]; + + DSPOp06 (); + + DSP1.out_count = 3; + DSP1.output [0] = Op06H; + DSP1.output [1] = Op06V; + DSP1.output [2] = Op06S; + break; + + case 0x0e: // Target + Op0EH = (int16) DSP1.parameters [0]; + Op0EV = (int16) DSP1.parameters [1]; + + DSPOp0E (); + + DSP1.out_count = 2; + DSP1.output [0] = Op0EX; + DSP1.output [1] = Op0EY; + break; + + // Extra commands used by Pilot Wings + case 0x01: // Set attitude matrix A + Op01m = (int16) DSP1.parameters [0]; + Op01Zr = (int16) DSP1.parameters [1]; + Op01Xr = (int16) DSP1.parameters [2]; + Op01Yr = (int16) DSP1.parameters [3]; + + DSPOp01 (); + break; + + case 0x11: // Set attitude matrix B + Op11m = (int16) DSP1.parameters [0]; + Op11Zr = (int16) DSP1.parameters [1]; + Op11Xr = (int16) DSP1.parameters [2]; + Op11Yr = (int16) DSP1.parameters [3]; + + DSPOp11 (); + break; + + case 0x21: // Set attitude matrix C + Op21m = (int16) DSP1.parameters [0]; + Op21Zr = (int16) DSP1.parameters [1]; + Op21Xr = (int16) DSP1.parameters [2]; + Op21Yr = (int16) DSP1.parameters [3]; + + DSPOp21 (); + break; + + case 0x0d: // Objective matrix A + Op0DX = (int16) DSP1.parameters [0]; + Op0DY = (int16) DSP1.parameters [1]; + Op0DZ = (int16) DSP1.parameters [2]; + + DSPOp0D (); + + DSP1.out_count = 3; + DSP1.output [0] = (uint16) Op0DF; + DSP1.output [1] = (uint16) Op0DL; + DSP1.output [2] = (uint16) Op0DU; + break; + + case 0x1d: // Objective matrix B + Op1DX = (int16) DSP1.parameters [0]; + Op1DY = (int16) DSP1.parameters [1]; + Op1DZ = (int16) DSP1.parameters [2]; + + DSPOp1D (); + + DSP1.out_count = 3; + DSP1.output [0] = (uint16) Op1DF; + DSP1.output [1] = (uint16) Op1DL; + DSP1.output [2] = (uint16) Op1DU; + break; + + case 0x2d: // Objective matrix C + Op2DX = (int16) DSP1.parameters [0]; + Op2DY = (int16) DSP1.parameters [1]; + Op2DZ = (int16) DSP1.parameters [2]; + + DSPOp2D (); + + DSP1.out_count = 3; + DSP1.output [0] = (uint16) Op2DF; + DSP1.output [1] = (uint16) Op2DL; + DSP1.output [2] = (uint16) Op2DU; + break; + + case 0x03: // Subjective matrix A + Op03F = (int16) DSP1.parameters [0]; + Op03L = (int16) DSP1.parameters [1]; + Op03U = (int16) DSP1.parameters [2]; + + DSPOp03 (); + + DSP1.out_count = 3; + DSP1.output [0] = (uint16) Op03X; + DSP1.output [1] = (uint16) Op03Y; + DSP1.output [2] = (uint16) Op03Z; + break; + + case 0x13: // Subjective matrix B + Op13F = (int16) DSP1.parameters [0]; + Op13L = (int16) DSP1.parameters [1]; + Op13U = (int16) DSP1.parameters [2]; + + DSPOp13 (); + + DSP1.out_count = 3; + DSP1.output [0] = (uint16) Op13X; + DSP1.output [1] = (uint16) Op13Y; + DSP1.output [2] = (uint16) Op13Z; + break; + + case 0x23: // Subjective matrix C + Op23F = (int16) DSP1.parameters [0]; + Op23L = (int16) DSP1.parameters [1]; + Op23U = (int16) DSP1.parameters [2]; + + DSPOp23 (); + + DSP1.out_count = 3; + DSP1.output [0] = (uint16) Op23X; + DSP1.output [1] = (uint16) Op23Y; + DSP1.output [2] = (uint16) Op23Z; + break; + + case 0x0b: + Op0BX = (int16) DSP1.parameters [0]; + Op0BY = (int16) DSP1.parameters [1]; + Op0BZ = (int16) DSP1.parameters [2]; + + DSPOp0B (); + + DSP1.out_count = 1; + DSP1.output [0] = (uint16) Op0BS; + break; + + case 0x1b: + Op1BX = (int16) DSP1.parameters [0]; + Op1BY = (int16) DSP1.parameters [1]; + Op1BZ = (int16) DSP1.parameters [2]; + + DSPOp1B (); + + DSP1.out_count = 1; + DSP1.output [0] = (uint16) Op1BS; + break; + + case 0x2b: + Op2BX = (int16) DSP1.parameters [0]; + Op2BY = (int16) DSP1.parameters [1]; + Op2BZ = (int16) DSP1.parameters [2]; + + DSPOp0B (); + + DSP1.out_count = 1; + DSP1.output [0] = (uint16) Op2BS; + break; + + case 0x14: // Gyrate + Op14Zr = (int16) DSP1.parameters [0]; + Op14Xr = (int16) DSP1.parameters [1]; + Op14Yr = (int16) DSP1.parameters [2]; + Op14U = (int16) DSP1.parameters [3]; + Op14F = (int16) DSP1.parameters [4]; + Op14L = (int16) DSP1.parameters [5]; + + DSPOp14 (); + + DSP1.out_count = 3; + DSP1.output [0] = (uint16) Op14Zrr; + DSP1.output [1] = (uint16) Op14Xrr; + DSP1.output [2] = (uint16) Op14Yrr; + break; + + default: + break; + } + } + else + DSP1.in_index++; + } + } + } + } +} diff --git a/src/snes4iphone_src/Makefile b/src/snes4iphone_src/Makefile new file mode 100755 index 0000000..55cab78 --- /dev/null +++ b/src/snes4iphone_src/Makefile @@ -0,0 +1,104 @@ +VERSION=2.0 +COPT = -F/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS${VERSION}.sdk/System/Library/Frameworks -F/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS${VERSION}.sdk/System/Library/PrivateFrameworks -I../../ -I../../Classes/ -I../../Classes/AdMob/ -I/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.0.sdk/usr/lib/gcc/arm-apple-darwin9/4.2.1/include -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS${VERSION}.sdk -L/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS${VERSION}.sdk/usr/lib +COPT += -march=armv6 -miphoneos-version-min=${VERSION} -I. -O3 -D__IPHONE__ -D_SNESPPC -DASM_SPC700 -DZLIB -DUNZIP_SUPPORT -DOLD_COLOUR_BLENDING -DUSE_SA1 -DSUPER_FX -DLSB_FIRST -DCPU_SHUTDOWN -DVAR_CYCLES +COPT += -fnested-functions -funsigned-char -ffast-math -fexpensive-optimizations -ftemplate-depth-36 -mstructure-size-boundary=32 -falign-functions=32 -falign-loops -falign-labels -falign-jumps -finline -finline-functions -fno-builtin -fno-common -fomit-frame-pointer -fpeel-loops -fstrength-reduce -funroll-loops -fstrict-aliasing +GCC = /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/arm-apple-darwin9-gcc-4.2.1 +GXX = /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/arm-apple-darwin9-g++-4.2.1 +#-DSPC700_SHUTDOWN +#-DRC_OPTIMIZED +# SNES stuff (c-based) +# cpuops.o sa1cpu.o +OBJS = apu.o c4.o c4emu.o cheats.o cheats2.o clip.o cpu.o cpuexec.o data.o +OBJS += dma.o dsp1.o fxemu.o fxinst.o gfx.o globals.o input.o ioapi.o loadzip.o memmap.o menu.o ppu.o +OBJS += sa1.o sdd1.o sdd1emu.o snapshot.o soundux.o spc700.o srtc.o tile.o unzip.o os9x_asm_cpu.o os9x_65c816.o spc700a.o +# +# ASM CPU Core, ripped from Yoyo's OpenSnes9X +# +#OBJS += os9x_65c816.o +# os9x_asm_cpu.o spc700a.o +# +# and some asm from LJP... +# +# OBJS += m3d_func.o +# +# Dave's minimal SDK +# +OBJS += iphone_sdk.o iphone_menutile.o iphone_highlightbar.o iphone_menu_header.o +OBJS += ../../main.o ../../NowPlayingController.o ../../Classes/helpers.o ../../Classes/OptionsController.o ../../Classes/RecentController.o ../../Classes/RomController.o ../../Classes/SaveStatesController.o ../../Classes/ShoutOutAppDelegate.o ../../Classes/SOApplication.o ../../Classes/TabBar.o + + +# +# and the glue code that sticks it all together :) +# +OBJS += main.o + +# Inopia's menu system, hacked for the GP2X under rlyeh's sdk +PRELIBS = -lobjc \ + -lpthread \ + -framework CoreFoundation \ + -framework Foundation \ + -framework UIKit \ + -framework QuartzCore \ + -framework CoreGraphics \ + -framework CoreSurface \ + -framework CoreLocation \ + -framework AudioToolbox \ + -framework GraphicsServices \ + -framework OpenGLES \ + -framework AddressBook ../../Classes/AdMob/libAdMobDevice.a ../../Classes/AdMob/MobClix.a ../../Classes/AdMob/MobClixAds.a ../../Classes/AdMob/MobClixBrowser.a ../../Classes/AdMob/MobClixFeedback.a -lsqlite3 -framework SystemConfiguration \ + -lz \ + -allow_stack_execute + +all: pocketsnes +clean: tidy + +.c.o: + $(GCC) $(COPT) -c $< -o $@ + +.cpp.o: + $(GXX) $(COPT) -c $< -o $@ + +%.o: %.m + $(GCC) ${COPT} -c $< -o $@ + +%.o: %.S + $(GCC) ${COPT} -c $< -o $@ + +%.o: %.s + $(GCC) ${COPT} -c $< -o $@ + +# make seems to lowercase the extensions, so files with '.S' end up being passed to the compiler as '.s', which means thousands of errors. +# this is a small workaround. + +#spc700a.o: spc700a.s +# $(GCC) $(COPT) -c $< -o $@ + +#os9x_65c816.o: os9x_65c816.s +# $(GCC) $(COPT) -c $< -o $@ + +#osnes9xgp_asmfunc.o: osnes9xgp_asmfunc.s +# $(GCC) $(COPT) -c $< -o $@ + +#m3d_func.o: m3d_func.S +# $(GCC) $(COPT) -c $< -o $@ + +#spc_decode.o: spc_decode.s +# $(GCC) $(COPT) -c $< -o $@ + +#memset.o: memset.s +# $(GCC) $(COPT) -c $< -o $@ + +#memcpy.o: memcpy.s +# $(GCC) $(COPT) -c $< -o $@ + +#dspMixer.o: dspMixer.s +# $(GCC) $(COPT) -c $< -o $@ + +pocketsnesd: $(OBJS) + $(GXX) $(COPT) $(OBJS) $(PRELIBS) -o $@ + +pocketsnes: pocketsnesd + cp pocketsnesd snes4iphone + +tidy: + rm *.o ../../*.o ../../Classes/*.o ../../Classes/AdMob/*.o diff --git a/src/snes4iphone_src/Makefile_giz b/src/snes4iphone_src/Makefile_giz new file mode 100755 index 0000000..f20d02c --- /dev/null +++ b/src/snes4iphone_src/Makefile_giz @@ -0,0 +1,88 @@ +#COPT = -static -g -I. -I C:/devkitGP2X/include -IC:/devkitGP2X/sysroot/usr/include -O3 -D__GP2X__ + +SDK_BASE = C:/cygwin/usr/local/arm-wince-pe/lib/KGSDK +ZLIB_BASE = C:/cygwin/usr/local/arm-wince-pe/lib/zlib + +#COPT = -IC:/cygwin/usr/local/arm-wince-pe/include -I$(SDK_BASE)/include -static -g -I. -O3 -mtune=arm920t -ftracer -fstrength-reduce -Wno-unused -funroll-loops -fomit-frame-pointer -fstrict-aliasing -ffast-math -D__GP2X__ +COPT = -IC:/cygwin/usr/local/arm-wince-pe/include -I$(SDK_BASE)/include -I$(ZLIB_BASE)/include -I . -mcpu=arm920 \ + -mtune=arm920t -O2 -msoft-float -ffast-math -fstrict-aliasing -mstructure-size-boundary=8 \ + -fexpensive-optimizations -fweb -frename-registers -fomit-frame-pointer -falign-functions -finline -finline-functions \ + -fno-builtin -fno-common -D__GIZ__ +GCC = arm-wince-pe-gcc +STRIP = arm-wince-pe-strip +ADSASM = armasm + +# +# SNES stuff (c-based) +# +OBJS = 2xsaiwin.o apu.o c4.o c4emu.o cheats.o cheats2.o clip.o cpu.o cpuexec.o data.o +OBJS += dma.o dsp1.o fxemu.o fxinst.o gfx.o globals.o loadzip.o memmap.o ppu.o +OBJS += sdd1.o snapshot.o soundux.o spc700.o srtc.o tile.o +# +# ASM CPU Core, ripped from Yoyo's OpenSnes9X +# +OBJS += os9x_asm_cpu.o os9x_65c816.o spc700a.o +#osnes9xgp_asmfunc.o +#RenderASM/render8.o +# +# and some asm from LJP... +# +OBJS += m3d_func.o spc_decode.o +# +# +# +OBJS += giz_kgsdk.o menu.o input.o gp2x_menutile.o gp2x_highlightbar.o \ + gp2x_menu_header.o unzip.o ioapi.o giz_kgsdkasm.o + +# +# and the glue code that sticks it all together :) +# +OBJS += main.o + +# Inopia's menu system, hacked for the GP2X under rlyeh's sdk +PRELIBS = -LC:/cygwin/usr/local/arm-wince-pe/lib -L$(ZLIB_BASE) -lzip -L$(SDK_BASE) -lKGSDK $(LIBS) + +all: squidgesnes.gpe +clean: tidy squidgesnes.gpe + +.c.o: + $(GCC) $(COPT) -c $< -o $@ + +.cpp.o: + $(GCC) $(COPT) -c $< -o $@ + +# make seems to lowercase the extensions, so files with '.S' end up being passed to the compiler as '.s', which means thousands of errors. +# this is a small workaround. + +myuname.o: myuname.S + $(GCC) $(COPT) -c $< -o $@ + +os9x_65c816.o: os9x_65c816.s + $(GCC) $(COPT) -c $< -o $@ + +osnes9xgp_asmfunc.o: osnes9xgp_asmfunc.S + $(GCC) $(COPT) -c $< -o $@ + +m3d_func.o: m3d_func.S + $(GCC) $(COPT) -c $< -o $@ + +spc_decode.o: spc_decode.s + $(GCC) $(COPT) -c $< -o $@ + +spc700a.o: spc700a.s + $(GCC) $(COPT) -c $< -o $@ + +giz_kgsdkasm.o: giz_kgsdkasm.s + $(GCC) $(COPT) -c $< -o $@ + +RenderASM/render8.o: RenderASM/render8.S + $(GCC) $(COPT) -c $< -o $@ + +squidgesnesd.gpe: $(OBJS) + $(GCC) $(COPT) $(OBJS) -static $(PRELIBS) -o $@ -lstdc++ -lm + +squidgesnes.gpe: squidgesnesd.gpe + $(STRIP) squidgesnesd.gpe -o squidgesnes.gpe + cp squidgesnes.gpe autorun.exe +tidy: + del *.o diff --git a/src/snes4iphone_src/PocketSNES.cpp b/src/snes4iphone_src/PocketSNES.cpp new file mode 100755 index 0000000..6be1ed3 --- /dev/null +++ b/src/snes4iphone_src/PocketSNES.cpp @@ -0,0 +1,2377 @@ +// PocketSNES.cpp : Defines the entry point for the application. +// + +#include "stdafx.h" +#include "PocketSNES.h" + +#include +#include +#include +#ifdef _WIN32_WCE_EMULATION +//#include "gapi.h" +#else +#include "gx.h" +#endif + +#include "snes9x.h" +#include "pocketpc.h" +#include "VOIMAGE.H" +#include "Prof/profiler.h" + +#define MAX_LOADSTRING 100 + +extern bool InitializeEmulation(int,int,int); +extern bool LoadROM(); +extern bool StartEmulation(HWND, HWND); +extern bool StopEmulation(HWND, HWND); +extern bool PauseEmulation(HWND, HWND); +extern bool ResumeEmulation(HWND, HWND); + +extern "C" void S9xReset(); +extern "C" void S9xSetTitle(const char *); +extern "C" void S9xMainLoop(void); + +extern bool g_bResumeAfterLoadState; +extern bool g_bResumeAfterSaveState; + +extern TCHAR g_szTitle[64]; +extern GXKeyList g_gxkl; + +class Skin +{ +public: + TCHAR *pszBitmap; + TCHAR *pszName; + TCHAR *pszAuthor; + short iVersion; + short iNumberOfColors; + unsigned short iColor[32]; + unsigned short iMask[32]; + bool bResource; + bool bLandscape; + + Skin() + : pszBitmap(NULL), pszName(NULL), pszAuthor(NULL), iNumberOfColors(0), iVersion(0), + bResource(false), bLandscape(false) + { + } + + ~Skin() + { + if (pszBitmap) + delete [] pszBitmap; + if (pszName) + delete [] pszName; + if (pszAuthor) + delete [] pszAuthor; + } + + void AddColor(DWORD _dwColor, DWORD _dwMask) + { + iColor[iNumberOfColors] = ((_dwColor & 0xf80000) >> 8)|((_dwColor & 0xfc00) >> 5)|((_dwColor & 0xf8) >> 3); + iMask[iNumberOfColors] = _dwMask; + + iNumberOfColors++; + } + + void AddColor(TCHAR *_pszColor, TCHAR *_pszMask) + { + DWORD dwColor = 0; + TCHAR *pszTemp = _pszColor; + + pszTemp += 2; + + dwColor = TextToInt(pszTemp); + iColor[iNumberOfColors] = ((dwColor & 0xf80000) >> 8)|((dwColor & 0xfc00) >> 5)|((dwColor & 0xf8) >> 3); + iMask[iNumberOfColors] = DecodeMask(_pszMask); + + iNumberOfColors++; + } + + void SetBitmap(TCHAR *_pszBitmap) + { + pszBitmap = new TCHAR [_tcslen(_pszBitmap) + 1]; + + _tcscpy(pszBitmap, _pszBitmap); + } + + void SetName(TCHAR *_pszName) + { + pszName = new TCHAR [_tcslen(_pszName) + 1]; + + _tcscpy(pszName, _pszName); + } + + void SetAuthor(TCHAR *_pszAuthor) + { + static TCHAR *szAuthor = L"Designed by: "; + + pszAuthor = new TCHAR [_tcslen(_pszAuthor) + 1 + _tcslen(szAuthor)]; + + _tcscpy(pszAuthor, szAuthor); + _tcscat(pszAuthor, _pszAuthor); + } + + void LoadBitmap(HBITMAP &_hbmSkin, HDC &_hSkinDC, HINSTANCE &_hInstance, HWND &_hWnd) + { + if (_hbmSkin) + DeleteObject(_hbmSkin); + if (_hSkinDC) + DeleteObject(_hSkinDC); + + HDC hDC = GetDC(_hWnd); + + if (bResource) + { + _hbmSkin = ::LoadBitmap(_hInstance, pszBitmap); + } + else + { + _hbmSkin = ::SHLoadDIBitmap(pszBitmap); + } + + if (_hbmSkin) + { + _hSkinDC = CreateCompatibleDC(hDC); + + SelectObject(_hSkinDC, _hbmSkin); + } + + ReleaseDC(_hWnd, hDC); + } + +private: + + DWORD TextToInt(TCHAR *_pszIn) + { + DWORD dwReturn = 0; + + for (int i = 0; i < (int) _tcslen(_pszIn); i++) + { + if ((_pszIn[i] >= _T('0')) && (_pszIn[i] <= _T('9'))) + { + dwReturn = (dwReturn * 16) + (_pszIn[i] - _T('0')); + } + else if ((_pszIn[i] >= _T('A')) && (_pszIn[i] <= _T('F'))) + { + dwReturn = (dwReturn * 16) + (_pszIn[i] - _T('A') + 10); + } + else if ((_pszIn[i] >= _T('a')) && (_pszIn[i] <= _T('f'))) + { + dwReturn = (dwReturn * 16) + (_pszIn[i] - _T('a') + 10); + } + } + + return dwReturn; + } + + unsigned short DecodeMask(TCHAR *_pszIn) + { + unsigned short iReturn = 0; + + TCHAR *pszToken = _tcstok(_pszIn, L"+"); + + while (pszToken != NULL) + { + if (_tcsicmp(pszToken, L"n") == 0) + { + iReturn |= SNES_UP_MASK; + } + else if (_tcsicmp(pszToken, L"s") == 0) + { + iReturn |= SNES_DOWN_MASK; + } + else if (_tcsicmp(pszToken, L"e") == 0) + { + iReturn |= SNES_RIGHT_MASK; + } + else if (_tcsicmp(pszToken, L"w") == 0) + { + iReturn |= SNES_LEFT_MASK; + } + else if (_tcsicmp(pszToken, L"ne") == 0) + { + iReturn |= SNES_UP_MASK|SNES_RIGHT_MASK; + } + else if (_tcsicmp(pszToken, L"se") == 0) + { + iReturn |= SNES_DOWN_MASK|SNES_RIGHT_MASK; + } + else if (_tcsicmp(pszToken, L"sw") == 0) + { + iReturn |= SNES_DOWN_MASK|SNES_LEFT_MASK; + } + else if (_tcsicmp(pszToken, L"nw") == 0) + { + iReturn |= SNES_UP_MASK|SNES_LEFT_MASK; + } + else if (_tcsicmp(pszToken, L"a") == 0) + { + iReturn |= SNES_A_MASK; + } + else if (_tcsicmp(pszToken, L"b") == 0) + { + iReturn |= SNES_B_MASK; + } + else if (_tcsicmp(pszToken, L"x") == 0) + { + iReturn |= SNES_X_MASK; + } + else if (_tcsicmp(pszToken, L"y") == 0) + { + iReturn |= SNES_Y_MASK; + } + else if (_tcsicmp(pszToken, L"l") == 0) + { + iReturn |= SNES_TL_MASK; + } + else if (_tcsicmp(pszToken, L"r") == 0) + { + iReturn |= SNES_TR_MASK; + } + else if (_tcsicmp(pszToken, L"start") == 0) + { + iReturn |= SNES_START_MASK; + } + else if (_tcsicmp(pszToken, L"select") == 0) + { + iReturn |= SNES_SELECT_MASK; + } + + pszToken = _tcstok(NULL, L"+"); + } + + return iReturn; + } +}; + +class Keymap +{ +public: + DWORD dwKeyMask[256]; + + Keymap() + { + memset(dwKeyMask, 0, sizeof(DWORD) * 256); + } + + short GetKeyFromMask(DWORD dwMask) + { + for (short i = 0; i < 256; i++) + { + if (dwKeyMask[i] == dwMask) + return i; + + } + + return 0; + } + + LPTSTR GetKeyDisplayFromMask(DWORD dwMask) + { + static TCHAR szDisplay[10]; + + if (dwMask == 0) + { + _tcscpy(szDisplay, L"..."); + } + else + { + short iKey = GetKeyFromMask(dwMask); + + if (iKey == 0) + { + _tcscpy(szDisplay, L"..."); + } + else + { + wsprintf(szDisplay, L"0x%2x", iKey); + } + } + + return szDisplay; + } + + void SetLandscape(Keymap &_kmPortrait) + { + for (short i = 0; i < 256; i++) + { + dwKeyMask[i] = _kmPortrait.dwKeyMask[i]; + + short iUp = _kmPortrait.GetKeyFromMask(SNES_UP_MASK); + short iDown = _kmPortrait.GetKeyFromMask(SNES_DOWN_MASK); + short iLeft = _kmPortrait.GetKeyFromMask(SNES_LEFT_MASK); + short iRight = _kmPortrait.GetKeyFromMask(SNES_RIGHT_MASK); + + dwKeyMask[iUp] = SNES_RIGHT_MASK; + dwKeyMask[iRight] = SNES_DOWN_MASK; + dwKeyMask[iDown] = SNES_LEFT_MASK; + dwKeyMask[iLeft] = SNES_UP_MASK; + } + } + + void SetLandscapeRight(Keymap &_kmPortrait) + { + for (short i = 0; i < 256; i++) + { + dwKeyMask[i] = _kmPortrait.dwKeyMask[i]; + + short iUp = _kmPortrait.GetKeyFromMask(SNES_UP_MASK); + short iDown = _kmPortrait.GetKeyFromMask(SNES_DOWN_MASK); + short iLeft = _kmPortrait.GetKeyFromMask(SNES_LEFT_MASK); + short iRight = _kmPortrait.GetKeyFromMask(SNES_RIGHT_MASK); + + dwKeyMask[iUp] = SNES_LEFT_MASK; + dwKeyMask[iRight] = SNES_UP_MASK; + dwKeyMask[iDown] = SNES_RIGHT_MASK; + dwKeyMask[iLeft] = SNES_DOWN_MASK; + } + } + + DWORD GetStaticIDFromMask(DWORD dwMask) + { + switch (dwMask) + { + case SNES_UP_MASK: + return IDC_STATIC_UP; + + case SNES_DOWN_MASK: + return IDC_STATIC_DOWN; + + case SNES_LEFT_MASK: + return IDC_STATIC_LEFT; + + case SNES_RIGHT_MASK: + return IDC_STATIC_RIGHT; + + case SNES_A_MASK: + return IDC_STATIC_A; + + case SNES_B_MASK: + return IDC_STATIC_B; + + case SNES_X_MASK: + return IDC_STATIC_X; + + case SNES_Y_MASK: + return IDC_STATIC_Y; + + case SNES_START_MASK: + return IDC_STATIC_START; + + case SNES_SELECT_MASK: + return IDC_STATIC_SELECT; + + case SNES_TL_MASK: + return IDC_STATIC_L; + + case SNES_TR_MASK: + return IDC_STATIC_R; + } + + return 0; + } +}; + +//------------------------------------------------------------------------------ +// Global Variables +//------------------------------------------------------------------------------ +bool g_bLoop = true; +HWND g_hWnd; +HINSTANCE g_hInstance; // The current instance +HWND hwndCB; // The command bar handle +HFONT g_hFontBold; +HFONT g_hFontNormal; +HFONT g_hFontPaused; +HFONT g_hFontHyperlink; +CVOImage g_pngLogo; +HDC g_hLogoDC; +static TCHAR g_sRootKey[256]; +Skin *g_pSkins = NULL; +int g_iSkinCount = 0; +int g_iSelectedSkin = 0; +HBITMAP g_hbmSkin = NULL; +HDC g_hSkinDC = NULL; +Keymap g_kmDefault; +Keymap g_kmCurrent; +Keymap g_kmLandscape; +Keymap *g_pkmInUse; +GXKeyList g_gxKeyList; +bool g_bSetButtonMode; +int g_iSetButton; +RECT g_rtLink; +HICON g_hiLeftArrow; +HICON g_hiRightArrow; +uint32 g_iFrameSkip; + +//------------------------------------------------------------------------------ +// Function definitions +//------------------------------------------------------------------------------ +bool LoadOptions(); +void SaveOptions(); +bool LoadSkins(); +void SaveSkins(); +bool CheckKeyPad(int, int, bool); +void ShowOptions(); +LRESULT CALLBACK SystemDlgProc(HWND, UINT, WPARAM, LPARAM); +LRESULT CALLBACK DisplayDlgProc(HWND, UINT, WPARAM, LPARAM); +LRESULT CALLBACK SoundDlgProc(HWND, UINT, WPARAM, LPARAM); +LRESULT CALLBACK SkinsDlgProc(HWND, UINT, WPARAM, LPARAM); +LRESULT CALLBACK KeysDlgProc(HWND, UINT, WPARAM, LPARAM); +LRESULT CALLBACK CreditsDlgProc(HWND, UINT, WPARAM, LPARAM); + +ATOM MyRegisterClass (HINSTANCE, LPTSTR); +BOOL InitInstance (HINSTANCE, int); +LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); +HWND CreateRpCommandBar(HWND); + + +//------------------------------------------------------------------------------ +// Joypad definitions +// Eight directions +// Eight buttons - start, select, A, B, X, Y, L, R +//------------------------------------------------------------------------------ +#define KP_JOYPAD_N 0 +#define KP_JOYPAD_E 1 +#define KP_JOYPAD_S 2 +#define KP_JOYPAD_W 3 +#define KP_JOYPAD_NE 4 +#define KP_JOYPAD_SE 5 +#define KP_JOYPAD_SW 6 +#define KP_JOYPAD_NW 7 +#define KP_BUTTON_START 8 +#define KP_BUTTON_SELECT 9 +#define KP_BUTTON_A 10 +#define KP_BUTTON_B 11 +#define KP_BUTTON_X 12 +#define KP_BUTTON_Y 13 +#define KP_BUTTON_L 14 +#define KP_BUTTON_R 15 + + + +int WINAPI WinMain( HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPTSTR lpCmdLine, + int nCmdShow) +{ + MSG msg; + HACCEL hAccelTable; + + // Perform application initialization: + if (!InitInstance (hInstance, nCmdShow)) + { + return FALSE; + } + + if (!InitializeEmulation(Settings.Transparency, Settings.APUEnabled, Settings.SixteenBitSound)) + { + MessageBox(NULL, L"PocketSNES needs more memory", NULL, MB_OK); + return FALSE; + } + + S9xSetTitle(""); + SetKeypad(); + + hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_POCKETSNES); + + // Main message loop: + while (g_bLoop) + { + if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + + if (g_emMode == emRunning) + { +#ifdef THREADCPU + Sleep(0); +#else + S9xMainLoop(); +#endif + } + } + + SaveOptions(); +#ifdef __PROFILER + __profiler_dump(); +#endif + return msg.wParam; +} + +// +// FUNCTION: MyRegisterClass() +// +// PURPOSE: Registers the window class. +// +// COMMENTS: +// +// It is important to call this function so that the application +// will get 'well formed' small icons associated with it. +// +ATOM MyRegisterClass(HINSTANCE hInstance, LPTSTR szWindowClass) +{ + WNDCLASS wc; + + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = (WNDPROC) WndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_POCKETSNES)); + wc.hCursor = 0; + wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); + wc.lpszMenuName = 0; + wc.lpszClassName = szWindowClass; + + return RegisterClass(&wc); +} + +// +// FUNCTION: InitInstance(HANDLE, int) +// +// PURPOSE: Saves instance handle and creates main window +// +// COMMENTS: +// +// In this function, we save the instance handle in a global variable and +// create and display the main program window. +// +BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) +{ + HWND hWnd = NULL; + TCHAR szTitle[MAX_LOADSTRING]; // The title bar text + TCHAR szWindowClass[MAX_LOADSTRING]; // The window class name + + g_hInstance = hInstance; // Store instance handle in our global variable + + // Initialize global strings + LoadString(hInstance, IDC_POCKETSNES, szWindowClass, MAX_LOADSTRING); + LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); + + //If it is already running, then focus on the window + hWnd = FindWindow(szWindowClass, szTitle); + if (hWnd) + { + SetForegroundWindow ((HWND) (((DWORD)hWnd) | 0x01)); + return FALSE; + } + + MyRegisterClass(hInstance, szWindowClass); + + RECT rect; + GetClientRect(hWnd, &rect); + + hWnd = CreateWindow(szWindowClass, szTitle, WS_VISIBLE, + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, + NULL, NULL, hInstance, NULL); + if (!hWnd) + { + MessageBox(NULL, L"PocketSNES failed to initialize", NULL, MB_OK); + return FALSE; + } + + //When the main window is created using CW_USEDEFAULT the height of the menubar (if one + // is created is not taken into account). So we resize the window after creating it + // if a menubar is present + { + RECT rc; + GetWindowRect(hWnd, &rc); + rc.bottom -= MENU_HEIGHT; + if (hwndCB) + MoveWindow(hWnd, rc.left, rc.top, rc.right, rc.bottom, FALSE); + } + + LOGFONT lfFont; + TCHAR szFontName[32] = L"Tahoma"; + HDC hDC = GetDC(hWnd); + + memset(&lfFont, 0, sizeof(LOGFONT)); + wcscpy(lfFont.lfFaceName, szFontName); + lfFont.lfWeight = FW_BOLD; + lfFont.lfHeight = (-12 * GetDeviceCaps(hDC, LOGPIXELSY)) / 72; + g_hFontBold = CreateFontIndirect(&lfFont); + + lfFont.lfWeight = FW_NORMAL; + lfFont.lfHeight = (-10 * GetDeviceCaps(hDC, LOGPIXELSY)) / 72; + g_hFontNormal = CreateFontIndirect(&lfFont); + + lfFont.lfUnderline = TRUE; + lfFont.lfHeight = (-10 * GetDeviceCaps(hDC, LOGPIXELSY)) / 72; + g_hFontHyperlink = CreateFontIndirect(&lfFont); + + lfFont.lfUnderline = FALSE; + lfFont.lfWeight = FW_BOLD; + g_hFontPaused = CreateFontIndirect(&lfFont); + + g_hLogoDC = CreateCompatibleDC(hDC); + + g_pngLogo.SetBitmap(g_hLogoDC, IDB_POCKETSNES, TEXT("IMAGE"), GetModuleHandle(NULL)); + SelectObject(g_hLogoDC, (HBITMAP)g_pngLogo); + + _tcscpy(g_sRootKey, _T("SOFTWARE\\Apps\\PocketSNES")); + LoadOptions(); + + g_hiLeftArrow = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_LEFT_ARROW)); + g_hiRightArrow = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_RIGHT_ARROW)); + + LoadSkins(); + g_pSkins[g_iSelectedSkin].LoadBitmap(g_hbmSkin, g_hSkinDC, g_hInstance, g_hWnd); + + ReleaseDC(hWnd, hDC); + + ShowWindow(hWnd, nCmdShow); + UpdateWindow(hWnd); + + g_hWnd = hWnd; + + return TRUE; +} + +// +// FUNCTION: WndProc(HWND, unsigned, WORD, LONG) +// +// PURPOSE: Processes messages for the main window. +// +// WM_COMMAND - process the application menu +// WM_PAINT - Paint the main window +// WM_DESTROY - post a quit message and return +// +// +LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + TCHAR szHello[MAX_LOADSTRING]; + + switch (message) + { + case WM_COMMAND: + { + int wmId = LOWORD(wParam); + int wmEvent = HIWORD(wParam); + + // Parse the menu selections: + switch (wmId) + { + case IDM_TOOLS_LOAD: + //CSNES + //StopEmulation(hWnd, hwndCB); + if (LoadROM()) //hack to keep from crashing if no rom + { + StopEmulation(hWnd, hwndCB); + LoadOptions(); + StartEmulation(hWnd, hwndCB); + } + break; + + case IDM_OPTIONS_RESET: + if(g_emMode != emStopped) + { + StopEmulation(hWnd, hwndCB); + S9xReset(); + StartEmulation(hWnd, hwndCB); + } + break; + + case IDM_OPTIONS_DISPLAY: + DialogBox(g_hInstance, (LPCTSTR)IDD_DISPLAY, hWnd, (DLGPROC)DisplayDlgProc); + SaveOptions(); + break; + + case IDM_OPTIONS_SOUND: + DialogBox(g_hInstance, (LPCTSTR)IDD_SOUND, hWnd, (DLGPROC)SoundDlgProc); + SaveOptions(); + break; + + case IDM_OPTIONS_SYSTEM: + DialogBox(g_hInstance, (LPCTSTR)IDD_SYSTEM, hWnd, (DLGPROC)SystemDlgProc); + SaveOptions(); + break; + + case IDM_OPTIONS_KEYS: + DialogBox(g_hInstance, (LPCTSTR)IDD_KEYS, hWnd, (DLGPROC)KeysDlgProc); + break; + + case IDM_TOOLS_SKINS: + DialogBox(g_hInstance, (LPCTSTR)IDD_SKINS, hWnd, (DLGPROC)SkinsDlgProc); + break; + + case IDM_TOOLS_CREDITS: + DialogBox(g_hInstance, (LPCTSTR)IDD_CREDITS, hWnd, (DLGPROC)CreditsDlgProc); + break; + + case IDM_TOOLS_EXIT: + StopEmulation(hWnd, hwndCB); + SendMessage(hWnd, WM_ACTIVATE, MAKEWPARAM(WA_INACTIVE, 0), (LPARAM)hWnd); + SendMessage(hWnd, WM_CLOSE, 0, 0); + g_bLoop = false; + break; + + case IDM_TOOLS_LOADSTATE: + LoadState(); + //StartEmulation(hWnd, hwndCB); + break; + case IDM_TOOLS_LOAD1: + LoadSlot(0); + break; + case IDM_TOOLS_LOAD2: + LoadSlot(1); + break; + case IDM_TOOLS_LOAD3: + LoadSlot(2); + break; + case IDM_TOOLS_LOAD4: + LoadSlot(3); + break; + case IDM_TOOLS_LOAD5: + LoadSlot(4); + break; + case IDM_TOOLS_LOAD6: + LoadSlot(5); + break; + case IDM_TOOLS_LOAD7: + LoadSlot(6); + break; + case IDM_TOOLS_LOAD8: + LoadSlot(7); + break; + case IDM_TOOLS_LOAD9: + LoadSlot(8); + break; + + case IDM_TOOLS_SAVESTATE: + SaveState(); + break; + case IDM_TOOLS_SAVE1: + SaveSlot(0); + break; + case IDM_TOOLS_SAVE2: + SaveSlot(1); + break; + case IDM_TOOLS_SAVE3: + SaveSlot(2); + break; + case IDM_TOOLS_SAVE4: + SaveSlot(3); + break; + case IDM_TOOLS_SAVE5: + SaveSlot(4); + break; + case IDM_TOOLS_SAVE6: + SaveSlot(5); + break; + case IDM_TOOLS_SAVE7: + SaveSlot(6); + break; + case IDM_TOOLS_SAVE8: + SaveSlot(7); + break; + case IDM_TOOLS_SAVE9: + SaveSlot(8); + break; + + case IDOK: + SendMessage(hWnd, WM_ACTIVATE, MAKEWPARAM(WA_INACTIVE, 0), (LPARAM)hWnd); + SendMessage(hWnd, WM_CLOSE, 0, 0); + break; + + default: + return DefWindowProc(hWnd, message, wParam, lParam); + } + } + break; + + case WM_CREATE: + hwndCB = CreateRpCommandBar(hWnd); + break; + + case WM_KILLFOCUS: + GXSuspend(); + break; + + case WM_SETFOCUS: + GXResume(); + break; + + case WM_PAINT: + if (g_emMode == emStopped) + { + RECT rtTop, rtBottom; + PAINTSTRUCT ps; + HDC hDC = BeginPaint(hWnd, &ps); + + GetClientRect(hWnd, &rtTop); + rtBottom = rtTop; + g_rtLink = rtTop; + rtBottom.top = ((rtBottom.bottom - rtBottom.top) / 2) + rtBottom.top + 36; + rtBottom.bottom = rtBottom.top + 48; + g_rtLink.top = rtBottom.bottom; + rtTop.bottom = rtBottom.top; + rtTop.top = rtTop.bottom - 36; + + BitBlt(hDC, 0, 8, 240, 113, g_hLogoDC, 0, 0, SRCCOPY); + + LoadString(g_hInstance, IDS_HELLO, szHello, MAX_LOADSTRING); + SelectObject(hDC, g_hFontBold); + SetTextColor(hDC, COLORREF(0x00ff0000)); + DrawText(hDC, szHello, _tcslen(szHello), &rtTop, DT_CENTER); + + LoadString(g_hInstance, IDS_HELLO2, szHello, MAX_LOADSTRING); + SelectObject(hDC, g_hFontNormal); + SetTextColor(hDC, COLORREF(0x00000000)); + DrawText(hDC, szHello, _tcslen(szHello), &rtBottom, DT_CENTER); + + LoadString(g_hInstance, IDS_LINK, szHello, MAX_LOADSTRING); + SelectObject(hDC, g_hFontHyperlink); + SetTextColor(hDC, COLORREF(0x00ff0000)); + DrawText(hDC, szHello, _tcslen(szHello), &g_rtLink, DT_CENTER); + EndPaint(hWnd, &ps); + } + else if (g_emMode == emPaused) + { + PAINTSTRUCT ps; + HDC hDC = BeginPaint(hWnd, &ps); + RECT rt = { 0, 224, 240, 320 - 52 }; + + BitBlt(hDC, 0, 0, 240, 224, g_hPausedDC, 0, 0, SRCCOPY); + + LoadString(g_hInstance, IDS_PAUSED, szHello, MAX_LOADSTRING); + SelectObject(hDC, g_hFontPaused); + SetTextColor(hDC, COLORREF(0x000000ff)); + DrawText(hDC, szHello, _tcslen(szHello), &rt, DT_CENTER|DT_SINGLELINE|DT_VCENTER); + + EndPaint(hWnd, &ps); + } + break; + + + case WM_LBUTTONDOWN: + { + POINT ptClick; + + ptClick.x = LOWORD(lParam); + ptClick.y = HIWORD(lParam); + + if (g_emMode == emRunning) + { + static RECT rtScreen = { 0, 0, 240, 180 }; + + if (!CheckKeyPad(ptClick.x, ptClick.y, true)) + { + if (PtInRect(&rtScreen, ptClick)) + { + PauseEmulation(hWnd, hwndCB); + } + } + } + else if (g_emMode == emPaused) + { + static RECT rtScreen = { 0, 26, 240, 320 - 26 }; + + if (PtInRect(&rtScreen, ptClick)) + { + ResumeEmulation(hWnd, hwndCB); + } + } + else if (PtInRect(&g_rtLink, ptClick)) + { + SHELLEXECUTEINFO seInfo; + TCHAR *szCommand = _T("\\Windows\\iexplore.exe"); + TCHAR *szURL = _T("http://www.pocketsnes.com"); + + memset(&seInfo, 0, sizeof(SHELLEXECUTEINFO)); + seInfo.cbSize = sizeof(SHELLEXECUTEINFO); + seInfo.lpFile = szCommand; + seInfo.lpParameters = szURL; + seInfo.nShow = SW_SHOW; + + ShellExecuteEx(&seInfo); + } + } + break; + + case WM_LBUTTONUP: + if (g_emMode == emRunning) + { + CheckKeyPad(LOWORD(lParam), HIWORD(lParam), false); + } + break; + + case WM_KEYDOWN: + g_iJoypadState |= g_pkmInUse->dwKeyMask[(short) wParam]; + break; + + case WM_KEYUP: + g_iJoypadState &= ~(g_pkmInUse->dwKeyMask[(short) wParam]); + break; + + case WM_DESTROY: + StopEmulation(hWnd, hwndCB); + CommandBar_Destroy(hwndCB); + PostQuitMessage(0); + g_bLoop = false; + break; + + case WM_SETTINGCHANGE: + { + SHACTIVATEINFO shaInfo; + + SHHandleWMSettingChange(hWnd, wParam, lParam, &shaInfo); + } + break; + + default: + return DefWindowProc(hWnd, message, wParam, lParam); + } + + return 0; +} + +HWND CreateRpCommandBar(HWND hwnd) +{ + SHMENUBARINFO mbi; + + memset(&mbi, 0, sizeof(SHMENUBARINFO)); + mbi.cbSize = sizeof(SHMENUBARINFO); + mbi.hwndParent = hwnd; + mbi.nToolBarId = IDM_MENU; + mbi.hInstRes = g_hInstance; + mbi.nBmpId = 0; + mbi.cBmpImages = 0; + + if (!SHCreateMenuBar(&mbi)) + return NULL; + + return mbi.hwndMB; +} + +// Message handler for the options dialog +LRESULT CALLBACK OptionsDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_INITDIALOG: + { + SendMessage(GetDlgItem(hDlg, IDC_TRANSPARENCY), BM_SETCHECK, (WPARAM) (Settings.Transparency == TRUE)?BST_CHECKED:BST_UNCHECKED, 0); + SendMessage(GetDlgItem(hDlg, IDC_LANDSCAPE), BM_SETCHECK, (WPARAM) (g_bLandscape)?BST_CHECKED:BST_UNCHECKED, 0); + SendMessage(GetDlgItem(hDlg, IDC_LEFT), BM_SETCHECK, (WPARAM) (g_bLandLeft)?BST_CHECKED:BST_UNCHECKED, 0); + SendMessage(GetDlgItem(hDlg, IDC_COMPAT), BM_SETCHECK, (WPARAM) (g_bCompat)?BST_CHECKED:BST_UNCHECKED, 0); + SendMessage(GetDlgItem(hDlg, IDC_AUTO), BM_SETCHECK, (WPARAM) (g_bAutoSkip)?BST_CHECKED:BST_UNCHECKED, 0); + SendMessage(GetDlgItem(hDlg, IDC_SMOOTHSTRETCH), BM_SETCHECK, (WPARAM) (g_bSmoothStretch)?BST_CHECKED:BST_UNCHECKED, 0); + SetDlgItemInt(hDlg, IDC_FRAMESKIP, g_iFrameSkip, false); + SetDlgItemInt(hDlg, IDC_CYCLES, g_iCycles, false); + SendMessage(GetDlgItem(hDlg, IDC_FRAMESKIP), UDM_SETRANGE32, (WPARAM) 1, (LPARAM) 20); + SendMessage(GetDlgItem(hDlg, IDC_CYCLES), UDM_SETRANGE32, (WPARAM) 1, (LPARAM) 20); + SendMessage(GetDlgItem(hDlg, IDC_SOUND), BM_SETCHECK, (WPARAM) (Settings.APUEnabled == TRUE)?BST_CHECKED:BST_UNCHECKED, 0); + SendMessage(GetDlgItem(hDlg, IDC_SIXTEENBIT), BM_SETCHECK, (WPARAM) (Settings.SixteenBitSound == TRUE)?BST_CHECKED:BST_UNCHECKED, 0); + SendMessage(GetDlgItem(hDlg, IDC_EIGHTBIT), BM_SETCHECK, (WPARAM) (Settings.SixteenBitSound == FALSE)?BST_CHECKED:BST_UNCHECKED, 0); + SendMessage(GetDlgItem(hDlg, IDC_SOUNDQUALITY), TBM_SETRANGE, (WPARAM)(BOOL) TRUE, (LPARAM) MAKELONG(1,3)); + SendMessage(GetDlgItem(hDlg, IDC_SOUNDQUALITY), TBM_SETPOS, (WPARAM)(BOOL) TRUE, (LPARAM) Settings.SoundPlaybackRate); + + SHINITDLGINFO shidi; + + // Create a Done button and size it. + shidi.dwMask = SHIDIM_FLAGS; + shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIZEDLGFULLSCREEN; + shidi.hDlg = hDlg; + + //initialzes the dialog based on the dwFlags parameter + SHInitDialog(&shidi); + } + return TRUE; + + case WM_COMMAND: + if (LOWORD(wParam) == IDOK) + { + Settings.Transparency = (BST_CHECKED == SendMessage(GetDlgItem(hDlg, IDC_TRANSPARENCY), BM_GETCHECK, 0, 0))?TRUE:FALSE; + g_bLandscape = (BST_CHECKED == SendMessage(GetDlgItem(hDlg, IDC_LANDSCAPE), BM_GETCHECK, 0, 0))?true:false; + g_bLandLeft = (BST_CHECKED == SendMessage(GetDlgItem(hDlg, IDC_LEFT), BM_GETCHECK, 0, 0))?true:false; + g_bCompat = (BST_CHECKED == SendMessage(GetDlgItem(hDlg, IDC_COMPAT), BM_GETCHECK, 0, 0))?true:false; + g_bAutoSkip = (BST_CHECKED == SendMessage(GetDlgItem(hDlg, IDC_AUTO), BM_GETCHECK, 0, 0))?true:false; + g_bSmoothStretch = (BST_CHECKED == SendMessage(GetDlgItem(hDlg, IDC_SMOOTHSTRETCH), BM_GETCHECK, 0, 0))?true:false; + g_iFrameSkip = GetDlgItemInt(hDlg, IDC_FRAMESKIP, NULL, false); + g_iCycles = GetDlgItemInt(hDlg, IDC_CYCLES, NULL, false); + Settings.CyclesPercentage = g_iCycles; + Settings.APUEnabled = (BST_CHECKED == SendMessage(GetDlgItem(hDlg, IDC_SOUND), BM_GETCHECK, 0, 0))?true:false; + Settings.SixteenBitSound = (BST_CHECKED == SendMessage(GetDlgItem(hDlg, IDC_SIXTEENBIT), BM_GETCHECK, 0, 0))?TRUE:FALSE; + Settings.SoundPlaybackRate = SendMessage(GetDlgItem(hDlg, IDC_SOUNDQUALITY), TBM_GETPOS, 0, 0); + + EndDialog(hDlg, LOWORD(wParam)); + return TRUE; + } + break; + + case WM_NOTIFY: + if ((int) wParam == IDC_SPIN_FRAMESKIP) + { + LPNMUPDOWN lpnmud = (LPNMUPDOWN) lParam; + + if ((lpnmud->iPos + lpnmud->iDelta) > 20) + return TRUE; + + return FALSE; + } + break; + + case WM_CTLCOLORSTATIC: + { + HDC hDC = (HDC) wParam; + HWND hctl = (HWND) lParam; + LOGFONT lf; + + if (GetDlgCtrlID(hctl) != IDC_STATIC_TITLE) + return DefWindowProc(hDlg, message, wParam, lParam); + + lf.lfWeight = FW_BOLD; + lf.lfEscapement = 0; + lf.lfOrientation = 0; + lf.lfHeight = 13; + lf.lfWidth = 0; + lf.lfCharSet = DEFAULT_CHARSET; + lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; + lf.lfItalic = FALSE; + lf.lfUnderline = FALSE; + lf.lfStrikeOut = FALSE; + lf.lfQuality = DEFAULT_QUALITY; + lf.lfOutPrecision = OUT_DEFAULT_PRECIS; + lf.lfPitchAndFamily = FF_SWISS | DEFAULT_PITCH; + + _tcscpy(lf.lfFaceName, _T("Tahoma")); + + SelectObject(hDC, CreateFontIndirect(&lf)); + SetTextColor(hDC, RGB(0,0,153)); + + return (BOOL) GetSysColorBrush(COLOR_STATIC); + } + + case WM_PAINT: + { + HDC hDC; + PAINTSTRUCT ps; + + hDC = BeginPaint(hDlg, &ps); // begin painting for window + + SelectObject(hDC, GetStockObject(BLACK_BRUSH)); + Rectangle(hDC, 0, 24, 240, 25); + + EndPaint(hDlg, &ps); + } + return TRUE; + + default: + return DefWindowProc(hDlg, message, wParam, lParam); + } + + return 0; +} + +// Message handler for the options dialog +LRESULT CALLBACK DisplayDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_INITDIALOG: + { + if(g_bLandscape) + { + if(g_bSmoothStretch) + { + if(g_bLandLeft) + { + SendMessage(GetDlgItem(hDlg, IDC_LANDLEFTSTRETCH), BM_SETCHECK, (WPARAM) (BST_CHECKED), 0); + } + else + { + SendMessage(GetDlgItem(hDlg, IDC_LANDRIGHTSTRETCH), BM_SETCHECK, (WPARAM) (BST_CHECKED), 0); + } + } + else + { + if(g_bLandLeft) + { + SendMessage(GetDlgItem(hDlg, IDC_LANDLEFT), BM_SETCHECK, (WPARAM) (BST_CHECKED), 0); + } + else + { + SendMessage(GetDlgItem(hDlg, IDC_LANDRIGHT), BM_SETCHECK, (WPARAM) (BST_CHECKED), 0); + } + } + } + else + { + SendMessage(GetDlgItem(hDlg, IDC_PORTRAIT), BM_SETCHECK, (WPARAM) (BST_CHECKED), 0); + } + + + SendMessage(GetDlgItem(hDlg, IDC_DISPLAYFRAMERATE), BM_SETCHECK, (WPARAM) (Settings.DisplayFrameRate == TRUE)?BST_CHECKED:BST_UNCHECKED, 0); + + + SendMessage(GetDlgItem(hDlg, IDC_TRANSPARENCY), BM_SETCHECK, (WPARAM) (Settings.Transparency == TRUE)?BST_CHECKED:BST_UNCHECKED, 0); + SendMessage(GetDlgItem(hDlg, IDC_AUTO), BM_SETCHECK, (WPARAM) (g_bAutoSkip)?BST_CHECKED:BST_UNCHECKED, 0); + SetDlgItemInt(hDlg, IDC_FRAMESKIP, g_iFrameSkip, false); + SetDlgItemInt(hDlg, IDC_CYCLES, g_iCycles, false); + SendMessage(GetDlgItem(hDlg, IDC_FRAMESKIP_SLIDER), UDM_SETRANGE32, (WPARAM) 0, (LPARAM) 10); + SendMessage(GetDlgItem(hDlg, IDC_CYCLES), UDM_SETRANGE32, (WPARAM) 1, (LPARAM) 20); + SHINITDLGINFO shidi; + + // Create a Done button and size it. + shidi.dwMask = SHIDIM_FLAGS; + shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIZEDLGFULLSCREEN; + shidi.hDlg = hDlg; + + //initialzes the dialog based on the dwFlags parameter + SHInitDialog(&shidi); + } + return TRUE; + + case WM_COMMAND: + if (LOWORD(wParam) == IDOK) + { + Settings.Transparency = (BST_CHECKED == SendMessage(GetDlgItem(hDlg, IDC_TRANSPARENCY), BM_GETCHECK, 0, 0))?TRUE:FALSE; + g_bCompat = (BST_CHECKED == SendMessage(GetDlgItem(hDlg, IDC_COMPAT), BM_GETCHECK, 0, 0))?true:false; + g_bAutoSkip = (BST_CHECKED == SendMessage(GetDlgItem(hDlg, IDC_AUTO), BM_GETCHECK, 0, 0))?true:false; + //g_bSmoothStretch = (BST_CHECKED == SendMessage(GetDlgItem(hDlg, IDC_SMOOTHSTRETCH), BM_GETCHECK, 0, 0))?true:false; + g_iFrameSkip = GetDlgItemInt(hDlg, IDC_FRAMESKIP, NULL, false); + //g_iCycles = GetDlgItemInt(hDlg, IDC_CYCLES, NULL, false); + + Settings.DisplayFrameRate = (BST_CHECKED == SendMessage(GetDlgItem(hDlg, IDC_DISPLAYFRAMERATE), BM_GETCHECK, 0, 0))?TRUE:FALSE; + + + + //Process DisplaySelection + //if((BST_CHECKED == SendMessage(GetDlgItem(hDlg, IDC_PORTRAIT), BM_GETCHECK, 0, 0))?TRUE:FALSE;)) + if(SendMessage(GetDlgItem(hDlg, IDC_PORTRAIT), BM_GETCHECK, 0, 0)) + { + g_bLandscape = false; + g_bLandLeft = false; + g_bSmoothStretch = false; + } + + if(SendMessage(GetDlgItem(hDlg, IDC_LANDLEFT), BM_GETCHECK, 0, 0)) + { + g_bLandscape = true; + g_bLandLeft = true; + g_bSmoothStretch = false; + } + + if(SendMessage(GetDlgItem(hDlg, IDC_LANDRIGHT), BM_GETCHECK, 0, 0)) + { + g_bLandscape = true; + g_bLandLeft = false; + g_bSmoothStretch = false; + } + + if(SendMessage(GetDlgItem(hDlg, IDC_LANDLEFTSTRETCH), BM_GETCHECK, 0, 0)) + { + g_bLandscape = true; + g_bLandLeft = true; + g_bSmoothStretch = true; + } + + if(SendMessage(GetDlgItem(hDlg, IDC_LANDRIGHTSTRETCH), BM_GETCHECK, 0, 0)) + { + g_bLandscape = true; + g_bLandLeft = false; + g_bSmoothStretch = true; + } + + + EndDialog(hDlg, LOWORD(wParam)); + return TRUE; + } + break; + + case WM_NOTIFY: + if ((int) wParam == IDC_SPIN_FRAMESKIP) + { + LPNMUPDOWN lpnmud = (LPNMUPDOWN) lParam; + + if ((lpnmud->iPos + lpnmud->iDelta) > 20) + return TRUE; + + return FALSE; + } + break; + + case WM_CTLCOLORSTATIC: + { + HDC hDC = (HDC) wParam; + HWND hctl = (HWND) lParam; + LOGFONT lf; + + if (GetDlgCtrlID(hctl) != IDC_STATIC_TITLE) + return DefWindowProc(hDlg, message, wParam, lParam); + + lf.lfWeight = FW_BOLD; + lf.lfEscapement = 0; + lf.lfOrientation = 0; + lf.lfHeight = 13; + lf.lfWidth = 0; + lf.lfCharSet = DEFAULT_CHARSET; + lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; + lf.lfItalic = FALSE; + lf.lfUnderline = FALSE; + lf.lfStrikeOut = FALSE; + lf.lfQuality = DEFAULT_QUALITY; + lf.lfOutPrecision = OUT_DEFAULT_PRECIS; + lf.lfPitchAndFamily = FF_SWISS | DEFAULT_PITCH; + + _tcscpy(lf.lfFaceName, _T("Tahoma")); + + SelectObject(hDC, CreateFontIndirect(&lf)); + SetTextColor(hDC, RGB(0,0,0)); + + return (BOOL) GetSysColorBrush(COLOR_STATIC); + } + + case WM_PAINT: + { + HDC hDC; + PAINTSTRUCT ps; + + hDC = BeginPaint(hDlg, &ps); // begin painting for window + + SelectObject(hDC, GetStockObject(LTGRAY_BRUSH)); + SelectObject(hDC, CreatePen(PS_NULL,2,RGB(50,50,50))); + + Rectangle(hDC, 5, 20, 235, 21); + + EndPaint(hDlg, &ps); + } + return TRUE; + + default: + return DefWindowProc(hDlg, message, wParam, lParam); + } + + return 0; +} + +// Message handler for the options dialog +LRESULT CALLBACK SoundDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_INITDIALOG: + { + SendMessage(GetDlgItem(hDlg, IDC_SOUND), BM_SETCHECK, (WPARAM) (Settings.APUEnabled == TRUE)?BST_CHECKED:BST_UNCHECKED, 0); + SendMessage(GetDlgItem(hDlg, IDC_SIXTEENBIT), BM_SETCHECK, (WPARAM) (Settings.SixteenBitSound == TRUE)?BST_CHECKED:BST_UNCHECKED, 0); + SendMessage(GetDlgItem(hDlg, IDC_EIGHTBIT), BM_SETCHECK, (WPARAM) (Settings.SixteenBitSound == FALSE)?BST_CHECKED:BST_UNCHECKED, 0); + SendMessage(GetDlgItem(hDlg, IDC_SOUNDQUALITY), TBM_SETRANGE, (WPARAM)(BOOL) TRUE, (LPARAM) MAKELONG(1,7)); + SendMessage(GetDlgItem(hDlg, IDC_SOUNDQUALITY), TBM_SETPOS, (WPARAM)(BOOL) TRUE, (LPARAM) Settings.SoundPlaybackRate); + + //CSNES + SendMessage(GetDlgItem(hDlg, IDC_ECHO), BM_SETCHECK, (WPARAM) (Settings.DisableSoundEcho == FALSE)?BST_CHECKED:BST_UNCHECKED, 0); + SendMessage(GetDlgItem(hDlg, IDC_STEREO), BM_SETCHECK, (WPARAM) (Settings.Stereo == TRUE)?BST_CHECKED:BST_UNCHECKED, 0); + SendMessage(GetDlgItem(hDlg, IDC_REVERSESTEREO), BM_SETCHECK, (WPARAM) (Settings.ReverseStereo == TRUE)?BST_CHECKED:BST_UNCHECKED, 0); + SendMessage(GetDlgItem(hDlg, IDC_SYNCSOUND), BM_SETCHECK, (WPARAM) (Settings.SoundSync == TRUE)?BST_CHECKED:BST_UNCHECKED, 0); + SendMessage(GetDlgItem(hDlg, IDC_INTERPOLATESOUND), BM_SETCHECK, (WPARAM) (Settings.InterpolatedSound == TRUE)?BST_CHECKED:BST_UNCHECKED, 0); + SendMessage(GetDlgItem(hDlg, IDC_ENVELOPEHEIGHT), BM_SETCHECK, (WPARAM) (Settings.SoundEnvelopeHeightReading == TRUE)?BST_CHECKED:BST_UNCHECKED, 0); + SendMessage(GetDlgItem(hDlg, IDC_ALTDECODE), BM_SETCHECK, (WPARAM) (Settings.AltSampleDecode == TRUE)?BST_CHECKED:BST_UNCHECKED, 0); + SendMessage(GetDlgItem(hDlg, IDC_FIXFREQUENCY), BM_SETCHECK, (WPARAM) (Settings.FixFrequency == TRUE)?BST_CHECKED:BST_UNCHECKED, 0); + + + SHINITDLGINFO shidi; + + // Create a Done button and size it. + shidi.dwMask = SHIDIM_FLAGS; + shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIZEDLGFULLSCREEN; + shidi.hDlg = hDlg; + + //initialzes the dialog based on the dwFlags parameter + SHInitDialog(&shidi); + } + return TRUE; + + case WM_COMMAND: + if (LOWORD(wParam) == IDOK) + { + Settings.APUEnabled = (BST_CHECKED == SendMessage(GetDlgItem(hDlg, IDC_SOUND), BM_GETCHECK, 0, 0))?true:false; + Settings.SixteenBitSound = SendMessage(GetDlgItem(hDlg, IDC_SIXTEENBIT), BM_GETCHECK, 0, 0); + Settings.SoundPlaybackRate = SendMessage(GetDlgItem(hDlg, IDC_SOUNDQUALITY), TBM_GETPOS, 0, 0); + Settings.Stereo = SendMessage(GetDlgItem(hDlg, IDC_STEREO) , BM_GETCHECK, 0, 0); + Settings.ReverseStereo = SendMessage(GetDlgItem(hDlg, IDC_REVERSESTEREO) , BM_GETCHECK, 0, 0); + Settings.DisableSoundEcho = !(SendMessage(GetDlgItem(hDlg, IDC_ECHO) , BM_GETCHECK, 0, 0)); + Settings.InterpolatedSound = SendMessage(GetDlgItem(hDlg, IDC_INTERPOLATESOUND), BM_GETCHECK, 0, 0); + Settings.SoundSync = SendMessage(GetDlgItem(hDlg, IDC_SYNCSOUND) , BM_GETCHECK, 0, 0); + Settings.FixFrequency = SendMessage(GetDlgItem(hDlg, IDC_FIXFREQUENCY) , BM_GETCHECK, 0, 0); + Settings.SoundEnvelopeHeightReading = SendMessage(GetDlgItem(hDlg, IDC_ENVELOPEHEIGHT) , BM_GETCHECK, 0, 0); + Settings.AltSampleDecode = SendMessage(GetDlgItem(hDlg, IDC_ALTDECODE) , BM_GETCHECK, 0, 0); + + //CSNES - turning on/off sound involves more than APUEnabled + /* + Settings.NextAPUEnabled = Settings.APUEnabled; + Settings.DisableSampleCaching = !(Settings.APUEnabled); + Settings.DisableMasterVolume = !(Settings.APUEnabled); + Settings.ThreadSound = FALSE; + Settings.Mute = !(Settings.APUEnabled); + */ + EndDialog(hDlg, LOWORD(wParam)); + return TRUE; + } + break; + + case WM_NOTIFY: + if ((int) wParam == IDC_SPIN_FRAMESKIP) + { + LPNMUPDOWN lpnmud = (LPNMUPDOWN) lParam; + + if ((lpnmud->iPos + lpnmud->iDelta) > 20) + return TRUE; + + return FALSE; + } + break; + + case WM_CTLCOLORSTATIC: + { + HDC hDC = (HDC) wParam; + HWND hctl = (HWND) lParam; + LOGFONT lf; + + if (GetDlgCtrlID(hctl) != IDC_STATIC_TITLE) + return DefWindowProc(hDlg, message, wParam, lParam); + + lf.lfWeight = FW_BOLD; + lf.lfEscapement = 0; + lf.lfOrientation = 0; + lf.lfHeight = 13; + lf.lfWidth = 0; + lf.lfCharSet = DEFAULT_CHARSET; + lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; + lf.lfItalic = FALSE; + lf.lfUnderline = FALSE; + lf.lfStrikeOut = FALSE; + lf.lfQuality = DEFAULT_QUALITY; + lf.lfOutPrecision = OUT_DEFAULT_PRECIS; + lf.lfPitchAndFamily = FF_SWISS | DEFAULT_PITCH; + + _tcscpy(lf.lfFaceName, _T("Tahoma")); + + SelectObject(hDC, CreateFontIndirect(&lf)); + SetTextColor(hDC, RGB(0,0,0)); + + return (BOOL) GetSysColorBrush(COLOR_STATIC); + } + + case WM_PAINT: + { + HDC hDC; + PAINTSTRUCT ps; + + hDC = BeginPaint(hDlg, &ps); // begin painting for window + + SelectObject(hDC, GetStockObject(LTGRAY_BRUSH)); + SelectObject(hDC, CreatePen(PS_NULL,2,RGB(50,50,50))); + + Rectangle(hDC, 5, 20, 235, 21); + + EndPaint(hDlg, &ps); + } + return TRUE; + + default: + return DefWindowProc(hDlg, message, wParam, lParam); + } + + return 0; +} + +// Message handler for the System dialog +LRESULT CALLBACK SystemDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_INITDIALOG: + { + //SendMessage(GetDlgItem(hDlg, IDC_TRANSPARENCY), BM_SETCHECK, (WPARAM) (Settings.Transparency == TRUE)?BST_CHECKED:BST_UNCHECKED, 0); + //SendMessage(GetDlgItem(hDlg, IDC_LANDSCAPE), BM_SETCHECK, (WPARAM) (g_bLandscape)?BST_CHECKED:BST_UNCHECKED, 0); + //SendMessage(GetDlgItem(hDlg, IDC_LEFT), BM_SETCHECK, (WPARAM) (g_bLandLeft)?BST_CHECKED:BST_UNCHECKED, 0); + SendMessage(GetDlgItem(hDlg, IDC_COMPAT), BM_SETCHECK, (WPARAM) (g_bCompat)?BST_CHECKED:BST_UNCHECKED, 0); + SendMessage(GetDlgItem(hDlg, IDC_AUTO), BM_SETCHECK, (WPARAM) (g_bAutoSkip)?BST_CHECKED:BST_UNCHECKED, 0); + //SendMessage(GetDlgItem(hDlg, IDC_SMOOTHSTRETCH), BM_SETCHECK, (WPARAM) (g_bSmoothStretch)?BST_CHECKED:BST_UNCHECKED, 0); + SetDlgItemInt(hDlg, IDC_FRAMESKIP, g_iFrameSkip, false); + SetDlgItemInt(hDlg, IDC_CYCLES, g_iCycles, false); + SendMessage(GetDlgItem(hDlg, IDC_FRAMESKIP), UDM_SETRANGE32, (WPARAM) 1, (LPARAM) 20); + SendMessage(GetDlgItem(hDlg, IDC_CYCLES), UDM_SETRANGE32, (WPARAM) 1, (LPARAM) 20); + SendMessage(GetDlgItem(hDlg, IDC_SOUND), BM_SETCHECK, (WPARAM) (Settings.APUEnabled == TRUE)?BST_CHECKED:BST_UNCHECKED, 0); + SendMessage(GetDlgItem(hDlg, IDC_SIXTEENBIT), BM_SETCHECK, (WPARAM) (Settings.SixteenBitSound == TRUE)?BST_CHECKED:BST_UNCHECKED, 0); + SendMessage(GetDlgItem(hDlg, IDC_EIGHTBIT), BM_SETCHECK, (WPARAM) (Settings.SixteenBitSound == FALSE)?BST_CHECKED:BST_UNCHECKED, 0); + SendMessage(GetDlgItem(hDlg, IDC_SOUNDQUALITY), TBM_SETRANGE, (WPARAM)(BOOL) TRUE, (LPARAM) MAKELONG(1,3)); + SendMessage(GetDlgItem(hDlg, IDC_SOUNDQUALITY), TBM_SETPOS, (WPARAM)(BOOL) TRUE, (LPARAM) Settings.SoundPlaybackRate); + + //CSNES + SendMessage(GetDlgItem(hDlg, IDC_RESUMEAFTERLOADSTATE), BM_SETCHECK, (WPARAM) (g_bResumeAfterLoadState)?BST_CHECKED:BST_UNCHECKED, 0); + SendMessage(GetDlgItem(hDlg, IDC_RESUMEAFTERSAVESTATE), BM_SETCHECK, (WPARAM) (g_bResumeAfterSaveState)?BST_CHECKED:BST_UNCHECKED, 0); + SendMessage(GetDlgItem(hDlg, IDC_DISPLAYFRAMERATE), BM_SETCHECK, (WPARAM) (Settings.DisplayFrameRate)?BST_CHECKED:BST_UNCHECKED, 0); + + SHINITDLGINFO shidi; + + // Create a Done button and size it. + shidi.dwMask = SHIDIM_FLAGS; + shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIZEDLGFULLSCREEN; + shidi.hDlg = hDlg; + + //initialzes the dialog based on the dwFlags parameter + SHInitDialog(&shidi); + } + return TRUE; + + case WM_COMMAND: + if (LOWORD(wParam) == IDOK) + { + g_iCycles = GetDlgItemInt(hDlg, IDC_CYCLES, NULL, false); + Settings.CyclesPercentage = g_iCycles; + + //CSNES + g_bResumeAfterLoadState = (BST_CHECKED == SendMessage(GetDlgItem(hDlg, IDC_RESUMEAFTERLOADSTATE), BM_GETCHECK, 0, 0))?true:false; + g_bResumeAfterSaveState = (BST_CHECKED == SendMessage(GetDlgItem(hDlg, IDC_RESUMEAFTERSAVESTATE), BM_GETCHECK, 0, 0))?true:false; + Settings.DisplayFrameRate = (BST_CHECKED == SendMessage(GetDlgItem(hDlg, IDC_DISPLAYFRAMERATE), BM_GETCHECK, 0, 0))?true:false; + + EndDialog(hDlg, LOWORD(wParam)); + return TRUE; + } + break; + + case WM_NOTIFY: + if ((int) wParam == IDC_SPIN_FRAMESKIP) + { + LPNMUPDOWN lpnmud = (LPNMUPDOWN) lParam; + + if ((lpnmud->iPos + lpnmud->iDelta) > 20) + return TRUE; + + return FALSE; + } + break; + + case WM_CTLCOLORSTATIC: + { + HDC hDC = (HDC) wParam; + HWND hctl = (HWND) lParam; + LOGFONT lf; + + if (GetDlgCtrlID(hctl) != IDC_STATIC_TITLE) + return DefWindowProc(hDlg, message, wParam, lParam); + + lf.lfWeight = FW_BOLD; + lf.lfEscapement = 0; + lf.lfOrientation = 0; + lf.lfHeight = 13; + lf.lfWidth = 0; + lf.lfCharSet = DEFAULT_CHARSET; + lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; + lf.lfItalic = FALSE; + lf.lfUnderline = FALSE; + lf.lfStrikeOut = FALSE; + lf.lfQuality = DEFAULT_QUALITY; + lf.lfOutPrecision = OUT_DEFAULT_PRECIS; + lf.lfPitchAndFamily = FF_SWISS | DEFAULT_PITCH; + + _tcscpy(lf.lfFaceName, _T("Tahoma")); + + SelectObject(hDC, CreateFontIndirect(&lf)); + SetTextColor(hDC, RGB(0,0,0)); + + return (BOOL) GetSysColorBrush(COLOR_STATIC); + } + + case WM_PAINT: + { + HDC hDC; + PAINTSTRUCT ps; + + hDC = BeginPaint(hDlg, &ps); // begin painting for window + + SelectObject(hDC, GetStockObject(LTGRAY_BRUSH)); + SelectObject(hDC, CreatePen(PS_NULL,2,RGB(50,50,50))); + + Rectangle(hDC, 5, 20, 235, 21); + + EndPaint(hDlg, &ps); + } + return TRUE; + + default: + return DefWindowProc(hDlg, message, wParam, lParam); + } + + return 0; +} + + + +// Message handler for the options dialog +LRESULT CALLBACK SkinsDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_INITDIALOG: + { + SHINITDLGINFO shidi; + + // Create a Done button and size it. + shidi.dwMask = SHIDIM_FLAGS; + shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIZEDLGFULLSCREEN; + shidi.hDlg = hDlg; + + //initialzes the dialog based on the dwFlags parameter + SHInitDialog(&shidi); + } + return TRUE; + + case WM_COMMAND: + { + static RECT rtPaint = { 0, 28, 240, 240 }; + + switch (LOWORD(wParam)) + { + case IDOK: + EndDialog(hDlg, LOWORD(wParam)); + return TRUE; + + case IDC_BUTTON_PREVIOUS: + g_iSelectedSkin--; + if (g_iSelectedSkin < 0) + g_iSelectedSkin = g_iSkinCount - 1; + g_pSkins[g_iSelectedSkin].LoadBitmap(g_hbmSkin, g_hSkinDC, g_hInstance, g_hWnd); + InvalidateRect(hDlg, &rtPaint, TRUE); + break; + + case IDC_BUTTON_NEXT: + g_iSelectedSkin = (g_iSelectedSkin + 1) % g_iSkinCount; + g_pSkins[g_iSelectedSkin].LoadBitmap(g_hbmSkin, g_hSkinDC, g_hInstance, g_hWnd); + InvalidateRect(hDlg, &rtPaint, TRUE); + break; + } + } + break; + + case WM_CTLCOLORSTATIC: + { + HDC hDC = (HDC) wParam; + HWND hctl = (HWND) lParam; + LOGFONT lf; + + if (GetDlgCtrlID(hctl) != IDC_STATIC_TITLE) + return DefWindowProc(hDlg, message, wParam, lParam); + + lf.lfWeight = FW_BOLD; + lf.lfEscapement = 0; + lf.lfOrientation = 0; + lf.lfHeight = 13; + lf.lfWidth = 0; + lf.lfCharSet = DEFAULT_CHARSET; + lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; + lf.lfItalic = FALSE; + lf.lfUnderline = FALSE; + lf.lfStrikeOut = FALSE; + lf.lfQuality = DEFAULT_QUALITY; + lf.lfOutPrecision = OUT_DEFAULT_PRECIS; + lf.lfPitchAndFamily = FF_SWISS | DEFAULT_PITCH; + + _tcscpy(lf.lfFaceName, _T("Tahoma")); + + SelectObject(hDC, CreateFontIndirect(&lf)); + SetTextColor(hDC, RGB(0,0,153)); + + return (BOOL) GetSysColorBrush(COLOR_STATIC); + } + + case WM_PAINT: + { + HDC hDC; + PAINTSTRUCT ps; + RECT rtName = { 0, 28, 240, 48 }; + RECT rtAuthor = { 0, 160, 240, 180 }; + + hDC = BeginPaint(hDlg, &ps); // begin painting for window + + SelectObject(hDC, GetStockObject(BLACK_BRUSH)); + Rectangle(hDC, 0, 24, 240, 25); + + Rectangle(hDC, 0, 51, 240, 52); + if (g_pSkins[g_iSelectedSkin].bLandscape) + { + BitBlt(hDC, 0, 52, 240, 64, g_hSkinDC, 0, 0, SRCCOPY); + Rectangle(hDC, 0, 52 + 96, 240, 52 + 64 + 1); + } + else + { + BitBlt(hDC, 0, 52, 240, 96, g_hSkinDC, 0, 0, SRCCOPY); + Rectangle(hDC, 0, 52 + 96, 240, 52 + 96 + 1); + } + + SelectObject(hDC, g_hFontPaused); + SetTextColor(hDC, COLORREF(0x00000000)); + DrawText(hDC, g_pSkins[g_iSelectedSkin].pszName, _tcslen(g_pSkins[g_iSelectedSkin].pszName), &rtName, DT_CENTER|DT_SINGLELINE|DT_VCENTER); + SelectObject(hDC, g_hFontNormal); + SetTextColor(hDC, COLORREF(0x0000000)); + DrawText(hDC, g_pSkins[g_iSelectedSkin].pszAuthor, _tcslen(g_pSkins[g_iSelectedSkin].pszAuthor), &rtAuthor, DT_CENTER|DT_SINGLELINE|DT_VCENTER); + + EndPaint(hDlg, &ps); + } + return TRUE; + + case WM_DRAWITEM: + { + DRAWITEMSTRUCT *psDrawItem = (LPDRAWITEMSTRUCT) lParam; + + if (psDrawItem->CtlID == IDC_BUTTON_PREVIOUS) + DrawIcon(psDrawItem->hDC, 0, 0, g_hiLeftArrow); + else + DrawIcon(psDrawItem->hDC, 0, 0, g_hiRightArrow); + } + return TRUE; + + default: + return DefWindowProc(hDlg, message, wParam, lParam); + } + + return 0; +} + +#define SETBUTTON(a,b) \ + { \ + DWORD dwCurrentMask = g_kmCurrent.dwKeyMask[vkKey]; \ + if (dwCurrentMask != 0) \ + SendMessage(GetDlgItem(GetParent(hWnd), g_kmCurrent.GetStaticIDFromMask(dwCurrentMask)), WM_SETTEXT, 0, (LPARAM)(LPCTSTR) g_kmCurrent.GetKeyDisplayFromMask(0)); \ + g_kmCurrent.dwKeyMask[g_kmCurrent.GetKeyFromMask(a)] = 0; \ + g_kmCurrent.dwKeyMask[vkKey] = a; \ + SendMessage(GetDlgItem(GetParent(hWnd), b), WM_SETTEXT, 0, (LPARAM)(LPCTSTR) g_kmCurrent.GetKeyDisplayFromMask(a)); \ + } + +DWORD g_pOriginalWndProc = NULL; + +LRESULT CALLBACK ButtonProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_GETDLGCODE: + return DLGC_WANTARROWS|DLGC_WANTALLKEYS; + + case WM_KEYDOWN: + if (g_bSetButtonMode) + { + short vkKey = (short) wParam; + + if (vkKey == VK_LWIN) + return TRUE; + + switch (g_iSetButton) + { + case IDC_BUTTON_UP: + SETBUTTON(SNES_UP_MASK, IDC_STATIC_UP); + break; + + case IDC_BUTTON_DOWN: + SETBUTTON(SNES_DOWN_MASK, IDC_STATIC_DOWN); + break; + + case IDC_BUTTON_LEFT: + SETBUTTON(SNES_LEFT_MASK, IDC_STATIC_LEFT); + break; + + case IDC_BUTTON_RIGHT: + SETBUTTON(SNES_RIGHT_MASK, IDC_STATIC_RIGHT); + break; + + case IDC_BUTTON_A: + SETBUTTON(SNES_A_MASK, IDC_STATIC_A); + break; + + case IDC_BUTTON_B: + SETBUTTON(SNES_B_MASK, IDC_STATIC_B); + break; + + case IDC_BUTTON_X: + SETBUTTON(SNES_X_MASK, IDC_STATIC_X); + break; + + case IDC_BUTTON_Y: + SETBUTTON(SNES_Y_MASK, IDC_STATIC_Y); + break; + + case IDC_BUTTON_START: + SETBUTTON(SNES_START_MASK, IDC_STATIC_START); + break; + + case IDC_BUTTON_SELECT: + SETBUTTON(SNES_SELECT_MASK, IDC_STATIC_SELECT); + break; + + case IDC_BUTTON_L: + SETBUTTON(SNES_TL_MASK, IDC_STATIC_L); + break; + + case IDC_BUTTON_R: + SETBUTTON(SNES_TR_MASK, IDC_STATIC_R); + break; + } + + g_bSetButtonMode = false; + + GXCloseInput(); + + return TRUE; + } + break; + + default: + break; + } + + return CallWindowProc((WNDPROC) g_pOriginalWndProc, hWnd, message, wParam, lParam); +} + +// Message handler for the keys dialog +LRESULT CALLBACK KeysDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_INITDIALOG: + { + SendMessage(GetDlgItem(hDlg, IDC_STATIC_UP), WM_SETTEXT, 0, (LPARAM)(LPCTSTR) g_kmCurrent.GetKeyDisplayFromMask(SNES_UP_MASK)); + SendMessage(GetDlgItem(hDlg, IDC_STATIC_DOWN), WM_SETTEXT, 0, (LPARAM)(LPCTSTR) g_kmCurrent.GetKeyDisplayFromMask(SNES_DOWN_MASK)); + SendMessage(GetDlgItem(hDlg, IDC_STATIC_LEFT), WM_SETTEXT, 0, (LPARAM)(LPCTSTR) g_kmCurrent.GetKeyDisplayFromMask(SNES_LEFT_MASK)); + SendMessage(GetDlgItem(hDlg, IDC_STATIC_RIGHT), WM_SETTEXT, 0, (LPARAM)(LPCTSTR) g_kmCurrent.GetKeyDisplayFromMask(SNES_RIGHT_MASK)); + SendMessage(GetDlgItem(hDlg, IDC_STATIC_B), WM_SETTEXT, 0, (LPARAM)(LPCTSTR) g_kmCurrent.GetKeyDisplayFromMask(SNES_B_MASK)); + SendMessage(GetDlgItem(hDlg, IDC_STATIC_A), WM_SETTEXT, 0, (LPARAM)(LPCTSTR) g_kmCurrent.GetKeyDisplayFromMask(SNES_A_MASK)); + SendMessage(GetDlgItem(hDlg, IDC_STATIC_Y), WM_SETTEXT, 0, (LPARAM)(LPCTSTR) g_kmCurrent.GetKeyDisplayFromMask(SNES_Y_MASK)); + SendMessage(GetDlgItem(hDlg, IDC_STATIC_X), WM_SETTEXT, 0, (LPARAM)(LPCTSTR) g_kmCurrent.GetKeyDisplayFromMask(SNES_X_MASK)); + SendMessage(GetDlgItem(hDlg, IDC_STATIC_START), WM_SETTEXT, 0, (LPARAM)(LPCTSTR) g_kmCurrent.GetKeyDisplayFromMask(SNES_START_MASK)); + SendMessage(GetDlgItem(hDlg, IDC_STATIC_SELECT), WM_SETTEXT, 0, (LPARAM)(LPCTSTR) g_kmCurrent.GetKeyDisplayFromMask(SNES_SELECT_MASK)); + SendMessage(GetDlgItem(hDlg, IDC_STATIC_L), WM_SETTEXT, 0, (LPARAM)(LPCTSTR) g_kmCurrent.GetKeyDisplayFromMask(SNES_TL_MASK)); + SendMessage(GetDlgItem(hDlg, IDC_STATIC_R), WM_SETTEXT, 0, (LPARAM)(LPCTSTR) g_kmCurrent.GetKeyDisplayFromMask(SNES_TR_MASK)); + + g_bSetButtonMode = false; + + g_pOriginalWndProc = SetWindowLong(GetDlgItem(hDlg, IDC_BUTTON_UP), GWL_WNDPROC, (DWORD) ButtonProc); + g_pOriginalWndProc = SetWindowLong(GetDlgItem(hDlg, IDC_BUTTON_DOWN), GWL_WNDPROC, (DWORD) ButtonProc); + g_pOriginalWndProc = SetWindowLong(GetDlgItem(hDlg, IDC_BUTTON_LEFT), GWL_WNDPROC, (DWORD) ButtonProc); + g_pOriginalWndProc = SetWindowLong(GetDlgItem(hDlg, IDC_BUTTON_RIGHT), GWL_WNDPROC, (DWORD) ButtonProc); + g_pOriginalWndProc = SetWindowLong(GetDlgItem(hDlg, IDC_BUTTON_A), GWL_WNDPROC, (DWORD) ButtonProc); + g_pOriginalWndProc = SetWindowLong(GetDlgItem(hDlg, IDC_BUTTON_B), GWL_WNDPROC, (DWORD) ButtonProc); + g_pOriginalWndProc = SetWindowLong(GetDlgItem(hDlg, IDC_BUTTON_X), GWL_WNDPROC, (DWORD) ButtonProc); + g_pOriginalWndProc = SetWindowLong(GetDlgItem(hDlg, IDC_BUTTON_Y), GWL_WNDPROC, (DWORD) ButtonProc); + g_pOriginalWndProc = SetWindowLong(GetDlgItem(hDlg, IDC_BUTTON_START), GWL_WNDPROC, (DWORD) ButtonProc); + g_pOriginalWndProc = SetWindowLong(GetDlgItem(hDlg, IDC_BUTTON_SELECT), GWL_WNDPROC, (DWORD) ButtonProc); + g_pOriginalWndProc = SetWindowLong(GetDlgItem(hDlg, IDC_BUTTON_L), GWL_WNDPROC, (DWORD) ButtonProc); + g_pOriginalWndProc = SetWindowLong(GetDlgItem(hDlg, IDC_BUTTON_R), GWL_WNDPROC, (DWORD) ButtonProc); + + SHINITDLGINFO shidi; + + // Create a Done button and size it. + shidi.dwMask = SHIDIM_FLAGS; + shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIZEDLGFULLSCREEN; + shidi.hDlg = hDlg; + + //initialzes the dialog based on the dwFlags parameter + SHInitDialog(&shidi); + } + return TRUE; + + case WM_COMMAND: + { + switch (LOWORD(wParam)) + { + case IDOK: + EndDialog(hDlg, LOWORD(wParam)); + return TRUE; + + case IDC_BUTTON_UP: + case IDC_BUTTON_DOWN: + case IDC_BUTTON_LEFT: + case IDC_BUTTON_RIGHT: + case IDC_BUTTON_A: + case IDC_BUTTON_B: + case IDC_BUTTON_X: + case IDC_BUTTON_Y: + case IDC_BUTTON_START: + case IDC_BUTTON_SELECT: + case IDC_BUTTON_L: + case IDC_BUTTON_R: + if (!g_bSetButtonMode) + { + if (GXOpenInput() != 0) + { + g_bSetButtonMode = true; + g_iSetButton = LOWORD(wParam); + } + } + else + { + // g_bSetButtonMode = false; + } + return TRUE; + + default: + break; + } + } + break; + + case WM_CTLCOLORSTATIC: + { + HDC hDC = (HDC) wParam; + HWND hctl = (HWND) lParam; + LOGFONT lf; + + if ((GetDlgCtrlID(hctl) != IDC_STATIC_TITLE) && + (GetDlgCtrlID(hctl) != IDC_STATIC_INFO)) + return DefWindowProc(hDlg, message, wParam, lParam); + + lf.lfWeight = FW_BOLD; + lf.lfEscapement = 0; + lf.lfOrientation = 0; + lf.lfHeight = 13; + lf.lfWidth = 0; + lf.lfCharSet = DEFAULT_CHARSET; + lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; + lf.lfItalic = FALSE; + lf.lfUnderline = FALSE; + lf.lfStrikeOut = FALSE; + lf.lfQuality = DEFAULT_QUALITY; + lf.lfOutPrecision = OUT_DEFAULT_PRECIS; + lf.lfPitchAndFamily = FF_SWISS | DEFAULT_PITCH; + + _tcscpy(lf.lfFaceName, _T("Tahoma")); + + SelectObject(hDC, CreateFontIndirect(&lf)); + if (GetDlgCtrlID(hctl) == IDC_STATIC_TITLE) + SetTextColor(hDC, RGB(0,0,153)); + else + SetTextColor(hDC, RGB(0,0,0)); + + return (BOOL) GetSysColorBrush(COLOR_STATIC); + } + + case WM_PAINT: + { + HDC hDC; + PAINTSTRUCT ps; + + hDC = BeginPaint(hDlg, &ps); // begin painting for window + + SelectObject(hDC, GetStockObject(BLACK_BRUSH)); + Rectangle(hDC, 0, 24, 240, 25); + + EndPaint(hDlg, &ps); + } + return TRUE; + + default: + return DefWindowProc(hDlg, message, wParam, lParam); + } + + return 0; +} + +#define CREDITS_LENGTH 4000 + +// Message handler for the credits dialog +LRESULT CALLBACK CreditsDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_INITDIALOG: + { + TCHAR szCredits[CREDITS_LENGTH]; + int iLength; + + LoadString(g_hInstance, IDS_CREDITS0, szCredits, CREDITS_LENGTH); + iLength = _tcslen(szCredits); + LoadString(g_hInstance, IDS_CREDITS1, &(szCredits[iLength]), CREDITS_LENGTH - iLength); + iLength = _tcslen(szCredits); + LoadString(g_hInstance, IDS_CREDITS2, &(szCredits[iLength]), CREDITS_LENGTH - iLength); + + SendMessage(GetDlgItem(hDlg, IDC_CREDITS), WM_SETTEXT, (WPARAM) 0, (LPARAM)(LPCTSTR) szCredits); + SendMessage(GetDlgItem(hDlg, IDC_CREDITS), EM_SETSEL, (WPARAM)(INT) -1, (LPARAM) 0); + + SHINITDLGINFO shidi; + + // Create a Done button and size it. + shidi.dwMask = SHIDIM_FLAGS; + shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIZEDLGFULLSCREEN; + shidi.hDlg = hDlg; + + //initialzes the dialog based on the dwFlags parameter + SHInitDialog(&shidi); + + RECT rc; + HWND hDlgItem = GetDlgItem(hDlg, IDC_CREDITS); + + rc.top = 25; + rc.left = 0; + rc.right = 240; + rc.bottom = 320 - 26 - 25; + MoveWindow(hDlgItem, rc.left, rc.top, rc.right, rc.bottom - rc.top, TRUE); + } + return TRUE; + + case WM_COMMAND: + if (LOWORD(wParam) == IDOK) + { + EndDialog(hDlg, LOWORD(wParam)); + return TRUE; + } + break; + + case WM_CTLCOLORSTATIC: + { + HDC hDC = (HDC) wParam; + HWND hctl = (HWND) lParam; + LOGFONT lf; + + if (GetDlgCtrlID(hctl) != IDC_STATIC_TITLE) + return DefWindowProc(hDlg, message, wParam, lParam); + + lf.lfWeight = FW_BOLD; + lf.lfEscapement = 0; + lf.lfOrientation = 0; + lf.lfHeight = 13; + lf.lfWidth = 0; + lf.lfCharSet = DEFAULT_CHARSET; + lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; + lf.lfItalic = FALSE; + lf.lfUnderline = FALSE; + lf.lfStrikeOut = FALSE; + lf.lfQuality = DEFAULT_QUALITY; + lf.lfOutPrecision = OUT_DEFAULT_PRECIS; + lf.lfPitchAndFamily = FF_SWISS | DEFAULT_PITCH; + + _tcscpy(lf.lfFaceName, _T("Tahoma")); + + SelectObject(hDC, CreateFontIndirect(&lf)); + SetTextColor(hDC, RGB(0,0,153)); + + return (BOOL) GetSysColorBrush(COLOR_STATIC); + } + + case WM_PAINT: + { + HDC hDC; + PAINTSTRUCT ps; + + hDC = BeginPaint(hDlg, &ps); // begin painting for window + + SelectObject(hDC, GetStockObject(BLACK_BRUSH)); + Rectangle(hDC, 0, 24, 240, 25); + + EndPaint(hDlg, &ps); + } + return TRUE; + + default: + return DefWindowProc(hDlg, message, wParam, lParam); + } + + return 0; +} + +// Eight directions +// Eight buttons - start, select, A, B, X, Y, L, R + +bool CheckKeyPad(int _iX, int _iY, bool _bDown) +{ + if (g_bLandscape || (g_pKeypad == NULL) || (_iY < 224)) + return false; + + DWORD dwColor = *(g_pKeypad + _iX + ((96 - (_iY - 224)) * 240)); + + for (int i = 0; i < g_pSkins[g_iSelectedSkin].iNumberOfColors; i++) + { + if (dwColor == g_pSkins[g_iSelectedSkin].iColor[i]) + { + if (_bDown) + g_iJoypadState |= g_pSkins[g_iSelectedSkin].iMask[i]; + else + g_iJoypadState &= ~(g_pSkins[g_iSelectedSkin].iMask[i]); + + return true; + } + } + + return false; +} + + +//------------------------------------------------------------------------------ +// OpenRegistry +// Opens and returns a key to the program's registry. +//------------------------------------------------------------------------------ +HKEY OpenRegistry() +{ + HKEY hRootKey; + DWORD dwDisposition; + + if (ERROR_SUCCESS == RegCreateKeyEx(HKEY_LOCAL_MACHINE, g_sRootKey, 0, NULL, 0, 0, NULL, &hRootKey, &dwDisposition)) + { + return hRootKey; + } + + return NULL; +} + +//------------------------------------------------------------------------------ +// CloseRegistry +// Closes the program's registry. +//------------------------------------------------------------------------------ +void CloseRegistry(HKEY hRootKey) +{ + RegCloseKey(hRootKey); +} + +//------------------------------------------------------------------------------ +// RegQueryBool +// Reads a boolean flag from the registry. +//------------------------------------------------------------------------------ +bool RegQueryBool(HKEY hKey, LPCWSTR lpValueName, bool bDefault = true) +{ + DWORD dwValue; + DWORD dwType; + DWORD dwSize = sizeof(dwValue); + + if (ERROR_SUCCESS == RegQueryValueEx(hKey, lpValueName, 0, &dwType, (unsigned char *) &dwValue, &dwSize)) + { + return ((DWORD) 0 != dwValue); + } + + return bDefault; +} + +//------------------------------------------------------------------------------ +// RegSetBool +// Sets a boolean flag in the registry. +//------------------------------------------------------------------------------ +void RegSetBool(HKEY hKey, LPCWSTR lpValueName, bool bValue) +{ + DWORD dwValue = (DWORD) bValue; + + RegSetValueEx(hKey, lpValueName, 0, REG_DWORD, (unsigned char *) &dwValue, sizeof(dwValue)); +} + +//------------------------------------------------------------------------------ +// RegQueryDword +// Reads a dword value from the registry. +//------------------------------------------------------------------------------ +DWORD RegQueryDword(HKEY hKey, LPCWSTR lpValueName, DWORD dwDefault) +{ + DWORD dwValue; + DWORD dwType; + DWORD dwSize = sizeof(dwValue); + + if (ERROR_SUCCESS == RegQueryValueEx(hKey, lpValueName, 0, &dwType, (unsigned char *) &dwValue, &dwSize)) + { + return dwValue; + } + + return dwDefault; +} + +//------------------------------------------------------------------------------ +// RegSetDword +// Sets a dword value in the registry. +//------------------------------------------------------------------------------ +void RegSetDword(HKEY hKey, LPCWSTR lpValueName, DWORD dwValue) +{ + RegSetValueEx(hKey, lpValueName, 0, REG_DWORD, (unsigned char *) &dwValue, sizeof(dwValue)); +} + +//------------------------------------------------------------------------------ +// LoadDefaultKeys +// Loads default key mappings. +//------------------------------------------------------------------------------ +void LoadDefaultKeys() +{ + g_gxKeyList = GXGetDefaultKeys(GX_NORMALKEYS); + + g_kmDefault.dwKeyMask[g_gxKeyList.vkUp] = SNES_UP_MASK; + g_kmDefault.dwKeyMask[g_gxKeyList.vkDown] = SNES_DOWN_MASK; + g_kmDefault.dwKeyMask[g_gxKeyList.vkLeft] = SNES_LEFT_MASK; + g_kmDefault.dwKeyMask[g_gxKeyList.vkRight] = SNES_RIGHT_MASK; + g_kmDefault.dwKeyMask[g_gxKeyList.vkA] = SNES_B_MASK; + g_kmDefault.dwKeyMask[g_gxKeyList.vkB] = SNES_A_MASK; + g_kmDefault.dwKeyMask[g_gxKeyList.vkC] = SNES_SELECT_MASK; + g_kmDefault.dwKeyMask[g_gxKeyList.vkStart] = SNES_START_MASK; + + g_kmDefault.dwKeyMask[0xc1] = SNES_X_MASK; + g_kmDefault.dwKeyMask[0xc2] = SNES_Y_MASK; +} + +//------------------------------------------------------------------------------ +// LoadOptions +// Loads stored options from the registry. +//------------------------------------------------------------------------------ +#define SETKEYMASK(a,b) \ + g_kmCurrent.dwKeyMask[RegQueryDword(hRootKey, a, g_kmDefault.GetKeyFromMask(b))] = b + +bool LoadOptions() +{ + HKEY hRootKey = OpenRegistry(); + bool bReturn = false; + + Settings.Transparency = RegQueryBool (hRootKey, L"Transparency"); + g_bLandscape = RegQueryBool (hRootKey, L"Landscape", false); + g_bLandLeft = RegQueryBool (hRootKey, L"LandscapeLeft", true); + g_bAutoSkip = RegQueryBool (hRootKey, L"AutoSkip", true); + g_bCompat = RegQueryBool (hRootKey, L"Compat", false); + g_bSmoothStretch = RegQueryBool (hRootKey, L"Widescreen", false); + g_iFrameSkip = RegQueryDword(hRootKey, L"FrameSkip", 5); + g_iCycles = RegQueryDword(hRootKey, L"Cycles", 100); + Settings.APUEnabled = RegQueryBool (hRootKey, L"SoundEmulation", false); + Settings.SixteenBitSound = RegQueryBool (hRootKey, L"SixteenBitSound", false); + Settings.SoundPlaybackRate = RegQueryDword(hRootKey, L"SoundQuality", 1); + //CSNES + g_bResumeAfterLoadState = RegQueryBool (hRootKey, L"ResumeAfterLoadState",false); + g_bResumeAfterSaveState = RegQueryBool (hRootKey, L"ResumeAfterSaveState",false); + Settings.DisplayFrameRate = RegQueryBool (hRootKey, L"DisplayFrameRate",false); + Settings.DisableSoundEcho = RegQueryBool (hRootKey, L"DisableSoundEcho",true); + Settings.Stereo = RegQueryBool (hRootKey, L"Stereo",false); + Settings.ReverseStereo = RegQueryBool (hRootKey, L"ReverseStereo",false); + Settings.SoundSync = RegQueryBool (hRootKey, L"SoundSync",true); + Settings.InterpolatedSound = RegQueryBool (hRootKey, L"InterpolatedSound",false); + Settings.FixFrequency = RegQueryBool (hRootKey, L"FixFrequency",false); + Settings.AltSampleDecode = RegQueryBool (hRootKey, L"AltSampleDecode",false); + Settings.SoundEnvelopeHeightReading = RegQueryBool (hRootKey, L"SoundEnvelopeHeightReading",false); + g_bUseGameFolders = RegQueryBool (hRootKey, L"UseGameFolders",false); + + LoadDefaultKeys(); + + SETKEYMASK(L"SNES up", SNES_UP_MASK); + SETKEYMASK(L"SNES down", SNES_DOWN_MASK); + SETKEYMASK(L"SNES left", SNES_LEFT_MASK); + SETKEYMASK(L"SNES right", SNES_RIGHT_MASK); + SETKEYMASK(L"SNES A", SNES_A_MASK); + SETKEYMASK(L"SNES B", SNES_B_MASK); + SETKEYMASK(L"SNES X", SNES_X_MASK); + SETKEYMASK(L"SNES Y", SNES_Y_MASK); + SETKEYMASK(L"SNES start", SNES_START_MASK); + SETKEYMASK(L"SNES select", SNES_SELECT_MASK); + SETKEYMASK(L"SNES L", SNES_TL_MASK); + SETKEYMASK(L"SNES R", SNES_TR_MASK); + + CloseRegistry(hRootKey); + + return bReturn; +} + +//------------------------------------------------------------------------------ +// SaveOptions +// Stores options into the registry. +//------------------------------------------------------------------------------ +void SaveOptions() +{ + HKEY hRootKey = OpenRegistry(); + + RegSetBool (hRootKey, L"Transparency", (Settings.Transparency == TRUE)?true:false); + RegSetBool (hRootKey, L"Landscape", g_bLandscape); + RegSetBool (hRootKey, L"LandscapeLeft", g_bLandLeft); + RegSetBool (hRootKey, L"AutoSkip", g_bAutoSkip); + RegSetBool (hRootKey, L"Compat", g_bCompat); + + RegSetBool (hRootKey, L"Widescreen", g_bSmoothStretch); + RegSetDword(hRootKey, L"FrameSkip", (DWORD) g_iFrameSkip); + RegSetDword(hRootKey, L"Cycles", (DWORD) g_iCycles); + RegSetBool (hRootKey, L"SoundEmulation", (Settings.APUEnabled == TRUE)?true:false); + RegSetBool (hRootKey, L"SixteenBitSound", (Settings.SixteenBitSound == TRUE)?true:false); + RegSetDword(hRootKey, L"SoundQuality", (DWORD)Settings.SoundPlaybackRate); + + RegSetDword(hRootKey, L"SNES up", g_kmCurrent.GetKeyFromMask(SNES_UP_MASK)); + RegSetDword(hRootKey, L"SNES down", g_kmCurrent.GetKeyFromMask(SNES_DOWN_MASK)); + RegSetDword(hRootKey, L"SNES left", g_kmCurrent.GetKeyFromMask(SNES_LEFT_MASK)); + RegSetDword(hRootKey, L"SNES right", g_kmCurrent.GetKeyFromMask(SNES_RIGHT_MASK)); + RegSetDword(hRootKey, L"SNES A", g_kmCurrent.GetKeyFromMask(SNES_A_MASK)); + RegSetDword(hRootKey, L"SNES B", g_kmCurrent.GetKeyFromMask(SNES_B_MASK)); + RegSetDword(hRootKey, L"SNES X", g_kmCurrent.GetKeyFromMask(SNES_X_MASK)); + RegSetDword(hRootKey, L"SNES Y", g_kmCurrent.GetKeyFromMask(SNES_Y_MASK)); + RegSetDword(hRootKey, L"SNES start", g_kmCurrent.GetKeyFromMask(SNES_START_MASK)); + RegSetDword(hRootKey, L"SNES select", g_kmCurrent.GetKeyFromMask(SNES_SELECT_MASK)); + RegSetDword(hRootKey, L"SNES L", g_kmCurrent.GetKeyFromMask(SNES_TL_MASK)); + RegSetDword(hRootKey, L"SNES R", g_kmCurrent.GetKeyFromMask(SNES_TR_MASK)); + + //CSNES + RegSetBool (hRootKey, L"DisplayFrameRate", (Settings.DisplayFrameRate == TRUE)?true:false); + RegSetBool (hRootKey, L"DisableSoundEcho", (Settings.DisableSoundEcho == TRUE)?true:false); + RegSetBool (hRootKey, L"ResumeAfterLoadState", (g_bResumeAfterLoadState == TRUE)?true:false); + RegSetBool (hRootKey, L"ResumeAfterSaveState", (g_bResumeAfterSaveState == TRUE)?true:false); + RegSetBool (hRootKey, L"Stereo", (Settings.Stereo == TRUE)?true:false); + RegSetBool (hRootKey, L"ReverseStereo", (Settings.ReverseStereo == TRUE)?true:false); + RegSetBool (hRootKey, L"SoundSync", (Settings.SoundSync == TRUE)?true:false); + RegSetBool (hRootKey, L"InterpolatedSound", (Settings.InterpolatedSound == TRUE)?true:false); + RegSetBool (hRootKey, L"DisableSoundEcho", (Settings.DisableSoundEcho == TRUE)?true:false); + RegSetBool (hRootKey, L"SoundEnvelopeHeightReading", (Settings.SoundEnvelopeHeightReading == TRUE)?true:false); + RegSetBool (hRootKey, L"AltSampleDecode", (Settings.AltSampleDecode == TRUE)?true:false); + RegSetBool (hRootKey, L"FixFrequency", (Settings.FixFrequency == TRUE)?true:false); + + + CloseRegistry(hRootKey); +} +//------------------------------------------------------------------------------ +// InitializeDefaultSkins +// Loads default skins. +//------------------------------------------------------------------------------ +bool InitializeDefaultSkins() +{ + g_pSkins[0].SetAuthor(L"999"); + g_pSkins[0].SetName(L"Four Button [default]"); + g_pSkins[0].bResource = true; + g_pSkins[0].pszBitmap = MAKEINTRESOURCE(IDB_4BUTTON); + g_pSkins[0].AddColor(0x0000ff, SNES_UP_MASK); + g_pSkins[0].AddColor(0xff0000, SNES_DOWN_MASK); + g_pSkins[0].AddColor(0xffff00, SNES_LEFT_MASK); + g_pSkins[0].AddColor(0x00ff00, SNES_RIGHT_MASK); + g_pSkins[0].AddColor(0xff9900, SNES_B_MASK); + g_pSkins[0].AddColor(0x593400, SNES_A_MASK); + g_pSkins[0].AddColor(0xff00ff, SNES_Y_MASK); + g_pSkins[0].AddColor(0x00ffff, SNES_X_MASK); + g_pSkins[0].AddColor(0x996363, SNES_TR_MASK); + g_pSkins[0].AddColor(0x990000, SNES_TL_MASK); + g_pSkins[0].AddColor(0x475911, SNES_START_MASK); + g_pSkins[0].AddColor(0x99bf26, SNES_SELECT_MASK); + + g_pSkins[1].SetAuthor(L"999"); + g_pSkins[1].SetName(L"Six Button [default]"); + g_pSkins[1].bResource = true; + g_pSkins[1].pszBitmap = MAKEINTRESOURCE(IDB_6BUTTON); + g_pSkins[1].AddColor(0x0000ff, SNES_UP_MASK); + g_pSkins[1].AddColor(0xff0000, SNES_DOWN_MASK); + g_pSkins[1].AddColor(0xffff00, SNES_LEFT_MASK); + g_pSkins[1].AddColor(0x00ff00, SNES_RIGHT_MASK); + g_pSkins[1].AddColor(0x00ffff, SNES_B_MASK); + g_pSkins[1].AddColor(0x00b8bf, SNES_A_MASK); + g_pSkins[1].AddColor(0xfd40ff, SNES_Y_MASK); + g_pSkins[1].AddColor(0xe200e5, SNES_X_MASK); + g_pSkins[1].AddColor(0x005559, SNES_TR_MASK); + g_pSkins[1].AddColor(0x570059, SNES_TL_MASK); + + return true; +} + +//------------------------------------------------------------------------------ +// LoadSkins +// Loads stored skins from the registry. +//------------------------------------------------------------------------------ +bool LoadSkins() +{ + HKEY hRootKey = OpenRegistry(); + bool bReturn = false; + TCHAR szSkinDir[128]; + TCHAR szSkinFilename[128]; + TCHAR szSkinSearch[128]; + DWORD dwType; + DWORD dwSize = 128 * sizeof(TCHAR); + + g_iSkinCount = 2; + g_pSkins = new Skin [32 + 2]; + + InitializeDefaultSkins(); + + if (ERROR_SUCCESS == RegQueryValueEx(hRootKey, L"Skins Path", 0, &dwType, (unsigned char *) szSkinDir, &dwSize)) + { + CreateDirectory(szSkinDir, NULL); + + _tcscpy(szSkinSearch, szSkinDir); + _tcscat(szSkinSearch, L"\\*.txt"); + + WIN32_FIND_DATA w32FindData; + HANDLE hSearch; + FILE *pFile; + bool bFinished = false; + TCHAR szBuffer[256]; + + hSearch = FindFirstFile(szSkinSearch, &w32FindData); + + if (INVALID_HANDLE_VALUE == hSearch) + return true; + + do + { + _tcscpy(szSkinFilename, szSkinDir); + _tcscat(szSkinFilename, _T("\\")); + _tcscat(szSkinFilename, w32FindData.cFileName); + + if ((pFile = _tfopen(szSkinFilename, _T("r"))) != NULL) + { + if (_fgetts(szBuffer, 256, pFile) != NULL) + { + if (_tcsnicmp(szBuffer, _T("PocketSNES.Skin.1"), 17) == 0) + { + while (_fgetts(szBuffer, 256, pFile) != NULL) + { + if (_tcsncmp(szBuffer, _T("//"), 2) == 0) + { + continue; + } + else if (_tcsnicmp(szBuffer, _T("Bitmap="), 7) == 0) + { + TCHAR szTemp[128]; + + _tcscpy(szTemp, szSkinDir); + _tcscat(szTemp, _T("\\")); + _tcscat(szTemp, &(szBuffer[7])); + szTemp[_tcslen(szTemp) - 1] = _T('\0'); + + g_pSkins[g_iSkinCount].SetBitmap(szTemp); + } + else if (_tcsnicmp(szBuffer, _T("Name="), 5) == 0) + { + szBuffer[_tcslen(szBuffer) - 1] = _T('\0'); + g_pSkins[g_iSkinCount].SetName(&(szBuffer[5])); + } + else if (_tcsnicmp(szBuffer, _T("Author="), 7) == 0) + { + szBuffer[_tcslen(szBuffer) - 1] = _T('\0'); + g_pSkins[g_iSkinCount].SetAuthor(&(szBuffer[7])); + } + else if (_tcsnicmp(szBuffer, _T("Landscape="), 10) == 0) + { + if (szBuffer[10] == _T('1')) + g_pSkins[g_iSkinCount].bLandscape = true; + } + else if (_tcsnicmp(szBuffer, _T("0x"), 2) == 0) + { + szBuffer[_tcslen(szBuffer) - 1] = _T('\0'); + szBuffer[8] = _T('\0'); + g_pSkins[g_iSkinCount].AddColor(szBuffer, &(szBuffer[9])); + } + } + + g_iSkinCount++; + } + } + + fclose(pFile); + } + + if (!FindNextFile(hSearch, &w32FindData)) + { + bFinished = true; + } + } while (!bFinished); + + FindClose(hSearch); + } + + return true; +} + + +void SetKeypad() +{ + if (g_bLandscape) + { + if(g_bLandLeft) + g_kmLandscape.SetLandscape(g_kmCurrent); + else + g_kmLandscape.SetLandscapeRight(g_kmCurrent); + + g_pkmInUse = &g_kmLandscape; + } + else + g_pkmInUse = &g_kmCurrent; +} diff --git a/src/snes4iphone_src/VOIMAGE.CPP b/src/snes4iphone_src/VOIMAGE.CPP new file mode 100755 index 0000000..230d707 --- /dev/null +++ b/src/snes4iphone_src/VOIMAGE.CPP @@ -0,0 +1,281 @@ +//------------------------------------------------------------------- +// VOImage implementation +//------------------------------------------------------------------- +// +// Copyright ©2000 Virtual Office Systems Incorporated +// All Rights Reserved +// +// This code may be used in compiled form in any way you desire. This +// file may be redistributed unmodified by any means PROVIDING it is +// not sold for profit without the authors written consent, and +// providing that this notice and the authors name is included. +// +// This code can be compiled, modified and distributed freely, providing +// that this copyright information remains intact in the distribution. +// +// This code may be compiled in original or modified form in any private +// or commercial application. +// +// This file is provided "as is" with no expressed or implied warranty. +// The author accepts no liability for any damage, in any form, caused +// by this code. Use it at your own risk. +//------------------------------------------------------------------- + +#include "stdafx.h" + +#include "VOImage.h" + +#ifdef _DEBUG +#undef THIS_FILE +static char THIS_FILE[]=__FILE__; +#define new DEBUG_NEW +#endif + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +HDC CVOImage::g_hdc; +int CVOImage::g_iScale = 100; +int CVOImage::g_iMaxWidth = 10000; +int CVOImage::g_iMaxHeight = 10000; +BOOL CVOImage::g_bStretchBlt = FALSE; + +CVOImage::CVOImage() +{ + m_hbitmap = 0; +} + +CVOImage::~CVOImage() +{ + if(m_hbitmap) + DeleteObject(m_hbitmap); +} + +BOOL CVOImage::Load(HDC hdc, LPCTSTR pcszFileName) +{ + if(m_hbitmap) + DeleteObject(m_hbitmap); + + if(!g_hdc) + g_hdc = CreateCompatibleDC(hdc); + + HRESULT hr; + BYTE szBuffer[1024] = {0}; + HANDLE hFile = INVALID_HANDLE_VALUE; + + DecompressImageInfo dii; + + hFile = CreateFile(pcszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); + if (hFile == INVALID_HANDLE_VALUE) + return FALSE; + + // Fill in the 'DecompressImageInfo' structure + dii.dwSize = sizeof( DecompressImageInfo ); // Size of this structure + dii.pbBuffer = szBuffer; // Pointer to the buffer to use for data + dii.dwBufferMax = 1024; // Size of the buffer + dii.dwBufferCurrent = 0; // The amount of data which is current in the buffer + dii.phBM = &m_hbitmap; // Pointer to the bitmap returned (can be NULL) + dii.ppImageRender = NULL; // Pointer to an IImageRender object (can be NULL) + dii.iBitDepth = GetDeviceCaps(hdc,BITSPIXEL); // Bit depth of the output image + dii.lParam = ( LPARAM ) hFile; // User parameter for callback functions + dii.hdc = g_hdc; // HDC to use for retrieving palettes + dii.iScale = g_iScale; // Scale factor (1 - 100) + dii.iMaxWidth = g_iMaxWidth; // Maximum width of the output image + dii.iMaxHeight = g_iMaxHeight; // Maxumum height of the output image + dii.pfnGetData = GetImageData; // Callback function to get image data + dii.pfnImageProgress = ImageProgress; // Callback function to notify caller of progress decoding the image + dii.crTransparentOverride = ( UINT ) -1; // If this color is not (UINT)-1, it will override the + // transparent color in the image with this color. (GIF ONLY) + + // Process and decompress the image data + hr = DecompressImageIndirect( &dii ); + + // Clean up + CloseHandle( hFile ); + + BITMAP bmp; + + GetObject(m_hbitmap, sizeof(BITMAP), &bmp); + + m_dwWidth = bmp.bmWidth; + m_dwHeight = bmp.bmHeight; + + return TRUE; +} + +HBITMAP CVOImage::Copy() +{ + BITMAP bm, bmNew; + HBITMAP hNew; + + SelectObject(g_hdc, m_hbitmap); + + ::GetObject(m_hbitmap, sizeof(BITMAP), &bm); + + HDC hdc = CreateCompatibleDC(g_hdc); + hNew = CreateCompatibleBitmap(g_hdc, bm.bmWidth, bm.bmHeight); + SelectObject(hdc, hNew); + + if(BitBlt(hdc, 0, 0, bm.bmWidth, bm.bmHeight, g_hdc, 0, 0, SRCCOPY)) + { + HBITMAP hPrev = (HBITMAP) ::GetObject(hNew, sizeof(BITMAP), &bmNew); + + ::SelectObject(hdc, hPrev); + } + + DeleteDC(hdc); + return hNew; +} + +BOOL CVOImage::Draw(HDC hdc, int x, int y, int cx, int cy) +{ + BITMAP bmp; + HGDIOBJ hOldBitmap; + + g_bStretchBlt = !(cx == -1 && cy == -1); + hOldBitmap = SelectObject(g_hdc, m_hbitmap); + GetObject(m_hbitmap, sizeof(BITMAP), &bmp); + + if (g_bStretchBlt) + { + // Stretch to fit + StretchBlt(hdc, x , y, cx, cy, g_hdc,0,0,bmp.bmWidth,bmp.bmHeight,SRCCOPY ); + } + else + { + BitBlt(hdc, x, y, bmp.bmWidth, bmp.bmHeight, g_hdc,0,0,SRCCOPY ); + } + + SelectObject(g_hdc, hOldBitmap); + + return TRUE; +} + +DWORD CVOImage::GetHeight() +{ + return m_dwHeight; +} + +DWORD CVOImage::GetWidth() +{ + return m_dwWidth; +} + +BOOL CVOImage::SetBitmap(HDC hdc, DWORD dwResourceID, LPCTSTR pcszClass, HMODULE hModule) +{ + if(!g_hdc) + g_hdc = CreateCompatibleDC(hdc); + + HRESULT hr; + BYTE szBuffer[1024] = {0}; + DecompressImageInfo dii; + + CVOResource res(hModule, dwResourceID, pcszClass); + + if(!res.IsLoaded()) + return FALSE; + + res.SetUserData(0); // Use this for the current resource offset + + // Fill in the 'DecompressImageInfo' structure + dii.dwSize = sizeof( DecompressImageInfo ); // Size of this structure + dii.pbBuffer = szBuffer; // Pointer to the buffer to use for data + dii.dwBufferMax = 1024; // Size of the buffer + dii.dwBufferCurrent = 0; // The amount of data which is current in the buffer + dii.phBM = &m_hbitmap; // Pointer to the bitmap returned (can be NULL) + dii.ppImageRender = NULL; // Pointer to an IImageRender object (can be NULL) + dii.iBitDepth = GetDeviceCaps(hdc,BITSPIXEL); // Bit depth of the output image + dii.lParam = ( LPARAM ) &res; // User parameter for callback functions + dii.hdc = g_hdc; // HDC to use for retrieving palettes + dii.iScale = g_iScale; // Scale factor (1 - 100) + dii.iMaxWidth = g_iMaxWidth; // Maximum width of the output image + dii.iMaxHeight = g_iMaxHeight; // Maxumum height of the output image + dii.pfnGetData = GetImageResourceData; // Callback function to get image data + dii.pfnImageProgress = ImageProgress; // Callback function to notify caller of progress decoding the image + dii.crTransparentOverride = ( UINT ) -1; // If this color is not (UINT)-1, it will override the + // transparent color in the image with this color. (GIF ONLY) + // Process and decompress the image data + hr = DecompressImageIndirect( &dii ); + + BITMAP bmp; + + GetObject(m_hbitmap, sizeof(BITMAP), &bmp); + + m_dwWidth = bmp.bmWidth; + m_dwHeight = bmp.bmHeight; + + return TRUE; +} + +DWORD CALLBACK CVOImage::GetImageData(LPSTR szBuffer, DWORD dwBufferMax, LPARAM lParam ) +{ + DWORD dwNumberOfBytesRead; + + if ( (HANDLE)lParam == INVALID_HANDLE_VALUE ) + return 0; + + ReadFile( (HANDLE)lParam, szBuffer, dwBufferMax, &dwNumberOfBytesRead, NULL ); + + // Return number of bytes read + return dwNumberOfBytesRead; +} + +DWORD CALLBACK CVOImage::GetImageResourceData(LPSTR szBuffer, DWORD dwBufferMax, LPARAM lParam) +{ + DWORD dwNumberOfBytesToRead = dwBufferMax; + CVOResource* pRes = (CVOResource*) lParam; + + if(!pRes) + return 0; + + DWORD dwResourceOffset = pRes->GetUserData(); + + if(dwResourceOffset + dwNumberOfBytesToRead > pRes->GetSize() ) + dwNumberOfBytesToRead = pRes->GetSize() - dwResourceOffset; + + memmove(szBuffer, pRes->GetData() + dwResourceOffset, dwNumberOfBytesToRead); + + pRes->SetUserData(dwResourceOffset + dwNumberOfBytesToRead); + return dwNumberOfBytesToRead; // return amount read +} + +void CALLBACK CVOImage::ImageProgress(IImageRender *pRender, BOOL bComplete, LPARAM lParam ) +{ + if( bComplete ) + { + ;// (Optional) add code here for completion processing + } +} + +BOOL CVOImage::IsLoaded() +{ + return (m_hbitmap != 0); +} + +CVOResource::CVOResource(HMODULE hModule, DWORD dwResourceID, LPCTSTR pcszClass) +{ + m_dwSize = 0; + m_hGlobal = 0; + m_pData = 0; + + m_hrsrc = FindResource(hModule, (LPCWSTR)dwResourceID, pcszClass); + + if(m_hrsrc == 0) + return; + + m_dwSize = SizeofResource(hModule, m_hrsrc); + m_hGlobal = LoadResource(hModule, m_hrsrc); + m_pData = (PBYTE) LockResource(m_hGlobal); +} + +CVOResource::~CVOResource() +{ + if(m_hGlobal) + DeleteObject(m_hGlobal); +} + +BOOL CVOResource::IsLoaded() +{ + return (m_pData != NULL); +} diff --git a/src/snes4iphone_src/VOIMAGE.H b/src/snes4iphone_src/VOIMAGE.H new file mode 100755 index 0000000..2825b58 --- /dev/null +++ b/src/snes4iphone_src/VOIMAGE.H @@ -0,0 +1,84 @@ +//------------------------------------------------------------------- +// VOImage Header File +//------------------------------------------------------------------- +// +// Copyright ©2000 Virtual Office Systems Incorporated +// All Rights Reserved +// +// This code may be used in compiled form in any way you desire. This +// file may be redistributed unmodified by any means PROVIDING it is +// not sold for profit without the authors written consent, and +// providing that this notice and the authors name is included. +// +// This code can be compiled, modified and distributed freely, providing +// that this copyright information remains intact in the distribution. +// +// This code may be compiled in original or modified form in any private +// or commercial application. +// +// This file is provided "as is" with no expressed or implied warranty. +// The author accepts no liability for any damage, in any form, caused +// by this code. Use it at your own risk. +//------------------------------------------------------------------- + +#if !defined(AFX_VOIMAGE_H__B83C4202_DB1E_48BE_92A5_21019F9EE6FC__INCLUDED_) +#define AFX_VOIMAGE_H__B83C4202_DB1E_48BE_92A5_21019F9EE6FC__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#include "imgdecmp.h" + +class CVOResource +{ +public: + CVOResource(HMODULE hModule, DWORD dwResourceID, LPCTSTR pcszClass); + ~CVOResource(); + + BOOL IsLoaded(); + + DWORD GetSize() { return m_dwSize; } + PBYTE GetData() { return m_pData; } + + void SetUserData(DWORD dwValue) { m_dwUser = dwValue; } + DWORD GetUserData() { return m_dwUser; } + +protected: + DWORD m_dwUser; + + DWORD m_dwSize; + PBYTE m_pData; + HGLOBAL m_hGlobal; + HRSRC m_hrsrc; +}; + +class CVOImage +{ +public: + HBITMAP Copy(); + static DWORD CALLBACK GetImageResourceData(LPSTR szBuffer, DWORD dwBufferMax, LPARAM lParam); + BOOL IsLoaded(); + static void CALLBACK ImageProgress( IImageRender *, BOOL, LPARAM); + static DWORD CALLBACK GetImageData( LPSTR, DWORD, LPARAM); + BOOL SetBitmap(HDC hdc, DWORD dwResourceID, LPCTSTR pcszClass = TEXT("IMAGE"), HMODULE hModule = 0 ); + DWORD GetWidth(); + DWORD GetHeight(); + BOOL Draw(HDC hdc, int x, int y, int cx = -1, int cy = -1); + BOOL Load(HDC hdc, LPCTSTR pcszFileName); + CVOImage(); + virtual ~CVOImage(); + operator HBITMAP() { return m_hbitmap; } + +protected: + DWORD m_dwHeight; + DWORD m_dwWidth; + HBITMAP m_hbitmap; + static BOOL g_bStretchBlt; + static int g_iMaxHeight; + static int g_iMaxWidth; + static int g_iScale; + static HDC g_hdc; +}; + +#endif // !defined(AFX_VOIMAGE_H__B83C4202_DB1E_48BE_92A5_21019F9EE6FC__INCLUDED_) diff --git a/src/snes4iphone_src/apu.cpp b/src/snes4iphone_src/apu.cpp new file mode 100755 index 0000000..146998a --- /dev/null +++ b/src/snes4iphone_src/apu.cpp @@ -0,0 +1,1173 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ + +#include "snes9x.h" +#include "spc700.h" +#include "apu.h" +#include "soundux.h" +#include "cpuexec.h" + +/* For note-triggered SPC dump support */ +//#include "snapshot.h" + +//extern int NoiseFreq [32]; +#ifdef DEBUGGER +void S9xTraceSoundDSP (const char *s, int i1 = 0, int i2 = 0, int i3 = 0, + int i4 = 0, int i5 = 0, int i6 = 0, int i7 = 0); +#endif + +#undef ABS +#define ABS(a) ((a) < 0 ? -(a) : (a)) +#define ENVX_SHIFT 24 + + +unsigned long AttackRate [16] = { + 4100, 2600, 1500, 1000, 640, 380, 260, 160, + 96, 64, 40, 24, 16, 10, 6, 1 +}; + +unsigned long DecayRate [8] = { + 1200, 740, 440, 290, 180, 110, 74, 37 +}; + +unsigned long SustainRate [32] = { + /*~0*/0xFFFFFFFF, 38000, 28000, 24000, 19000, 14000, 12000, 9400, + 7100, 5900, 4700, 3500, 2900, 2400, 1800, 1500, + 1200, 880, 740, 590, 440, 370, 290, 220, + 180, 150, 110, 92, 74, 55, 37, 18 +}; + +unsigned long IncreaseRate [32] = { + /*~0*/0xFFFFFFFF, 4100, 3100, 2600, 2000, 1500, 1300, 1000, + 770, 640, 510, 380, 320, 260, 190, 160, + 130, 96, 80, 64, 48, 40, 32, 24, + 20, 16, 12, 10, 8, 6, 4, 2 +}; + +unsigned long DecreaseRateExp [32] = { + /*~0*/0xFFFFFFFF, 38000, 28000, 24000, 19000, 14000, 12000, 9400, + 7100, 5900, 4700, 3500, 2900, 2400, 1800, 1500, + 1200, 880, 740, 590, 440, 370, 290, 220, + 180, 150, 110, 92, 74, 55, 37, 18 +}; + +// precalculated env rates for S9xSetEnvRate +unsigned long AttackERate [16][10]; +unsigned long DecayERate [8][10]; +unsigned long SustainERate [32][10]; +unsigned long IncreaseERate [32][10]; +unsigned long DecreaseERateExp[32][10]; +unsigned long KeyOffERate[10]; + + +static inline void S9xSetEnvelopeRate (int channel, unsigned long rate, int direction, int target, unsigned int mode) +{ + S9xSetEnvRate (&SoundData.channels [channel], rate, direction, target, mode); +} + +static inline void S9xSetSoundADSR (int channel, int attack_ind, int decay_ind, + int sustain_ind, int sustain_level, int release_rate) +{ + int attack_rate = AttackRate [attack_ind]; + int decay_rate = DecayRate [decay_ind]; + int sustain_rate = SustainRate [sustain_ind]; + + // Hack for ROMs that use a very short attack rate, key on a + // channel, then switch to decay mode. e.g. Final Fantasy II. + if (attack_rate == 1) + attack_rate = 0; + + SoundData.channels[channel].env_ind_attack = attack_ind; + SoundData.channels[channel].env_ind_decay = decay_ind; + SoundData.channels[channel].env_ind_sustain = sustain_ind; + + SoundData.channels[channel].attack_rate = attack_rate; + SoundData.channels[channel].decay_rate = decay_rate; + SoundData.channels[channel].sustain_rate = sustain_rate; + SoundData.channels[channel].release_rate = release_rate; + SoundData.channels[channel].sustain_level = sustain_level + 1; + + switch (SoundData.channels[channel].state) + { + case SOUND_ATTACK: + S9xSetEnvelopeRate (channel, attack_rate, 1, 127, 0); + break; + + case SOUND_DECAY: + S9xSetEnvelopeRate (channel, decay_rate, -1, + (MAX_ENVELOPE_HEIGHT * (sustain_level + 1)) >> 3, 1<<28); + break; + case SOUND_SUSTAIN: + S9xSetEnvelopeRate (channel, sustain_rate, -1, 0, 2<<28); + break; + } +} + +static inline void S9xSetSoundVolume (int channel, short volume_left, short volume_right) +{ + Channel *ch = &SoundData.channels[channel]; + if (!so.stereo) + volume_left = (ABS(volume_right) + ABS(volume_left)) / 2; + + ch->volume_left = volume_left; + ch->volume_right = volume_right; + ch-> left_vol_level = (ch->envx * volume_left) / 128; + ch->right_vol_level = (ch->envx * volume_right) / 128; +} + +static inline void S9xSetMasterVolume (short volume_left, short volume_right) +{ + if (Settings.DisableMasterVolume) + { + SoundData.master_volume_left = 127; + SoundData.master_volume_right = 127; + SoundData.master_volume [0] = SoundData.master_volume [1] = 127; + } + else + { + if (!so.stereo) + volume_left = (ABS (volume_right) + ABS (volume_left)) / 2; + SoundData.master_volume_left = volume_left; + SoundData.master_volume_right = volume_right; + SoundData.master_volume [0] = volume_left; + SoundData.master_volume [1] = volume_right; + } +} + +static inline void S9xSetEchoVolume (short volume_left, short volume_right) +{ + if (!so.stereo) + volume_left = (ABS (volume_right) + ABS (volume_left)) / 2; + SoundData.echo_volume_left = volume_left; + SoundData.echo_volume_right = volume_right; + SoundData.echo_volume [0] = volume_left; + SoundData.echo_volume [1] = volume_right; +} + +static inline void S9xSetEchoWriteEnable (uint8 byte) +{ + SoundData.echo_write_enabled = byte; + S9xSetEchoDelay (APU.DSP [APU_EDL] & 15); +} + +static inline void S9xSetFrequencyModulationEnable (uint8 byte) +{ + SoundData.pitch_mod = byte & (0xFE);//~1; +} + +static inline int S9xGetEnvelopeHeight (int channel) +{ + if ((Settings.SoundEnvelopeHeightReading || + SNESGameFixes.SoundEnvelopeHeightReading2) && + SoundData.channels[channel].state != SOUND_SILENT && + SoundData.channels[channel].state != SOUND_GAIN) + { + return (SoundData.channels[channel].envx); + } + + //siren fix from XPP + if (SNESGameFixes.SoundEnvelopeHeightReading2 && + SoundData.channels[channel].state != SOUND_SILENT) + { + return (SoundData.channels[channel].envx); + } + + return (0); +} + +static inline void S9xSetSoundHertz (int channel, int hertz) +{ + SoundData.channels[channel].hertz = hertz; + S9xSetSoundFrequency (channel, hertz); +} + +static inline void S9xSetSoundType (int channel, int type_of_sound) +{ + SoundData.channels[channel].type = type_of_sound; +} + +static inline bool8 S9xSetSoundMode (int channel, int mode) +{ + Channel *ch = &SoundData.channels[channel]; + + switch (mode) + { + case MODE_RELEASE: + if (ch->mode != MODE_NONE) + { + ch->mode = MODE_RELEASE; + return (TRUE); + } + break; + + case MODE_DECREASE_LINEAR: + case MODE_DECREASE_EXPONENTIAL: + case MODE_GAIN: + if (ch->mode != MODE_RELEASE) + { + ch->mode = mode; + if (ch->state != SOUND_SILENT) + ch->state = mode; + + return (TRUE); + } + break; + + case MODE_INCREASE_LINEAR: + case MODE_INCREASE_BENT_LINE: + if (ch->mode != MODE_RELEASE) + { + ch->mode = mode; + if (ch->state != SOUND_SILENT) + ch->state = mode; + + return (TRUE); + } + break; + + case MODE_ADSR: + if (ch->mode == MODE_NONE || ch->mode == MODE_ADSR) + { + ch->mode = mode; + return (TRUE); + } + } + + return (FALSE); +} + +static inline void S9xPlaySample (int channel) +{ + Channel *ch = &SoundData.channels[channel]; + + ch->state = SOUND_SILENT; + ch->mode = MODE_NONE; + ch->envx = 0; + ch->envxx = 0; + + ch->g_index=0; + ch->gaussian[0]=ch->gaussian[1]=ch->gaussian[2]=ch->gaussian[3]=0; + + S9xFixEnvelope (channel, + APU.DSP [APU_GAIN + (channel << 4)], + APU.DSP [APU_ADSR1 + (channel << 4)], + APU.DSP [APU_ADSR2 + (channel << 4)]); + + ch->sample_number = APU.DSP [APU_SRCN + channel * 0x10]; + if (APU.DSP [APU_NON] & (1 << channel)) + ch->type = SOUND_NOISE; + else + ch->type = SOUND_SAMPLE; + + S9xSetSoundFrequency (channel, ch->hertz); + ch->loop = FALSE; + ch->needs_decode = TRUE; + ch->last_block = FALSE; + ch->previous [0] = ch->previous[1] = 0; + ch->block_pointer = *S9xGetSampleAddress(ch->sample_number); + ch->sample_pointer = 0; + ch->env_error = 0; + ch->next_sample = 0; + ch->interpolate = 0; + ch->last_valid_header=0; + switch (ch->mode) + { + case MODE_ADSR: + if (ch->attack_rate == 0) + { + if (ch->decay_rate == 0 || ch->sustain_level == 8) + { + ch->state = SOUND_SUSTAIN; + ch->envx = (MAX_ENVELOPE_HEIGHT * ch->sustain_level) >> 3; + S9xSetEnvRate (ch, ch->sustain_rate, -1, 0, 2<<28); + } + else + { + ch->state = SOUND_DECAY; + ch->envx = MAX_ENVELOPE_HEIGHT; + S9xSetEnvRate (ch, ch->decay_rate, -1, + (MAX_ENVELOPE_HEIGHT * ch->sustain_level) >> 3, 1<<28); + } + ch-> left_vol_level = (ch->envx * ch->volume_left) / 128; + ch->right_vol_level = (ch->envx * ch->volume_right) / 128; + } + else + { + ch->state = SOUND_ATTACK; + ch->envx = 0; + ch->left_vol_level = 0; + ch->right_vol_level = 0; + S9xSetEnvRate (ch, ch->attack_rate, 1, MAX_ENVELOPE_HEIGHT, 0); + } + ch->envxx = ch->envx << ENVX_SHIFT; + break; + + case MODE_GAIN: + ch->state = SOUND_GAIN; + break; + + case MODE_INCREASE_LINEAR: + ch->state = SOUND_INCREASE_LINEAR; + break; + + case MODE_INCREASE_BENT_LINE: + ch->state = SOUND_INCREASE_BENT_LINE; + break; + + case MODE_DECREASE_LINEAR: + ch->state = SOUND_DECREASE_LINEAR; + break; + + case MODE_DECREASE_EXPONENTIAL: + ch->state = SOUND_DECREASE_EXPONENTIAL; + break; + + default: + break; + } + + S9xFixEnvelope (channel, + APU.DSP [APU_GAIN + (channel << 4)], + APU.DSP [APU_ADSR1 + (channel << 4)], + APU.DSP [APU_ADSR2 + (channel << 4)]); +} + +#ifdef ASM_SPC700 +extern "C" uint32 Spc700JumpTab; +#endif + +bool8 S9xInitAPU () +{ + // notaz + memset(&IAPU, 0, sizeof(IAPU)); + IAPU.ExtraRAM = APU.ExtraRAM; +#ifdef ASM_SPC700 + IAPU.asmJumpTab = &Spc700JumpTab; +#endif + + IAPU.RAM = (uint8 *) malloc (0x10000); + IAPU.ShadowRAM = NULL;//(uint8 *) malloc (0x10000); + IAPU.CachedSamples = NULL;//(uint8 *) malloc (0x40000); + + if (!IAPU.RAM /*|| !IAPU.ShadowRAM || !IAPU.CachedSamples*/) + { + S9xDeinitAPU (); + return (FALSE); + } + + return (TRUE); +} + +void S9xDeinitAPU () +{ + if (IAPU.RAM) + { + free ((char *) IAPU.RAM); + IAPU.RAM = NULL; + } + if (IAPU.ShadowRAM) + { + free ((char *) IAPU.ShadowRAM); + IAPU.ShadowRAM = NULL; + } + if (IAPU.CachedSamples) + { + free ((char *) IAPU.CachedSamples); + IAPU.CachedSamples = NULL; + } +} + +EXTERN_C uint8 APUROM [64]; + +void S9xResetAPU () +{ +// Settings.APUEnabled = Settings.NextAPUEnabled; + + memset (IAPU.RAM, Settings.APURAMInitialValue, 0x10000); + //memset (IAPU.ShadowRAM, Settings.APURAMInitialValue, 0x10000); + + //ZeroMemory (IAPU.CachedSamples, 0x40000); + ZeroMemory (APU.OutPorts, 4); + IAPU.DirectPage = IAPU.RAM; + memmove (&IAPU.RAM [0xffc0], APUROM, sizeof (APUROM)); + memmove (APU.ExtraRAM, APUROM, sizeof (APUROM)); + IAPU.PC = IAPU.RAM + IAPU.RAM [0xfffe] + (IAPU.RAM [0xffff] << 8); + CPU.APU_Cycles = 0; + IAPU.YA.W = 0; + IAPU.X = 0; + IAPU.S = 0xff; + IAPU.P = 0; + S9xAPUUnpackStatus (); + CPU.APU_APUExecuting = Settings.APUEnabled; +#ifdef SPC700_SHUTDOWN + IAPU.WaitAddress1 = NULL; + IAPU.WaitAddress2 = NULL; + IAPU.WaitCounter = 0; +#endif + APU.ShowROM = TRUE; + IAPU.RAM [0xf1] = 0x80; + + int i; + + for (i = 0; i < 3; i++) + { + APU.TimerEnabled [i] = FALSE; + APU.TimerValueWritten [i] = 0; + APU.TimerTarget [i] = 0; + APU.Timer [i] = 0; + } + for (int j = 0; j < 0x80; j++) + APU.DSP [j] = 0; + + IAPU.TwoCycles = IAPU.OneCycle * 2; + + for (i = 0; i < 256; i++) + S9xAPUCycles [i] = S9xAPUCycleLengths [i] * IAPU.OneCycle; + + APU.DSP [APU_ENDX] = 0; + APU.DSP [APU_KOFF] = 0; + APU.DSP [APU_KON] = 0; + APU.DSP [APU_FLG] = APU_MUTE | APU_ECHO_DISABLED; + APU.KeyedChannels = 0; + + S9xResetSound (TRUE); + S9xSetEchoEnable (0); +} + +extern int framecpto; +void S9xSetAPUDSP (uint8 byte) +{ + uint8 reg = IAPU.RAM [0xf2]; + static uint8 KeyOn; + static uint8 KeyOnPrev; + int i; + +/* char str[64]; + if (byte!=0) + { + sprintf(str,"fr : %d\nwrite dsp %d\ncpu cycle=%d pc=%04X",framecpto,byte,CPU.Cycles,CPU.PC-CPU.PCBase); + S9xMessage(0,0,str); + gp32_pause(); + }*/ + + //extern uint8 spc_dump_dsp[0x100]; + + //spc_dump_dsp[reg] = byte; + + switch (reg) + { + case APU_FLG: + if (byte & APU_SOFT_RESET) + { + APU.DSP [reg] = APU_MUTE | APU_ECHO_DISABLED | (byte & 0x1f); + APU.DSP [APU_ENDX] = 0; + APU.DSP [APU_KOFF] = 0; + APU.DSP [APU_KON] = 0; + S9xSetEchoWriteEnable (FALSE); +#ifdef DEBUGGER + if (Settings.TraceSoundDSP) + S9xTraceSoundDSP ("[%d] DSP reset\n", ICPU.Scanline); +#endif + // Kill sound + S9xResetSound (FALSE); + } + else + { + S9xSetEchoWriteEnable (!(byte & APU_ECHO_DISABLED)); + if (byte & APU_MUTE) + { +#ifdef DEBUGGER + if (Settings.TraceSoundDSP) + S9xTraceSoundDSP ("[%d] Mute sound\n", ICPU.Scanline); +#endif + S9xSetSoundMute (TRUE); + } + else + S9xSetSoundMute (FALSE); + + SoundData.noise_hertz = NoiseFreq [byte & 0x1f]; + for (i = 0; i < 8; i++) + { + if (SoundData.channels [i].type == SOUND_NOISE) + S9xSetSoundFrequency (i, SoundData.noise_hertz); + } + } + break; + case APU_NON: + if (byte != APU.DSP [APU_NON]) + { +#ifdef DEBUGGER + if (Settings.TraceSoundDSP) + S9xTraceSoundDSP ("[%d] Noise:", ICPU.Scanline); +#endif + uint8 mask = 1; + for (int c = 0; c < 8; c++, mask <<= 1) + { + int type; + if (byte & mask) + { + type = SOUND_NOISE; +#ifdef DEBUGGER + if (Settings.TraceSoundDSP) + { + if (APU.DSP [reg] & mask) + S9xTraceSoundDSP ("%d,", c); + else + S9xTraceSoundDSP ("%d(on),", c); + } +#endif + } + else + { + type = SOUND_SAMPLE; +#ifdef DEBUGGER + if (Settings.TraceSoundDSP) + { + if (APU.DSP [reg] & mask) + S9xTraceSoundDSP ("%d(off),", c); + } +#endif + } + S9xSetSoundType (c, type); + } +#ifdef DEBUGGER + if (Settings.TraceSoundDSP) + S9xTraceSoundDSP ("\n"); +#endif + } + break; + case APU_MVOL_LEFT: + if (byte != APU.DSP [APU_MVOL_LEFT]) + { +#ifdef DEBUGGER + if (Settings.TraceSoundDSP) + S9xTraceSoundDSP ("[%d] Master volume left:%d\n", + ICPU.Scanline, (signed char) byte); +#endif + S9xSetMasterVolume ((signed char) byte, + (signed char) APU.DSP [APU_MVOL_RIGHT]); + } + break; + case APU_MVOL_RIGHT: + if (byte != APU.DSP [APU_MVOL_RIGHT]) + { +#ifdef DEBUGGER + if (Settings.TraceSoundDSP) + S9xTraceSoundDSP ("[%d] Master volume right:%d\n", + ICPU.Scanline, (signed char) byte); +#endif + S9xSetMasterVolume ((signed char) APU.DSP [APU_MVOL_LEFT], + (signed char) byte); + } + break; + case APU_EVOL_LEFT: + if (byte != APU.DSP [APU_EVOL_LEFT]) + { +#ifdef DEBUGGER + if (Settings.TraceSoundDSP) + S9xTraceSoundDSP ("[%d] Echo volume left:%d\n", + ICPU.Scanline, (signed char) byte); +#endif + S9xSetEchoVolume ((signed char) byte, + (signed char) APU.DSP [APU_EVOL_RIGHT]); + } + break; + case APU_EVOL_RIGHT: + if (byte != APU.DSP [APU_EVOL_RIGHT]) + { +#ifdef DEBUGGER + if (Settings.TraceSoundDSP) + S9xTraceSoundDSP ("[%d] Echo volume right:%d\n", + ICPU.Scanline, (signed char) byte); +#endif + S9xSetEchoVolume ((signed char) APU.DSP [APU_EVOL_LEFT], + (signed char) byte); + } + break; + case APU_ENDX: +#ifdef DEBUGGER + if (Settings.TraceSoundDSP) + S9xTraceSoundDSP ("[%d] Reset ENDX\n", ICPU.Scanline); +#endif + byte = 0; + break; + + case APU_KOFF: + // if (byte) + { + uint8 mask = 1; +#ifdef DEBUGGER + if (Settings.TraceSoundDSP) + S9xTraceSoundDSP ("[%d] Key off:", ICPU.Scanline); +#endif + for (int c = 0; c < 8; c++, mask <<= 1) + { + if ((byte & mask) != 0) + { +#ifdef DEBUGGER + + if (Settings.TraceSoundDSP) + S9xTraceSoundDSP ("%d,", c); +#endif + if (APU.KeyedChannels & mask) + { + { + KeyOnPrev&=~mask; + APU.KeyedChannels &= ~mask; + APU.DSP [APU_KON] &= ~mask; + //APU.DSP [APU_KOFF] |= mask; + S9xSetSoundKeyOff (c); + } + } + } + else if((KeyOnPrev&mask)!=0) + { + KeyOnPrev&=~mask; + APU.KeyedChannels |= mask; + //APU.DSP [APU_KON] |= mask; + APU.DSP [APU_KOFF] &= ~mask; + APU.DSP [APU_ENDX] &= ~mask; + S9xPlaySample (c); + } + } +#ifdef DEBUGGER + if (Settings.TraceSoundDSP) + S9xTraceSoundDSP ("\n"); +#endif + } + //KeyOnPrev=0; + APU.DSP [APU_KOFF] = byte; + return; + case APU_KON: + + if (byte) + { + uint8 mask = 1; +#ifdef DEBUGGER + + if (Settings.TraceSoundDSP) + S9xTraceSoundDSP ("[%d] Key on:", ICPU.Scanline); +#endif + for (int c = 0; c < 8; c++, mask <<= 1) + { + if ((byte & mask) != 0) + { +#ifdef DEBUGGER + if (Settings.TraceSoundDSP) + S9xTraceSoundDSP ("%d,", c); +#endif + // Pac-In-Time requires that channels can be key-on + // regardeless of their current state. + if((APU.DSP [APU_KOFF] & mask) ==0) + { + KeyOnPrev&=~mask; + APU.KeyedChannels |= mask; + //APU.DSP [APU_KON] |= mask; + //APU.DSP [APU_KOFF] &= ~mask; + APU.DSP [APU_ENDX] &= ~mask; + S9xPlaySample (c); + } + else KeyOn|=mask; + } + } +#ifdef DEBUGGER + if (Settings.TraceSoundDSP) + S9xTraceSoundDSP ("\n"); +#endif + } + //spc_is_dumping_temp = byte; + return; + + case APU_VOL_LEFT + 0x00: + case APU_VOL_LEFT + 0x10: + case APU_VOL_LEFT + 0x20: + case APU_VOL_LEFT + 0x30: + case APU_VOL_LEFT + 0x40: + case APU_VOL_LEFT + 0x50: + case APU_VOL_LEFT + 0x60: + case APU_VOL_LEFT + 0x70: +// At Shin Megami Tensei suggestion 6/11/00 +// if (byte != APU.DSP [reg]) + { +#ifdef DEBUGGER + if (Settings.TraceSoundDSP) + S9xTraceSoundDSP ("[%d] %d volume left: %d\n", + ICPU.Scanline, reg>>4, (signed char) byte); +#endif + S9xSetSoundVolume (reg >> 4, (signed char) byte, + (signed char) APU.DSP [reg + 1]); + } + break; + case APU_VOL_RIGHT + 0x00: + case APU_VOL_RIGHT + 0x10: + case APU_VOL_RIGHT + 0x20: + case APU_VOL_RIGHT + 0x30: + case APU_VOL_RIGHT + 0x40: + case APU_VOL_RIGHT + 0x50: + case APU_VOL_RIGHT + 0x60: + case APU_VOL_RIGHT + 0x70: +// At Shin Megami Tensei suggestion 6/11/00 +// if (byte != APU.DSP [reg]) + { +#ifdef DEBUGGER + if (Settings.TraceSoundDSP) + S9xTraceSoundDSP ("[%d] %d volume right: %d\n", + ICPU.Scanline, reg >>4, (signed char) byte); +#endif + S9xSetSoundVolume (reg >> 4, (signed char) APU.DSP [reg - 1], + (signed char) byte); + } + break; + + case APU_P_LOW + 0x00: + case APU_P_LOW + 0x10: + case APU_P_LOW + 0x20: + case APU_P_LOW + 0x30: + case APU_P_LOW + 0x40: + case APU_P_LOW + 0x50: + case APU_P_LOW + 0x60: + case APU_P_LOW + 0x70: +#ifdef DEBUGGER + if (Settings.TraceSoundDSP) + S9xTraceSoundDSP ("[%d] %d freq low: %d\n", + ICPU.Scanline, reg>>4, byte); +#endif + S9xSetSoundHertz (reg >> 4, (((byte + (APU.DSP [reg + 1] << 8)) & FREQUENCY_MASK) * 32000) >> 12); + break; + + case APU_P_HIGH + 0x00: + case APU_P_HIGH + 0x10: + case APU_P_HIGH + 0x20: + case APU_P_HIGH + 0x30: + case APU_P_HIGH + 0x40: + case APU_P_HIGH + 0x50: + case APU_P_HIGH + 0x60: + case APU_P_HIGH + 0x70: +#ifdef DEBUGGER + if (Settings.TraceSoundDSP) + S9xTraceSoundDSP ("[%d] %d freq high: %d\n", + ICPU.Scanline, reg>>4, byte); +#endif + S9xSetSoundHertz (reg >> 4, + (((byte << 8) + APU.DSP [reg - 1]) & FREQUENCY_MASK) * 8); + break; + + case APU_SRCN + 0x00: + case APU_SRCN + 0x10: + case APU_SRCN + 0x20: + case APU_SRCN + 0x30: + case APU_SRCN + 0x40: + case APU_SRCN + 0x50: + case APU_SRCN + 0x60: + case APU_SRCN + 0x70: + if (byte != APU.DSP [reg]) + { +#ifdef DEBUGGER + if (Settings.TraceSoundDSP) + S9xTraceSoundDSP ("[%d] %d sample number: %d\n", + ICPU.Scanline, reg>>4, byte); +#endif + //S9xSetSoundSample (reg >> 4, byte); // notaz: seems to be unused? + } + break; + + case APU_ADSR1 + 0x00: + case APU_ADSR1 + 0x10: + case APU_ADSR1 + 0x20: + case APU_ADSR1 + 0x30: + case APU_ADSR1 + 0x40: + case APU_ADSR1 + 0x50: + case APU_ADSR1 + 0x60: + case APU_ADSR1 + 0x70: + if (byte != APU.DSP [reg]) + { +#ifdef DEBUGGER + if (Settings.TraceSoundDSP) + S9xTraceSoundDSP ("[%d] %d adsr1: %02x\n", + ICPU.Scanline, reg>>4, byte); +#endif + { + S9xFixEnvelope (reg >> 4, APU.DSP [reg + 2], byte, + APU.DSP [reg + 1]); + } + } + break; + + case APU_ADSR2 + 0x00: + case APU_ADSR2 + 0x10: + case APU_ADSR2 + 0x20: + case APU_ADSR2 + 0x30: + case APU_ADSR2 + 0x40: + case APU_ADSR2 + 0x50: + case APU_ADSR2 + 0x60: + case APU_ADSR2 + 0x70: + if (byte != APU.DSP [reg]) + { +#ifdef DEBUGGER + if (Settings.TraceSoundDSP) + S9xTraceSoundDSP ("[%d] %d adsr2: %02x\n", + ICPU.Scanline, reg>>4, byte); +#endif + { + S9xFixEnvelope (reg >> 4, APU.DSP [reg + 1], APU.DSP [reg - 1], + byte); + } + } + break; + + case APU_GAIN + 0x00: + case APU_GAIN + 0x10: + case APU_GAIN + 0x20: + case APU_GAIN + 0x30: + case APU_GAIN + 0x40: + case APU_GAIN + 0x50: + case APU_GAIN + 0x60: + case APU_GAIN + 0x70: + if (byte != APU.DSP [reg]) + { +#ifdef DEBUGGER + if (Settings.TraceSoundDSP) + S9xTraceSoundDSP ("[%d] %d gain: %02x\n", + ICPU.Scanline, reg>>4, byte); +#endif + { + S9xFixEnvelope (reg >> 4, byte, APU.DSP [reg - 2], + APU.DSP [reg - 1]); + } + } + break; + + case APU_ENVX + 0x00: + case APU_ENVX + 0x10: + case APU_ENVX + 0x20: + case APU_ENVX + 0x30: + case APU_ENVX + 0x40: + case APU_ENVX + 0x50: + case APU_ENVX + 0x60: + case APU_ENVX + 0x70: + break; + + case APU_OUTX + 0x00: + case APU_OUTX + 0x10: + case APU_OUTX + 0x20: + case APU_OUTX + 0x30: + case APU_OUTX + 0x40: + case APU_OUTX + 0x50: + case APU_OUTX + 0x60: + case APU_OUTX + 0x70: + break; + + case APU_DIR: +#ifdef DEBUGGER + if (Settings.TraceSoundDSP) + S9xTraceSoundDSP ("[%d] Sample directory to: %02x\n", + ICPU.Scanline, byte); +#endif + break; + + case APU_PMON: + if (byte != APU.DSP [APU_PMON]) + { +#ifdef DEBUGGER + if (Settings.TraceSoundDSP) + { + S9xTraceSoundDSP ("[%d] FreqMod:", ICPU.Scanline); + uint8 mask = 1; + for (int c = 0; c < 8; c++, mask <<= 1) + { + if (byte & mask) + { + if (APU.DSP [reg] & mask) + S9xTraceSoundDSP ("%d", c); + else + S9xTraceSoundDSP ("%d(on),", c); + } + else + { + if (APU.DSP [reg] & mask) + S9xTraceSoundDSP ("%d(off),", c); + } + } + S9xTraceSoundDSP ("\n"); + } +#endif + S9xSetFrequencyModulationEnable (byte); + } + break; + + case APU_EON: + if (byte != APU.DSP [APU_EON]) + { +#ifdef DEBUGGER + if (Settings.TraceSoundDSP) + { + S9xTraceSoundDSP ("[%d] Echo:", ICPU.Scanline); + uint8 mask = 1; + for (int c = 0; c < 8; c++, mask <<= 1) + { + if (byte & mask) + { + if (APU.DSP [reg] & mask) + S9xTraceSoundDSP ("%d", c); + else + S9xTraceSoundDSP ("%d(on),", c); + } + else + { + if (APU.DSP [reg] & mask) + S9xTraceSoundDSP ("%d(off),", c); + } + } + S9xTraceSoundDSP ("\n"); + } +#endif + S9xSetEchoEnable (byte); + } + break; + + case APU_EFB: + S9xSetEchoFeedback ((signed char) byte); + break; + + case APU_ESA: + break; + + case APU_EDL: + S9xSetEchoDelay (byte & 0xf); + break; + + case APU_C0: + case APU_C1: + case APU_C2: + case APU_C3: + case APU_C4: + case APU_C5: + case APU_C6: + case APU_C7: + S9xSetFilterCoefficient (reg >> 4, (signed char) byte); + break; + default: +// XXX +//printf ("Write %02x to unknown APU register %02x\n", byte, reg); + break; + } + + KeyOnPrev|=KeyOn; + KeyOn=0; + + if (reg < 0x80) + APU.DSP [reg] = byte; +} + +void S9xFixEnvelope (int channel, uint8 gain, uint8 adsr1, uint8 adsr2) +{ + if (adsr1 & 0x80) + { + // ADSR mode + + // XXX: can DSP be switched to ADSR mode directly from GAIN/INCREASE/ + // DECREASE mode? And if so, what stage of the sequence does it start + // at? + if (S9xSetSoundMode (channel, MODE_ADSR)) + { + S9xSetSoundADSR (channel, adsr1 & 0xf, (adsr1 >> 4) & 7, adsr2 & 0x1f, (adsr2 >> 5) & 7, 8); + } + } + else + { + // Gain mode + if ((gain & 0x80) == 0) + { + if (S9xSetSoundMode (channel, MODE_GAIN)) + { + S9xSetEnvelopeRate (channel, 0, 0, gain & 0x7f, 0); + S9xSetEnvelopeHeight (channel, gain & 0x7f); + } + } + else + { + + if (gain & 0x40) + { + // Increase mode + if (S9xSetSoundMode (channel, (gain & 0x20) ? + MODE_INCREASE_BENT_LINE : + MODE_INCREASE_LINEAR)) + { + S9xSetEnvelopeRate (channel, IncreaseRate [gain & 0x1f], 1, 127, (3<<28)|gain); + } + } + else + { + if(gain & 0x20) { + if (S9xSetSoundMode (channel, MODE_DECREASE_EXPONENTIAL)) + S9xSetEnvelopeRate (channel, DecreaseRateExp [gain & 0x1f] / 2, -1, 0, (4<<28)|gain); + } else { + if (S9xSetSoundMode (channel, MODE_DECREASE_LINEAR)) + S9xSetEnvelopeRate (channel, IncreaseRate [gain & 0x1f], -1, 0, (3<<28)|gain); + } + } + } + } +} + +void S9xSetAPUControl (uint8 byte) +{ +//if (byte & 0x40) +//printf ("*** Special SPC700 timing enabled\n"); + if ((byte & 1) != 0 && !APU.TimerEnabled [0]) + { + APU.Timer [0] = 0; + IAPU.RAM [0xfd] = 0; + if ((APU.TimerTarget [0] = IAPU.RAM [0xfa]) == 0) + APU.TimerTarget [0] = 0x100; + } + if ((byte & 2) != 0 && !APU.TimerEnabled [1]) + { + APU.Timer [1] = 0; + IAPU.RAM [0xfe] = 0; + if ((APU.TimerTarget [1] = IAPU.RAM [0xfb]) == 0) + APU.TimerTarget [1] = 0x100; + } + if ((byte & 4) != 0 && !APU.TimerEnabled [2]) + { + APU.Timer [2] = 0; + IAPU.RAM [0xff] = 0; + if ((APU.TimerTarget [2] = IAPU.RAM [0xfc]) == 0) + APU.TimerTarget [2] = 0x100; + } + APU.TimerEnabled [0] = byte & 1; + APU.TimerEnabled [1] = (byte & 2) >> 1; + APU.TimerEnabled [2] = (byte & 4) >> 2; + + if (byte & 0x10) + IAPU.RAM [0xF4] = IAPU.RAM [0xF5] = 0; + + if (byte & 0x20) + IAPU.RAM [0xF6] = IAPU.RAM [0xF7] = 0; + + if (byte & 0x80) + { + if (!APU.ShowROM) + { + memmove (&IAPU.RAM [0xffc0], APUROM, sizeof (APUROM)); + APU.ShowROM = TRUE; + } + } + else + { + if (APU.ShowROM) + { + APU.ShowROM = FALSE; + memmove (&IAPU.RAM [0xffc0], APU.ExtraRAM, sizeof (APUROM)); + } + } + IAPU.RAM [0xf1] = byte; +} + +void S9xSetAPUTimer (uint16 Address, uint8 byte) +{ + IAPU.RAM [Address] = byte; + + switch (Address) + { + case 0xfa: + if ((APU.TimerTarget [0] = IAPU.RAM [0xfa]) == 0) + APU.TimerTarget [0] = 0x100; + APU.TimerValueWritten [0] = TRUE; + break; + case 0xfb: + if ((APU.TimerTarget [1] = IAPU.RAM [0xfb]) == 0) + APU.TimerTarget [1] = 0x100; + APU.TimerValueWritten [1] = TRUE; + break; + case 0xfc: + if ((APU.TimerTarget [2] = IAPU.RAM [0xfc]) == 0) + APU.TimerTarget [2] = 0x100; + APU.TimerValueWritten [2] = TRUE; + break; + } +} + +uint8 S9xGetAPUDSP () +{ + uint8 reg = IAPU.RAM [0xf2] & 0x7f; + uint8 byte = APU.DSP [reg]; + + switch (reg) + { + case APU_KON: + break; + case APU_KOFF: + break; + case APU_OUTX + 0x00: + case APU_OUTX + 0x10: + case APU_OUTX + 0x20: + case APU_OUTX + 0x30: + case APU_OUTX + 0x40: + case APU_OUTX + 0x50: + case APU_OUTX + 0x60: + case APU_OUTX + 0x70: + if (SoundData.channels [reg >> 4].state == SOUND_SILENT) + return (0); + return ((SoundData.channels [reg >> 4].sample >> 8) | + (SoundData.channels [reg >> 4].sample & 0xff)); + + case APU_ENVX + 0x00: + case APU_ENVX + 0x10: + case APU_ENVX + 0x20: + case APU_ENVX + 0x30: + case APU_ENVX + 0x40: + case APU_ENVX + 0x50: + case APU_ENVX + 0x60: + case APU_ENVX + 0x70: + return 0; +// return ((uint8) S9xGetEnvelopeHeight (reg >> 4)); + + case APU_ENDX: +// To fix speech in Magical Drop 2 6/11/00 +// APU.DSP [APU_ENDX] = 0; + break; + default: + break; + } + return (byte); +} diff --git a/src/snes4iphone_src/apu.h b/src/snes4iphone_src/apu.h new file mode 100755 index 0000000..f64a118 --- /dev/null +++ b/src/snes4iphone_src/apu.h @@ -0,0 +1,192 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#ifndef _apu_h_ +#define _apu_h_ + +#include "spc700.h" + +/* +typedef union +{ + struct { uint8 A, Y; } B; + uint16 W; +} YAndA; +*/ + +struct SIAPU +{ + uint8 *DirectPage; // 0x00 + uint32 Address; // 0x04 c core only + uint8 *WaitAddress1; // 0x08 + uint8 *WaitAddress2; // 0x0C + uint32 WaitCounter; // 0x10 + uint8 *ShadowRAM; // 0x14 + uint8 *CachedSamples; // 0x18 + uint8 _Carry; // 0x1C c core only + uint8 _Overflow; // 0x1D c core only + uint8 Bit; // 0x1E c core only + uint8 pad0; + uint32 TimerErrorCounter; // 0x20 + uint32 Scanline; // 0x24 + int32 OneCycle; // 0x28 + int32 TwoCycles; // 0x2C + // notaz: reordered and moved everything here, for faster context load/save + uint32 *asmJumpTab; // 0x30 + uint8 *PC; // 0x34 + YAndA YA; // 0x38 0x0000YYAA + uint8 P; // 0x3C flags: NODBHIZC + uint8 pad1; + uint8 pad2; + uint8 _Zero; // 0x3F Z=0, when this!=0; also stores neg flag in &0x80 + uint8 X; // 0x40 + uint8 S; // 0x41 stack pointer, default: 0xff + uint16 pad3; + uint8 *RAM; // 0x44 + + uint8 *ExtraRAM; // 0x48 shortcut to APU.ExtraRAM +}; + +struct SAPU +{ + int32 Cycles; + bool8 ShowROM; + uint8 Flags; + uint8 KeyedChannels; + uint8 OutPorts [4]; + uint8 DSP [0x80]; + uint8 ExtraRAM [64]; + uint16 Timer [3]; + uint16 TimerTarget [3]; + bool8 TimerEnabled [3]; + bool8 TimerValueWritten [3]; +}; + +EXTERN_C struct SAPU APU; +EXTERN_C struct SIAPU IAPU; + +STATIC inline void S9xAPUUnpackStatus() +{ + IAPU._Zero =((IAPU.P & Zero) == 0) | (IAPU.P & Negative); + +#ifndef ASM_SPC700 + IAPU._Carry = (IAPU.P & Carry); + IAPU._Overflow = (IAPU.P & Overflow); +#endif +} + +STATIC inline void S9xAPUPackStatus() +{ +#ifdef ASM_SPC700 + IAPU.P &= ~(Zero | Negative); + if(!IAPU._Zero) IAPU.P |= Zero; + if(IAPU._Zero & 0x80) IAPU.P |= Negative; +#else + IAPU.P &= ~(Zero | Negative | Carry | Overflow); + if(IAPU._Carry) IAPU.P |= Carry; + if(!IAPU._Zero) IAPU.P |= Zero; + if(IAPU._Overflow) IAPU.P |= Overflow; + if(IAPU._Zero & 0x80) IAPU.P |= Negative; +#endif +} + +START_EXTERN_C +void S9xResetAPU (void); +bool8 S9xInitAPU (); +void S9xDeinitAPU (); +void S9xDecacheSamples (); +int S9xTraceAPU (); +int S9xAPUOPrint (char *buffer, uint16 Address); +void S9xSetAPUControl (uint8 byte); +void S9xSetAPUDSP (uint8 byte); +uint8 S9xGetAPUDSP (); +void S9xSetAPUTimer (uint16 Address, uint8 byte); +void S9xOpenCloseSoundTracingFile (bool8); +void S9xPrintAPUState (); +extern int32 S9xAPUCycles [256]; // Scaled cycle lengths +extern int32 S9xAPUCycleLengths [256]; // Raw data. +extern void (*S9xApuOpcodes [256]) (void); +extern void (*S9xApuOpcodesReal [256]) (void); +END_EXTERN_C + + +#define APU_VOL_LEFT 0x00 +#define APU_VOL_RIGHT 0x01 +#define APU_P_LOW 0x02 +#define APU_P_HIGH 0x03 +#define APU_SRCN 0x04 +#define APU_ADSR1 0x05 +#define APU_ADSR2 0x06 +#define APU_GAIN 0x07 +#define APU_ENVX 0x08 +#define APU_OUTX 0x09 + +#define APU_MVOL_LEFT 0x0c +#define APU_MVOL_RIGHT 0x1c +#define APU_EVOL_LEFT 0x2c +#define APU_EVOL_RIGHT 0x3c +#define APU_KON 0x4c +#define APU_KOFF 0x5c +#define APU_FLG 0x6c +#define APU_ENDX 0x7c + +#define APU_EFB 0x0d +#define APU_PMON 0x2d +#define APU_NON 0x3d +#define APU_EON 0x4d +#define APU_DIR 0x5d +#define APU_ESA 0x6d +#define APU_EDL 0x7d + +#define APU_C0 0x0f +#define APU_C1 0x1f +#define APU_C2 0x2f +#define APU_C3 0x3f +#define APU_C4 0x4f +#define APU_C5 0x5f +#define APU_C6 0x6f +#define APU_C7 0x7f + +#define APU_SOFT_RESET 0x80 +#define APU_MUTE 0x40 +#define APU_ECHO_DISABLED 0x20 + +#define FREQUENCY_MASK 0x3fff +#endif diff --git a/src/snes4iphone_src/apumem.h b/src/snes4iphone_src/apumem.h new file mode 100755 index 0000000..c4cc165 --- /dev/null +++ b/src/snes4iphone_src/apumem.h @@ -0,0 +1,198 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#ifndef _apumemory_h_ +#define _apumemory_h_ + +START_EXTERN_C +extern uint8 W4; +extern uint8 APUROM[64]; +END_EXTERN_C + +INLINE uint8 S9xAPUGetByteZ (uint8 Address) +{ + if (Address >= 0xf0 && IAPU.DirectPage == IAPU.RAM) + { + if (Address >= 0xf4 && Address <= 0xf7) + { +#ifdef SPC700_SHUTDOWN + IAPU.WaitAddress2 = IAPU.WaitAddress1; + IAPU.WaitAddress1 = IAPU.PC; +#endif + return (IAPU.RAM [Address]); + } + if (Address >= 0xfd) + { +#ifdef SPC700_SHUTDOWN + IAPU.WaitAddress2 = IAPU.WaitAddress1; + IAPU.WaitAddress1 = IAPU.PC; +#endif + uint8 t = IAPU.RAM [Address]; + IAPU.RAM [Address] = 0; + return (t); + } + else + if (Address == 0xf3) + return (S9xGetAPUDSP ()); + + return (IAPU.RAM [Address]); + } + else + return (IAPU.DirectPage [Address]); +} + +INLINE void S9xAPUSetByteZ (uint8 val, uint8 Address) +{ + if (Address >= 0xf0 && IAPU.DirectPage == IAPU.RAM) + { + if (Address == 0xf3) + S9xSetAPUDSP (val); + else + if (Address >= 0xf4 && Address <= 0xf7) + APU.OutPorts [Address - 0xf4] = val; + else + if (Address == 0xf1) + S9xSetAPUControl (val); + else + if (Address < 0xfd) + { + IAPU.RAM [Address] = val; + if (Address >= 0xfa) + { + if (val == 0) + APU.TimerTarget [Address - 0xfa] = 0x100; + else + APU.TimerTarget [Address - 0xfa] = val; + } + } + } + else + IAPU.DirectPage [Address] = val; +} + +INLINE uint8 S9xAPUGetByte (uint32 Address) +{ + Address &= 0xffff; + + if (Address <= 0xff && Address >= 0xf0) + { + if (Address >= 0xf4 && Address <= 0xf7) + { +#ifdef SPC700_SHUTDOWN + IAPU.WaitAddress2 = IAPU.WaitAddress1; + IAPU.WaitAddress1 = IAPU.PC; +#endif + return (IAPU.RAM [Address]); + } + else + if (Address == 0xf3) + return (S9xGetAPUDSP ()); + if (Address >= 0xfd) + { +#ifdef SPC700_SHUTDOWN + IAPU.WaitAddress2 = IAPU.WaitAddress1; + IAPU.WaitAddress1 = IAPU.PC; +#endif + uint8 t = IAPU.RAM [Address]; + IAPU.RAM [Address] = 0; + return (t); + } + return (IAPU.RAM [Address]); + } + else + return (IAPU.RAM [Address]); +} + +INLINE void S9xAPUSetByte (uint8 val, uint32 Address) +{ + Address &= 0xffff; + + if (Address <= 0xff && Address >= 0xf0) + { + if (Address == 0xf3) + S9xSetAPUDSP (val); + else + if (Address >= 0xf4 && Address <= 0xf7) + APU.OutPorts [Address - 0xf4] = val; + else + if (Address == 0xf1) + S9xSetAPUControl (val); + else + if (Address < 0xfd) + { + IAPU.RAM [Address] = val; + if (Address >= 0xfa) + { + if (val == 0) + APU.TimerTarget [Address - 0xfa] = 0x100; + else + APU.TimerTarget [Address - 0xfa] = val; + } + } + } + else + { +#if 0 +if (Address >= 0x2500 && Address <= 0x2504) +printf ("%06d %04x <- %02x\n", ICPU.Scanline, Address, val); +if (Address == 0x26c6) +{ + extern FILE *apu_trace; + extern FILE *trace; + APU.Flags |= TRACE_FLAG; + CPU.Flags |= TRACE_FLAG; + if (apu_trace == NULL) + apu_trace = fopen ("aputrace.log", "wb"); + if (trace == NULL) + trace = fopen ("trace.log", "wb"); + printf ("TRACING SWITCHED ON\n"); +} +#endif + if (Address < 0xffc0) + IAPU.RAM [Address] = val; + else + { + APU.ExtraRAM [Address - 0xffc0] = val; + if (!APU.ShowROM) + IAPU.RAM [Address] = val; + } + } +} +#endif diff --git a/src/snes4iphone_src/asmmemfuncs.h b/src/snes4iphone_src/asmmemfuncs.h new file mode 100755 index 0000000..d6f508c --- /dev/null +++ b/src/snes4iphone_src/asmmemfuncs.h @@ -0,0 +1,206 @@ +#ifndef _ASMMEMFUNCS_H_ +#define _ASMMEMFUNCS_H_ + +#define memset32(_dst, _c, _count) \ +({ uint32_t *dst = (_dst); uint32_t c = (_c); int count = (_count); uint32_t dummy0, dummy1, dummy2; \ + __asm__ __volatile__ ( \ + " cmp %[count], #4\n" \ + " blt 2f\n" \ + " mov %[dummy0], %[c]\n" \ + " tst %[dst], #4\n" \ + " strne %[c], [%[dst]], #4\n" \ + " subne %[count], %[count], #1\n" \ + " tst %[dst], #8\n" \ + " stmneia %[dst]!, {%[dummy0], %[c]}\n" \ + " subne %[count], %[count], #2\n" \ + " mov %[dummy1], %[c]\n" \ + " mov %[dummy2], %[c]\n" \ + "1:\n"\ + " subs %[count], %[count], #4\n" \ + " stmgeia %[dst]!, {%[dummy0], %[dummy1], %[dummy2], %[c]}\n" \ + " bge 1b\n" \ + " add %[count], %[count], #4\n" \ + "2:\n"\ + " subs %[count], %[count], #1\n" \ + " strge %[c], [%[dst]], #4\n" \ + " subs %[count], %[count], #1\n" \ + " strge %[c], [%[dst]], #4\n" \ + " subs %[count], %[count], #1\n" \ + " strge %[c], [%[dst]], #4\n" \ + "\n" \ + : [dst] "+&r" (dst), [count] "+&r" (count), [dummy0] "=&r" (dummy0), [dummy1] "=&r" (dummy1), [dummy2] "=&r" (dummy2), [c] "+&r" (c) \ + : \ + : "cc", "memory" \ + ); _dst; \ +}) + +#define memset16(_dst, _c, _count) \ +({ uint16_t *dst = (_dst); uint16_t c = (_c); int count = (_count); uint32_t dummy0, dummy1, dummy2; \ + __asm__ __volatile__ ( \ + " cmp %[count], #2\n" \ + " blt 3f\n" \ + /* Alignment is known to be at least 16-bit */ \ + " tst %[dst], #2\n" \ + " strneh %[c], [%[dst]], #2\n" \ + " subne %[count], %[count], #1\n" \ + /* Now we are 32-bit aligned (need to upgrade 'c' to 32-bit )*/ \ + " orr %[c], %[c], %[c], asl #16\n" \ + " mov %[dummy0], %[c]\n" \ + " cmp %[count], #8\n" \ + " blt 2f\n" \ + " tst %[dst], #4\n" \ + " strne %[c], [%[dst]], #4\n" \ + " subne %[count], %[count], #2\n" \ + " tst %[dst], #8\n" \ + " stmneia %[dst]!, {%[dummy0], %[c]}\n" \ + " subne %[count], %[count], #4\n" \ + /* Now we are 128-bit aligned */ \ + " mov %[dummy1], %[c]\n" \ + " mov %[dummy2], %[c]\n" \ + "1:\n" /* Copy 4 32-bit values per loop iteration */ \ + " subs %[count], %[count], #8\n" \ + " stmgeia %[dst]!, {%[dummy0], %[dummy1], %[dummy2], %[c]}\n" \ + " bge 1b\n" \ + " add %[count], %[count], #8\n" \ + "2:\n" /* Copy up to 3 remaining 32-bit values */ \ + " tst %[count], #4\n" \ + " stmneia %[dst]!, {%[dummy0], %[c]}\n" \ + " tst %[count], #2\n" \ + " strne %[c], [%[dst]], #4\n" \ + " and %[count], %[count], #1\n" \ + "3:\n" /* Copy up to 1 remaining 16-bit value */ \ + " subs %[count], %[count], #1\n" \ + " strgeh %[c], [%[dst]], #2\n" \ + "\n" \ + : [dst] "+&r" (dst), [count] "+&r" (count), [dummy0] "=&r" (dummy0), [dummy1] "=&r" (dummy1), [dummy2] "=&r" (dummy2), [c] "+&r" (c) \ + : \ + : "cc", "memory" \ + ); _dst;\ +}) + +#define memcpy32(_dst, _src, _count) \ +({ uint32_t *dst = (_dst); uint32_t *src = (_src); int count = (_count); \ + __asm__ __volatile__ ( \ + " cmp %[count], #4\n" \ + " blt 2f\n" \ + " tst %[dst], #4\n" \ + " ldrne r4, [%[src]], #4\n" \ + " strne r4, [%[dst]], #4\n" \ + " subne %[count], %[count], #1\n" \ + " tst %[dst], #8\n" \ + " ldmneia %[src]!, {r4-r5}\n" \ + " stmneia %[dst]!, {r4-r5}\n" \ + " subne %[count], %[count], #2\n" \ + "1:\n" \ + " subs %[count], %[count], #4\n" \ + " ldmgeia %[src]!, {r4-r7}\n" \ + " stmgeia %[dst]!, {r4-r7}\n" \ + " bge 1b\n" \ + " add %[count], %[count], #4\n" \ + "2:\n" \ + " tst %[count], #2\n" \ + " ldmneia %[src]!, {r4-r5}\n" \ + " stmneia %[dst]!, {r4-r5}\n" \ + " tst %[count], #1\n" \ + " ldrne r4, [%[src]], #4\n" \ + " strne r4, [%[dst]], #4\n" \ + "\n" \ + : [dst] "+&r" (dst), [src] "+&r" (src), [count] "+&r" (count) \ + : \ + : "r4", "r5", "r6", "r7", "cc", "memory" \ + ); _dst; \ +}) + +#define memcpy16(_dst, _src, _count) \ +({ uint16_t *dst = (_dst); uint16_t *src = (_src); int count = (_count); uint32_t dummy0; \ + __asm__ __volatile__ ( \ + " cmp %[count], #2\n" \ + " blt 6f\n" \ + /* Alignment is known to be at least 16-bit */ \ + " tst %[dst], #2\n" \ + " ldrneh r4, [%[src]], #2\n" \ + " strneh r4, [%[dst]], #2\n" \ + " subne %[count], %[count], #1\n" \ + /* Now destination address is 32-bit aligned, still need to check whether */ \ + /* source is 32-bit aligned or not */ \ + " tst %[src], #2\n" \ + " bne 3f\n" \ + /* Both destination and source are 32-bit aligned */ \ + " cmp %[count], #8\n" \ + " blt 2f\n" \ + " tst %[dst], #4\n" \ + " ldrne r4, [%[src]], #4\n" \ + " strne r4, [%[dst]], #4\n" \ + " subne %[count], %[count], #2\n" \ + " tst %[dst], #8\n" \ + " ldmneia %[src]!, {r4-r5}\n" \ + " stmneia %[dst]!, {r4-r5}\n" \ + " subne %[count], %[count], #4\n" \ + /* Destination address is 128-bit aligned, source address is 32-bit aligned */ \ + "1: subs %[count], %[count], #8\n" \ + " ldmgeia %[src]!, {r4-r7}\n" \ + " stmgeia %[dst]!, {r4-r7}\n" \ + " bge 1b\n" \ + " add %[count], %[count], #8\n" \ + /* Copy up to 3 remaining aligned 32-bit values */ \ + "2: tst %[count], #4\n" \ + " ldmneia %[src]!, {r4-r5}\n" \ + " stmneia %[dst]!, {r4-r5}\n" \ + " tst %[count], #2\n" \ + " ldrne r4, [%[src]], #4\n" \ + " strne r4, [%[dst]], #4\n" \ + " and %[count], %[count], #1\n" \ + " b 6f\n" \ + /* Destination is 32-bit aligned, but source is only 16-bit aligned */ \ + "3: cmp %[count], #8\n" \ + " blt 5f\n" \ + " tst %[dst], #4\n" \ + " ldrneh r4, [%[src]], #2\n" \ + " ldrneh r5, [%[src]], #2\n" \ + " orrne r4, r4, r5, asl #16\n" \ + " strne r4, [%[dst]], #4\n" \ + " subne %[count], %[count], #2\n" \ + " tst %[dst], #8\n" \ + " ldrneh r4, [%[src]], #2\n" \ + " ldrne r5, [%[src]], #4\n" \ + " ldrneh r6, [%[src]], #2\n" \ + " orrne r4, r4, r5, asl #16\n" \ + " movne r5, r5, lsr #16\n" \ + " orrne r5, r5, r6, asl #16\n" \ + " stmneia %[dst]!, {r4-r5}\n" \ + " subne %[count], %[count], #4\n" \ + /* Destination is 128-bit aligned, but source is only 16-bit aligned */ \ + "4: subs %[count], %[count], #8\n" \ + " ldrgeh r4, [%[src]], #2\n" \ + " ldmgeia %[src]!, {r5-r7}\n" \ + " ldrgeh %[dummy0], [%[src]], #2\n" \ + " orrge r4, r4, r5, asl #16\n" \ + " movge r5, r5, lsr #16\n" \ + " orrge r5, r5, r6, asl #16\n" \ + " movge r6, r6, lsr #16\n" \ + " orrge r6, r6, r7, asl #16\n" \ + " movge r7, r7, lsr #16\n" \ + " orrge r7, r7, %[dummy0], asl #16\n" \ + " stmgeia %[dst]!, {r4-r7}\n" \ + " bge 4b\n" \ + " add %[count], %[count], #8\n" \ + /* Copy up to 6 remaining 16-bit values (to 32-bit aligned destination) */ \ + "5: subs %[count], %[count], #2\n" \ + " ldrgeh r4, [%[src]], #2\n" \ + " ldrgeh r5, [%[src]], #2\n" \ + " orrge r4, r4, r5, asl #16\n" \ + " strge r4, [%[dst]], #4\n" \ + " bge 5b\n" \ + " add %[count], %[count], #2\n" \ + /* Copy the last remaining 16-bit value if any */ \ + "6: subs %[count], %[count], #1\n" \ + " ldrgeh r4, [%[src]], #2\n" \ + " strgeh r4, [%[dst]], #2\n" \ + "\n" \ + : [dst] "+&r" (dst), [src] "+&r" (src), [count] "+&r" (count), [dummy0] "=&r" (dummy0) \ + : \ + : "r4", "r5", "r6", "r7", "cc", "memory" \ + ); _dst; \ +}) + +#endif diff --git a/src/snes4iphone_src/c4.cpp b/src/snes4iphone_src/c4.cpp new file mode 100755 index 0000000..93ab724 --- /dev/null +++ b/src/snes4iphone_src/c4.cpp @@ -0,0 +1,228 @@ +/******************************************************************************* + Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + + (c) Copyright 1996 - 2003 Gary Henderson (gary.henderson@ntlworld.com) and + Jerremy Koot (jkoot@snes9x.com) + + (c) Copyright 2002 - 2003 Matthew Kendora and + Brad Jorsch (anomie@users.sourceforge.net) + + + + C4 x86 assembler and some C emulation code + (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com), + _Demo_ (_demo_@zsnes.com), and + Nach (n-a-c-h@users.sourceforge.net) + + C4 C++ code + (c) Copyright 2003 Brad Jorsch + + DSP-1 emulator code + (c) Copyright 1998 - 2003 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson, + John Weidman (jweidman@slip.net), + neviksti (neviksti@hotmail.com), and + Kris Bleakley (stinkfish@bigpond.com) + + DSP-2 emulator code + (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and + Lord Nightmare (lord_nightmare@users.sourceforge.net + + OBC1 emulator code + (c) Copyright 2001 - 2003 zsKnight, pagefault (pagefault@zsnes.com) + Ported from x86 assembler to C by sanmaiwashi + + SPC7110 and RTC C++ emulator code + (c) Copyright 2002 Matthew Kendora with research by + zsKnight, John Weidman, and Dark Force + + S-RTC C emulator code + (c) Copyright 2001 John Weidman + + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + + Super FX C emulator code + (c) Copyright 1997 - 1999 Ivar and Gary Henderson. + + + + + Specific ports contains the works of other authors. See headers in + individual files. + + Snes9x homepage: http://www.snes9x.com + + Permission to use, copy, modify and distribute Snes9x in both binary and + source form, for non-commercial purposes, is hereby granted without fee, + providing that this license information and copyright notice appear with + all copies and any derived work. + + This software is provided 'as-is', without any express or implied + warranty. In no event shall the authors be held liable for any damages + arising from the use of this software. + + Snes9x is freeware for PERSONAL USE only. Commercial users should + seek permission of the copyright holders first. Commercial use includes + charging money for Snes9x or software derived from Snes9x. + + The copyright holders request that bug fixes and improvements to the code + should be forwarded to them so everyone can benefit from the modifications + in future versions. + + Super NES and Super Nintendo Entertainment System are trademarks of + Nintendo Co., Limited and its subsidiary companies. +*******************************************************************************/ + +#ifndef __GP32__ +#include +#endif + +#include +#include "c4.h" +//#include "memmap.h" + +extern "C" { + +short C4WFXVal; +short C4WFYVal; +short C4WFZVal; +short C4WFX2Val; +short C4WFY2Val; +short C4WFDist; +short C4WFScale; + +static double tanval; +static double c4x, c4y, c4z; +static double c4x2, c4y2, c4z2; + +void C4TransfWireFrame () +{ + c4x = (double) C4WFXVal; + c4y = (double) C4WFYVal; + c4z = (double) C4WFZVal - 0x95; + + // Rotate X + tanval = -(double) C4WFX2Val * 3.14159265 * 2 / 128; + c4y2 = c4y * cos (tanval) - c4z * sin (tanval); + c4z2 = c4y * sin (tanval) + c4z * cos (tanval); + + // Rotate Y + tanval = -(double)C4WFY2Val*3.14159265*2/128; + c4x2 = c4x * cos (tanval) + c4z2 * sin (tanval); + c4z = c4x * - sin (tanval) + c4z2 * cos (tanval); + + // Rotate Z + tanval = -(double) C4WFDist * 3.14159265*2 / 128; + c4x = c4x2 * cos (tanval) - c4y2 * sin (tanval); + c4y = c4x2 * sin (tanval) + c4y2 * cos (tanval); + + // Scale + C4WFXVal = (short) (c4x*(double)C4WFScale/(0x90*(c4z+0x95))*0x95); + C4WFYVal = (short) (c4y*(double)C4WFScale/(0x90*(c4z+0x95))*0x95); +} + +void C4TransfWireFrame2 () +{ + c4x = (double)C4WFXVal; + c4y = (double)C4WFYVal; + c4z = (double)C4WFZVal; + + // Rotate X + tanval = -(double) C4WFX2Val * 3.14159265 * 2 / 128; + c4y2 = c4y * cos (tanval) - c4z * sin (tanval); + c4z2 = c4y * sin (tanval) + c4z * cos (tanval); + + // Rotate Y + tanval = -(double) C4WFY2Val * 3.14159265 * 2 / 128; + c4x2 = c4x * cos (tanval) + c4z2 * sin (tanval); + c4z = c4x * -sin (tanval) + c4z2 * cos (tanval); + + // Rotate Z + tanval = -(double)C4WFDist * 3.14159265 * 2 / 128; + c4x = c4x2 * cos (tanval) - c4y2 * sin (tanval); + c4y = c4x2 * sin (tanval) + c4y2 * cos (tanval); + + // Scale + C4WFXVal =(short)(c4x * (double)C4WFScale / 0x100); + C4WFYVal =(short)(c4y * (double)C4WFScale / 0x100); +} + +void C4CalcWireFrame () +{ + C4WFXVal = C4WFX2Val - C4WFXVal; + C4WFYVal = C4WFY2Val - C4WFYVal; + if (abs (C4WFXVal) > abs (C4WFYVal)) + { + C4WFDist = abs (C4WFXVal) + 1; + C4WFYVal = (short) (256 * (double) C4WFYVal / abs (C4WFXVal)); + if (C4WFXVal < 0) + C4WFXVal = -256; + else + C4WFXVal = 256; + } + else + { + if (C4WFYVal != 0) + { + C4WFDist = abs(C4WFYVal)+1; + C4WFXVal = (short) (256 * (double)C4WFXVal / abs (C4WFYVal)); + if (C4WFYVal < 0) + C4WFYVal = -256; + else + C4WFYVal = 256; + } + else + C4WFDist = 0; + } +} + +short C41FXVal; +short C41FYVal; +short C41FAngleRes; +short C41FDist; +short C41FDistVal; + +void C4Op1F () +{ + if (C41FXVal == 0) + { + if (C41FYVal > 0) + C41FAngleRes = 0x80; + else + C41FAngleRes = 0x180; + } + else + { + tanval = (double) C41FYVal / C41FXVal; + C41FAngleRes = (short) (atan (tanval) / (3.141592675 * 2) * 512); + C41FAngleRes = C41FAngleRes; + if (C41FXVal< 0) + C41FAngleRes += 0x100; + C41FAngleRes &= 0x1FF; + } +} + +void C4Op15() +{ + tanval = sqrt ((double) C41FYVal * C41FYVal + (double) C41FXVal * C41FXVal); + C41FDist = (short) tanval; +} + +void C4Op0D() +{ + tanval = sqrt ((double) C41FYVal * C41FYVal + (double) C41FXVal * C41FXVal); + tanval = C41FDistVal / tanval; + C41FYVal = (short) (C41FYVal * tanval * 0.99); + C41FXVal = (short) (C41FXVal * tanval * 0.98); +} + +#ifdef ZSNES_C4 +void C4LoaDMem(char *C4RAM) +{ + memmove(C4RAM+(READ_WORD(C4RAM+0x1f45)&0x1fff), + S9xGetMemPointer(READ_3WORD(C4RAM+0x1f40)), + READ_WORD(C4RAM+0x1f43)); +} +#endif +}//end extern C + diff --git a/src/snes4iphone_src/c4.h b/src/snes4iphone_src/c4.h new file mode 100755 index 0000000..2bc9919 --- /dev/null +++ b/src/snes4iphone_src/c4.h @@ -0,0 +1,109 @@ +/******************************************************************************* + Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + + (c) Copyright 1996 - 2003 Gary Henderson (gary.henderson@ntlworld.com) and + Jerremy Koot (jkoot@snes9x.com) + + (c) Copyright 2002 - 2003 Matthew Kendora and + Brad Jorsch (anomie@users.sourceforge.net) + + + + C4 x86 assembler and some C emulation code + (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com), + _Demo_ (_demo_@zsnes.com), and + Nach (n-a-c-h@users.sourceforge.net) + + C4 C++ code + (c) Copyright 2003 Brad Jorsch + + DSP-1 emulator code + (c) Copyright 1998 - 2003 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson, + John Weidman (jweidman@slip.net), + neviksti (neviksti@hotmail.com), and + Kris Bleakley (stinkfish@bigpond.com) + + DSP-2 emulator code + (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and + Lord Nightmare (lord_nightmare@users.sourceforge.net + + OBC1 emulator code + (c) Copyright 2001 - 2003 zsKnight, pagefault (pagefault@zsnes.com) + Ported from x86 assembler to C by sanmaiwashi + + SPC7110 and RTC C++ emulator code + (c) Copyright 2002 Matthew Kendora with research by + zsKnight, John Weidman, and Dark Force + + S-RTC C emulator code + (c) Copyright 2001 John Weidman + + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + + Super FX C emulator code + (c) Copyright 1997 - 1999 Ivar and Gary Henderson. + + + + + Specific ports contains the works of other authors. See headers in + individual files. + + Snes9x homepage: http://www.snes9x.com + + Permission to use, copy, modify and distribute Snes9x in both binary and + source form, for non-commercial purposes, is hereby granted without fee, + providing that this license information and copyright notice appear with + all copies and any derived work. + + This software is provided 'as-is', without any express or implied + warranty. In no event shall the authors be held liable for any damages + arising from the use of this software. + + Snes9x is freeware for PERSONAL USE only. Commercial users should + seek permission of the copyright holders first. Commercial use includes + charging money for Snes9x or software derived from Snes9x. + + The copyright holders request that bug fixes and improvements to the code + should be forwarded to them so everyone can benefit from the modifications + in future versions. + + Super NES and Super Nintendo Entertainment System are trademarks of + Nintendo Co., Limited and its subsidiary companies. +*******************************************************************************/ +#ifndef _C4_H_ +#define _C4_H_ + +#include "port.h" + +extern "C" { + +extern int16 C4WFXVal; +extern int16 C4WFYVal; +extern int16 C4WFZVal; +extern int16 C4WFX2Val; +extern int16 C4WFY2Val; +extern int16 C4WFDist; +extern int16 C4WFScale; + +void C4TransfWireFrame(); +void C4TransfWireFrame2(); +void C4CalcWireFrame(); + +extern int16 C41FXVal; +extern int16 C41FYVal; +extern int16 C41FAngleRes; +extern int16 C41FDist; +extern int16 C41FDistVal; + +void C4Op1F(); +void C4Op15(); +void C4Op0D(); + +extern int16 C4CosTable[]; +extern int16 C4SinTable[]; + +} + +#endif diff --git a/src/snes4iphone_src/c4emu.cpp b/src/snes4iphone_src/c4emu.cpp new file mode 100755 index 0000000..7d0095e --- /dev/null +++ b/src/snes4iphone_src/c4emu.cpp @@ -0,0 +1,1007 @@ +/******************************************************************************* + Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + + (c) Copyright 1996 - 2003 Gary Henderson (gary.henderson@ntlworld.com) and + Jerremy Koot (jkoot@snes9x.com) + + (c) Copyright 2002 - 2003 Matthew Kendora and + Brad Jorsch (anomie@users.sourceforge.net) + + + + C4 x86 assembler and some C emulation code + (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com), + _Demo_ (_demo_@zsnes.com), and + Nach (n-a-c-h@users.sourceforge.net) + + C4 C++ code + (c) Copyright 2003 Brad Jorsch + + DSP-1 emulator code + (c) Copyright 1998 - 2003 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson, + John Weidman (jweidman@slip.net), + neviksti (neviksti@hotmail.com), and + Kris Bleakley (stinkfish@bigpond.com) + + DSP-2 emulator code + (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and + Lord Nightmare (lord_nightmare@users.sourceforge.net + + OBC1 emulator code + (c) Copyright 2001 - 2003 zsKnight, pagefault (pagefault@zsnes.com) + Ported from x86 assembler to C by sanmaiwashi + + SPC7110 and RTC C++ emulator code + (c) Copyright 2002 Matthew Kendora with research by + zsKnight, John Weidman, and Dark Force + + S-RTC C emulator code + (c) Copyright 2001 John Weidman + + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + + Super FX C emulator code + (c) Copyright 1997 - 1999 Ivar and Gary Henderson. + + + + + Specific ports contains the works of other authors. See headers in + individual files. + + Snes9x homepage: http://www.snes9x.com + + Permission to use, copy, modify and distribute Snes9x in both binary and + source form, for non-commercial purposes, is hereby granted without fee, + providing that this license information and copyright notice appear with + all copies and any derived work. + + This software is provided 'as-is', without any express or implied + warranty. In no event shall the authors be held liable for any damages + arising from the use of this software. + + Snes9x is freeware for PERSONAL USE only. Commercial users should + seek permission of the copyright holders first. Commercial use includes + charging money for Snes9x or software derived from Snes9x. + + The copyright holders request that bug fixes and improvements to the code + should be forwarded to them so everyone can benefit from the modifications + in future versions. + + Super NES and Super Nintendo Entertainment System are trademarks of + Nintendo Co., Limited and its subsidiary companies. +*******************************************************************************/ + +#ifndef __GP32__ +#ifdef HAVE_CONFIG_H + #include +#endif +#endif + +#include +#include "snes9x.h" +#include "sar.h" +#include "memmap.h" +#include "ppu.h" +#include "c4.h" + +void S9xInitC4 () +{ + // Stupid zsnes code, we can't do the logical thing without breaking + // savestates +// Memory.C4RAM = &Memory.FillRAM [0x6000]; + memset(Memory.C4RAM, 0, 0x2000); +} + +uint8 S9xGetC4 (uint16 Address) +{ +#ifdef DEBUGGER + if(Settings.BGLayering) printf("%02x from %04x\n", Memory.C4RAM[Address-0x6000], Address); +#endif + if(Address==0x7f5e) return 0; + return (Memory.C4RAM [Address-0x6000]); +} + +static uint8 C4TestPattern [12 * 4] = +{ + 0x00, 0x00, 0x00, 0xff, + 0xff, 0xff, 0x00, 0xff, + 0x00, 0x00, 0x00, 0xff, + 0xff, 0xff, 0x00, 0x00, + 0xff, 0xff, 0x00, 0x00, + 0x80, 0xff, 0xff, 0x7f, + 0x00, 0x80, 0x00, 0xff, + 0x7f, 0x00, 0xff, 0x7f, + 0xff, 0x7f, 0xff, 0xff, + 0x00, 0x00, 0x01, 0xff, + 0xff, 0xfe, 0x00, 0x01, + 0x00, 0xff, 0xfe, 0x00 +}; + + +static void C4ConvOAM(void){ + uint8 *OAMptr=Memory.C4RAM+(Memory.C4RAM[0x626]<<2); + for(uint8 *i=Memory.C4RAM+0x1fd; i>OAMptr; i-=4){ + // Clear OAM-to-be + *i=0xe0; + } + + uint16 globalX, globalY; + uint8 *OAMptr2; + int16 SprX, SprY; + uint8 SprName, SprAttr; + uint8 SprCount; + + globalX=READ_WORD(Memory.C4RAM+0x0621); + globalY=READ_WORD(Memory.C4RAM+0x0623); + OAMptr2=Memory.C4RAM+0x200+(Memory.C4RAM[0x626]>>2); + +#ifdef DEBUGGER + if(Memory.C4RAM[0x625]!=0) printf("$6625=%02x, expected 00\n", Memory.C4RAM[0x625]); + if((Memory.C4RAM[0x626]>>2)!=Memory.C4RAM[0x629]) printf("$6629=%02x, expected %02x\n", Memory.C4RAM[0x629], (Memory.C4RAM[0x626]>>2)); + if(((uint16)Memory.C4RAM[0x626]<<2)!=READ_WORD(Memory.C4RAM+0x627)) printf("$6627=%04x, expected %04x\n", READ_WORD(Memory.C4RAM+0x627), ((uint16)Memory.C4RAM[0x626]<<2)); +#endif + + if(Memory.C4RAM[0x0620]!=0){ + SprCount=128-Memory.C4RAM[0x626]; + uint8 offset=(Memory.C4RAM[0x626]&3)*2; + uint8 *srcptr=Memory.C4RAM+0x220; + for(int i=Memory.C4RAM[0x0620]; i>0 && SprCount>0; i--, srcptr+=16){ + SprX=READ_WORD(srcptr)-globalX; + SprY=READ_WORD(srcptr+2)-globalY; + SprName=srcptr[5]; + SprAttr=srcptr[4] | srcptr[0x06]; // XXX: mask bits? + + uint8 *sprptr=S9xGetMemPointer(READ_3WORD(srcptr+7)); + if(*sprptr!=0){ + int16 X, Y; + for(int SprCnt=*sprptr++; SprCnt>0 && SprCount>0; SprCnt--, sprptr+=4){ + X=(int8)sprptr[1]; + if(SprAttr&0x40){ // flip X + X=-X-((sprptr[0]&0x20)?16:8); + } + X+=SprX; + if(X>=-16 && X<=272){ + Y=(int8)sprptr[2]; + if(SprAttr&0x80){ + Y=-Y-((sprptr[0]&0x20)?16:8); + } + Y+=SprY; + if(Y>=-16 && Y<=224){ + OAMptr[0]=X&0xff; + OAMptr[1]=(uint8)Y; + OAMptr[2]=SprName+sprptr[3]; + OAMptr[3]=SprAttr^(sprptr[0]&0xc0); // XXX: Carry from SprName addition? + *OAMptr2 &= ~(3<0){ + OAMptr[0]=(uint8)SprX; + OAMptr[1]=(uint8)SprY; + OAMptr[2]=SprName; + OAMptr[3]=SprAttr; + *OAMptr2 &= ~(3<>12)>=w || (Y>>12)>=h){ + byte=0; + } else { + uint32 addr=(Y>>12)*w+(X>>12); + byte=Memory.C4RAM[0x600+(addr>>1)]; + if(addr&1) byte>>=4; + } + + // De-bitplanify + if(byte&1) Memory.C4RAM[outidx]|=bit; + if(byte&2) Memory.C4RAM[outidx+1]|=bit; + if(byte&4) Memory.C4RAM[outidx+16]|=bit; + if(byte&8) Memory.C4RAM[outidx+17]|=bit; + + bit>>=1; + if(bit==0){ + bit=0x80; + outidx+=32; + } + + X+=A; // Add 1 to output x => add an A and a C + Y+=C; + } + outidx+=2+row_padding; + if(outidx&0x10){ + outidx&=~0x10; + } else { + outidx-=w*4+row_padding; + } + LineX+=B; // Add 1 to output y => add a B and a D + LineY+=D; + } +} + +static void C4DrawLine(int32 X1, int32 Y1, int16 Z1, + int32 X2, int32 Y2, int16 Z2, uint8 Color){ + // Transform coordinates + C4WFXVal=(short)X1; + C4WFYVal=(short)Y1; + C4WFZVal=Z1; + C4WFScale=Memory.C4RAM[0x1f90]; + C4WFX2Val=Memory.C4RAM[0x1f86]; + C4WFY2Val=Memory.C4RAM[0x1f87]; + C4WFDist=Memory.C4RAM[0x1f88]; + C4TransfWireFrame2(); + X1=(C4WFXVal+48)<<8; + Y1=(C4WFYVal+48)<<8; + + C4WFXVal=(short)X2; + C4WFYVal=(short)Y2; + C4WFZVal=Z2; + C4TransfWireFrame2(); + X2=(C4WFXVal+48)<<8; + Y2=(C4WFYVal+48)<<8; + + // get line info + C4WFXVal=(short)(X1>>8); + C4WFYVal=(short)(Y1>>8); + C4WFX2Val=(short)(X2>>8); + C4WFY2Val=(short)(Y2>>8); + C4CalcWireFrame(); + X2=(int16)C4WFXVal; + Y2=(int16)C4WFYVal; + + // render line + for(int i=C4WFDist?C4WFDist:1; i>0; i--) + { //.loop + if(X1>0xff && Y1>0xff && X1<0x6000 && Y1<0x6000) + { + uint16 addr=((X1&~0x7ff) + (Y1&~0x7ff)*12 + (Y1&0x700))>>7; + addr=(((Y1>>8)>>3)<<8)-(((Y1>>8)>>3)<<6)+(((X1>>8)>>3)<<4)+((Y1>>8)&7)*2; + uint8 bit=0x80>>((X1>>8)&7); + Memory.C4RAM[addr+0x300]&=~bit; + Memory.C4RAM[addr+0x301]&=~bit; + if(Color&1) Memory.C4RAM[addr+0x300]|=bit; + if(Color&2) Memory.C4RAM[addr+0x301]|=bit; + } + X1+=X2; + Y1+=Y2; + } +} + +static void C4DrawWireFrame(void) +{ + uint8 *line=S9xGetMemPointer(READ_3WORD(Memory.C4RAM+0x1f80)); + uint8 *point1, *point2; + int16 X1, Y1, Z1; + int16 X2, Y2, Z2; + uint8 Color; + +#ifdef DEBUGGER + if(READ_3WORD(Memory.C4RAM+0x1f8f)&0xff00ff) printf("wireframe: Unexpected value in $7f8f: %06x\n", READ_3WORD(Memory.C4RAM+0x1f8f)); + if(READ_3WORD(Memory.C4RAM+0x1fa4)!=0x001000) printf("wireframe: Unexpected value in $7fa4: %06x\n", READ_3WORD(Memory.C4RAM+0x1fa4)); +#endif + + for(int i=Memory.C4RAM[0x0295]; i>0; i--, line+=5){ + if(line[0]==0xff && line[1]==0xff){ + uint8 *tmp=line-5; + while(line[2]==0xff && line[3]==0xff) tmp-=5; + point1=S9xGetMemPointer((Memory.C4RAM[0x1f82]<<16) | (tmp[2]<<8) | tmp[3]); + } else { + point1=S9xGetMemPointer((Memory.C4RAM[0x1f82]<<16) | (line[0]<<8) | line[1]); + } + point2=S9xGetMemPointer((Memory.C4RAM[0x1f82]<<16) | (line[2]<<8) | line[3]); + + X1=(point1[0]<<8) | point1[1]; + Y1=(point1[2]<<8) | point1[3]; + Z1=(point1[4]<<8) | point1[5]; + X2=(point2[0]<<8) | point2[1]; + Y2=(point2[2]<<8) | point2[3]; + Z2=(point2[4]<<8) | point2[5]; + Color=line[4]; + C4DrawLine(X1, Y1, Z1, X2, Y2, Z2, Color); + } +} + +static void C4TransformLines(void){ + C4WFX2Val=Memory.C4RAM[0x1f83]; + C4WFY2Val=Memory.C4RAM[0x1f86]; + C4WFDist=Memory.C4RAM[0x1f89]; + C4WFScale=Memory.C4RAM[0x1f8c]; + +#ifdef DEBUGGER + if(Memory.C4RAM[0x1f8a]!=0x90) printf("lines: $7f8a = %02x, expected 90\n", READ_WORD(Memory.C4RAM+0x1f8a)); +#endif + + // transform vertices + uint8 *ptr=Memory.C4RAM; + { + for(int i=READ_WORD(Memory.C4RAM+0x1f80); i>0; i--, ptr+=0x10) + { + C4WFXVal=READ_WORD(ptr+1); + C4WFYVal=READ_WORD(ptr+5); + C4WFZVal=READ_WORD(ptr+9); + C4TransfWireFrame(); + + // displace + WRITE_WORD(ptr+1, C4WFXVal+0x80); + WRITE_WORD(ptr+5, C4WFYVal+0x50); + } + } + WRITE_WORD(Memory.C4RAM+0x600, 23); + WRITE_WORD(Memory.C4RAM+0x602, 0x60); + WRITE_WORD(Memory.C4RAM+0x605, 0x40); + WRITE_WORD(Memory.C4RAM+0x600+8, 23); + WRITE_WORD(Memory.C4RAM+0x602+8, 0x60); + WRITE_WORD(Memory.C4RAM+0x605+8, 0x40); + + ptr=Memory.C4RAM+0xb02; + uint8 *ptr2=Memory.C4RAM; + { + for(int i=READ_WORD(Memory.C4RAM+0xb00); i>0; i--, ptr+=2, ptr2+=8) + { + C4WFXVal=READ_WORD(Memory.C4RAM+(ptr[0]<<4)+1); + C4WFYVal=READ_WORD(Memory.C4RAM+(ptr[0]<<4)+5); + C4WFX2Val=READ_WORD(Memory.C4RAM+(ptr[1]<<4)+1); + C4WFY2Val=READ_WORD(Memory.C4RAM+(ptr[1]<<4)+5); + C4CalcWireFrame(); + WRITE_WORD(ptr2+0x600, C4WFDist?C4WFDist:1); + WRITE_WORD(ptr2+0x602, C4WFXVal); + WRITE_WORD(ptr2+0x605, C4WFYVal); + } + } +} +static void C4BitPlaneWave(){ + static uint16 bmpdata[]={ + 0x0000, 0x0002, 0x0004, 0x0006, 0x0008, 0x000A, 0x000C, 0x000E, + 0x0200, 0x0202, 0x0204, 0x0206, 0x0208, 0x020A, 0x020C, 0x020E, + 0x0400, 0x0402, 0x0404, 0x0406, 0x0408, 0x040A, 0x040C, 0x040E, + 0x0600, 0x0602, 0x0604, 0x0606, 0x0608, 0x060A, 0x060C, 0x060E, + 0x0800, 0x0802, 0x0804, 0x0806, 0x0808, 0x080A, 0x080C, 0x080E + }; + + uint8 *dst=Memory.C4RAM; + uint32 waveptr=Memory.C4RAM[0x1f83]; + uint16 mask1=0xc0c0; + uint16 mask2=0x3f3f; + +#ifdef DEBUGGER + if(READ_3WORD(Memory.C4RAM+0x1f80) != Memory.C4RAM[waveptr+0xb00]) printf("$7f80=%06x, expected %02x\n", READ_3WORD(Memory.C4RAM+0x1f80), Memory.C4RAM[waveptr+0xb00]); +#endif + + for(int j=0; j<0x10; j++){ + do { + int16 height=-((int8)Memory.C4RAM[waveptr+0xb00])-16; + for(int i=0; i<40; i++){ + uint16 tmp=READ_WORD(dst+bmpdata[i]) & mask2; + if(height>=0){ + if(height<8){ + tmp|=mask1&READ_WORD(Memory.C4RAM+0xa00+height*2); + } else { + tmp|=mask1&0xff00; + } + } + WRITE_WORD(dst+bmpdata[i], tmp); + height++; + } + waveptr=(waveptr+1)&0x7f; + mask1=(mask1>>2)|(mask1<<6); + mask2=(mask2>>2)|(mask2<<6); + } while(mask1!=0xc0c0); + dst+=16; + + do { + int16 height=-((int8)Memory.C4RAM[waveptr+0xb00])-16; + for(int i=0; i<40; i++){ + uint16 tmp=READ_WORD(dst+bmpdata[i]) & mask2; + if(height>=0){ + if(height<8){ + tmp|=mask1&READ_WORD(Memory.C4RAM+0xa10+height*2); + } else { + tmp|=mask1&0xff00; + } + } + WRITE_WORD(dst+bmpdata[i], tmp); + height++; + } + waveptr=(waveptr+1)&0x7f; + mask1=(mask1>>2)|(mask1<<6); + mask2=(mask2>>2)|(mask2<<6); + } while(mask1!=0xc0c0); + dst+=16; + } +} + +static void C4SprDisintegrate() +{ + uint8 width, height; + uint32 StartX, StartY; + uint8 *src; + int32 scaleX, scaleY; + int32 Cx, Cy; + + width=Memory.C4RAM[0x1f89]; + height=Memory.C4RAM[0x1f8c]; + Cx=(int16)READ_WORD(Memory.C4RAM+0x1f80); + Cy=(int16)READ_WORD(Memory.C4RAM+0x1f83); + +#ifdef DEBUGGER + if((Cx&~1)!=width/2 || (Cy&~1)!=height/2) printf("Center is not middle of image for disintegrate! (%d, %d) != (%d, %d)\n", Cx, Cy, width/2, height/2); +#endif + + scaleX=(int16)READ_WORD(Memory.C4RAM+0x1f86); + scaleY=(int16)READ_WORD(Memory.C4RAM+0x1f8f); + StartX=-Cx*scaleX+(Cx<<8); + StartY=-Cy*scaleY+(Cy<<8); + src=Memory.C4RAM+0x600; + + memset(Memory.C4RAM, 0, width*height/2); + + for(uint32 y=StartY, i=0; i>8)>8)>8)*width+(x>>8)<0x2000) + { + uint8 pixel=(j&1)?(*src>>4):*src; + int idx=(y>>11)*width*4+(x>>11)*32+((y>>8)&7)*2; + uint8 mask=0x80>>((x>>8)&7); + if(pixel&1) Memory.C4RAM[idx]|=mask; + if(pixel&2) Memory.C4RAM[idx+1]|=mask; + if(pixel&4) Memory.C4RAM[idx+16]|=mask; + if(pixel&8) Memory.C4RAM[idx+17]|=mask; + } + if(j&1) src++; + } + } +} + +static void S9xC4ProcessSprites() +{ + switch(Memory.C4RAM[0x1f4d]) + { + case 0x00: // Build OAM +#ifdef DEBUGGER +// printf("00 00 Build OAM!\n"); +#endif + C4ConvOAM(); + break; + + case 0x03: // Scale/Rotate +#ifdef DEBUGGER +// printf("00 03 Scale/Rotate!\n"); +#endif + C4DoScaleRotate(0); + break; + + case 0x05: // Transform Lines +#ifdef DEBUGGER +// printf("00 05 Transform Lines!\n"); +#endif + C4TransformLines(); + break; + + case 0x07: // Scale/Rotate +#ifdef DEBUGGER +// printf("00 07 Scale/Rotate!\n"); +#endif + C4DoScaleRotate(64); + break; + + case 0x08: // Draw wireframe +#ifdef DEBUGGER +// printf("00 08 Draw wireframe!\n"); +#endif + C4DrawWireFrame(); + break; + + case 0x0b: // Disintegrate +#ifdef DEBUGGER + printf("00 0b Disintegrate!\n"); +#endif + C4SprDisintegrate(); + break; + + case 0x0c: // Wave +#ifdef DEBUGGER +// printf("00 0b Wave!\n"); +#endif + C4BitPlaneWave(); + break; + + default: +#ifdef DEBUGGER + printf ("Unknown C4 sprite command (%02x)\n", Memory.C4RAM [0x1f4d]); +#endif + break; + } +} + +void S9xSetC4 (uint8 byte, uint16 Address) +{ + int i; + +#ifdef DEBUGGER + if(Settings.BGLayering) printf("%02x to %04x\n", byte, Address); +#endif + Memory.C4RAM [Address-0x6000] = byte; + if (Address == 0x7f4f) + { + if(Memory.C4RAM[0x1f4d]==0x0e && byte<0x40 && (byte&3)==0) + { +#ifdef DEBUGGER + printf("Test command %02x 0e used!\n", byte); +#endif + Memory.C4RAM[0x1f80]=byte>>2; + } + else + { + switch (byte) + { + case 0x00: // Sprite + S9xC4ProcessSprites(); + break; + + case 0x01: // Draw wireframe +#ifdef DEBUGGER + //printf("01 Draw wireframe used!\n"); + if(Memory.C4RAM[0x1f4d]!=8) printf("$7f4d=%02x, expected 08 for command 01 %02x\n", Memory.C4RAM[0x1f4d], Memory.C4RAM[0x1f4d]); +#endif + memset(Memory.C4RAM+0x300, 0, 16*12*3*4); + C4DrawWireFrame(); + break; + + case 0x05: // Propulsion (?) +#ifdef DEBUGGER + printf("05 Propulsion (?)!\n"); + if(Memory.C4RAM[0x1f4d]!=2) printf("$7f4d=%02x, expected 02 for command 05 %02x\n", Memory.C4RAM[0x1f4d], Memory.C4RAM[0x1f4d]); +#endif + { + int32 tmp=0x10000; + if(READ_WORD(Memory.C4RAM+0x1f83)){ + tmp=SAR((tmp/READ_WORD(Memory.C4RAM+0x1f83))*READ_WORD(Memory.C4RAM+0x1f81), 8); + } + WRITE_WORD(Memory.C4RAM+0x1f80, (uint16)tmp); + } + break; + + case 0x0d: // Set vector length +#ifdef DEBUGGER + printf("0d Set vector length!\n"); + if(Memory.C4RAM[0x1f4d]!=2) printf("$7f4d=%02x, expected 02 for command 0d %02x\n", Memory.C4RAM[0x1f4d], Memory.C4RAM[0x1f4d]); +#endif + C41FXVal=READ_WORD(Memory.C4RAM+0x1f80); + C41FYVal=READ_WORD(Memory.C4RAM+0x1f83); + C41FDistVal=READ_WORD(Memory.C4RAM+0x1f86); + C4Op0D(); + WRITE_WORD(Memory.C4RAM+0x1f89, C41FXVal); + WRITE_WORD(Memory.C4RAM+0x1f8c, C41FYVal); + break; + + case 0x10: // Polar to rectangluar +#ifdef DEBUGGER +// printf("10 Polar->Rect!\n"); + if(Memory.C4RAM[0x1f4d]!=2) printf("$7f4d=%02x, expected 02 for command 10 %02x\n", Memory.C4RAM[0x1f4d], Memory.C4RAM[0x1f4d]); +#endif + { + int32 tmp=SAR((int32)READ_WORD(Memory.C4RAM+0x1f83)*C4CosTable[READ_WORD(Memory.C4RAM+0x1f80)&0x1ff]*2, 16); + WRITE_3WORD(Memory.C4RAM+0x1f86, tmp); + tmp=SAR((int32)READ_WORD(Memory.C4RAM+0x1f83)*C4SinTable[READ_WORD(Memory.C4RAM+0x1f80)&0x1ff]*2, 16); + WRITE_3WORD(Memory.C4RAM+0x1f89, (tmp-SAR(tmp, 6))); + } + break; + + case 0x13: // Polar to rectangluar +#ifdef DEBUGGER +// printf("13 Polar->Rect!\n"); + if(Memory.C4RAM[0x1f4d]!=2) printf("$7f4d=%02x, expected 02 for command 13 %02x\n", Memory.C4RAM[0x1f4d], Memory.C4RAM[0x1f4d]); +#endif + { + int32 tmp=SAR((int32)READ_WORD(Memory.C4RAM+0x1f83)*C4CosTable[READ_WORD(Memory.C4RAM+0x1f80)&0x1ff]*2, 8); + WRITE_3WORD(Memory.C4RAM+0x1f86, tmp); + tmp=SAR((int32)READ_WORD(Memory.C4RAM+0x1f83)*C4SinTable[READ_WORD(Memory.C4RAM+0x1f80)&0x1ff]*2, 8); + WRITE_3WORD(Memory.C4RAM+0x1f89, tmp); + } + break; + + case 0x15: // Pythagorean +#ifdef DEBUGGER + printf("15 Pythagorean!\n"); + if(Memory.C4RAM[0x1f4d]!=2) printf("$7f4d=%02x, expected 02 for command 15 %02x\n", Memory.C4RAM[0x1f4d], Memory.C4RAM[0x1f4d]); +#endif + C41FXVal=READ_WORD(Memory.C4RAM+0x1f80); + C41FYVal=READ_WORD(Memory.C4RAM+0x1f83); + C41FDist=(int16)sqrt((double)C41FXVal*C41FXVal + (double)C41FYVal*C41FYVal); + WRITE_WORD(Memory.C4RAM+0x1f80, C41FDist); + break; + + case 0x1f: // atan +#ifdef DEBUGGER +// printf("1f atan!\n"); + if(Memory.C4RAM[0x1f4d]!=2) printf("$7f4d=%02x, expected 02 for command 1f %02x\n", Memory.C4RAM[0x1f4d], Memory.C4RAM[0x1f4d]); +#endif + C41FXVal=READ_WORD(Memory.C4RAM+0x1f80); + C41FYVal=READ_WORD(Memory.C4RAM+0x1f83); + C4Op1F(); + WRITE_WORD(Memory.C4RAM+0x1f86, C41FAngleRes); + break; + + case 0x22: // Trapezoid + { +#ifdef DEBUGGER +// printf("22 Trapezoid!\n"); + if(Memory.C4RAM[0x1f4d]!=2) printf("$7f4d=%02x, expected 02 for command 22 %02x\n", Memory.C4RAM[0x1f4d], Memory.C4RAM[0x1f4d]); +#endif + int16 angle1=READ_WORD(Memory.C4RAM+0x1f8c)&0x1ff; + int16 angle2=READ_WORD(Memory.C4RAM+0x1f8f)&0x1ff; +#ifdef DEBUGGER + if(C4CosTable[angle1]==0) fprintf(stderr, "22 Trapezoid: Invalid tangent! angle1=%d\n", angle1); + if(C4CosTable[angle2]==0) fprintf(stderr, "22 Trapezoid: Invalid tangent! angle2=%d\n", angle2); +#endif + int32 tan1=(C4CosTable[angle1]!=0)?((((int32)C4SinTable[angle1])<<16)/C4CosTable[angle1]):0x80000000; + int32 tan2=(C4CosTable[angle2]!=0)?((((int32)C4SinTable[angle2])<<16)/C4CosTable[angle2]):0x80000000; + int16 y = READ_WORD(Memory.C4RAM+0x1f83) - READ_WORD(Memory.C4RAM+0x1f89); + int16 left, right; + for(int j=0; j<225; j++) + { + if(y>=0) + { + left = SAR((int32)tan1*y, 16) - + READ_WORD(Memory.C4RAM+0x1f80) + + READ_WORD(Memory.C4RAM+0x1f86); + right = SAR((int32)tan2*y, 16) - + READ_WORD(Memory.C4RAM+0x1f80) + + READ_WORD(Memory.C4RAM+0x1f86) + + READ_WORD(Memory.C4RAM+0x1f93); + + if(left<0 && right<0){ + left=1; + right=0; + } else if(left<0){ + left=0; + } else if(right<0){ + right=0; + } + if(left>255 && right>255){ + left=255; + right=254; + } else if(left>255){ + left=255; + } else if(right>255){ + right=255; + } + } + else + { + left=1; + right=0; + } + Memory.C4RAM[j+0x800] = (uint8)left; + Memory.C4RAM[j+0x900] = (uint8)right; + y++; + } + } + break; + + case 0x25: // Multiply +#ifdef DEBUGGER + printf("25 Multiply!\n"); + if(Memory.C4RAM[0x1f4d]!=2) printf("$7f4d=%02x, expected 02 for command 25 %02x\n", Memory.C4RAM[0x1f4d], Memory.C4RAM[0x1f4d]); +#endif + { + int32 foo=READ_3WORD(Memory.C4RAM+0x1f80); + int32 bar=READ_3WORD(Memory.C4RAM+0x1f83); + foo*=bar; + WRITE_3WORD(Memory.C4RAM+0x1f80, foo); + } + break; + + case 0x2d: // Transform Coords +#ifdef DEBUGGER +// printf("2d Transform Coords!\n"); + if(Memory.C4RAM[0x1f4d]!=2) printf("$7f4d=%02x, expected 02 for command 2d %02x\n", Memory.C4RAM[0x1f4d], Memory.C4RAM[0x1f4d]); + if(READ_3WORD(Memory.C4RAM+0x1f8f)&0xff00ff) printf("2d transform coords: Unexpected value in $7f8f: %06x\n", READ_3WORD(Memory.C4RAM+0x1f8f)); + if(READ_3WORD(Memory.C4RAM+0x1f8c)!=0x001000) printf("0d transform coords: Unexpected value in $7f8c: %06x\n", READ_3WORD(Memory.C4RAM+0x1f8c)); +#endif + C4WFXVal=READ_WORD(Memory.C4RAM+0x1f81); + C4WFYVal=READ_WORD(Memory.C4RAM+0x1f84); + C4WFZVal=READ_WORD(Memory.C4RAM+0x1f87); + C4WFX2Val=Memory.C4RAM[0x1f89]; + C4WFY2Val=Memory.C4RAM[0x1f8a]; + C4WFDist=Memory.C4RAM[0x1f8b]; + C4WFScale=READ_WORD(Memory.C4RAM+0x1f90); + C4TransfWireFrame2(); + WRITE_WORD(Memory.C4RAM+0x1f80, C4WFXVal); + WRITE_WORD(Memory.C4RAM+0x1f83, C4WFYVal); + break; + + case 0x40: // Sum +#ifdef DEBUGGER + printf("40 Sum!\n"); + if(Memory.C4RAM[0x1f4d]!=0x0e) printf("$7f4d=%02x, expected 0e for command 40 %02x\n", Memory.C4RAM[0x1f4d], Memory.C4RAM[0x1f4d]); +#endif + { + uint16 sum=0; + for(int i=0; i<0x800; sum+=Memory.C4RAM[i++]); + WRITE_WORD(Memory.C4RAM+0x1f80, sum); + } + break; + + case 0x54: // Square +#ifdef DEBUGGER + printf("54 Square!\n"); + if(Memory.C4RAM[0x1f4d]!=0x0e) printf("$7f4d=%02x, expected 0e for command 54 %02x\n", Memory.C4RAM[0x1f4d], Memory.C4RAM[0x1f4d]); +#endif + { + int64 a=SAR((int64)READ_3WORD(Memory.C4RAM+0x1f80)<<40, 40); + // printf("%08X%08X\n", (uint32)(a>>32), (uint32)(a&0xFFFFFFFF)); + a*=a; + // printf("%08X%08X\n", (uint32)(a>>32), (uint32)(a&0xFFFFFFFF)); + WRITE_3WORD(Memory.C4RAM+0x1f83, a); + WRITE_3WORD(Memory.C4RAM+0x1f86, (a>>24)); + } + break; + + case 0x5c: // Immediate Reg +#ifdef DEBUGGER + printf("5c Immediate Reg!\n"); + if(Memory.C4RAM[0x1f4d]!=0x0e) printf("$7f4d=%02x, expected 0e for command 5c %02x\n", Memory.C4RAM[0x1f4d], Memory.C4RAM[0x1f4d]); +#endif + for (i = 0; i < 12 * 4; i++) + Memory.C4RAM [i] = C4TestPattern [i]; + break; + + case 0x89: // Immediate ROM +#ifdef DEBUGGER + printf("89 Immediate ROM!\n"); + if(Memory.C4RAM[0x1f4d]!=0x0e) printf("$7f4d=%02x, expected 0e for command 89 %02x\n", Memory.C4RAM[0x1f4d], Memory.C4RAM[0x1f4d]); +#endif + Memory.C4RAM [0x1f80] = 0x36; + Memory.C4RAM [0x1f81] = 0x43; + Memory.C4RAM [0x1f82] = 0x05; + break; + + default: +#ifdef DEBUGGER + printf ("Unknown C4 command (%02x)\n", byte); +#endif + break; + } + } + } else if (Address == 0x7f47) { +#ifdef DEBUGGER +// printf("C4 load memory %06x => %04x, %04x bytes\n", READ_3WORD(Memory.C4RAM+0x1f40), READ_WORD(Memory.C4RAM+0x1f45), READ_WORD(Memory.C4RAM+0x1f43)); + if(byte != 0) printf("C4 load: non-0 written to $7f47! Wrote %02x\n", byte); + if(READ_WORD(Memory.C4RAM+0x1f45) < 0x6000 || (READ_WORD(Memory.C4RAM+0x1f45) + READ_WORD(Memory.C4RAM+0x1f43)) > 0x6c00) printf("C4 load: Dest unusual! It's %04x\n", READ_WORD(Memory.C4RAM+0x1f45)); +#endif + memmove(Memory.C4RAM+(READ_WORD(Memory.C4RAM+0x1f45)&0x1fff), + S9xGetMemPointer(READ_3WORD(Memory.C4RAM+0x1f40)), + READ_WORD(Memory.C4RAM+0x1f43)); + } +} + +int16 C4SinTable[512] = { + 0, 402, 804, 1206, 1607, 2009, 2410, 2811, + 3211, 3611, 4011, 4409, 4808, 5205, 5602, 5997, + 6392, 6786, 7179, 7571, 7961, 8351, 8739, 9126, + 9512, 9896, 10278, 10659, 11039, 11416, 11793, 12167, + 12539, 12910, 13278, 13645, 14010, 14372, 14732, 15090, + 15446, 15800, 16151, 16499, 16846, 17189, 17530, 17869, + 18204, 18537, 18868, 19195, 19519, 19841, 20159, 20475, + 20787, 21097, 21403, 21706, 22005, 22301, 22594, 22884, + 23170, 23453, 23732, 24007, 24279, 24547, 24812, 25073, + 25330, 25583, 25832, 26077, 26319, 26557, 26790, 27020, + 27245, 27466, 27684, 27897, 28106, 28310, 28511, 28707, + 28898, 29086, 29269, 29447, 29621, 29791, 29956, 30117, + 30273, 30425, 30572, 30714, 30852, 30985, 31114, 31237, + 31357, 31471, 31581, 31685, 31785, 31881, 31971, 32057, + 32138, 32214, 32285, 32351, 32413, 32469, 32521, 32568, + 32610, 32647, 32679, 32706, 32728, 32745, 32758, 32765, + 32767, 32765, 32758, 32745, 32728, 32706, 32679, 32647, + 32610, 32568, 32521, 32469, 32413, 32351, 32285, 32214, + 32138, 32057, 31971, 31881, 31785, 31685, 31581, 31471, + 31357, 31237, 31114, 30985, 30852, 30714, 30572, 30425, + 30273, 30117, 29956, 29791, 29621, 29447, 29269, 29086, + 28898, 28707, 28511, 28310, 28106, 27897, 27684, 27466, + 27245, 27020, 26790, 26557, 26319, 26077, 25832, 25583, + 25330, 25073, 24812, 24547, 24279, 24007, 23732, 23453, + 23170, 22884, 22594, 22301, 22005, 21706, 21403, 21097, + 20787, 20475, 20159, 19841, 19519, 19195, 18868, 18537, + 18204, 17869, 17530, 17189, 16846, 16499, 16151, 15800, + 15446, 15090, 14732, 14372, 14010, 13645, 13278, 12910, + 12539, 12167, 11793, 11416, 11039, 10659, 10278, 9896, + 9512, 9126, 8739, 8351, 7961, 7571, 7179, 6786, + 6392, 5997, 5602, 5205, 4808, 4409, 4011, 3611, + 3211, 2811, 2410, 2009, 1607, 1206, 804, 402, + 0, -402, -804, -1206, -1607, -2009, -2410, -2811, + -3211, -3611, -4011, -4409, -4808, -5205, -5602, -5997, + -6392, -6786, -7179, -7571, -7961, -8351, -8739, -9126, + -9512, -9896, -10278, -10659, -11039, -11416, -11793, -12167, + -12539, -12910, -13278, -13645, -14010, -14372, -14732, -15090, + -15446, -15800, -16151, -16499, -16846, -17189, -17530, -17869, + -18204, -18537, -18868, -19195, -19519, -19841, -20159, -20475, + -20787, -21097, -21403, -21706, -22005, -22301, -22594, -22884, + -23170, -23453, -23732, -24007, -24279, -24547, -24812, -25073, + -25330, -25583, -25832, -26077, -26319, -26557, -26790, -27020, + -27245, -27466, -27684, -27897, -28106, -28310, -28511, -28707, + -28898, -29086, -29269, -29447, -29621, -29791, -29956, -30117, + -30273, -30425, -30572, -30714, -30852, -30985, -31114, -31237, + -31357, -31471, -31581, -31685, -31785, -31881, -31971, -32057, + -32138, -32214, -32285, -32351, -32413, -32469, -32521, -32568, + -32610, -32647, -32679, -32706, -32728, -32745, -32758, -32765, + -32767, -32765, -32758, -32745, -32728, -32706, -32679, -32647, + -32610, -32568, -32521, -32469, -32413, -32351, -32285, -32214, + -32138, -32057, -31971, -31881, -31785, -31685, -31581, -31471, + -31357, -31237, -31114, -30985, -30852, -30714, -30572, -30425, + -30273, -30117, -29956, -29791, -29621, -29447, -29269, -29086, + -28898, -28707, -28511, -28310, -28106, -27897, -27684, -27466, + -27245, -27020, -26790, -26557, -26319, -26077, -25832, -25583, + -25330, -25073, -24812, -24547, -24279, -24007, -23732, -23453, + -23170, -22884, -22594, -22301, -22005, -21706, -21403, -21097, + -20787, -20475, -20159, -19841, -19519, -19195, -18868, -18537, + -18204, -17869, -17530, -17189, -16846, -16499, -16151, -15800, + -15446, -15090, -14732, -14372, -14010, -13645, -13278, -12910, + -12539, -12167, -11793, -11416, -11039, -10659, -10278, -9896, + -9512, -9126, -8739, -8351, -7961, -7571, -7179, -6786, + -6392, -5997, -5602, -5205, -4808, -4409, -4011, -3611, + -3211, -2811, -2410, -2009, -1607, -1206, -804, -402 +}; + +int16 C4CosTable[512] = { + 32767, 32765, 32758, 32745, 32728, 32706, 32679, 32647, + 32610, 32568, 32521, 32469, 32413, 32351, 32285, 32214, + 32138, 32057, 31971, 31881, 31785, 31685, 31581, 31471, + 31357, 31237, 31114, 30985, 30852, 30714, 30572, 30425, + 30273, 30117, 29956, 29791, 29621, 29447, 29269, 29086, + 28898, 28707, 28511, 28310, 28106, 27897, 27684, 27466, + 27245, 27020, 26790, 26557, 26319, 26077, 25832, 25583, + 25330, 25073, 24812, 24547, 24279, 24007, 23732, 23453, + 23170, 22884, 22594, 22301, 22005, 21706, 21403, 21097, + 20787, 20475, 20159, 19841, 19519, 19195, 18868, 18537, + 18204, 17869, 17530, 17189, 16846, 16499, 16151, 15800, + 15446, 15090, 14732, 14372, 14010, 13645, 13278, 12910, + 12539, 12167, 11793, 11416, 11039, 10659, 10278, 9896, + 9512, 9126, 8739, 8351, 7961, 7571, 7179, 6786, + 6392, 5997, 5602, 5205, 4808, 4409, 4011, 3611, + 3211, 2811, 2410, 2009, 1607, 1206, 804, 402, + 0, -402, -804, -1206, -1607, -2009, -2410, -2811, + -3211, -3611, -4011, -4409, -4808, -5205, -5602, -5997, + -6392, -6786, -7179, -7571, -7961, -8351, -8739, -9126, + -9512, -9896, -10278, -10659, -11039, -11416, -11793, -12167, + -12539, -12910, -13278, -13645, -14010, -14372, -14732, -15090, + -15446, -15800, -16151, -16499, -16846, -17189, -17530, -17869, + -18204, -18537, -18868, -19195, -19519, -19841, -20159, -20475, + -20787, -21097, -21403, -21706, -22005, -22301, -22594, -22884, + -23170, -23453, -23732, -24007, -24279, -24547, -24812, -25073, + -25330, -25583, -25832, -26077, -26319, -26557, -26790, -27020, + -27245, -27466, -27684, -27897, -28106, -28310, -28511, -28707, + -28898, -29086, -29269, -29447, -29621, -29791, -29956, -30117, + -30273, -30425, -30572, -30714, -30852, -30985, -31114, -31237, + -31357, -31471, -31581, -31685, -31785, -31881, -31971, -32057, + -32138, -32214, -32285, -32351, -32413, -32469, -32521, -32568, + -32610, -32647, -32679, -32706, -32728, -32745, -32758, -32765, + -32767, -32765, -32758, -32745, -32728, -32706, -32679, -32647, + -32610, -32568, -32521, -32469, -32413, -32351, -32285, -32214, + -32138, -32057, -31971, -31881, -31785, -31685, -31581, -31471, + -31357, -31237, -31114, -30985, -30852, -30714, -30572, -30425, + -30273, -30117, -29956, -29791, -29621, -29447, -29269, -29086, + -28898, -28707, -28511, -28310, -28106, -27897, -27684, -27466, + -27245, -27020, -26790, -26557, -26319, -26077, -25832, -25583, + -25330, -25073, -24812, -24547, -24279, -24007, -23732, -23453, + -23170, -22884, -22594, -22301, -22005, -21706, -21403, -21097, + -20787, -20475, -20159, -19841, -19519, -19195, -18868, -18537, + -18204, -17869, -17530, -17189, -16846, -16499, -16151, -15800, + -15446, -15090, -14732, -14372, -14010, -13645, -13278, -12910, + -12539, -12167, -11793, -11416, -11039, -10659, -10278, -9896, + -9512, -9126, -8739, -8351, -7961, -7571, -7179, -6786, + -6392, -5997, -5602, -5205, -4808, -4409, -4011, -3611, + -3211, -2811, -2410, -2009, -1607, -1206, -804, -402, + 0, 402, 804, 1206, 1607, 2009, 2410, 2811, + 3211, 3611, 4011, 4409, 4808, 5205, 5602, 5997, + 6392, 6786, 7179, 7571, 7961, 8351, 8739, 9126, + 9512, 9896, 10278, 10659, 11039, 11416, 11793, 12167, + 12539, 12910, 13278, 13645, 14010, 14372, 14732, 15090, + 15446, 15800, 16151, 16499, 16846, 17189, 17530, 17869, + 18204, 18537, 18868, 19195, 19519, 19841, 20159, 20475, + 20787, 21097, 21403, 21706, 22005, 22301, 22594, 22884, + 23170, 23453, 23732, 24007, 24279, 24547, 24812, 25073, + 25330, 25583, 25832, 26077, 26319, 26557, 26790, 27020, + 27245, 27466, 27684, 27897, 28106, 28310, 28511, 28707, + 28898, 29086, 29269, 29447, 29621, 29791, 29956, 30117, + 30273, 30425, 30572, 30714, 30852, 30985, 31114, 31237, + 31357, 31471, 31581, 31685, 31785, 31881, 31971, 32057, + 32138, 32214, 32285, 32351, 32413, 32469, 32521, 32568, + 32610, 32647, 32679, 32706, 32728, 32745, 32758, 32765 +}; diff --git a/src/snes4iphone_src/cheats.cpp b/src/snes4iphone_src/cheats.cpp new file mode 100755 index 0000000..966e0b9 --- /dev/null +++ b/src/snes4iphone_src/cheats.cpp @@ -0,0 +1,391 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#include +#include +#include +#include "snes9x.h" +#include "cheats.h" +#include "memmap.h" + +static bool8 S9xAllHex (const char *code, int len) +{ + for (int i = 0; i < len; i++) + if ((code [i] < '0' || code [i] > '9') && + (code [i] < 'a' || code [i] > 'f') && + (code [i] < 'A' || code [i] > 'F')) + return (FALSE); + + return (TRUE); +} + +const char *S9xProActionReplayToRaw (const char *code, uint32 &address, uint8 &byte) +{ + uint32 data = 0; + if (strlen (code) != 8 || !S9xAllHex (code, 8) || + sscanf (code, "%x", &data) != 1) + return ("Invalid Pro Action Replay code - should be 8 hex digits in length."); + + address = data >> 8; + byte = (uint8) data; + return (NULL); +} + +const char *S9xGoldFingerToRaw (const char *code, uint32 &address, bool8 &sram, + uint8 &num_bytes, uint8 bytes[3]) +{ + char tmp [15]; + if (strlen (code) != 14) + return ("Invalid Gold Finger code should be 14 hex digits in length."); + + strncpy (tmp, code, 5); + tmp [5] = 0; + if (sscanf (tmp, "%x", &address) != 1) + return ("Invalid Gold Finger code."); + + int i; + for (i = 0; i < 3; i++) + { + strncpy (tmp, code + 5 + i * 2, 2); + tmp [2] = 0; + int byte; + if (sscanf (tmp, "%x", &byte) != 1) + break; + bytes [i] = (uint8) byte; + } + num_bytes = i; + sram = code [13] == '1'; + return (NULL); +} + +const char *S9xGameGenieToRaw (const char *code, uint32 &address, uint8 &byte) +{ + char new_code [12]; + + if (strlen (code) != 9 || *(code + 4) != '-' || !S9xAllHex (code, 4) || + !S9xAllHex (code + 5, 4)) + return ("Invalid Game Genie(tm) code - should be 'xxxx-xxxx'."); + + strcpy (new_code, "0x"); + strncpy (new_code + 2, code, 4); + strcpy (new_code + 6, code + 5); + + static char *real_hex = "0123456789ABCDEF"; + static char *genie_hex = "DF4709156BC8A23E"; + + for (int i = 2; i < 10; i++) + { + if (islower (new_code [i])) + new_code [i] = toupper (new_code [i]); + int j; + for (j = 0; j < 16; j++) + { + if (new_code [i] == genie_hex [j]) + { + new_code [i] = real_hex [j]; + break; + } + } + if (j == 16) + return ("Invalid hex-character in Game Genie(tm) code"); + } + uint32 data = 0; + sscanf (new_code, "%x", &data); + byte = (uint8)(data >> 24); + address = data & 0xffffff; + address = ((address & 0x003c00) << 10) + + ((address & 0x00003c) << 14) + + ((address & 0xf00000) >> 8) + + ((address & 0x000003) << 10) + + ((address & 0x00c000) >> 6) + + ((address & 0x0f0000) >> 12) + + ((address & 0x0003c0) >> 6); + + return (NULL); +} + +void S9xStartCheatSearch (SCheatData *d) +{ + memmove (d->CWRAM, d->RAM, 0x20000); + memmove (d->CSRAM, d->SRAM, 0x10000); + memmove (d->CIRAM, &d->FillRAM [0x3000], 0x2000); + memset ((char *) d->WRAM_BITS, 0xff, 0x20000 >> 3); + memset ((char *) d->SRAM_BITS, 0xff, 0x10000 >> 3); + memset ((char *) d->IRAM_BITS, 0xff, 0x2000 >> 3); +} + +#define BIT_CLEAR(a,v) \ +(a)[(v) >> 5] &= ~(1 << ((v) & 31)) + +#define BIT_SET(a,v) \ +(a)[(v) >> 5] |= 1 << ((v) & 31) + +#define TEST_BIT(a,v) \ +((a)[(v) >> 5] & (1 << ((v) & 31))) + +#define _C(c,a,b) \ +((c) == S9X_LESS_THAN ? (a) < (b) : \ + (c) == S9X_GREATER_THAN ? (a) > (b) : \ + (c) == S9X_LESS_THAN_OR_EQUAL ? (a) <= (b) : \ + (c) == S9X_GREATER_THAN_OR_EQUAL ? (a) >= (b) : \ + (c) == S9X_EQUAL ? (a) == (b) : \ + (a) != (b)) + +#define _D(s,m,o) \ +((s) == S9X_8_BITS ? (uint8) (*((m) + (o))) : \ + (s) == S9X_16_BITS ? ((uint16) (*((m) + (o)) + (*((m) + (o) + 1) << 8))) : \ + (s) == S9X_24_BITS ? ((uint32) (*((m) + (o)) + (*((m) + (o) + 1) << 8) + (*((m) + (o) + 2) << 16))) : \ +((uint32) (*((m) + (o)) + (*((m) + (o) + 1) << 8) + (*((m) + (o) + 2) << 16) + (*((m) + (o) + 3) << 24)))) + +#define _DS(s,m,o) \ +((s) == S9X_8_BITS ? ((int8) *((m) + (o))) : \ + (s) == S9X_16_BITS ? ((int16) (*((m) + (o)) + (*((m) + (o) + 1) << 8))) : \ + (s) == S9X_24_BITS ? (((int32) ((*((m) + (o)) + (*((m) + (o) + 1) << 8) + (*((m) + (o) + 2) << 16)) << 8)) >> 8): \ + ((int32) (*((m) + (o)) + (*((m) + (o) + 1) << 8) + (*((m) + (o) + 2) << 16) + (*((m) + (o) + 3) << 24)))) + +void S9xSearchForChange (SCheatData *d, S9xCheatComparisonType cmp, + S9xCheatDataSize size, bool8 is_signed, bool8 update) +{ + int l; + + switch (size) + { + case S9X_8_BITS: l = 0; break; + case S9X_16_BITS: l = 1; break; + case S9X_24_BITS: l = 2; break; + default: + case S9X_32_BITS: l = 3; break; + } + + int i; + if (is_signed) + { + for (i = 0; i < 0x20000 - l; i++) + { + if (TEST_BIT (d->WRAM_BITS, i) && + _C(cmp, _DS(size, d->RAM, i), _DS(size, d->CWRAM, i))) + { + if (update) + d->CWRAM [i] = d->RAM [i]; + } + else + BIT_CLEAR (d->WRAM_BITS, i); + } + + for (i = 0; i < 0x10000 - l; i++) + { + if (TEST_BIT (d->SRAM_BITS, i) && + _C(cmp, _DS(size, d->SRAM, i), _DS(size, d->CSRAM, i))) + { + if (update) + d->CSRAM [i] = d->SRAM [i]; + } + else + BIT_CLEAR (d->SRAM_BITS, i); + } + + for (i = 0; i < 0x2000 - l; i++) + { + if (TEST_BIT (d->IRAM_BITS, i) && + _C(cmp, _DS(size, d->FillRAM + 0x3000, i), _DS(size, d->CIRAM, i))) + { + if (update) + d->CIRAM [i] = d->FillRAM [i + 0x3000]; + } + else + BIT_CLEAR (d->IRAM_BITS, i); + } + } + else + { + for (i = 0; i < 0x20000 - l; i++) + { + if (TEST_BIT (d->WRAM_BITS, i) && + _C(cmp, _D(size, d->RAM, i), _D(size, d->CWRAM, i))) + { + if (update) + d->CWRAM [i] = d->RAM [i]; + } + else + BIT_CLEAR (d->WRAM_BITS, i); + } + + for (i = 0; i < 0x10000 - l; i++) + { + if (TEST_BIT (d->SRAM_BITS, i) && + _C(cmp, _D(size, d->SRAM, i), _D(size, d->CSRAM, i))) + { + if (update) + d->CSRAM [i] = d->SRAM [i]; + } + else + BIT_CLEAR (d->SRAM_BITS, i); + } + + for (i = 0; i < 0x2000 - l; i++) + { + if (TEST_BIT (d->IRAM_BITS, i) && + _C(cmp, _D(size, d->FillRAM + 0x3000, i), _D(size, d->CIRAM, i))) + { + if (update) + d->CIRAM [i] = d->FillRAM [i + 0x3000]; + } + else + BIT_CLEAR (d->IRAM_BITS, i); + } + } +} + +void S9xSearchForValue (SCheatData *d, S9xCheatComparisonType cmp, + S9xCheatDataSize size, uint32 value, + bool8 is_signed, bool8 update) +{ + int l; + + switch (size) + { + case S9X_8_BITS: l = 0; break; + case S9X_16_BITS: l = 1; break; + case S9X_24_BITS: l = 2; break; + default: + case S9X_32_BITS: l = 3; break; + } + + int i; + + if (is_signed) + { + for (i = 0; i < 0x20000 - l; i++) + { + if (TEST_BIT (d->WRAM_BITS, i) && + _C(cmp, _DS(size, d->RAM, i), (int32) value)) + { + if (update) + d->CWRAM [i] = d->RAM [i]; + } + else + BIT_CLEAR (d->WRAM_BITS, i); + } + + for (i = 0; i < 0x10000 - l; i++) + { + if (TEST_BIT (d->SRAM_BITS, i) && + _C(cmp, _DS(size, d->SRAM, i), (int32) value)) + { + if (update) + d->CSRAM [i] = d->SRAM [i]; + } + else + BIT_CLEAR (d->SRAM_BITS, i); + } + + for (i = 0; i < 0x2000 - l; i++) + { + if (TEST_BIT (d->IRAM_BITS, i) && + _C(cmp, _DS(size, d->FillRAM + 0x3000, i), (int32) value)) + { + if (update) + d->CIRAM [i] = d->FillRAM [i + 0x3000]; + } + else + BIT_CLEAR (d->IRAM_BITS, i); + } + } + else + { + for (i = 0; i < 0x20000 - l; i++) + { + if (TEST_BIT (d->WRAM_BITS, i) && + _C(cmp, _D(size, d->RAM, i), value)) + { + if (update) + d->CWRAM [i] = d->RAM [i]; + } + else + BIT_CLEAR (d->WRAM_BITS, i); + } + + for (i = 0; i < 0x10000 - l; i++) + { + if (TEST_BIT (d->SRAM_BITS, i) && + _C(cmp, _D(size, d->SRAM, i), value)) + { + if (update) + d->CSRAM [i] = d->SRAM [i]; + } + else + BIT_CLEAR (d->SRAM_BITS, i); + } + + for (i = 0; i < 0x2000 - l; i++) + { + if (TEST_BIT (d->IRAM_BITS, i) && + _C(cmp, _D(size, d->FillRAM + 0x3000, i), value)) + { + if (update) + d->CIRAM [i] = d->FillRAM [i + 0x3000]; + } + else + BIT_CLEAR (d->IRAM_BITS, i); + } + } +} + +void S9xOutputCheatSearchResults (SCheatData *d) +{ + int i; + for (i = 0; i < 0x20000; i++) + { + if (TEST_BIT (d->WRAM_BITS, i)) + printf ("WRAM: %05x: %02x\n", i, d->RAM [i]); + } + + for (i = 0; i < 0x10000; i++) + { + if (TEST_BIT (d->SRAM_BITS, i)) + printf ("SRAM: %04x: %02x\n", i, d->SRAM [i]); + } + + for (i = 0; i < 0x2000; i++) + { + if (TEST_BIT (d->IRAM_BITS, i)) + printf ("IRAM: %05x: %02x\n", i, d->FillRAM [i + 0x3000]); + } +} diff --git a/src/snes4iphone_src/cheats.h b/src/snes4iphone_src/cheats.h new file mode 100755 index 0000000..0ac09ec --- /dev/null +++ b/src/snes4iphone_src/cheats.h @@ -0,0 +1,109 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#ifndef _CHEATS_H_ +#define _CHEATS_H_ + +struct SCheat +{ + uint32 address; + uint8 byte; + uint8 saved_byte; + bool8 enabled; + bool8 saved; + char name [22]; +}; + +#define MAX_CHEATS 75 + +struct SCheatData +{ + struct SCheat c [MAX_CHEATS]; + uint32 num_cheats; + uint8 CWRAM [0x20000]; + uint8 CSRAM [0x10000]; + uint8 CIRAM [0x2000]; + uint8 *RAM; + uint8 *FillRAM; + uint8 *SRAM; + uint32 WRAM_BITS [0x20000 >> 3]; + uint32 SRAM_BITS [0x10000 >> 3]; + uint32 IRAM_BITS [0x2000 >> 3]; +}; + +typedef enum +{ + S9X_LESS_THAN, S9X_GREATER_THAN, S9X_LESS_THAN_OR_EQUAL, + S9X_GREATER_THAN_OR_EQUAL, S9X_EQUAL, S9X_NOT_EQUAL +} S9xCheatComparisonType; + +typedef enum +{ + S9X_8_BITS, S9X_16_BITS, S9X_24_BITS, S9X_32_BITS +} S9xCheatDataSize; + +void S9xInitCheatData (); + +const char *S9xGameGenieToRaw (const char *code, uint32 &address, uint8 &byte); +const char *S9xProActionReplayToRaw (const char *code, uint32 &address, uint8 &byte); +const char *S9xGoldFingerToRaw (const char *code, uint32 &address, bool8 &sram, + uint8 &num_bytes, uint8 bytes[3]); +void S9xApplyCheats (); +void S9xApplyCheat (uint32 which1); +void S9xRemoveCheats (); +void S9xRemoveCheat (uint32 which1); +void S9xEnableCheat (uint32 which1); +void S9xDisableCheat (uint32 which1); +void S9xAddCheat (bool8 enable, bool8 save_current_value, uint32 address, + uint8 byte); +void S9xDeleteCheats (); +void S9xDeleteCheat (uint32 which1); +bool8 S9xLoadCheatFile (const char *filename); +bool8 S9xSaveCheatFile (const char *filename); + +void S9xStartCheatSearch (SCheatData *); +void S9xSearchForChange (SCheatData *, S9xCheatComparisonType cmp, + S9xCheatDataSize size, bool8 is_signed, bool8 update); +void S9xSearchForValue (SCheatData *, S9xCheatComparisonType cmp, + S9xCheatDataSize size, uint32 value, + bool8 is_signed, bool8 update); +void S9xOutputCheatSearchResults (SCheatData *); + +#endif diff --git a/src/snes4iphone_src/cheats2.cpp b/src/snes4iphone_src/cheats2.cpp new file mode 100755 index 0000000..1805a34 --- /dev/null +++ b/src/snes4iphone_src/cheats2.cpp @@ -0,0 +1,232 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#include +#include +#include +#include "snes9x.h" +#include "cheats.h" +#include "memmap.h" + +extern SCheatData Cheat; + +void S9xInitCheatData () +{ + Cheat.RAM = Memory.RAM; + Cheat.SRAM = ::SRAM; + Cheat.FillRAM = Memory.FillRAM; +} + +void S9xAddCheat (bool8 enable, bool8 save_current_value, + uint32 address, uint8 byte) +{ + if (Cheat.num_cheats < sizeof (Cheat.c) / sizeof (Cheat. c [0])) + { + Cheat.c [Cheat.num_cheats].address = address; + Cheat.c [Cheat.num_cheats].byte = byte; + Cheat.c [Cheat.num_cheats].enabled = TRUE; + if (save_current_value) + { + Cheat.c [Cheat.num_cheats].saved_byte = S9xGetByte (address); + Cheat.c [Cheat.num_cheats].saved = TRUE; + } + Cheat.num_cheats++; + } +} + +void S9xDeleteCheat (uint32 which1) +{ + if (which1 < Cheat.num_cheats) + { + if (Cheat.c [which1].enabled) + S9xRemoveCheat (which1); + + memmove (&Cheat.c [which1], &Cheat.c [which1 + 1], + sizeof (Cheat.c [0]) * (Cheat.num_cheats - which1 - 1)); + Cheat.num_cheats = 0; + } +} + +void S9xDeleteCheats () +{ + S9xRemoveCheats (); + Cheat.num_cheats = 0; +} + +void S9xEnableCheat (uint32 which1) +{ + if (which1 < Cheat.num_cheats && !Cheat.c [which1].enabled) + { + Cheat.c [which1].enabled = TRUE; + S9xApplyCheat (which1); + } +} + +void S9xDisableCheat (uint32 which1) +{ + if (which1 < Cheat.num_cheats && Cheat.c [which1].enabled) + { + S9xRemoveCheat (which1); + Cheat.c [which1].enabled = FALSE; + } +} + +void S9xRemoveCheat (uint32 which1) +{ + if (Cheat.c [which1].saved) + { + uint32 address = Cheat.c [which1].address; + + int block = (address >> MEMMAP_SHIFT) & MEMMAP_MASK; + uint8 *ptr = Memory.Map [block]; + + if (ptr >= (uint8 *) CMemory::MAP_LAST) + *(ptr + (address & 0xffff)) = Cheat.c [which1].saved_byte; + else + S9xSetByte (address, Cheat.c [which1].saved_byte); + } +} + +void S9xApplyCheat (uint32 which1) +{ + uint32 address = Cheat.c [which1].address; + + if (!Cheat.c [which1].saved) + Cheat.c [which1].saved_byte = S9xGetByte (address); + + int block = (address >> MEMMAP_SHIFT) & MEMMAP_MASK; + uint8 *ptr = Memory.Map [block]; + + if (ptr >= (uint8 *) CMemory::MAP_LAST) + *(ptr + (address & 0xffff)) = Cheat.c [which1].byte; + else + S9xSetByte (address, Cheat.c [which1].byte); + Cheat.c [which1].saved = TRUE; +} + +void S9xApplyCheats () +{ + if (Settings.ApplyCheats) + { + for (uint32 i = 0; i < Cheat.num_cheats; i++) + if (Cheat.c [i].enabled) + S9xApplyCheat (i); + } +} + +void S9xRemoveCheats () +{ + for (uint32 i = 0; i < Cheat.num_cheats; i++) + if (Cheat.c [i].enabled) + S9xRemoveCheat (i); +} + +bool8 S9xLoadCheatFile (const char *filename) +{ + Cheat.num_cheats = 0; + + FILE *fs = fopen (filename, "rb"); + uint8 data [28]; + + if (!fs) + return (FALSE); + + while (fread ((void *) data, 1, 28, fs) == 28) + { + Cheat.c [Cheat.num_cheats].enabled = (data [0] & 4) == 0; + Cheat.c [Cheat.num_cheats].byte = data [1]; + Cheat.c [Cheat.num_cheats].address = data [2] | (data [3] << 8) | (data [4] << 16); + Cheat.c [Cheat.num_cheats].saved_byte = data [5]; + Cheat.c [Cheat.num_cheats].saved = (data [0] & 8) != 0; + memmove (Cheat.c [Cheat.num_cheats].name, &data [8], 20); + Cheat.c [Cheat.num_cheats++].name [20] = 0; + } + fclose (fs); + + return (TRUE); +} + +bool8 S9xSaveCheatFile (const char *filename) +{ + if (Cheat.num_cheats == 0) + { +#ifndef _SNESPPC + (void) remove (filename); +#endif + return (TRUE); + } + + FILE *fs = fopen (filename, "wb"); + uint8 data [28]; + + if (!fs) + return (FALSE); + + uint32 i; + for (i = 0; i < Cheat.num_cheats; i++) + { + memset (data, 0, 28); + if (i == 0) + { + data [6] = 254; + data [7] = 252; + } + if (!Cheat.c [i].enabled) + data [0] |= 4; + + if (Cheat.c [i].saved) + data [0] |= 8; + + data [1] = Cheat.c [i].byte; + data [2] = (uint8) Cheat.c [i].address; + data [3] = (uint8) (Cheat.c [i].address >> 8); + data [4] = (uint8) (Cheat.c [i].address >> 16); + data [5] = Cheat.c [i].saved_byte; + + memmove (&data [8], Cheat.c [i].name, 19); + if (fwrite (data, 28, 1, fs) != 1) + { + fclose (fs); + return (FALSE); + } + } + return (fclose (fs) == 0); +} + diff --git a/src/snes4iphone_src/clip.cpp b/src/snes4iphone_src/clip.cpp new file mode 100755 index 0000000..2c4ddac --- /dev/null +++ b/src/snes4iphone_src/clip.cpp @@ -0,0 +1,727 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#include + +#include "snes9x.h" +#include "memmap.h" +#include "ppu.h" + +struct Band +{ + uint32 Left; + uint32 Right; +}; + +#undef MIN +#undef MAX +#define MIN(A,B) ((A) < (B) ? (A) : (B)) +#define MAX(A,B) ((A) > (B) ? (A) : (B)) +#define BAND_EMPTY(B) (B.Left >= B.Right) +#define BANDS_INTERSECT(A,B) ((A.Left >= B.Left && A.Left < B.Right) || \ + (A.Right > B.Left && A.Right <= B.Right)) +#define OR_BANDS(R,A,B) {\ + R.Left = MIN(A.Left, B.Left); \ + R.Right = MAX(A.Right, B.Right);} + +#define AND_BANDS(R,A,B) {\ + R.Left = MAX(A.Left, B.Left); \ + R.Right = MIN(A.Right, B.Right);} + +#if !defined(_SNESPPC) || defined(__IPHONE__) +static int IntCompare (const void *d1, const void *d2) +#else +static int _cdecl IntCompare (const void *d1, const void *d2) +#endif +{ + if (*(uint32 *) d1 > *(uint32 *) d2) + return (1); + else + if (*(uint32 *) d1 < *(uint32 *) d2) + return (-1); + return (0); +} + +#if !defined(_SNESPPC) || defined(__IPHONE__) +static int BandCompare (const void *d1, const void *d2) +#else +static int _cdecl BandCompare (const void *d1, const void *d2) +#endif +{ + if (((struct Band *) d1)->Left > ((struct Band *) d2)->Left) + return (1); + else + if (((struct Band *) d1)->Left < ((struct Band *) d2)->Left) + return (-1); + return (0); +} + +void ComputeClipWindows () +{ + struct ClipData *pClip = &IPPU.Clip [0]; + + // Loop around the main screen then the sub-screen. + for (int c = 0; c < 2; c++, pClip++) + { + // Loop around the colour window then a clip window for each of the + // background layers. + for (int w = 5; w >= 0; w--) + { + pClip->Count[w] = 0; + + if (w == 5) // The colour window... + { + if (c == 0) // ... on the main screen + { + if ((Memory.FillRAM [0x2130] & 0xc0) == 0xc0) + { + // The whole of the main screen is switched off, + // completely clip everything. + for (int i = 0; i < 6; i++) + { + IPPU.Clip [c].Count [i] = 1; + IPPU.Clip [c].Left [0][i] = 1; + IPPU.Clip [c].Right [0][i] = 0; + } + continue; + } + else + if ((Memory.FillRAM [0x2130] & 0xc0) == 0x00) + continue; + } + else + { + // .. colour window on the sub-screen. + if ((Memory.FillRAM [0x2130] & 0x30) == 0x30) + { + // The sub-screen is switched off, completely + // clip everything. + for (int i = 0; i < 6; i++) + { + IPPU.Clip [1].Count [i] = 1; + IPPU.Clip [1].Left [0][i] = 1; + IPPU.Clip [1].Right [0][i] = 0; + } + return; + } + else + if ((Memory.FillRAM [0x2130] & 0x30) == 0x00) + continue; + } + } + if (!Settings.DisableGraphicWindows) + { + if (w == 5 || pClip->Count [5] || + (Memory.FillRAM [0x212c + c] & + Memory.FillRAM [0x212e + c] & (1 << w))) + { + struct Band Win1[3]; + struct Band Win2[3]; + uint32 Window1Enabled = 0; + uint32 Window2Enabled = 0; + bool8_32 invert = (w == 5 && + ((c == 1 && (Memory.FillRAM [0x2130] & 0x30) == 0x10) || + (c == 0 && (Memory.FillRAM [0x2130] & 0xc0) == 0x40))); + + if (w == 5 || + (Memory.FillRAM [0x212c + c] & Memory.FillRAM [0x212e + c] & (1 << w))) + { + if (PPU.ClipWindow1Enable [w]) + { + if (!PPU.ClipWindow1Inside [w]) + { + Win1[Window1Enabled].Left = PPU.Window1Left; + Win1[Window1Enabled++].Right = PPU.Window1Right + 1; + } + else + { + if (PPU.Window1Left <= PPU.Window1Right) + { + if (PPU.Window1Left > 0) + { + Win1[Window1Enabled].Left = 0; + Win1[Window1Enabled++].Right = PPU.Window1Left; + } + if (PPU.Window1Right < 255) + { + Win1[Window1Enabled].Left = PPU.Window1Right + 1; + Win1[Window1Enabled++].Right = 256; + } + if (Window1Enabled == 0) + { + Win1[Window1Enabled].Left = 1; + Win1[Window1Enabled++].Right = 0; + } + } + else + { + // 'outside' a window with no range - + // appears to be the whole screen. + Win1[Window1Enabled].Left = 0; + Win1[Window1Enabled++].Right = 256; + } + } + } + if (PPU.ClipWindow2Enable [w]) + { + if (!PPU.ClipWindow2Inside [w]) + { + Win2[Window2Enabled].Left = PPU.Window2Left; + Win2[Window2Enabled++].Right = PPU.Window2Right + 1; + } + else + { + if (PPU.Window2Left <= PPU.Window2Right) + { + if (PPU.Window2Left > 0) + { + Win2[Window2Enabled].Left = 0; + Win2[Window2Enabled++].Right = PPU.Window2Left; + } + if (PPU.Window2Right < 255) + { + Win2[Window2Enabled].Left = PPU.Window2Right + 1; + Win2[Window2Enabled++].Right = 256; + } + if (Window2Enabled == 0) + { + Win2[Window2Enabled].Left = 1; + Win2[Window2Enabled++].Right = 0; + } + } + else + { + Win2[Window2Enabled].Left = 0; + Win2[Window2Enabled++].Right = 256; + } + } + } + } + if (Window1Enabled && Window2Enabled) + { + // Overlap logic + // + // Each window will be in one of three states: + // 1. (Left > Right. One band) + // 2. | ---------------- | (Left >= 0, Right <= 255, Left <= Right. One band) + // 3. |------------ ----------| (Left1 == 0, Right1 < Left2; Left2 > Right1, Right2 == 255. Two bands) + + struct Band Bands [6]; + int B = 0; + switch (PPU.ClipWindowOverlapLogic [w] ^ 1) + { + case CLIP_OR: + if (Window1Enabled == 1) + { + if (BAND_EMPTY(Win1[0])) + { + B = Window2Enabled; + memmove (Bands, Win2, + sizeof(Win2[0]) * Window2Enabled); + } + else + { + if (Window2Enabled == 1) + { + if (BAND_EMPTY (Win2[0])) + Bands[B++] = Win1[0]; + else + { + if (BANDS_INTERSECT (Win1[0], Win2[0])) + { + OR_BANDS(Bands[0],Win1[0], Win2[0]) + B = 1; + } + else + { + Bands[B++] = Win1[0]; + Bands[B++] = Win2[0]; + } + } + } + else + { + if (BANDS_INTERSECT(Win1[0], Win2[0])) + { + OR_BANDS(Bands[0], Win1[0], Win2[0]) + if (BANDS_INTERSECT(Win1[0], Win2[1])) + OR_BANDS(Bands[1], Win1[0], Win2[1]) + else + Bands[1] = Win2[1]; + B = 1; + if (BANDS_INTERSECT(Bands[0], Bands[1])) + OR_BANDS(Bands[0], Bands[0], Bands[1]) + else + B = 2; + } + else + if (BANDS_INTERSECT(Win1[0], Win2[1])) + { + Bands[B++] = Win2[0]; + OR_BANDS(Bands[B], Win1[0], Win2[1]); + B++; + } + else + { + Bands[0] = Win2[0]; + Bands[1] = Win1[0]; + Bands[2] = Win2[1]; + B = 3; + } + } + } + } + else + if (Window2Enabled == 1) + { + if (BAND_EMPTY(Win2[0])) + { + // Window 2 defines an empty range - just + // use window 1 as the clipping (which + // could also be empty). + B = Window1Enabled; + memmove (Bands, Win1, + sizeof(Win1[0]) * Window1Enabled); + } + else + { + // Window 1 has two bands and Window 2 has one. + // Neither is an empty region. + if (BANDS_INTERSECT(Win2[0], Win1[0])) + { + OR_BANDS(Bands[0], Win2[0], Win1[0]) + if (BANDS_INTERSECT(Win2[0], Win1[1])) + OR_BANDS(Bands[1], Win2[0], Win1[1]) + else + Bands[1] = Win1[1]; + B = 1; + if (BANDS_INTERSECT(Bands[0], Bands[1])) + OR_BANDS(Bands[0], Bands[0], Bands[1]) + else + B = 2; + } + else + if (BANDS_INTERSECT(Win2[0], Win1[1])) + { + Bands[B++] = Win1[0]; + OR_BANDS(Bands[B], Win2[0], Win1[1]); + B++; + } + else + { + Bands[0] = Win1[0]; + Bands[1] = Win2[0]; + Bands[2] = Win1[1]; + B = 3; + } + } + } + else + { + // Both windows have two bands + OR_BANDS(Bands[0], Win1[0], Win2[0]); + OR_BANDS(Bands[1], Win1[1], Win2[1]); + B = 1; + if (BANDS_INTERSECT(Bands[0], Bands[1])) + OR_BANDS(Bands[0], Bands[0], Bands[1]) + else + B = 2; + } + break; + + case CLIP_AND: + if (Window1Enabled == 1) + { + // Window 1 has one band + if (BAND_EMPTY(Win1[0])) + Bands [B++] = Win1[0]; + else + if (Window2Enabled == 1) + { + if (BAND_EMPTY (Win2[0])) + Bands [B++] = Win2[0]; + else + { + AND_BANDS(Bands[0], Win1[0], Win2[0]); + B = 1; + } + } + else + { + AND_BANDS(Bands[0], Win1[0], Win2[0]); + AND_BANDS(Bands[1], Win1[0], Win2[1]); + B = 2; + } + } + else + if (Window2Enabled == 1) + { + if (BAND_EMPTY(Win2[0])) + Bands[B++] = Win2[0]; + else + { + // Window 1 has two bands. + AND_BANDS(Bands[0], Win1[0], Win2[0]); + AND_BANDS(Bands[1], Win1[1], Win2[0]); + B = 2; + } + } + else + { + // Both windows have two bands. + AND_BANDS(Bands[0], Win1[0], Win2[0]); + AND_BANDS(Bands[1], Win1[1], Win2[1]); + B = 2; + if (BANDS_INTERSECT(Win1[0], Win2[1])) + { + AND_BANDS(Bands[2], Win1[0], Win2[1]); + B = 3; + } + else + if (BANDS_INTERSECT(Win1[1], Win2[0])) + { + AND_BANDS(Bands[2], Win1[1], Win2[0]); + B = 3; + } + } + break; + case CLIP_XNOR: + invert = !invert; + // Fall... + + case CLIP_XOR: + if (Window1Enabled == 1 && BAND_EMPTY(Win1[0])) + { + B = Window2Enabled; + memmove (Bands, Win2, + sizeof(Win2[0]) * Window2Enabled); + } + else + if (Window2Enabled == 1 && BAND_EMPTY(Win2[0])) + { + B = Window1Enabled; + memmove (Bands, Win1, + sizeof(Win1[0]) * Window1Enabled); + } + else + { + uint32 p = 0; + uint32 points [10]; + uint32 i; + + invert = !invert; + // Build an array of points (window edges) + points [p++] = 0; + for (i = 0; i < Window1Enabled; i++) + { + points [p++] = Win1[i].Left; + points [p++] = Win1[i].Right; + } + for (i = 0; i < Window2Enabled; i++) + { + points [p++] = Win2[i].Left; + points [p++] = Win2[i].Right; + } + points [p++] = 256; + // Sort them + qsort ((void *) points, p, sizeof (points [0]), + IntCompare); + for (i = 0; i < p; i += 2) + { + if (points [i] == points [i + 1]) + continue; + Bands [B].Left = points [i]; + while (i + 2 < p && + points [i + 1] == points [i + 2]) + { + i += 2; + } + Bands [B++].Right = points [i + 1]; + } + } + break; + } + if (invert) + { + int b; + int j = 0; + int empty_band_count = 0; + + // First remove all empty bands from the list. + for (b = 0; b < B; b++) + { + if (!BAND_EMPTY(Bands[b])) + { + if (b != j) + Bands[j] = Bands[b]; + j++; + } + else + empty_band_count++; + } + + if (j > 0) + { + if (j == 1) + { + j = 0; + // Easy case to deal with, so special case it. + + if (Bands[0].Left > 0) + { + pClip->Left[j][w] = 0; + pClip->Right[j++][w] = Bands[0].Left + 1; + } + if (Bands[0].Right < 256) + { + pClip->Left[j][w] = Bands[0].Right; + pClip->Right[j++][w] = 256; + } + if (j == 0) + { + pClip->Left[j][w] = 1; + pClip->Right[j++][w] = 0; + } + } + else + { + // Now sort the bands into order + B = j; + qsort ((void *) Bands, B, + sizeof (Bands [0]), BandCompare); + + // Now invert the area the bands cover + j = 0; + for (b = 0; b < B; b++) + { + if (b == 0 && Bands[b].Left > 0) + { + pClip->Left[j][w] = 0; + pClip->Right[j++][w] = Bands[b].Left + 1; + } + else + if (b == B - 1 && Bands[b].Right < 256) + { + pClip->Left[j][w] = Bands[b].Right; + pClip->Right[j++][w] = 256; + } + if (b < B - 1) + { + pClip->Left[j][w] = Bands[b].Right; + pClip->Right[j++][w] = Bands[b + 1].Left + 1; + } + } + } + } + else + { + // Inverting a window that consisted of only + // empty bands is the whole width of the screen. + // Needed for Mario Kart's rear-view mirror display. + if (empty_band_count) + { + pClip->Left[j][w] = 0; + pClip->Right[j][w] = 256; + j++; + } + } + pClip->Count[w] = j; + } + else + { + for (int j = 0; j < B; j++) + { + pClip->Left[j][w] = Bands[j].Left; + pClip->Right[j][w] = Bands[j].Right; + } + pClip->Count [w] = B; + } + } + else + { + // Only one window enabled so no need to perform + // complex overlap logic... + + if (Window1Enabled) + { + if (invert) + { + int j = 0; + + if (Window1Enabled == 1) + { + if (Win1[0].Left <= Win1[0].Right) + { + if (Win1[0].Left > 0) + { + pClip->Left[j][w] = 0; + pClip->Right[j++][w] = Win1[0].Left; + } + if (Win1[0].Right < 256) + { + pClip->Left[j][w] = Win1[0].Right; + pClip->Right[j++][w] = 256; + } + if (j == 0) + { + pClip->Left[j][w] = 1; + pClip->Right[j++][w] = 0; + } + } + else + { + pClip->Left[j][w] = 0; + pClip->Right[j++][w] = 256; + } + } + else + { + pClip->Left [j][w] = Win1[0].Right; + pClip->Right[j++][w] = Win1[1].Left; + } + pClip->Count [w] = j; + } + else + { + for (uint32 j = 0; j < Window1Enabled; j++) + { + pClip->Left [j][w] = Win1[j].Left; + pClip->Right [j][w] = Win1[j].Right; + } + pClip->Count [w] = Window1Enabled; + } + } + else + if (Window2Enabled) + { + if (invert) + { + int j = 0; + if (Window2Enabled == 1) + { + if (Win2[0].Left <= Win2[0].Right) + { + if (Win2[0].Left > 0) + { + pClip->Left[j][w] = 0; + pClip->Right[j++][w] = Win2[0].Left; + } + if (Win2[0].Right < 256) + { + pClip->Left[j][w] = Win2[0].Right; + pClip->Right[j++][w] = 256; + } + if (j == 0) + { + pClip->Left[j][w] = 1; + pClip->Right[j++][w] = 0; + } + } + else + { + pClip->Left[j][w] = 0; + pClip->Right[j++][w] = 256; + } + } + else + { + pClip->Left [j][w] = Win2[0].Right; + pClip->Right[j++][w] = Win2[1].Left + 1; + } + pClip->Count [w] = j; + } + else + { + for (uint32 j = 0; j < Window2Enabled; j++) + { + pClip->Left [j][w] = Win2[j].Left; + pClip->Right [j][w] = Win2[j].Right; + } + pClip->Count [w] = Window2Enabled; + } + } + } + + if (w != 5) + { + if (pClip->Count [5]) + { + // Colour window enabled. Set the + // clip windows for all remaining backgrounds to be + // the same as the colour window. + if (pClip->Count [w] == 0) + { + pClip->Count [w] = pClip->Count [5]; + for (uint32 i = 0; i < pClip->Count [w]; i++) + { + pClip->Left [i][w] = pClip->Left [i][5]; + pClip->Right [i][w] = pClip->Right [i][5]; + } + } + else + { + // Intersect the colour window with the bg's + // own clip window. + for (uint32 i = 0; i < pClip->Count [w]; i++) + { + uint32 j; + for (j = 0; j < pClip->Count [5]; j++) + { + if((pClip->Left[i][w] >= pClip->Left[j][5] && pClip->Left[i][w] < pClip->Right[j][5]) || (pClip->Left[j][5] >= pClip->Left[i][w] && pClip->Left[j][5] < pClip->Right[i][w])){ + // Found an intersection! + pClip->Left[i][w]=MAX(pClip->Left[i][w], pClip->Left[j][5]); + pClip->Right[i][w]=MIN(pClip->Right[i][w], pClip->Right[j][5]); + goto Clip_ok; + } + } + // no intersection, nullify it + pClip->Left[i][w]=1; + pClip->Right[i][w]=0; +Clip_ok: + j=0; // dummy statement + } + } + } + } + } // if (w == 5 | ... + } // if (!Settings.DisableGraphicWindows) + } // for (int w... + } // for (int c... +} diff --git a/src/snes4iphone_src/copyright.h b/src/snes4iphone_src/copyright.h new file mode 100755 index 0000000..7e02c4c --- /dev/null +++ b/src/snes4iphone_src/copyright.h @@ -0,0 +1,70 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996, 1997, 1998, 1999 Gary Henderson (gary@daniver.demon.co.uk) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code (c) Copyright 1997, 1998 Ivar and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ diff --git a/src/snes4iphone_src/cpu.cpp b/src/snes4iphone_src/cpu.cpp new file mode 100755 index 0000000..7254f4c --- /dev/null +++ b/src/snes4iphone_src/cpu.cpp @@ -0,0 +1,167 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#include "snes9x.h" +#include "memmap.h" +#include "ppu.h" +#include "dsp1.h" +#include "cpuexec.h" +#include "debug.h" +#include "apu.h" +#include "dma.h" +#ifdef USE_SA1 +#include "sa1.h" +#endif +//#include "cheats.h" +#include "srtc.h" +#include "sdd1.h" +//#include "spc7110.h" + +#include "soundux.h" + +#ifdef SUPER_FX +#include "fxemu.h" + +extern struct FxInit_s SuperFX; + +void S9xResetSuperFX () +{ + SuperFX.vFlags = 0; //FX_FLAG_ROM_BUFFER;// | FX_FLAG_ADDRESS_CHECKING; + FxReset (&SuperFX); +} +#endif + +void S9xResetCPU () +{ + Registers.PB = 0; + Registers.PC = S9xGetWord (0xFFFC); + Registers.D.W = 0; + Registers.DB = 0; + Registers.SH = 1; + Registers.SL = 0xFF; + Registers.XH = 0; + Registers.YH = 0; + Registers.P.W = 0; + + ICPU.ShiftedPB = 0; + ICPU.ShiftedDB = 0; + SetFlags (MemoryFlag | IndexFlag | IRQ | Emulation); + ClearFlags (Decimal); + + CPU.Flags = CPU.Flags & (DEBUG_MODE_FLAG | TRACE_FLAG); + CPU.BranchSkip = FALSE; + CPU.NMIActive = FALSE; + CPU.IRQActive = FALSE; + CPU.WaitingForInterrupt = FALSE; + CPU.InDMA = FALSE; + CPU.WhichEvent = HBLANK_START_EVENT; + CPU.PC = NULL; + CPU.PCBase = NULL; + CPU.PCAtOpcodeStart = NULL; + CPU.WaitAddress = NULL; + CPU.WaitCounter = 0; + CPU.Cycles = 0; + CPU.NextEvent = Settings.HBlankStart; + CPU.V_Counter = 0; + CPU.MemSpeed = SLOW_ONE_CYCLE; + CPU.MemSpeedx2 = SLOW_ONE_CYCLE * 2; + CPU.FastROMSpeed = SLOW_ONE_CYCLE; + CPU.AutoSaveTimer = 0; + CPU.SRAMModified = FALSE; + // CPU.NMITriggerPoint = 4; // Set when ROM image loaded + CPU.BRKTriggered = FALSE; + //CPU.TriedInterleavedMode2 = FALSE; // Reset when ROM image loaded + CPU.NMICycleCount = 0; + CPU.IRQCycleCount = 0; + S9xSetPCBase (Registers.PC); + +#ifndef VAR_CYCLES + //ICPU.Speed = S9xE1M1X1; // unused +#endif + //ICPU.S9xOpcodes = S9xOpcodesM1X1; // unused + ICPU.CPUExecuting = TRUE; + + //S9xUnpackStatus(); // not needed +} + + +void S9xReset (void) +{ +#ifdef SUPER_FX + if (Settings.SuperFX) + S9xResetSuperFX (); +#endif + + ZeroMemory (Memory.FillRAM, 0x8000); + memset (Memory.VRAM, 0x00, 0x10000); + memset (Memory.RAM, 0x55, 0x20000); + +/* if(Settings.SPC7110) + S9xSpc7110Reset();*/ + S9xResetCPU (); + S9xResetPPU (); + S9xResetSRTC (); + if (Settings.SDD1) + S9xResetSDD1 (); + + S9xResetDMA (); + S9xResetAPU (); + S9xResetDSP1 (); +#ifdef USE_SA1 + S9xSA1Init (); +#endif + + if (Settings.C4) + S9xInitC4 (); + + S9xResetSound(1); + + Settings.Paused = FALSE; + + //Init CPU Map & co + CPU.Memory_Map=(uint8*)&(Memory.Map); + CPU.Memory_WriteMap=(uint8*)&(Memory.WriteMap); + CPU.Memory_MemorySpeed=(uint8*)&(Memory.MemorySpeed); + CPU.Memory_BlockIsRAM=(uint8*)&(Memory.BlockIsRAM); + CPU.Memory_SRAM=Memory.SRAM; + CPU.Memory_BWRAM=Memory.BWRAM; +// CPU.Memory_SRAMMask=Memory.SRAMMask; + +} diff --git a/src/snes4iphone_src/cpuaddr.h b/src/snes4iphone_src/cpuaddr.h new file mode 100755 index 0000000..5d8d393 --- /dev/null +++ b/src/snes4iphone_src/cpuaddr.h @@ -0,0 +1,338 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#ifndef _CPUADDR_H_ +#define _CPUADDR_H_ + +//EXTERN_C long OpAddress; + +STATIC INLINE long FASTCALL Immediate8 (struct SRegisters * reg, struct SICPU * icpu, struct SCPUState * cpu) +{ + long OpAddress = icpu->ShiftedPB + cpu->PC - cpu->PCBase; + cpu->PC++; + return OpAddress; +} + +STATIC INLINE long FASTCALL Immediate16 (struct SRegisters * reg, struct SICPU * icpu, struct SCPUState * cpu) +{ + long OpAddress = icpu->ShiftedPB + cpu->PC - cpu->PCBase; + cpu->PC += 2; + return OpAddress; +} + +STATIC INLINE long FASTCALL Relative (struct SRegisters * reg, struct SICPU * icpu, struct SCPUState * cpu) +{ + int8 Int8 = *cpu->PC++; +#ifdef VAR_CYCLES + cpu->Cycles += cpu->MemSpeed; +#endif + return ((int) (cpu->PC - cpu->PCBase) + Int8) & 0xffff; +} + +STATIC INLINE long FASTCALL RelativeLong (struct SRegisters * reg, struct SICPU * icpu, struct SCPUState * cpu) +{ +#ifdef FAST_LSB_WORD_ACCESS + long OpAddress = *(uint16 *) cpu->PC; +#else + long OpAddress = *cpu->PC + (*(cpu->PC + 1) << 8); +#endif +#ifdef VAR_CYCLES + cpu->Cycles += cpu->MemSpeedx2 + ONE_CYCLE; +#endif + cpu->PC += 2; + OpAddress += (cpu->PC - cpu->PCBase); + OpAddress &= 0xffff; + return OpAddress; +} + +STATIC INLINE long FASTCALL AbsoluteIndexedIndirect (struct SRegisters * reg, struct SICPU * icpu, struct SCPUState * cpu) +{ +#ifdef FAST_LSB_WORD_ACCESS + long OpAddress = (reg->X.W + *(uint16 *) cpu->PC) & 0xffff; +#else + long OpAddress = (reg->X.W + *cpu->PC + (*(cpu->PC + 1) << 8)) & 0xffff; +#endif +#ifdef VAR_CYCLES + cpu->Cycles += cpu->MemSpeedx2; +#endif + cpu->PC += 2; + return S9xGetWord (icpu->ShiftedPB + OpAddress, cpu); +} + +STATIC INLINE long FASTCALL AbsoluteIndirectLong (struct SRegisters * reg, struct SICPU * icpu, struct SCPUState * cpu) +{ +#ifdef FAST_LSB_WORD_ACCESS + long OpAddress = *(uint16 *) cpu->PC; +#else + long OpAddress = *cpu->PC + (*(cpu->PC + 1) << 8); +#endif + +#ifdef VAR_CYCLES + cpu->Cycles += cpu->MemSpeedx2; +#endif + cpu->PC += 2; + return S9xGetWord (OpAddress, cpu) | (S9xGetByte (OpAddress + 2, cpu) << 16); +} + +STATIC INLINE long FASTCALL AbsoluteIndirect (struct SRegisters * reg, struct SICPU * icpu, struct SCPUState * cpu) +{ +#ifdef FAST_LSB_WORD_ACCESS + long OpAddress = *(uint16 *) cpu->PC; +#else + long OpAddress = *cpu->PC + (*(cpu->PC + 1) << 8); +#endif + +#ifdef VAR_CYCLES + cpu->Cycles += cpu->MemSpeedx2; +#endif + cpu->PC += 2; + return S9xGetWord (OpAddress, cpu) + icpu->ShiftedPB; +} + +STATIC INLINE long FASTCALL Absolute (struct SRegisters * reg, struct SICPU * icpu, struct SCPUState * cpu) +{ +#ifdef FAST_LSB_WORD_ACCESS + long OpAddress = *(uint16 *) cpu->PC + icpu->ShiftedDB; +#else + long OpAddress = *cpu->PC + (*(cpu->PC + 1) << 8) + icpu->ShiftedDB; +#endif + cpu->PC += 2; +#ifdef VAR_CYCLES + cpu->Cycles += cpu->MemSpeedx2; +#endif + return OpAddress; +} + +STATIC INLINE long FASTCALL AbsoluteLong (struct SRegisters * reg, struct SICPU * icpu, struct SCPUState * cpu) +{ +#ifdef FAST_LSB_WORD_ACCESS + long OpAddress = (*(uint32 *) cpu->PC) & 0xffffff; +#else + long OpAddress = *cpu->PC + (*(cpu->PC + 1) << 8) + (*(cpu->PC + 2) << 16); +#endif + cpu->PC += 3; +#ifdef VAR_CYCLES + cpu->Cycles += cpu->MemSpeedx2 + cpu->MemSpeed; +#endif + return OpAddress; +} + +STATIC INLINE long FASTCALL Direct(struct SRegisters * reg, struct SICPU * icpu, struct SCPUState * cpu) +{ + long OpAddress = (*cpu->PC++ + reg->D.W) & 0xffff; +#ifdef VAR_CYCLES + cpu->Cycles += cpu->MemSpeed; +#endif +// if (reg->DL != 0) cpu->Cycles += ONE_CYCLE; + return OpAddress; +} + +STATIC INLINE long FASTCALL DirectIndirectIndexed (struct SRegisters * reg, struct SICPU * icpu, struct SCPUState * cpu) +{ + long OpAddress = (*cpu->PC++ + reg->D.W) & 0xffff; +#ifdef VAR_CYCLES + cpu->Cycles += cpu->MemSpeed; +#endif + + OpAddress = icpu->ShiftedDB + S9xGetWord (OpAddress, cpu) + reg->Y.W; + +// if (reg->DL != 0) cpu->Cycles += ONE_CYCLE; + // XXX: always add one if STA + // XXX: else Add one cycle if crosses page boundary + return OpAddress; +} + +STATIC INLINE long FASTCALL DirectIndirectIndexedLong (struct SRegisters * reg, struct SICPU * icpu, struct SCPUState * cpu) +{ + long OpAddress = (*cpu->PC++ + reg->D.W) & 0xffff; +#ifdef VAR_CYCLES + cpu->Cycles += cpu->MemSpeed; +#endif + + OpAddress = S9xGetWord (OpAddress, cpu) + (S9xGetByte (OpAddress + 2, cpu) << 16) + + reg->Y.W; +// if (reg->DL != 0) cpu->Cycles += ONE_CYCLE; + return OpAddress; +} + +STATIC INLINE long FASTCALL DirectIndexedIndirect(struct SRegisters * reg, struct SICPU * icpu, struct SCPUState * cpu) +{ + long OpAddress = (*cpu->PC++ + reg->D.W + reg->X.W) & 0xffff; +#ifdef VAR_CYCLES + cpu->Cycles += cpu->MemSpeed; +#endif + + OpAddress = S9xGetWord (OpAddress, cpu) + icpu->ShiftedDB; + +#ifdef VAR_CYCLES +// if (reg->DL != 0) +// cpu->Cycles += TWO_CYCLES; +// else + cpu->Cycles += ONE_CYCLE; +#endif + return OpAddress; +} + +STATIC INLINE long FASTCALL DirectIndexedX (struct SRegisters * reg, struct SICPU * icpu, struct SCPUState * cpu) +{ + long OpAddress = (*cpu->PC++ + reg->D.W + reg->X.W) & 0xffff; +#ifdef VAR_CYCLES + cpu->Cycles += cpu->MemSpeed; +#endif + +#ifdef VAR_CYCLES +// if (reg->DL != 0) +// cpu->Cycles += TWO_CYCLES; +// else + cpu->Cycles += ONE_CYCLE; +#endif + return OpAddress; +} + +STATIC INLINE long FASTCALL DirectIndexedY (struct SRegisters * reg, struct SICPU * icpu, struct SCPUState * cpu) +{ + long OpAddress = (*cpu->PC++ + reg->D.W + reg->Y.W) & 0xffff; +#ifdef VAR_CYCLES + cpu->Cycles += cpu->MemSpeed; +#endif + +#ifdef VAR_CYCLES +// if (reg->DL != 0) +// cpu->Cycles += TWO_CYCLES; +// else + cpu->Cycles += ONE_CYCLE; +#endif + return OpAddress; +} + +STATIC INLINE long FASTCALL AbsoluteIndexedX (struct SRegisters * reg, struct SICPU * icpu, struct SCPUState * cpu) +{ +#ifdef FAST_LSB_WORD_ACCESS + long OpAddress = icpu->ShiftedDB + *(uint16 *) cpu->PC + reg->X.W; +#else + long OpAddress = icpu->ShiftedDB + *cpu->PC + (*(cpu->PC + 1) << 8) + + reg->X.W; +#endif + cpu->PC += 2; +#ifdef VAR_CYCLES + cpu->Cycles += cpu->MemSpeedx2; +#endif + // XXX: always add one cycle for ROL, LSR, etc + // XXX: else is cross page boundary add one cycle + return OpAddress; +} + +STATIC INLINE long FASTCALL AbsoluteIndexedY (struct SRegisters * reg, struct SICPU * icpu, struct SCPUState * cpu) +{ +#ifdef FAST_LSB_WORD_ACCESS + long OpAddress = icpu->ShiftedDB + *(uint16 *) cpu->PC + reg->Y.W; +#else + long OpAddress = icpu->ShiftedDB + *cpu->PC + (*(cpu->PC + 1) << 8) + + reg->Y.W; +#endif + cpu->PC += 2; +#ifdef VAR_CYCLES + cpu->Cycles += cpu->MemSpeedx2; +#endif + // XXX: always add cycle for STA + // XXX: else is cross page boundary add one cycle + return OpAddress; +} + +STATIC INLINE long FASTCALL AbsoluteLongIndexedX (struct SRegisters * reg, struct SICPU * icpu, struct SCPUState * cpu) +{ +#ifdef FAST_LSB_WORD_ACCESS + long OpAddress = (*(uint32 *) cpu->PC + reg->X.W) & 0xffffff; +#else + long OpAddress = (*cpu->PC + (*(cpu->PC + 1) << 8) + (*(cpu->PC + 2) << 16) + reg->X.W) & 0xffffff; +#endif + cpu->PC += 3; +#ifdef VAR_CYCLES + cpu->Cycles += cpu->MemSpeedx2 + cpu->MemSpeed; +#endif + return OpAddress; +} + +STATIC INLINE long FASTCALL DirectIndirect (struct SRegisters * reg, struct SICPU * icpu, struct SCPUState * cpu) +{ + long OpAddress = (*cpu->PC++ + reg->D.W) & 0xffff; +#ifdef VAR_CYCLES + cpu->Cycles += cpu->MemSpeed; +#endif + OpAddress = S9xGetWord (OpAddress, cpu) + icpu->ShiftedDB; + +// if (reg->DL != 0) cpu->Cycles += ONE_CYCLE; + return OpAddress; +} + +STATIC INLINE long FASTCALL DirectIndirectLong (struct SRegisters * reg, struct SICPU * icpu, struct SCPUState * cpu) +{ + long OpAddress = (*cpu->PC++ + reg->D.W) & 0xffff; +#ifdef VAR_CYCLES + cpu->Cycles += cpu->MemSpeed; +#endif + OpAddress = S9xGetWord (OpAddress, cpu) + + (S9xGetByte (OpAddress + 2, cpu) << 16); +// if (reg->DL != 0) cpu->Cycles += ONE_CYCLE; + return OpAddress; +} + +STATIC INLINE long FASTCALL StackRelative (struct SRegisters * reg, struct SICPU * icpu, struct SCPUState * cpu) +{ + long OpAddress = (*cpu->PC++ + reg->S.W) & 0xffff; +#ifdef VAR_CYCLES + cpu->Cycles += cpu->MemSpeed; + cpu->Cycles += ONE_CYCLE; +#endif + return OpAddress; +} + +STATIC INLINE long FASTCALL StackRelativeIndirectIndexed (struct SRegisters * reg, struct SICPU * icpu, struct SCPUState * cpu) +{ + long OpAddress = (*cpu->PC++ + reg->S.W) & 0xffff; +#ifdef VAR_CYCLES + cpu->Cycles += cpu->MemSpeed; + cpu->Cycles += TWO_CYCLES; +#endif + OpAddress = (S9xGetWord (OpAddress, cpu) + icpu->ShiftedDB + + reg->Y.W) & 0xffffff; + return OpAddress; +} +#endif diff --git a/src/snes4iphone_src/cpuexec.cpp b/src/snes4iphone_src/cpuexec.cpp new file mode 100755 index 0000000..cab6a0c --- /dev/null +++ b/src/snes4iphone_src/cpuexec.cpp @@ -0,0 +1,277 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ + + + +#include "snes9x.h" + +#include "memmap.h" +//#include "cpuops.h" +#include "ppu.h" +#include "cpuexec.h" +#include "debug.h" +#include "snapshot.h" +#include "gfx.h" +#include "missing.h" +#include "apu.h" +#include "dma.h" +#include "fxemu.h" +#ifdef USE_SA1 +#include "sa1.h" +#endif + + +#include "os9x_asm_cpu.h" + + +// for asm core: +uint16 mem_check=0; + + +#if defined(__showframe__) +int framecpt=0; +#endif + + +void S9xMainLoop (void) +{ +#if defined(__showframe__) + framecpt++; + char stra[64]; + sprintf(stra,"framecpt : %d",framecpt); + S9xMessage(0,0,stra); +#endif + +// asm_S9xMainLoop(); + asmMainLoop(&CPU); + Registers.PC = CPU.PC - CPU.PCBase; + //S9xPackStatus (); // not needed + S9xAPUPackStatus (); + + if (CPU.Flags & SCAN_KEYS_FLAG) + { + CPU.Flags &= ~SCAN_KEYS_FLAG; + } + + if (CPU.BRKTriggered && Settings.SuperFX && !CPU.TriedInterleavedMode2) + { + CPU.TriedInterleavedMode2 = TRUE; + CPU.BRKTriggered = FALSE; + S9xDeinterleaveMode2 (); + } +} + +void S9xSetIRQ (uint32 source) +{ + CPU.IRQActive |= source; + CPU.Flags |= IRQ_PENDING_FLAG; + CPU.IRQCycleCount = 3; + if (CPU.WaitingForInterrupt) + { + // Force IRQ to trigger immediately after WAI - + // Final Fantasy Mystic Quest crashes without this. + CPU.IRQCycleCount = 0; + CPU.WaitingForInterrupt = FALSE; + CPU.PC++; + } +} + +void S9xClearIRQ (uint32 source) +{ + CLEAR_IRQ_SOURCE (source); +} + + +void S9xDoHBlankProcessing () +{ +#ifdef CPU_SHUTDOWN + CPU.WaitCounter++; +#endif + switch (CPU.WhichEvent) + { + case HBLANK_START_EVENT: + if (IPPU.HDMA && CPU.V_Counter <= PPU.ScreenHeight) + IPPU.HDMA = S9xDoHDMA (IPPU.HDMA); + break; + + case HBLANK_END_EVENT: + APU_EXECUTE(3); // notaz: run spc700 in sound 'speed hack' mode + + if(Settings.SuperFX) + S9xSuperFXExec (); + + CPU.Cycles -= Settings.H_Max; + if (/*IAPU.APUExecuting*/CPU.APU_APUExecuting) + CPU.APU_Cycles -= Settings.H_Max; + else + CPU.APU_Cycles = 0; + + CPU.NextEvent = -1; + ICPU.Scanline++; + + if (++CPU.V_Counter > (Settings.PAL ? SNES_MAX_PAL_VCOUNTER : SNES_MAX_NTSC_VCOUNTER)) + { + PPU.OAMAddr = PPU.SavedOAMAddr; + PPU.OAMFlip = 0; + CPU.V_Counter = 0; + CPU.NMIActive = FALSE; + ICPU.Frame++; + PPU.HVBeamCounterLatched = 0; + CPU.Flags |= SCAN_KEYS_FLAG; + S9xStartHDMA (); + } + + if (PPU.VTimerEnabled && !PPU.HTimerEnabled && + CPU.V_Counter == PPU.IRQVBeamPos) + { + S9xSetIRQ (PPU_V_BEAM_IRQ_SOURCE); + } + + if (CPU.V_Counter == PPU.ScreenHeight + FIRST_VISIBLE_LINE) + { + // Start of V-blank + S9xEndScreenRefresh (); + PPU.FirstSprite = 0; + IPPU.HDMA = 0; + // Bits 7 and 6 of $4212 are computed when read in S9xGetPPU. + missing.dma_this_frame = 0; + IPPU.MaxBrightness = PPU.Brightness; + PPU.ForcedBlanking = (Memory.FillRAM [0x2100] >> 7) & 1; + + Memory.FillRAM[0x4210] = 0x80; + if (Memory.FillRAM[0x4200] & 0x80) + { + CPU.NMIActive = TRUE; + CPU.Flags |= NMI_FLAG; + CPU.NMICycleCount = CPU.NMITriggerPoint; + } + + #ifdef OLD_SNAPSHOT_CODE + if (CPU.Flags & SAVE_SNAPSHOT_FLAG) + { + CPU.Flags &= ~SAVE_SNAPSHOT_FLAG; + Registers.PC = CPU.PC - CPU.PCBase; + //S9xPackStatus (); // not needed + S9xAPUPackStatus (); + Snapshot (NULL); + } + #endif + } + + if (CPU.V_Counter == PPU.ScreenHeight + 3) + S9xUpdateJoypads (); + + if (CPU.V_Counter == FIRST_VISIBLE_LINE) + { + Memory.FillRAM[0x4210] = 0; + CPU.Flags &= ~NMI_FLAG; + S9xStartScreenRefresh (); + } + if (CPU.V_Counter >= FIRST_VISIBLE_LINE && + CPU.V_Counter < PPU.ScreenHeight + FIRST_VISIBLE_LINE) + { + RenderLine (CPU.V_Counter - FIRST_VISIBLE_LINE); + } + // Use TimerErrorCounter to skip update of SPC700 timers once + // every 128 updates. Needed because this section of code is called + // once every emulated 63.5 microseconds, which coresponds to + // 15.750KHz, but the SPC700 timers need to be updated at multiples + // of 8KHz, hence the error correction. + // IAPU.TimerErrorCounter++; + // if (IAPU.TimerErrorCounter >= ) + // IAPU.TimerErrorCounter = 0; + // else + { + if (APU.TimerEnabled [2]) + { + APU.Timer [2] += 4; + while (APU.Timer [2] >= APU.TimerTarget [2]) + { + IAPU.RAM [0xff] = (IAPU.RAM [0xff] + 1) & 0xf; + APU.Timer [2] -= APU.TimerTarget [2]; +#ifdef SPC700_SHUTDOWN + IAPU.WaitCounter++; + /*IAPU.APUExecuting*/CPU.APU_APUExecuting= TRUE; +#endif + } + } + if (CPU.V_Counter & 1) + { + if (APU.TimerEnabled [0]) + { + APU.Timer [0]++; + if (APU.Timer [0] >= APU.TimerTarget [0]) + { + IAPU.RAM [0xfd] = (IAPU.RAM [0xfd] + 1) & 0xf; + APU.Timer [0] = 0; +#ifdef SPC700_SHUTDOWN + IAPU.WaitCounter++; + /*IAPU.APUExecuting*/CPU.APU_APUExecuting = TRUE; +#endif + } + } + if (APU.TimerEnabled [1]) + { + APU.Timer [1]++; + if (APU.Timer [1] >= APU.TimerTarget [1]) + { + IAPU.RAM [0xfe] = (IAPU.RAM [0xfe] + 1) & 0xf; + APU.Timer [1] = 0; +#ifdef SPC700_SHUTDOWN + IAPU.WaitCounter++; + /*IAPU.APUExecuting*/CPU.APU_APUExecuting = TRUE; +#endif + } + } + } + } + break; + case HTIMER_BEFORE_EVENT: + case HTIMER_AFTER_EVENT: + if (PPU.HTimerEnabled && + (!PPU.VTimerEnabled || CPU.V_Counter == PPU.IRQVBeamPos)) + { + S9xSetIRQ (PPU_H_BEAM_IRQ_SOURCE); + } + break; + } + S9xReschedule (); +} diff --git a/src/snes4iphone_src/cpuexec.h b/src/snes4iphone_src/cpuexec.h new file mode 100755 index 0000000..bed1216 --- /dev/null +++ b/src/snes4iphone_src/cpuexec.h @@ -0,0 +1,201 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#ifndef _CPUEXEC_H_ +#define _CPUEXEC_H_ +#include "ppu.h" +#include "memmap.h" +#include "65c816.h" + +#define DO_HBLANK_CHECK() \ + if (CPU.Cycles >= CPU.NextEvent) \ + S9xDoHBlankProcessing (); + +struct SOpcodes { +#ifdef __WIN32__ + void (__cdecl *S9xOpcode)( void); +#else + void (*S9xOpcode)( void); +#endif +}; + +struct SICPU +{ +/* + uint8 *Speed; + struct SOpcodes *S9xOpcodes; + uint8 _Carry; + uint8 _Zero; + uint8 _Negative; + uint8 _Overflow; +*/ + bool8 CPUExecuting; + uint32 ShiftedPB; + uint32 ShiftedDB; + uint32 Frame; + uint32 Scanline; + uint32 FrameAdvanceCount; +}; + +START_EXTERN_C +void S9xMainLoop (void); +void S9xReset (void); +void S9xDoHBlankProcessing (); +void S9xClearIRQ (uint32); +void S9xSetIRQ (uint32); + +extern struct SOpcodes S9xOpcodesM1X1 [256]; +extern struct SOpcodes S9xOpcodesM1X0 [256]; +extern struct SOpcodes S9xOpcodesM0X1 [256]; +extern struct SOpcodes S9xOpcodesM0X0 [256]; + +#ifndef VAR_CYCLES +extern uint8 S9xE1M1X1 [256]; +extern uint8 S9xE0M1X0 [256]; +extern uint8 S9xE0M1X1 [256]; +extern uint8 S9xE0M0X0 [256]; +extern uint8 S9xE0M0X1 [256]; +#endif + +extern struct SICPU ICPU; +END_EXTERN_C + +STATIC inline void CLEAR_IRQ_SOURCE (uint32 M) +{ + CPU.IRQActive &= ~M; + if (!CPU.IRQActive) + CPU.Flags &= ~IRQ_PENDING_FLAG; +} + +#if 0 +STATIC inline void S9xUnpackStatus() +{ + ICPU._Zero = (Registers.PL & Zero) == 0; + ICPU._Negative = (Registers.PL & Negative); + ICPU._Carry = (Registers.PL & Carry); + ICPU._Overflow = (Registers.PL & Overflow) >> 6; +} + +STATIC inline void S9xPackStatus() +{ + Registers.PL &= ~(Zero | Negative | Carry | Overflow); + Registers.PL |= ICPU._Carry | ((ICPU._Zero == 0) << 1) | + (ICPU._Negative & 0x80) | (ICPU._Overflow << 6); +} + +STATIC inline void S9xFixCycles () +{ + if (CheckEmulation ()) + { +#ifndef VAR_CYCLES + ICPU.Speed = S9xE1M1X1; +#endif + ICPU.S9xOpcodes = S9xOpcodesM1X1; + } + else + if (CheckMemory ()) + { + if (CheckIndex ()) + { +#ifndef VAR_CYCLES + ICPU.Speed = S9xE0M1X1; +#endif + ICPU.S9xOpcodes = S9xOpcodesM1X1; + } + else + { +#ifndef VAR_CYCLES + ICPU.Speed = S9xE0M1X0; +#endif + ICPU.S9xOpcodes = S9xOpcodesM1X0; + } + } + else + { + if (CheckIndex ()) + { +#ifndef VAR_CYCLES + ICPU.Speed = S9xE0M0X1; +#endif + ICPU.S9xOpcodes = S9xOpcodesM0X1; + } + else + { +#ifndef VAR_CYCLES + ICPU.Speed = S9xE0M0X0; +#endif + ICPU.S9xOpcodes = S9xOpcodesM0X0; + } + } +} +#endif + +STATIC inline void S9xReschedule () +{ + uint8 which; + long max; + + if (CPU.WhichEvent == HBLANK_START_EVENT || + CPU.WhichEvent == HTIMER_AFTER_EVENT) + { + which = HBLANK_END_EVENT; + max = Settings.H_Max; + } + else + { + which = HBLANK_START_EVENT; + max = Settings.HBlankStart; + } + + if (PPU.HTimerEnabled && + (long) PPU.HTimerPosition < max && + (long) PPU.HTimerPosition > CPU.NextEvent && + (!PPU.VTimerEnabled || + (PPU.VTimerEnabled && CPU.V_Counter == PPU.IRQVBeamPos))) + { + which = (long) PPU.HTimerPosition < Settings.HBlankStart ? + HTIMER_BEFORE_EVENT : HTIMER_AFTER_EVENT; + max = PPU.HTimerPosition; + } + CPU.NextEvent = max; + CPU.WhichEvent = which; +} + +#endif diff --git a/src/snes4iphone_src/cpumacro.h b/src/snes4iphone_src/cpumacro.h new file mode 100755 index 0000000..4830998 --- /dev/null +++ b/src/snes4iphone_src/cpumacro.h @@ -0,0 +1,820 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#ifndef _CPUMACRO_H_ +#define _CPUMACRO_H_ + +STATIC inline void SetZN16 (uint16 Work) +{ + ICPU._Zero = Work != 0; + ICPU._Negative = (uint8) (Work >> 8); +} + +STATIC inline void SetZN8 (uint8 Work) +{ + ICPU._Zero = Work; + ICPU._Negative = Work; +} + +STATIC inline void ADC8 () +{ + Work8 = S9xGetByte (OpAddress); + + if (CheckDecimal ()) + { + A1 = (Registers.A.W) & 0xF; + A2 = (Registers.A.W >> 4) & 0xF; + W1 = Work8 & 0xF; + W2 = (Work8 >> 4) & 0xF; + + A1 += W1 + CheckCarry(); + if (A1 > 9) + { + A1 -= 10; + A2++; + } + + A2 += W2; + if (A2 > 9) + { + A2 -= 10; + SetCarry (); + } + else + { + ClearCarry (); + } + + Ans8 = (A2 << 4) | A1; + if (~(Registers.AL ^ Work8) & + (Work8 ^ Ans8) & 0x80) + SetOverflow(); + else + ClearOverflow(); + Registers.AL = Ans8; + SetZN8 (Registers.AL); + } + else + { + Ans16 = Registers.AL + Work8 + CheckCarry(); + + ICPU._Carry = Ans16 >= 0x100; + + if (~(Registers.AL ^ Work8) & + (Work8 ^ (uint8) Ans16) & 0x80) + SetOverflow(); + else + ClearOverflow(); + Registers.AL = (uint8) Ans16; + SetZN8 (Registers.AL); + + } +} + +STATIC inline void ADC16 () +{ + Work16 = S9xGetWord (OpAddress); + + if (CheckDecimal ()) + { + A1 = (Registers.A.W) & 0xF; + A2 = (Registers.A.W >> 4) & 0xF; + A3 = (Registers.A.W >> 8) & 0xF; + A4 = (Registers.A.W >> 12) & 0xF; + W1 = Work16 & 0xF; + W2 = (Work16 >> 4) & 0xF; + W3 = (Work16 >> 8) & 0xF; + W4 = (Work16 >> 12) & 0xF; + + A1 += W1 + CheckCarry (); + if (A1 > 9) + { + A1 -= 10; + A2++; + } + + A2 += W2; + if (A2 > 9) + { + A2 -= 10; + A3++; + } + + A3 += W3; + if (A3 > 9) + { + A3 -= 10; + A4++; + } + + A4 += W4; + if (A4 > 9) + { + A4 -= 10; + SetCarry (); + } + else + { + ClearCarry (); + } + + Ans16 = (A4 << 12) | (A3 << 8) | (A2 << 4) | (A1); + if (~(Registers.A.W ^ Work16) & + (Work16 ^ Ans16) & 0x8000) + SetOverflow(); + else + ClearOverflow(); + Registers.A.W = Ans16; + SetZN16 (Registers.A.W); + } + else + { + Ans32 = Registers.A.W + Work16 + CheckCarry(); + + ICPU._Carry = Ans32 >= 0x10000; + + if (~(Registers.A.W ^ Work16) & + (Work16 ^ (uint16) Ans32) & 0x8000) + SetOverflow(); + else + ClearOverflow(); + Registers.A.W = (uint16) Ans32; + SetZN16 (Registers.A.W); + } +} + +STATIC inline void AND16 () +{ + Registers.A.W &= S9xGetWord (OpAddress); + SetZN16 (Registers.A.W); +} + +STATIC inline void AND8 () +{ + Registers.AL &= S9xGetByte (OpAddress); + SetZN8 (Registers.AL); +} + +STATIC inline void A_ASL16 () +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + ICPU._Carry = (Registers.AH & 0x80) != 0; + Registers.A.W <<= 1; + SetZN16 (Registers.A.W); +} + +STATIC inline void A_ASL8 () +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + ICPU._Carry = (Registers.AL & 0x80) != 0; + Registers.AL <<= 1; + SetZN8 (Registers.AL); +} + +STATIC inline void ASL16 () +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + Work16 = S9xGetWord (OpAddress); + ICPU._Carry = (Work16 & 0x8000) != 0; + Work16 <<= 1; + S9xSetWord (Work16, OpAddress); + SetZN16 (Work16); +} + +STATIC inline void ASL8 () +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + Work8 = S9xGetByte (OpAddress); + ICPU._Carry = (Work8 & 0x80) != 0; + Work8 <<= 1; + S9xSetByte (Work8, OpAddress); + SetZN8 (Work8); +} + +STATIC inline void BIT16 () +{ + Work16 = S9xGetWord (OpAddress); + ICPU._Overflow = (Work16 & 0x4000) != 0; + ICPU._Negative = (uint8) (Work16 >> 8); + ICPU._Zero = (Work16 & Registers.A.W) != 0; +} + +STATIC inline void BIT8 () +{ + Work8 = S9xGetByte (OpAddress); + ICPU._Overflow = (Work8 & 0x40) != 0; + ICPU._Negative = Work8; + ICPU._Zero = Work8 & Registers.AL; +} + +STATIC inline void CMP16 () +{ + s9xInt32 = (long) Registers.A.W - + (long) S9xGetWord (OpAddress); + ICPU._Carry = s9xInt32 >= 0; + SetZN16 ((uint16) s9xInt32); +} + +STATIC inline void CMP8 () +{ + s9xInt16 = (short) Registers.AL - + (short) S9xGetByte (OpAddress); + ICPU._Carry = s9xInt16 >= 0; + SetZN8 ((uint8) s9xInt16); +} + +STATIC inline void CMX16 () +{ + s9xInt32 = (long) Registers.X.W - + (long) S9xGetWord (OpAddress); + ICPU._Carry = s9xInt32 >= 0; + SetZN16 ((uint16) s9xInt32); +} + +STATIC inline void CMX8 () +{ + s9xInt16 = (short) Registers.XL - + (short) S9xGetByte (OpAddress); + ICPU._Carry = s9xInt16 >= 0; + SetZN8 ((uint8) s9xInt16); +} + +STATIC inline void CMY16 () +{ + s9xInt32 = (long) Registers.Y.W - + (long) S9xGetWord (OpAddress); + ICPU._Carry = s9xInt32 >= 0; + SetZN16 ((uint16) s9xInt32); +} + +STATIC inline void CMY8 () +{ + s9xInt16 = (short) Registers.YL - + (short) S9xGetByte (OpAddress); + ICPU._Carry = s9xInt16 >= 0; + SetZN8 ((uint8) s9xInt16); +} + +STATIC inline void A_DEC16 () +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif +#ifdef CPU_SHUTDOWN + CPU.WaitAddress = NULL; +#endif + + Registers.A.W--; + SetZN16 (Registers.A.W); +} + +STATIC inline void A_DEC8 () +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif +#ifdef CPU_SHUTDOWN + CPU.WaitAddress = NULL; +#endif + + Registers.AL--; + SetZN8 (Registers.AL); +} + +STATIC inline void DEC16 () +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif +#ifdef CPU_SHUTDOWN + CPU.WaitAddress = NULL; +#endif + + Work16 = S9xGetWord (OpAddress) - 1; + S9xSetWord (Work16, OpAddress); + SetZN16 (Work16); +} + +STATIC inline void DEC8 () +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif +#ifdef CPU_SHUTDOWN + CPU.WaitAddress = NULL; +#endif + + Work8 = S9xGetByte (OpAddress) - 1; + S9xSetByte (Work8, OpAddress); + SetZN8 (Work8); +} + +STATIC inline void EOR16 () +{ + Registers.A.W ^= S9xGetWord (OpAddress); + SetZN16 (Registers.A.W); +} + +STATIC inline void EOR8 () +{ + Registers.AL ^= S9xGetByte (OpAddress); + SetZN8 (Registers.AL); +} + +STATIC inline void A_INC16 () +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif +#ifdef CPU_SHUTDOWN + CPU.WaitAddress = NULL; +#endif + + Registers.A.W++; + SetZN16 (Registers.A.W); +} + +STATIC inline void A_INC8 () +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif +#ifdef CPU_SHUTDOWN + CPU.WaitAddress = NULL; +#endif + + Registers.AL++; + SetZN8 (Registers.AL); +} + +STATIC inline void INC16 () +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif +#ifdef CPU_SHUTDOWN + CPU.WaitAddress = NULL; +#endif + + Work16 = S9xGetWord (OpAddress) + 1; + S9xSetWord (Work16, OpAddress); + SetZN16 (Work16); +} + +STATIC inline void INC8 () +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif +#ifdef CPU_SHUTDOWN + CPU.WaitAddress = NULL; +#endif + + Work8 = S9xGetByte (OpAddress) + 1; + S9xSetByte (Work8, OpAddress); + SetZN8 (Work8); +} + +STATIC inline void LDA16 () +{ + Registers.A.W = S9xGetWord (OpAddress); + SetZN16 (Registers.A.W); +} + +STATIC inline void LDA8 () +{ + Registers.AL = S9xGetByte (OpAddress); + SetZN8 (Registers.AL); +} + +STATIC inline void LDX16 () +{ + Registers.X.W = S9xGetWord (OpAddress); + SetZN16 (Registers.X.W); +} + +STATIC inline void LDX8 () +{ + Registers.XL = S9xGetByte (OpAddress); + SetZN8 (Registers.XL); +} + +STATIC inline void LDY16 () +{ + Registers.Y.W = S9xGetWord (OpAddress); + SetZN16 (Registers.Y.W); +} + +STATIC inline void LDY8 () +{ + Registers.YL = S9xGetByte (OpAddress); + SetZN8 (Registers.YL); +} + +STATIC inline void A_LSR16 () +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + ICPU._Carry = Registers.AL & 1; + Registers.A.W >>= 1; + SetZN16 (Registers.A.W); +} + +STATIC inline void A_LSR8 () +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + ICPU._Carry = Registers.AL & 1; + Registers.AL >>= 1; + SetZN8 (Registers.AL); +} + +STATIC inline void LSR16 () +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + Work16 = S9xGetWord (OpAddress); + ICPU._Carry = Work16 & 1; + Work16 >>= 1; + S9xSetWord (Work16, OpAddress); + SetZN16 (Work16); +} + +STATIC inline void LSR8 () +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + Work8 = S9xGetByte (OpAddress); + ICPU._Carry = Work8 & 1; + Work8 >>= 1; + S9xSetByte (Work8, OpAddress); + SetZN8 (Work8); +} + +STATIC inline void ORA16 () +{ + Registers.A.W |= S9xGetWord (OpAddress); + SetZN16 (Registers.A.W); +} + +STATIC inline void ORA8 () +{ + Registers.AL |= S9xGetByte (OpAddress); + SetZN8 (Registers.AL); +} + +STATIC inline void A_ROL16 () +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + Work32 = (Registers.A.W << 1) | CheckCarry(); + ICPU._Carry = Work32 >= 0x10000; + Registers.A.W = (uint16) Work32; + SetZN16 ((uint16) Work32); +} + +STATIC inline void A_ROL8 () +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + Work16 = Registers.AL; + Work16 <<= 1; + Work16 |= CheckCarry(); + ICPU._Carry = Work16 >= 0x100; + Registers.AL = (uint8) Work16; + SetZN8 ((uint8) Work16); +} + +STATIC inline void ROL16 () +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + Work32 = S9xGetWord (OpAddress); + Work32 <<= 1; + Work32 |= CheckCarry(); + ICPU._Carry = Work32 >= 0x10000; + S9xSetWord ((uint16) Work32, OpAddress); + SetZN16 ((uint16) Work32); +} + +STATIC inline void ROL8 () +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + Work16 = S9xGetByte (OpAddress); + Work16 <<= 1; + Work16 |= CheckCarry (); + ICPU._Carry = Work16 >= 0x100; + S9xSetByte ((uint8) Work16, OpAddress); + SetZN8 ((uint8) Work16); +} + +STATIC inline void A_ROR16 () +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + Work32 = Registers.A.W; + Work32 |= (int) CheckCarry() << 16; + ICPU._Carry = (uint8) (Work32 & 1); + Work32 >>= 1; + Registers.A.W = (uint16) Work32; + SetZN16 ((uint16) Work32); +} + +STATIC inline void A_ROR8 () +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + Work16 = Registers.AL | ((uint16) CheckCarry() << 8); + ICPU._Carry = (uint8) Work16 & 1; + Work16 >>= 1; + Registers.AL = (uint8) Work16; + SetZN8 ((uint8) Work16); +} + +STATIC inline void ROR16 () +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + Work32 = S9xGetWord (OpAddress); + Work32 |= (int) CheckCarry() << 16; + ICPU._Carry = (uint8) (Work32 & 1); + Work32 >>= 1; + S9xSetWord ((uint16) Work32, OpAddress); + SetZN16 ((uint16) Work32); +} + +STATIC inline void ROR8 () +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + Work16 = S9xGetByte (OpAddress); + Work16 |= (int) CheckCarry () << 8; + ICPU._Carry = (uint8) (Work16 & 1); + Work16 >>= 1; + S9xSetByte ((uint8) Work16, OpAddress); + SetZN8 ((uint8) Work16); +} + +STATIC inline void SBC16 () +{ + Work16 = S9xGetWord (OpAddress); + + if (CheckDecimal ()) + { + A1 = (Registers.A.W) & 0xF; + A2 = (Registers.A.W >> 4) & 0xF; + A3 = (Registers.A.W >> 8) & 0xF; + A4 = (Registers.A.W >> 12) & 0xF; + W1 = Work16 & 0xF; + W2 = (Work16 >> 4) & 0xF; + W3 = (Work16 >> 8) & 0xF; + W4 = (Work16 >> 12) & 0xF; + + A1 -= W1 + !CheckCarry (); + A2 -= W2; + A3 -= W3; + A4 -= W4; + if (A1 > 9) + { + A1 += 10; + A2--; + } + if (A2 > 9) + { + A2 += 10; + A3--; + } + if (A3 > 9) + { + A3 += 10; + A4--; + } + if (A4 > 9) + { + A4 += 10; + ClearCarry (); + } + else + { + SetCarry (); + } + + Ans16 = (A4 << 12) | (A3 << 8) | (A2 << 4) | (A1); + if ((Registers.A.W ^ Work16) & + (Registers.A.W ^ Ans16) & 0x8000) + SetOverflow(); + else + ClearOverflow(); + Registers.A.W = Ans16; + SetZN16 (Registers.A.W); + } + else + { + + s9xInt32 = (long) Registers.A.W - (long) Work16 + (long) CheckCarry() - 1; + + ICPU._Carry = s9xInt32 >= 0; + + if ((Registers.A.W ^ Work16) & + (Registers.A.W ^ (uint16) s9xInt32) & 0x8000) + SetOverflow(); + else + ClearOverflow (); + Registers.A.W = (uint16) s9xInt32; + SetZN16 (Registers.A.W); + } +} + +STATIC inline void SBC8 () +{ + Work8 = S9xGetByte (OpAddress); + if (CheckDecimal ()) + { + A1 = (Registers.A.W) & 0xF; + A2 = (Registers.A.W >> 4) & 0xF; + W1 = Work8 & 0xF; + W2 = (Work8 >> 4) & 0xF; + + A1 -= W1 + !CheckCarry (); + A2 -= W2; + if (A1 > 9) + { + A1 += 10; + A2--; + } + if (A2 > 9) + { + A2 += 10; + ClearCarry (); + } + else + { + SetCarry (); + } + + Ans8 = (A2 << 4) | A1; + if ((Registers.AL ^ Work8) & + (Registers.AL ^ Ans8) & 0x80) + SetOverflow (); + else + ClearOverflow (); + Registers.AL = Ans8; + SetZN8 (Registers.AL); + } + else + { + s9xInt16 = (short) Registers.AL - (short) Work8 + (short) CheckCarry() - 1; + + ICPU._Carry = s9xInt16 >= 0; + if ((Registers.AL ^ Work8) & + (Registers.AL ^ (uint8) s9xInt16) & 0x80) + SetOverflow (); + else + ClearOverflow (); + Registers.AL = (uint8) s9xInt16; + SetZN8 (Registers.AL); + } +} + +STATIC inline void STA16 () +{ + S9xSetWord (Registers.A.W, OpAddress); +} + +STATIC inline void STA8 () +{ + S9xSetByte (Registers.AL, OpAddress); +} + +STATIC inline void STX16 () +{ + S9xSetWord (Registers.X.W, OpAddress); +} + +STATIC inline void STX8 () +{ + S9xSetByte (Registers.XL, OpAddress); +} + +STATIC inline void STY16 () +{ + S9xSetWord (Registers.Y.W, OpAddress); +} + +STATIC inline void STY8 () +{ + S9xSetByte (Registers.YL, OpAddress); +} + +STATIC inline void STZ16 () +{ + S9xSetWord (0, OpAddress); +} + +STATIC inline void STZ8 () +{ + S9xSetByte (0, OpAddress); +} + +STATIC inline void TSB16 () +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + Work16 = S9xGetWord (OpAddress); + ICPU._Zero = (Work16 & Registers.A.W) != 0; + Work16 |= Registers.A.W; + S9xSetWord (Work16, OpAddress); +} + +STATIC inline void TSB8 () +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + Work8 = S9xGetByte (OpAddress); + ICPU._Zero = Work8 & Registers.AL; + Work8 |= Registers.AL; + S9xSetByte (Work8, OpAddress); +} + +STATIC inline void TRB16 () +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + Work16 = S9xGetWord (OpAddress); + ICPU._Zero = (Work16 & Registers.A.W) != 0; + Work16 &= ~Registers.A.W; + S9xSetWord (Work16, OpAddress); +} + +STATIC inline void TRB8 () +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + Work8 = S9xGetByte (OpAddress); + ICPU._Zero = Work8 & Registers.AL; + Work8 &= ~Registers.AL; + S9xSetByte (Work8, OpAddress); +} +#endif diff --git a/src/snes4iphone_src/cpuops.cpp b/src/snes4iphone_src/cpuops.cpp new file mode 100755 index 0000000..78ad7d8 --- /dev/null +++ b/src/snes4iphone_src/cpuops.cpp @@ -0,0 +1,4302 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +/**********************************************************************************************/ +/* CPU-S9xOpcodes.CPP */ +/* This file contains all the opcodes */ +/**********************************************************************************************/ + +#include "snes9x.h" +#include "memmap.h" +#include "debug.h" +#include "missing.h" +#include "apu.h" +#include "sa1.h" + +START_EXTERN_C +extern uint8 A1, A2, A3, A4, W1, W2, W3, W4; +extern uint8 Ans8; +extern uint16 Ans16; +extern uint32 Ans32; +extern uint8 Work8; +extern uint16 Work16; +extern uint32 Work32; + +extern signed char s9xInt8; +extern short s9xInt16; +extern long s9xInt32; +END_EXTERN_C + +#include "cpuexec.h" +#include "cpuaddr.h" +#include "cpuops.h" +#include "cpumacro.h" +#include "apu.h" + +/* ADC *************************************************************************************** */ +static void Op69M1 (void) +{ + Immediate8 (); + ADC8 (); +} + +static void Op69M0 (void) +{ + Immediate16 (); + ADC16 (); +} + +static void Op65M1 (void) +{ + Direct (); + ADC8 (); +} + +static void Op65M0 (void) +{ + Direct (); + ADC16 (); +} + +static void Op75M1 (void) +{ + DirectIndexedX (); + ADC8 (); +} + +static void Op75M0 (void) +{ + DirectIndexedX (); + ADC16 (); +} + +static void Op72M1 (void) +{ + DirectIndirect (); + ADC8 (); +} + +static void Op72M0 (void) +{ + DirectIndirect (); + ADC16 (); +} + +static void Op61M1 (void) +{ + DirectIndexedIndirect (); + ADC8 (); +} + +static void Op61M0 (void) +{ + DirectIndexedIndirect (); + ADC16 (); +} + +static void Op71M1 (void) +{ + DirectIndirectIndexed (); + ADC8 (); +} + +static void Op71M0 (void) +{ + DirectIndirectIndexed (); + ADC16 (); +} + +static void Op67M1 (void) +{ + DirectIndirectLong (); + ADC8 (); +} + +static void Op67M0 (void) +{ + DirectIndirectLong (); + ADC16 (); +} + +static void Op77M1 (void) +{ + DirectIndirectIndexedLong (); + ADC8 (); +} + +static void Op77M0 (void) +{ + DirectIndirectIndexedLong (); + ADC16 (); +} + +static void Op6DM1 (void) +{ + Absolute (); + ADC8 (); +} + +static void Op6DM0 (void) +{ + Absolute (); + ADC16 (); +} + +static void Op7DM1 (void) +{ + AbsoluteIndexedX (); + ADC8 (); +} + +static void Op7DM0 (void) +{ + AbsoluteIndexedX (); + ADC16 (); +} + +static void Op79M1 (void) +{ + AbsoluteIndexedY (); + ADC8 (); +} + +static void Op79M0 (void) +{ + AbsoluteIndexedY (); + ADC16 (); +} + +static void Op6FM1 (void) +{ + AbsoluteLong (); + ADC8 (); +} + +static void Op6FM0 (void) +{ + AbsoluteLong (); + ADC16 (); +} + +static void Op7FM1 (void) +{ + AbsoluteLongIndexedX (); + ADC8 (); +} + +static void Op7FM0 (void) +{ + AbsoluteLongIndexedX (); + ADC16 (); +} + +static void Op63M1 (void) +{ + StackRelative (); + ADC8 (); +} + +static void Op63M0 (void) +{ + StackRelative (); + ADC16 (); +} + +static void Op73M1 (void) +{ + StackRelativeIndirectIndexed (); + ADC8 (); +} + +static void Op73M0 (void) +{ + StackRelativeIndirectIndexed (); + ADC16 (); +} + +/**********************************************************************************************/ + +/* AND *************************************************************************************** */ +static void Op29M1 (void) +{ + Registers.AL &= *CPU.PC++; +#ifdef VAR_CYCLES + CPU.Cycles += CPU.MemSpeed; +#endif + SetZN8 (Registers.AL); +} + +static void Op29M0 (void) +{ +#ifdef FAST_LSB_WORD_ACCESS + Registers.A.W &= *(uint16 *) CPU.PC; +#else + Registers.A.W &= *CPU.PC + (*(CPU.PC + 1) << 8); +#endif + CPU.PC += 2; +#ifdef VAR_CYCLES + CPU.Cycles += CPU.MemSpeedx2; +#endif + SetZN16 (Registers.A.W); +} + +static void Op25M1 (void) +{ + Direct (); + AND8 (); +} + +static void Op25M0 (void) +{ + Direct (); + AND16 (); +} + +static void Op35M1 (void) +{ + DirectIndexedX (); + AND8 (); +} + +static void Op35M0 (void) +{ + DirectIndexedX (); + AND16 (); +} + +static void Op32M1 (void) +{ + DirectIndirect (); + AND8 (); +} + +static void Op32M0 (void) +{ + DirectIndirect (); + AND16 (); +} + +static void Op21M1 (void) +{ + DirectIndexedIndirect (); + AND8 (); +} + +static void Op21M0 (void) +{ + DirectIndexedIndirect (); + AND16 (); +} + +static void Op31M1 (void) +{ + DirectIndirectIndexed (); + AND8 (); +} + +static void Op31M0 (void) +{ + DirectIndirectIndexed (); + AND16 (); +} + +static void Op27M1 (void) +{ + DirectIndirectLong (); + AND8 (); +} + +static void Op27M0 (void) +{ + DirectIndirectLong (); + AND16 (); +} + +static void Op37M1 (void) +{ + DirectIndirectIndexedLong (); + AND8 (); +} + +static void Op37M0 (void) +{ + DirectIndirectIndexedLong (); + AND16 (); +} + +static void Op2DM1 (void) +{ + Absolute (); + AND8 (); +} + +static void Op2DM0 (void) +{ + Absolute (); + AND16 (); +} + +static void Op3DM1 (void) +{ + AbsoluteIndexedX (); + AND8 (); +} + +static void Op3DM0 (void) +{ + AbsoluteIndexedX (); + AND16 (); +} + +static void Op39M1 (void) +{ + AbsoluteIndexedY (); + AND8 (); +} + +static void Op39M0 (void) +{ + AbsoluteIndexedY (); + AND16 (); +} + +static void Op2FM1 (void) +{ + AbsoluteLong (); + AND8 (); +} + +static void Op2FM0 (void) +{ + AbsoluteLong (); + AND16 (); +} + +static void Op3FM1 (void) +{ + AbsoluteLongIndexedX (); + AND8 (); +} + +static void Op3FM0 (void) +{ + AbsoluteLongIndexedX (); + AND16 (); +} + +static void Op23M1 (void) +{ + StackRelative (); + AND8 (); +} + +static void Op23M0 (void) +{ + StackRelative (); + AND16 (); +} + +static void Op33M1 (void) +{ + StackRelativeIndirectIndexed (); + AND8 (); +} + +static void Op33M0 (void) +{ + StackRelativeIndirectIndexed (); + AND16 (); +} +/**********************************************************************************************/ + +/* ASL *************************************************************************************** */ +static void Op0AM1 (void) +{ + A_ASL8 (); +} + +static void Op0AM0 (void) +{ + A_ASL16 (); +} + +static void Op06M1 (void) +{ + Direct (); + ASL8 (); +} + +static void Op06M0 (void) +{ + Direct (); + ASL16 (); +} + +static void Op16M1 (void) +{ + DirectIndexedX (); + ASL8 (); +} + +static void Op16M0 (void) +{ + DirectIndexedX (); + ASL16 (); +} + +static void Op0EM1 (void) +{ + Absolute (); + ASL8 (); +} + +static void Op0EM0 (void) +{ + Absolute (); + ASL16 (); +} + +static void Op1EM1 (void) +{ + AbsoluteIndexedX (); + ASL8 (); +} + +static void Op1EM0 (void) +{ + AbsoluteIndexedX (); + ASL16 (); +} +/**********************************************************************************************/ + +/* BIT *************************************************************************************** */ +static void Op89M1 (void) +{ + ICPU._Zero = Registers.AL & *CPU.PC++; +#ifdef VAR_CYCLES + CPU.Cycles += CPU.MemSpeed; +#endif +} + +static void Op89M0 (void) +{ +#ifdef FAST_LSB_WORD_ACCESS + ICPU._Zero = (Registers.A.W & *(uint16 *) CPU.PC) != 0; +#else + ICPU._Zero = (Registers.A.W & (*CPU.PC + (*(CPU.PC + 1) << 8))) != 0; +#endif +#ifdef VAR_CYCLES + CPU.Cycles += CPU.MemSpeedx2; +#endif + CPU.PC += 2; +} + +static void Op24M1 (void) +{ + Direct (); + BIT8 (); +} + +static void Op24M0 (void) +{ + Direct (); + BIT16 (); +} + +static void Op34M1 (void) +{ + DirectIndexedX (); + BIT8 (); +} + +static void Op34M0 (void) +{ + DirectIndexedX (); + BIT16 (); +} + +static void Op2CM1 (void) +{ + Absolute (); + BIT8 (); +} + +static void Op2CM0 (void) +{ + Absolute (); + BIT16 (); +} + +static void Op3CM1 (void) +{ + AbsoluteIndexedX (); + BIT8 (); +} + +static void Op3CM0 (void) +{ + AbsoluteIndexedX (); + BIT16 (); +} +/**********************************************************************************************/ + +/* CMP *************************************************************************************** */ +static void OpC9M1 (void) +{ + s9xInt32 = (int) Registers.AL - (int) *CPU.PC++; + ICPU._Carry = s9xInt32 >= 0; + SetZN8 ((uint8) s9xInt32); +#ifdef VAR_CYCLES + CPU.Cycles += CPU.MemSpeed; +#endif +} + +static void OpC9M0 (void) +{ +#ifdef FAST_LSB_WORD_ACCESS + s9xInt32 = (long) Registers.A.W - (long) *(uint16 *) CPU.PC; +#else + s9xInt32 = (long) Registers.A.W - + (long) (*CPU.PC + (*(CPU.PC + 1) << 8)); +#endif + ICPU._Carry = s9xInt32 >= 0; + SetZN16 ((uint16) s9xInt32); + CPU.PC += 2; +#ifdef VAR_CYCLES + CPU.Cycles += CPU.MemSpeedx2; +#endif +} + +static void OpC5M1 (void) +{ + Direct (); + CMP8 (); +} + +static void OpC5M0 (void) +{ + Direct (); + CMP16 (); +} + +static void OpD5M1 (void) +{ + DirectIndexedX (); + CMP8 (); +} + +static void OpD5M0 (void) +{ + DirectIndexedX (); + CMP16 (); +} + +static void OpD2M1 (void) +{ + DirectIndirect (); + CMP8 (); +} + +static void OpD2M0 (void) +{ + DirectIndirect (); + CMP16 (); +} + +static void OpC1M1 (void) +{ + DirectIndexedIndirect (); + CMP8 (); +} + +static void OpC1M0 (void) +{ + DirectIndexedIndirect (); + CMP16 (); +} + +static void OpD1M1 (void) +{ + DirectIndirectIndexed (); + CMP8 (); +} + +static void OpD1M0 (void) +{ + DirectIndirectIndexed (); + CMP16 (); +} + +static void OpC7M1 (void) +{ + DirectIndirectLong (); + CMP8 (); +} + +static void OpC7M0 (void) +{ + DirectIndirectLong (); + CMP16 (); +} + +static void OpD7M1 (void) +{ + DirectIndirectIndexedLong (); + CMP8 (); +} + +static void OpD7M0 (void) +{ + DirectIndirectIndexedLong (); + CMP16 (); +} + +static void OpCDM1 (void) +{ + Absolute (); + CMP8 (); +} + +static void OpCDM0 (void) +{ + Absolute (); + CMP16 (); +} + +static void OpDDM1 (void) +{ + AbsoluteIndexedX (); + CMP8 (); +} + +static void OpDDM0 (void) +{ + AbsoluteIndexedX (); + CMP16 (); +} + +static void OpD9M1 (void) +{ + AbsoluteIndexedY (); + CMP8 (); +} + +static void OpD9M0 (void) +{ + AbsoluteIndexedY (); + CMP16 (); +} + +static void OpCFM1 (void) +{ + AbsoluteLong (); + CMP8 (); +} + +static void OpCFM0 (void) +{ + AbsoluteLong (); + CMP16 (); +} + +static void OpDFM1 (void) +{ + AbsoluteLongIndexedX (); + CMP8 (); +} + +static void OpDFM0 (void) +{ + AbsoluteLongIndexedX (); + CMP16 (); +} + +static void OpC3M1 (void) +{ + StackRelative (); + CMP8 (); +} + +static void OpC3M0 (void) +{ + StackRelative (); + CMP16 (); +} + +static void OpD3M1 (void) +{ + StackRelativeIndirectIndexed (); + CMP8 (); +} + +static void OpD3M0 (void) +{ + StackRelativeIndirectIndexed (); + CMP16 (); +} + +/**********************************************************************************************/ + +/* CMX *************************************************************************************** */ +static void OpE0X1 (void) +{ + s9xInt32 = (int) Registers.XL - (int) *CPU.PC++; + ICPU._Carry = s9xInt32 >= 0; + SetZN8 ((uint8) s9xInt32); +#ifdef VAR_CYCLES + CPU.Cycles += CPU.MemSpeed; +#endif +} + +static void OpE0X0 (void) +{ +#ifdef FAST_LSB_WORD_ACCESS + s9xInt32 = (long) Registers.X.W - (long) *(uint16 *) CPU.PC; +#else + s9xInt32 = (long) Registers.X.W - + (long) (*CPU.PC + (*(CPU.PC + 1) << 8)); +#endif + ICPU._Carry = s9xInt32 >= 0; + SetZN16 ((uint16) s9xInt32); + CPU.PC += 2; +#ifdef VAR_CYCLES + CPU.Cycles += CPU.MemSpeedx2; +#endif +} + +static void OpE4X1 (void) +{ + Direct (); + CMX8 (); +} + +static void OpE4X0 (void) +{ + Direct (); + CMX16 (); +} + +static void OpECX1 (void) +{ + Absolute (); + CMX8 (); +} + +static void OpECX0 (void) +{ + Absolute (); + CMX16 (); +} + +/**********************************************************************************************/ + +/* CMY *************************************************************************************** */ +static void OpC0X1 (void) +{ + s9xInt32 = (int) Registers.YL - (int) *CPU.PC++; + ICPU._Carry = s9xInt32 >= 0; + SetZN8 ((uint8) s9xInt32); +#ifdef VAR_CYCLES + CPU.Cycles += CPU.MemSpeed; +#endif +} + +static void OpC0X0 (void) +{ +#ifdef FAST_LSB_WORD_ACCESS + s9xInt32 = (long) Registers.Y.W - (long) *(uint16 *) CPU.PC; +#else + s9xInt32 = (long) Registers.Y.W - + (long) (*CPU.PC + (*(CPU.PC + 1) << 8)); +#endif + ICPU._Carry = s9xInt32 >= 0; + SetZN16 ((uint16) s9xInt32); + CPU.PC += 2; +#ifdef VAR_CYCLES + CPU.Cycles += CPU.MemSpeedx2; +#endif +} + +static void OpC4X1 (void) +{ + Direct (); + CMY8 (); +} + +static void OpC4X0 (void) +{ + Direct (); + CMY16 (); +} + +static void OpCCX1 (void) +{ + Absolute (); + CMY8 (); +} + +static void OpCCX0 (void) +{ + Absolute (); + CMY16 (); +} + +/**********************************************************************************************/ + +/* DEC *************************************************************************************** */ +static void Op3AM1 (void) +{ + A_DEC8 (); +} + +static void Op3AM0 (void) +{ + A_DEC16 (); +} + +static void OpC6M1 (void) +{ + Direct (); + DEC8 (); +} + +static void OpC6M0 (void) +{ + Direct (); + DEC16 (); +} + +static void OpD6M1 (void) +{ + DirectIndexedX (); + DEC8 (); +} + +static void OpD6M0 (void) +{ + DirectIndexedX (); + DEC16 (); +} + +static void OpCEM1 (void) +{ + Absolute (); + DEC8 (); +} + +static void OpCEM0 (void) +{ + Absolute (); + DEC16 (); +} + +static void OpDEM1 (void) +{ + AbsoluteIndexedX (); + DEC8 (); +} + +static void OpDEM0 (void) +{ + AbsoluteIndexedX (); + DEC16 (); +} + +/**********************************************************************************************/ + +/* EOR *************************************************************************************** */ +static void Op49M1 (void) +{ + Registers.AL ^= *CPU.PC++; +#ifdef VAR_CYCLES + CPU.Cycles += CPU.MemSpeed; +#endif + SetZN8 (Registers.AL); +} + +static void Op49M0 (void) +{ +#ifdef FAST_LSB_WORD_ACCESS + Registers.A.W ^= *(uint16 *) CPU.PC; +#else + Registers.A.W ^= *CPU.PC + (*(CPU.PC + 1) << 8); +#endif + CPU.PC += 2; +#ifdef VAR_CYCLES + CPU.Cycles += CPU.MemSpeedx2; +#endif + SetZN16 (Registers.A.W); +} + +static void Op45M1 (void) +{ + Direct (); + EOR8 (); +} + +static void Op45M0 (void) +{ + Direct (); + EOR16 (); +} + +static void Op55M1 (void) +{ + DirectIndexedX (); + EOR8 (); +} + +static void Op55M0 (void) +{ + DirectIndexedX (); + EOR16 (); +} + +static void Op52M1 (void) +{ + DirectIndirect (); + EOR8 (); +} + +static void Op52M0 (void) +{ + DirectIndirect (); + EOR16 (); +} + +static void Op41M1 (void) +{ + DirectIndexedIndirect (); + EOR8 (); +} + +static void Op41M0 (void) +{ + DirectIndexedIndirect (); + EOR16 (); +} + +static void Op51M1 (void) +{ + DirectIndirectIndexed (); + EOR8 (); +} + +static void Op51M0 (void) +{ + DirectIndirectIndexed (); + EOR16 (); +} + +static void Op47M1 (void) +{ + DirectIndirectLong (); + EOR8 (); +} + +static void Op47M0 (void) +{ + DirectIndirectLong (); + EOR16 (); +} + +static void Op57M1 (void) +{ + DirectIndirectIndexedLong (); + EOR8 (); +} + +static void Op57M0 (void) +{ + DirectIndirectIndexedLong (); + EOR16 (); +} + +static void Op4DM1 (void) +{ + Absolute (); + EOR8 (); +} + +static void Op4DM0 (void) +{ + Absolute (); + EOR16 (); +} + +static void Op5DM1 (void) +{ + AbsoluteIndexedX (); + EOR8 (); +} + +static void Op5DM0 (void) +{ + AbsoluteIndexedX (); + EOR16 (); +} + +static void Op59M1 (void) +{ + AbsoluteIndexedY (); + EOR8 (); +} + +static void Op59M0 (void) +{ + AbsoluteIndexedY (); + EOR16 (); +} + +static void Op4FM1 (void) +{ + AbsoluteLong (); + EOR8 (); +} + +static void Op4FM0 (void) +{ + AbsoluteLong (); + EOR16 (); +} + +static void Op5FM1 (void) +{ + AbsoluteLongIndexedX (); + EOR8 (); +} + +static void Op5FM0 (void) +{ + AbsoluteLongIndexedX (); + EOR16 (); +} + +static void Op43M1 (void) +{ + StackRelative (); + EOR8 (); +} + +static void Op43M0 (void) +{ + StackRelative (); + EOR16 (); +} + +static void Op53M1 (void) +{ + StackRelativeIndirectIndexed (); + EOR8 (); +} + +static void Op53M0 (void) +{ + StackRelativeIndirectIndexed (); + EOR16 (); +} + +/**********************************************************************************************/ + +/* INC *************************************************************************************** */ +static void Op1AM1 (void) +{ + A_INC8 (); +} + +static void Op1AM0 (void) +{ + A_INC16 (); +} + +static void OpE6M1 (void) +{ + Direct (); + INC8 (); +} + +static void OpE6M0 (void) +{ + Direct (); + INC16 (); +} + +static void OpF6M1 (void) +{ + DirectIndexedX (); + INC8 (); +} + +static void OpF6M0 (void) +{ + DirectIndexedX (); + INC16 (); +} + +static void OpEEM1 (void) +{ + Absolute (); + INC8 (); +} + +static void OpEEM0 (void) +{ + Absolute (); + INC16 (); +} + +static void OpFEM1 (void) +{ + AbsoluteIndexedX (); + INC8 (); +} + +static void OpFEM0 (void) +{ + AbsoluteIndexedX (); + INC16 (); +} + +/**********************************************************************************************/ +/* LDA *************************************************************************************** */ +static void OpA9M1 (void) +{ + Registers.AL = *CPU.PC++; +#ifdef VAR_CYCLES + CPU.Cycles += CPU.MemSpeed; +#endif + SetZN8 (Registers.AL); +} + +static void OpA9M0 (void) +{ +#ifdef FAST_LSB_WORD_ACCESS + Registers.A.W = *(uint16 *) CPU.PC; +#else + Registers.A.W = *CPU.PC + (*(CPU.PC + 1) << 8); +#endif + + CPU.PC += 2; +#ifdef VAR_CYCLES + CPU.Cycles += CPU.MemSpeedx2; +#endif + SetZN16 (Registers.A.W); +} + +static void OpA5M1 (void) +{ + Direct (); + LDA8 (); +} + +static void OpA5M0 (void) +{ + Direct (); + LDA16 (); +} + +static void OpB5M1 (void) +{ + DirectIndexedX (); + LDA8 (); +} + +static void OpB5M0 (void) +{ + DirectIndexedX (); + LDA16 (); +} + +static void OpB2M1 (void) +{ + DirectIndirect (); + LDA8 (); +} + +static void OpB2M0 (void) +{ + DirectIndirect (); + LDA16 (); +} + +static void OpA1M1 (void) +{ + DirectIndexedIndirect (); + LDA8 (); +} + +static void OpA1M0 (void) +{ + DirectIndexedIndirect (); + LDA16 (); +} + +static void OpB1M1 (void) +{ + DirectIndirectIndexed (); + LDA8 (); +} + +static void OpB1M0 (void) +{ + DirectIndirectIndexed (); + LDA16 (); +} + +static void OpA7M1 (void) +{ + DirectIndirectLong (); + LDA8 (); +} + +static void OpA7M0 (void) +{ + DirectIndirectLong (); + LDA16 (); +} + +static void OpB7M1 (void) +{ + DirectIndirectIndexedLong (); + LDA8 (); +} + +static void OpB7M0 (void) +{ + DirectIndirectIndexedLong (); + LDA16 (); +} + +static void OpADM1 (void) +{ + Absolute (); + LDA8 (); +} + +static void OpADM0 (void) +{ + Absolute (); + LDA16 (); +} + +static void OpBDM1 (void) +{ + AbsoluteIndexedX (); + LDA8 (); +} + +static void OpBDM0 (void) +{ + AbsoluteIndexedX (); + LDA16 (); +} + +static void OpB9M1 (void) +{ + AbsoluteIndexedY (); + LDA8 (); +} + +static void OpB9M0 (void) +{ + AbsoluteIndexedY (); + LDA16 (); +} + +static void OpAFM1 (void) +{ + AbsoluteLong (); + LDA8 (); +} + +static void OpAFM0 (void) +{ + AbsoluteLong (); + LDA16 (); +} + +static void OpBFM1 (void) +{ + AbsoluteLongIndexedX (); + LDA8 (); +} + +static void OpBFM0 (void) +{ + AbsoluteLongIndexedX (); + LDA16 (); +} + +static void OpA3M1 (void) +{ + StackRelative (); + LDA8 (); +} + +static void OpA3M0 (void) +{ + StackRelative (); + LDA16 (); +} + +static void OpB3M1 (void) +{ + StackRelativeIndirectIndexed (); + LDA8 (); +} + +static void OpB3M0 (void) +{ + StackRelativeIndirectIndexed (); + LDA16 (); +} + +/**********************************************************************************************/ + +/* LDX *************************************************************************************** */ +static void OpA2X1 (void) +{ + Registers.XL = *CPU.PC++; +#ifdef VAR_CYCLES + CPU.Cycles += CPU.MemSpeed; +#endif + SetZN8 (Registers.XL); +} + +static void OpA2X0 (void) +{ +#ifdef FAST_LSB_WORD_ACCESS + Registers.X.W = *(uint16 *) CPU.PC; +#else + Registers.X.W = *CPU.PC + (*(CPU.PC + 1) << 8); +#endif + CPU.PC += 2; +#ifdef VAR_CYCLES + CPU.Cycles += CPU.MemSpeedx2; +#endif + SetZN16 (Registers.X.W); +} + +static void OpA6X1 (void) +{ + Direct (); + LDX8 (); +} + +static void OpA6X0 (void) +{ + Direct (); + LDX16 (); +} + +static void OpB6X1 (void) +{ + DirectIndexedY (); + LDX8 (); +} + +static void OpB6X0 (void) +{ + DirectIndexedY (); + LDX16 (); +} + +static void OpAEX1 (void) +{ + Absolute (); + LDX8 (); +} + +static void OpAEX0 (void) +{ + Absolute (); + LDX16 (); +} + +static void OpBEX1 (void) +{ + AbsoluteIndexedY (); + LDX8 (); +} + +static void OpBEX0 (void) +{ + AbsoluteIndexedY (); + LDX16 (); +} +/**********************************************************************************************/ + +/* LDY *************************************************************************************** */ +static void OpA0X1 (void) +{ + Registers.YL = *CPU.PC++; +#ifdef VAR_CYCLES + CPU.Cycles += CPU.MemSpeed; +#endif + SetZN8 (Registers.YL); +} + +static void OpA0X0 (void) +{ +#ifdef FAST_LSB_WORD_ACCESS + Registers.Y.W = *(uint16 *) CPU.PC; +#else + Registers.Y.W = *CPU.PC + (*(CPU.PC + 1) << 8); +#endif + + CPU.PC += 2; +#ifdef VAR_CYCLES + CPU.Cycles += CPU.MemSpeedx2; +#endif + SetZN16 (Registers.Y.W); +} + +static void OpA4X1 (void) +{ + Direct (); + LDY8 (); +} + +static void OpA4X0 (void) +{ + Direct (); + LDY16 (); +} + +static void OpB4X1 (void) +{ + DirectIndexedX (); + LDY8 (); +} + +static void OpB4X0 (void) +{ + DirectIndexedX (); + LDY16 (); +} + +static void OpACX1 (void) +{ + Absolute (); + LDY8 (); +} + +static void OpACX0 (void) +{ + Absolute (); + LDY16 (); +} + +static void OpBCX1 (void) +{ + AbsoluteIndexedX (); + LDY8 (); +} + +static void OpBCX0 (void) +{ + AbsoluteIndexedX (); + LDY16 (); +} +/**********************************************************************************************/ + +/* LSR *************************************************************************************** */ +static void Op4AM1 (void) +{ + A_LSR8 (); +} + +static void Op4AM0 (void) +{ + A_LSR16 (); +} + +static void Op46M1 (void) +{ + Direct (); + LSR8 (); +} + +static void Op46M0 (void) +{ + Direct (); + LSR16 (); +} + +static void Op56M1 (void) +{ + DirectIndexedX (); + LSR8 (); +} + +static void Op56M0 (void) +{ + DirectIndexedX (); + LSR16 (); +} + +static void Op4EM1 (void) +{ + Absolute (); + LSR8 (); +} + +static void Op4EM0 (void) +{ + Absolute (); + LSR16 (); +} + +static void Op5EM1 (void) +{ + AbsoluteIndexedX (); + LSR8 (); +} + +static void Op5EM0 (void) +{ + AbsoluteIndexedX (); + LSR16 (); +} + +/**********************************************************************************************/ + +/* ORA *************************************************************************************** */ +static void Op09M1 (void) +{ + Registers.AL |= *CPU.PC++; +#ifdef VAR_CYCLES + CPU.Cycles += CPU.MemSpeed; +#endif + SetZN8 (Registers.AL); +} + +static void Op09M0 (void) +{ +#ifdef FAST_LSB_WORD_ACCESS + Registers.A.W |= *(uint16 *) CPU.PC; +#else + Registers.A.W |= *CPU.PC + (*(CPU.PC + 1) << 8); +#endif + CPU.PC += 2; +#ifdef VAR_CYCLES + CPU.Cycles += CPU.MemSpeedx2; +#endif + SetZN16 (Registers.A.W); +} + +static void Op05M1 (void) +{ + Direct (); + ORA8 (); +} + +static void Op05M0 (void) +{ + Direct (); + ORA16 (); +} + +static void Op15M1 (void) +{ + DirectIndexedX (); + ORA8 (); +} + +static void Op15M0 (void) +{ + DirectIndexedX (); + ORA16 (); +} + +static void Op12M1 (void) +{ + DirectIndirect (); + ORA8 (); +} + +static void Op12M0 (void) +{ + DirectIndirect (); + ORA16 (); +} + +static void Op01M1 (void) +{ + DirectIndexedIndirect (); + ORA8 (); +} + +static void Op01M0 (void) +{ + DirectIndexedIndirect (); + ORA16 (); +} + +static void Op11M1 (void) +{ + DirectIndirectIndexed (); + ORA8 (); +} + +static void Op11M0 (void) +{ + DirectIndirectIndexed (); + ORA16 (); +} + +static void Op07M1 (void) +{ + DirectIndirectLong (); + ORA8 (); +} + +static void Op07M0 (void) +{ + DirectIndirectLong (); + ORA16 (); +} + +static void Op17M1 (void) +{ + DirectIndirectIndexedLong (); + ORA8 (); +} + +static void Op17M0 (void) +{ + DirectIndirectIndexedLong (); + ORA16 (); +} + +static void Op0DM1 (void) +{ + Absolute (); + ORA8 (); +} + +static void Op0DM0 (void) +{ + Absolute (); + ORA16 (); +} + +static void Op1DM1 (void) +{ + AbsoluteIndexedX (); + ORA8 (); +} + +static void Op1DM0 (void) +{ + AbsoluteIndexedX (); + ORA16 (); +} + +static void Op19M1 (void) +{ + AbsoluteIndexedY (); + ORA8 (); +} + +static void Op19M0 (void) +{ + AbsoluteIndexedY (); + ORA16 (); +} + +static void Op0FM1 (void) +{ + AbsoluteLong (); + ORA8 (); +} + +static void Op0FM0 (void) +{ + AbsoluteLong (); + ORA16 (); +} + +static void Op1FM1 (void) +{ + AbsoluteLongIndexedX (); + ORA8 (); +} + +static void Op1FM0 (void) +{ + AbsoluteLongIndexedX (); + ORA16 (); +} + +static void Op03M1 (void) +{ + StackRelative (); + ORA8 (); +} + +static void Op03M0 (void) +{ + StackRelative (); + ORA16 (); +} + +static void Op13M1 (void) +{ + StackRelativeIndirectIndexed (); + ORA8 (); +} + +static void Op13M0 (void) +{ + StackRelativeIndirectIndexed (); + ORA16 (); +} + +/**********************************************************************************************/ + +/* ROL *************************************************************************************** */ +static void Op2AM1 (void) +{ + A_ROL8 (); +} + +static void Op2AM0 (void) +{ + A_ROL16 (); +} + +static void Op26M1 (void) +{ + Direct (); + ROL8 (); +} + +static void Op26M0 (void) +{ + Direct (); + ROL16 (); +} + +static void Op36M1 (void) +{ + DirectIndexedX (); + ROL8 (); +} + +static void Op36M0 (void) +{ + DirectIndexedX (); + ROL16 (); +} + +static void Op2EM1 (void) +{ + Absolute (); + ROL8 (); +} + +static void Op2EM0 (void) +{ + Absolute (); + ROL16 (); +} + +static void Op3EM1 (void) +{ + AbsoluteIndexedX (); + ROL8 (); +} + +static void Op3EM0 (void) +{ + AbsoluteIndexedX (); + ROL16 (); +} +/**********************************************************************************************/ + +/* ROR *************************************************************************************** */ +static void Op6AM1 (void) +{ + A_ROR8 (); +} + +static void Op6AM0 (void) +{ + A_ROR16 (); +} + +static void Op66M1 (void) +{ + Direct (); + ROR8 (); +} + +static void Op66M0 (void) +{ + Direct (); + ROR16 (); +} + +static void Op76M1 (void) +{ + DirectIndexedX (); + ROR8 (); +} + +static void Op76M0 (void) +{ + DirectIndexedX (); + ROR16 (); +} + +static void Op6EM1 (void) +{ + Absolute (); + ROR8 (); +} + +static void Op6EM0 (void) +{ + Absolute (); + ROR16 (); +} + +static void Op7EM1 (void) +{ + AbsoluteIndexedX (); + ROR8 (); +} + +static void Op7EM0 (void) +{ + AbsoluteIndexedX (); + ROR16 (); +} +/**********************************************************************************************/ + +/* SBC *************************************************************************************** */ +static void OpE9M1 (void) +{ + Immediate8 (); + SBC8 (); +} + +static void OpE9M0 (void) +{ + Immediate16 (); + SBC16 (); +} + +static void OpE5M1 (void) +{ + Direct (); + SBC8 (); +} + +static void OpE5M0 (void) +{ + Direct (); + SBC16 (); +} + +static void OpF5M1 (void) +{ + DirectIndexedX (); + SBC8 (); +} + +static void OpF5M0 (void) +{ + DirectIndexedX (); + SBC16 (); +} + +static void OpF2M1 (void) +{ + DirectIndirect (); + SBC8 (); +} + +static void OpF2M0 (void) +{ + DirectIndirect (); + SBC16 (); +} + +static void OpE1M1 (void) +{ + DirectIndexedIndirect (); + SBC8 (); +} + +static void OpE1M0 (void) +{ + DirectIndexedIndirect (); + SBC16 (); +} + +static void OpF1M1 (void) +{ + DirectIndirectIndexed (); + SBC8 (); +} + +static void OpF1M0 (void) +{ + DirectIndirectIndexed (); + SBC16 (); +} + +static void OpE7M1 (void) +{ + DirectIndirectLong (); + SBC8 (); +} + +static void OpE7M0 (void) +{ + DirectIndirectLong (); + SBC16 (); +} + +static void OpF7M1 (void) +{ + DirectIndirectIndexedLong (); + SBC8 (); +} + +static void OpF7M0 (void) +{ + DirectIndirectIndexedLong (); + SBC16 (); +} + +static void OpEDM1 (void) +{ + Absolute (); + SBC8 (); +} + +static void OpEDM0 (void) +{ + Absolute (); + SBC16 (); +} + +static void OpFDM1 (void) +{ + AbsoluteIndexedX (); + SBC8 (); +} + +static void OpFDM0 (void) +{ + AbsoluteIndexedX (); + SBC16 (); +} + +static void OpF9M1 (void) +{ + AbsoluteIndexedY (); + SBC8 (); +} + +static void OpF9M0 (void) +{ + AbsoluteIndexedY (); + SBC16 (); +} + +static void OpEFM1 (void) +{ + AbsoluteLong (); + SBC8 (); +} + +static void OpEFM0 (void) +{ + AbsoluteLong (); + SBC16 (); +} + +static void OpFFM1 (void) +{ + AbsoluteLongIndexedX (); + SBC8 (); +} + +static void OpFFM0 (void) +{ + AbsoluteLongIndexedX (); + SBC16 (); +} + +static void OpE3M1 (void) +{ + StackRelative (); + SBC8 (); +} + +static void OpE3M0 (void) +{ + StackRelative (); + SBC16 (); +} + +static void OpF3M1 (void) +{ + StackRelativeIndirectIndexed (); + SBC8 (); +} + +static void OpF3M0 (void) +{ + StackRelativeIndirectIndexed (); + SBC16 (); +} +/**********************************************************************************************/ + +/* STA *************************************************************************************** */ +static void Op85M1 (void) +{ + Direct (); + STA8 (); +} + +static void Op85M0 (void) +{ + Direct (); + STA16 (); +} + +static void Op95M1 (void) +{ + DirectIndexedX (); + STA8 (); +} + +static void Op95M0 (void) +{ + DirectIndexedX (); + STA16 (); +} + +static void Op92M1 (void) +{ + DirectIndirect (); + STA8 (); +} + +static void Op92M0 (void) +{ + DirectIndirect (); + STA16 (); +} + +static void Op81M1 (void) +{ + DirectIndexedIndirect (); + STA8 (); +#ifdef noVAR_CYCLES + if (CheckIndex ()) + CPU.Cycles += ONE_CYCLE; +#endif +} + +static void Op81M0 (void) +{ + DirectIndexedIndirect (); + STA16 (); +#ifdef noVAR_CYCLES + if (CheckIndex ()) + CPU.Cycles += ONE_CYCLE; +#endif +} + +static void Op91M1 (void) +{ + DirectIndirectIndexed (); + STA8 (); +} + +static void Op91M0 (void) +{ + DirectIndirectIndexed (); + STA16 (); +} + +static void Op87M1 (void) +{ + DirectIndirectLong (); + STA8 (); +} + +static void Op87M0 (void) +{ + DirectIndirectLong (); + STA16 (); +} + +static void Op97M1 (void) +{ + DirectIndirectIndexedLong (); + STA8 (); +} + +static void Op97M0 (void) +{ + DirectIndirectIndexedLong (); + STA16 (); +} + +static void Op8DM1 (void) +{ + Absolute (); + STA8 (); +} + +static void Op8DM0 (void) +{ + Absolute (); + STA16 (); +} + +static void Op9DM1 (void) +{ + AbsoluteIndexedX (); + STA8 (); +} + +static void Op9DM0 (void) +{ + AbsoluteIndexedX (); + STA16 (); +} + +static void Op99M1 (void) +{ + AbsoluteIndexedY (); + STA8 (); +} + +static void Op99M0 (void) +{ + AbsoluteIndexedY (); + STA16 (); +} + +static void Op8FM1 (void) +{ + AbsoluteLong (); + STA8 (); +} + +static void Op8FM0 (void) +{ + AbsoluteLong (); + STA16 (); +} + +static void Op9FM1 (void) +{ + AbsoluteLongIndexedX (); + STA8 (); +} + +static void Op9FM0 (void) +{ + AbsoluteLongIndexedX (); + STA16 (); +} + +static void Op83M1 (void) +{ + StackRelative (); + STA8 (); +} + +static void Op83M0 (void) +{ + StackRelative (); + STA16 (); +} + +static void Op93M1 (void) +{ + StackRelativeIndirectIndexed (); + STA8 (); +} + +static void Op93M0 (void) +{ + StackRelativeIndirectIndexed (); + STA16 (); +} +/**********************************************************************************************/ + +/* STX *************************************************************************************** */ +static void Op86X1 (void) +{ + Direct (); + STX8 (); +} + +static void Op86X0 (void) +{ + Direct (); + STX16 (); +} + +static void Op96X1 (void) +{ + DirectIndexedY (); + STX8 (); +} + +static void Op96X0 (void) +{ + DirectIndexedY (); + STX16 (); +} + +static void Op8EX1 (void) +{ + Absolute (); + STX8 (); +} + +static void Op8EX0 (void) +{ + Absolute (); + STX16 (); +} +/**********************************************************************************************/ + +/* STY *************************************************************************************** */ +static void Op84X1 (void) +{ + Direct (); + STY8 (); +} + +static void Op84X0 (void) +{ + Direct (); + STY16 (); +} + +static void Op94X1 (void) +{ + DirectIndexedX (); + STY8 (); +} + +static void Op94X0 (void) +{ + DirectIndexedX (); + STY16 (); +} + +static void Op8CX1 (void) +{ + Absolute (); + STY8 (); +} + +static void Op8CX0 (void) +{ + Absolute (); + STY16 (); +} +/**********************************************************************************************/ + +/* STZ *************************************************************************************** */ +static void Op64M1 (void) +{ + Direct (); + STZ8 (); +} + +static void Op64M0 (void) +{ + Direct (); + STZ16 (); +} + +static void Op74M1 (void) +{ + DirectIndexedX (); + STZ8 (); +} + +static void Op74M0 (void) +{ + DirectIndexedX (); + STZ16 (); +} + +static void Op9CM1 (void) +{ + Absolute (); + STZ8 (); +} + +static void Op9CM0 (void) +{ + Absolute (); + STZ16 (); +} + +static void Op9EM1 (void) +{ + AbsoluteIndexedX (); + STZ8 (); +} + +static void Op9EM0 (void) +{ + AbsoluteIndexedX (); + STZ16 (); +} + +/**********************************************************************************************/ + +/* TRB *************************************************************************************** */ +static void Op14M1 (void) +{ + Direct (); + TRB8 (); +} + +static void Op14M0 (void) +{ + Direct (); + TRB16 (); +} + +static void Op1CM1 (void) +{ + Absolute (); + TRB8 (); +} + +static void Op1CM0 (void) +{ + Absolute (); + TRB16 (); +} +/**********************************************************************************************/ + +/* TSB *************************************************************************************** */ +static void Op04M1 (void) +{ + Direct (); + TSB8 (); +} + +static void Op04M0 (void) +{ + Direct (); + TSB16 (); +} + +static void Op0CM1 (void) +{ + Absolute (); + TSB8 (); +} + +static void Op0CM0 (void) +{ + Absolute (); + TSB16 (); +} + +/**********************************************************************************************/ + +/* Branch Instructions *********************************************************************** */ +#ifndef SA1_OPCODES +#define BranchCheck0()\ + if( CPU.BranchSkip)\ + {\ + CPU.BranchSkip = FALSE;\ + if (!Settings.SoundSkipMethod)\ + if( CPU.PC - CPU.PCBase > OpAddress)\ + return;\ + } + +#define BranchCheck1()\ + if( CPU.BranchSkip)\ + {\ + CPU.BranchSkip = FALSE;\ + if (!Settings.SoundSkipMethod) {\ + if( CPU.PC - CPU.PCBase > OpAddress)\ + return;\ + } else \ + if (Settings.SoundSkipMethod == 1)\ + return;\ + if (Settings.SoundSkipMethod == 3)\ + if( CPU.PC - CPU.PCBase > OpAddress)\ + return;\ + else\ + CPU.PC = CPU.PCBase + OpAddress;\ + } + +#define BranchCheck2()\ + if( CPU.BranchSkip)\ + {\ + CPU.BranchSkip = FALSE;\ + if (!Settings.SoundSkipMethod) {\ + if( CPU.PC - CPU.PCBase > OpAddress)\ + return;\ + } else \ + if (Settings.SoundSkipMethod == 1)\ + CPU.PC = CPU.PCBase + OpAddress;\ + if (Settings.SoundSkipMethod == 3)\ + if (CPU.PC - CPU.PCBase > OpAddress)\ + return;\ + else\ + CPU.PC = CPU.PCBase + OpAddress;\ + } +#else +#define BranchCheck0() +#define BranchCheck1() +#define BranchCheck2() +#endif + +#ifdef CPU_SHUTDOWN +#ifndef SA1_OPCODES +inline void CPUShutdown() +{ + if (Settings.Shutdown && CPU.PC == CPU.WaitAddress) + { + // Don't skip cycles with a pending NMI or IRQ - could cause delayed + // interrupt. Interrupts are delayed for a few cycles already, but + // the delay could allow the shutdown code to cycle skip again. + // Was causing screen flashing on Top Gear 3000. + + if (CPU.WaitCounter == 0 && + !(CPU.Flags & (IRQ_PENDING_FLAG | NMI_FLAG))) + { + CPU.WaitAddress = NULL; + if (Settings.SA1) + S9xSA1ExecuteDuringSleep (); + CPU.Cycles = CPU.NextEvent; + if (CPU.APU_APUExecuting) + { + ICPU.CPUExecuting = FALSE; + do + { + APU_EXECUTE1(); + } while (CPU.APU_Cycles < CPU.NextEvent); + ICPU.CPUExecuting = TRUE; + } + } + else + if (CPU.WaitCounter >= 2) + CPU.WaitCounter = 1; + else + CPU.WaitCounter--; + } +} +#else +inline void CPUShutdown() +{ + if (Settings.Shutdown && CPU.PC == CPU.WaitAddress) + { + if (CPU.WaitCounter >= 1) + { + SA1.Executing = FALSE; + SA1.CPUExecuting = FALSE; + } + else + CPU.WaitCounter++; + } +} +#endif +#else +#define CPUShutdown() +#endif + +/* BCC */ +static void Op90 (void) +{ + Relative (); + BranchCheck0 (); + if (!CheckCarry ()) + { + CPU.PC = CPU.PCBase + OpAddress; +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#else +#ifndef SA1_OPCODES + CPU.Cycles++; +#endif +#endif + CPUShutdown (); + } +} + +/* BCS */ +static void OpB0 (void) +{ + Relative (); + BranchCheck0 (); + if (CheckCarry ()) + { + CPU.PC = CPU.PCBase + OpAddress; +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#else +#ifndef SA1_OPCODES + CPU.Cycles++; +#endif +#endif + CPUShutdown (); + } +} + +/* BEQ */ +static void OpF0 (void) +{ + Relative (); + BranchCheck2 (); + if (CheckZero ()) + { + CPU.PC = CPU.PCBase + OpAddress; +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#else +#ifndef SA1_OPCODES + CPU.Cycles++; +#endif +#endif + CPUShutdown (); + } +} + +/* BMI */ +static void Op30 (void) +{ + Relative (); + BranchCheck1 (); + if (CheckNegative ()) + { + CPU.PC = CPU.PCBase + OpAddress; +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#else +#ifndef SA1_OPCODES + CPU.Cycles++; +#endif +#endif + CPUShutdown (); + } +} + +/* BNE */ +static void OpD0 (void) +{ + Relative (); + BranchCheck1 (); + if (!CheckZero ()) + { + CPU.PC = CPU.PCBase + OpAddress; + +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#else +#ifndef SA1_OPCODES + CPU.Cycles++; +#endif +#endif + CPUShutdown (); + } +} + +/* BPL */ +static void Op10 (void) +{ + Relative (); + BranchCheck1 (); + if (!CheckNegative ()) + { + CPU.PC = CPU.PCBase + OpAddress; +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#else +#ifndef SA1_OPCODES + CPU.Cycles++; +#endif +#endif + CPUShutdown (); + } +} + +/* BRA */ +static void Op80 (void) +{ + Relative (); + CPU.PC = CPU.PCBase + OpAddress; +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#else +#ifndef SA1_OPCODES + CPU.Cycles++; +#endif +#endif + CPUShutdown (); +} + +/* BVC */ +static void Op50 (void) +{ + Relative (); + BranchCheck0 (); + if (!CheckOverflow ()) + { + CPU.PC = CPU.PCBase + OpAddress; +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#else +#ifndef SA1_OPCODES + CPU.Cycles++; +#endif +#endif + CPUShutdown (); + } +} + +/* BVS */ +static void Op70 (void) +{ + Relative (); + BranchCheck0 (); + if (CheckOverflow ()) + { + CPU.PC = CPU.PCBase + OpAddress; +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#else +#ifndef SA1_OPCODES + CPU.Cycles++; +#endif +#endif + CPUShutdown (); + } +} +/**********************************************************************************************/ + +/* ClearFlag Instructions ******************************************************************** */ +/* CLC */ +static void Op18 (void) +{ + ClearCarry (); +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif +} + +/* CLD */ +static void OpD8 (void) +{ + ClearDecimal (); +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif +} + +/* CLI */ +static void Op58 (void) +{ + ClearIRQ (); +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif +/* CHECK_FOR_IRQ(); */ +} + +/* CLV */ +static void OpB8 (void) +{ + ClearOverflow (); +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif +} +/**********************************************************************************************/ + +/* DEX/DEY *********************************************************************************** */ +static void OpCAX1 (void) +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif +#ifdef CPU_SHUTDOWN + CPU.WaitAddress = NULL; +#endif + + Registers.XL--; + SetZN8 (Registers.XL); +} + +static void OpCAX0 (void) +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif +#ifdef CPU_SHUTDOWN + CPU.WaitAddress = NULL; +#endif + + Registers.X.W--; + SetZN16 (Registers.X.W); +} + +static void Op88X1 (void) +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif +#ifdef CPU_SHUTDOWN + CPU.WaitAddress = NULL; +#endif + + Registers.YL--; + SetZN8 (Registers.YL); +} + +static void Op88X0 (void) +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif +#ifdef CPU_SHUTDOWN + CPU.WaitAddress = NULL; +#endif + + Registers.Y.W--; + SetZN16 (Registers.Y.W); +} +/**********************************************************************************************/ + +/* INX/INY *********************************************************************************** */ +static void OpE8X1 (void) +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif +#ifdef CPU_SHUTDOWN + CPU.WaitAddress = NULL; +#endif + + Registers.XL++; + SetZN8 (Registers.XL); +} + +static void OpE8X0 (void) +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif +#ifdef CPU_SHUTDOWN + CPU.WaitAddress = NULL; +#endif + + Registers.X.W++; + SetZN16 (Registers.X.W); +} + +static void OpC8X1 (void) +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif +#ifdef CPU_SHUTDOWN + CPU.WaitAddress = NULL; +#endif + + Registers.YL++; + SetZN8 (Registers.YL); +} + +static void OpC8X0 (void) +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif +#ifdef CPU_SHUTDOWN + CPU.WaitAddress = NULL; +#endif + + Registers.Y.W++; + SetZN16 (Registers.Y.W); +} + +/**********************************************************************************************/ + +/* NOP *************************************************************************************** */ +static void OpEA (void) +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + +} +/**********************************************************************************************/ + +/* PUSH Instructions ************************************************************************* */ +#define PushW(w) \ + S9xSetWord (w, Registers.S.W - 1);\ + Registers.S.W -= 2; +#define PushB(b)\ + S9xSetByte (b, Registers.S.W--); + +static void OpF4 (void) +{ + Absolute (); + PushW ((unsigned short)OpAddress); +} + +static void OpD4 (void) +{ + DirectIndirect (); + PushW ((unsigned short)OpAddress); +} + +static void Op62 (void) +{ + RelativeLong (); + PushW ((unsigned short)OpAddress); +} + +static void Op48M1 (void) +{ + PushB (Registers.AL); +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif +} + +static void Op48M0 (void) +{ + PushW (Registers.A.W); +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif +} + +static void Op8B (void) +{ + PushB (Registers.DB); +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif +} + +static void Op0B (void) +{ + PushW (Registers.D.W); +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif +} + +static void Op4B (void) +{ + PushB (Registers.PB); +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif +} + +static void Op08 (void) +{ + S9xPackStatus (); + PushB (Registers.PL); +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif +} + +static void OpDAX1 (void) +{ + PushB (Registers.XL); +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif +} + +static void OpDAX0 (void) +{ + PushW (Registers.X.W); +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif +} + +static void Op5AX1 (void) +{ + PushB (Registers.YL); +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif +} + +static void Op5AX0 (void) +{ + PushW (Registers.Y.W); +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif +} +/**********************************************************************************************/ + +/* PULL Instructions ************************************************************************* */ +#define PullW(w) \ + w = S9xGetWord (Registers.S.W + 1); \ + Registers.S.W += 2; + +#define PullB(b)\ + b = S9xGetByte (++Registers.S.W); + +static void Op68M1 (void) +{ +#ifdef VAR_CYCLES + CPU.Cycles += TWO_CYCLES; +#endif + PullB (Registers.AL); + SetZN8 (Registers.AL); +} + +static void Op68M0 (void) +{ +#ifdef VAR_CYCLES + CPU.Cycles += TWO_CYCLES; +#endif + PullW (Registers.A.W); + SetZN16 (Registers.A.W); +} + +static void OpAB (void) +{ +#ifdef VAR_CYCLES + CPU.Cycles += TWO_CYCLES; +#endif + PullB (Registers.DB); + SetZN8 (Registers.DB); + ICPU.ShiftedDB = Registers.DB << 16; +} + +/* PHP */ +static void Op2B (void) +{ +#ifdef VAR_CYCLES + CPU.Cycles += TWO_CYCLES; +#endif + PullW (Registers.D.W); + SetZN16 (Registers.D.W); +} + +/* PLP */ +static void Op28 (void) +{ +#ifdef VAR_CYCLES + CPU.Cycles += TWO_CYCLES; +#endif + PullB (Registers.PL); + S9xUnpackStatus (); + + if (CheckIndex ()) + { + Registers.XH = 0; + Registers.YH = 0; + } + S9xFixCycles(); +/* CHECK_FOR_IRQ();*/ +} + +static void OpFAX1 (void) +{ +#ifdef VAR_CYCLES + CPU.Cycles += TWO_CYCLES; +#endif + PullB (Registers.XL); + SetZN8 (Registers.XL); +} + +static void OpFAX0 (void) +{ +#ifdef VAR_CYCLES + CPU.Cycles += TWO_CYCLES; +#endif + PullW (Registers.X.W); + SetZN16 (Registers.X.W); +} + +static void Op7AX1 (void) +{ +#ifdef VAR_CYCLES + CPU.Cycles += TWO_CYCLES; +#endif + PullB (Registers.YL); + SetZN8 (Registers.YL); +} + +static void Op7AX0 (void) +{ +#ifdef VAR_CYCLES + CPU.Cycles += TWO_CYCLES; +#endif + PullW (Registers.Y.W); + SetZN16 (Registers.Y.W); +} + +/**********************************************************************************************/ + +/* SetFlag Instructions ********************************************************************** */ +/* SEC */ +static void Op38 (void) +{ + SetCarry (); +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif +} + +/* SED */ +static void OpF8 (void) +{ + SetDecimal (); +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + missing.decimal_mode = 1; +} + +/* SEI */ +static void Op78 (void) +{ + SetIRQ (); +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif +} +/**********************************************************************************************/ + +/* Transfer Instructions ********************************************************************* */ +/* TAX8 */ +static void OpAAX1 (void) +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + Registers.XL = Registers.AL; + SetZN8 (Registers.XL); +} + +/* TAX16 */ +static void OpAAX0 (void) +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + Registers.X.W = Registers.A.W; + SetZN16 (Registers.X.W); +} + +/* TAY8 */ +static void OpA8X1 (void) +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + Registers.YL = Registers.AL; + SetZN8 (Registers.YL); +} + +/* TAY16 */ +static void OpA8X0 (void) +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + Registers.Y.W = Registers.A.W; + SetZN16 (Registers.Y.W); +} + +static void Op5B (void) +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + Registers.D.W = Registers.A.W; + SetZN16 (Registers.D.W); +} + +static void Op1B (void) +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + Registers.S.W = Registers.A.W; + if (CheckEmulation()) + Registers.SH = 1; +} + +static void Op7B (void) +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + Registers.A.W = Registers.D.W; + SetZN16 (Registers.A.W); +} + +static void Op3B (void) +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + Registers.A.W = Registers.S.W; + SetZN16 (Registers.A.W); +} + +static void OpBAX1 (void) +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + Registers.XL = Registers.SL; + SetZN8 (Registers.XL); +} + +static void OpBAX0 (void) +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + Registers.X.W = Registers.S.W; + SetZN16 (Registers.X.W); +} + +static void Op8AM1 (void) +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + Registers.AL = Registers.XL; + SetZN8 (Registers.AL); +} + +static void Op8AM0 (void) +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + Registers.A.W = Registers.X.W; + SetZN16 (Registers.A.W); +} + +static void Op9A (void) +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + Registers.S.W = Registers.X.W; + if (CheckEmulation()) + Registers.SH = 1; +} + +static void Op9BX1 (void) +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + Registers.YL = Registers.XL; + SetZN8 (Registers.YL); +} + +static void Op9BX0 (void) +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + Registers.Y.W = Registers.X.W; + SetZN16 (Registers.Y.W); +} + +static void Op98M1 (void) +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + Registers.AL = Registers.YL; + SetZN8 (Registers.AL); +} + +static void Op98M0 (void) +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + Registers.A.W = Registers.Y.W; + SetZN16 (Registers.A.W); +} + +static void OpBBX1 (void) +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + Registers.XL = Registers.YL; + SetZN8 (Registers.XL); +} + +static void OpBBX0 (void) +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + Registers.X.W = Registers.Y.W; + SetZN16 (Registers.X.W); +} + +/**********************************************************************************************/ + +/* XCE *************************************************************************************** */ +static void OpFB (void) +{ +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + + A1 = ICPU._Carry; + A2 = Registers.PH; + ICPU._Carry = A2 & 1; + Registers.PH = A1; + + if (CheckEmulation()) + { + SetFlags (MemoryFlag | IndexFlag); + Registers.SH = 1; + missing.emulate6502 = 1; + } + if (CheckIndex ()) + { + Registers.XH = 0; + Registers.YH = 0; + } + S9xFixCycles(); +} +/**********************************************************************************************/ + +/* BRK *************************************************************************************** */ +static void Op00 (void) +{ +#ifdef DEBUGGER + if (CPU.Flags & TRACE_FLAG) + S9xTraceMessage ("*** BRK"); +#endif + +#ifndef SA1_OPCODES + CPU.BRKTriggered = TRUE; +#endif + + if (!CheckEmulation()) + { + PushB (Registers.PB); + PushW (CPU.PC - CPU.PCBase + 1); + S9xPackStatus (); + PushB (Registers.PL); + ClearDecimal (); + SetIRQ (); + + Registers.PB = 0; + ICPU.ShiftedPB = 0; + S9xSetPCBase (S9xGetWord (0xFFE6)); +#ifdef VAR_CYCLES + CPU.Cycles += TWO_CYCLES; +#else +#ifndef SA1_OPCODES + CPU.Cycles += 8; +#endif +#endif + } + else + { + PushW (CPU.PC - CPU.PCBase); + S9xPackStatus (); + PushB (Registers.PL); + ClearDecimal (); + SetIRQ (); + + Registers.PB = 0; + ICPU.ShiftedPB = 0; + S9xSetPCBase (S9xGetWord (0xFFFE)); +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#else +#ifndef SA1_OPCODES + CPU.Cycles += 6; +#endif +#endif + } +} +/**********************************************************************************************/ + +/* BRL ************************************************************************************** */ +static void Op82 (void) +{ + RelativeLong (); + S9xSetPCBase (ICPU.ShiftedPB + OpAddress); +} +/**********************************************************************************************/ + +/* IRQ *************************************************************************************** */ +void S9xOpcode_IRQ (void) +{ +#ifdef DEBUGGER + if (CPU.Flags & TRACE_FLAG) + S9xTraceMessage ("*** IRQ"); +#endif + if (!CheckEmulation()) + { + PushB (Registers.PB); + PushW (CPU.PC - CPU.PCBase); + S9xPackStatus (); + PushB (Registers.PL); + ClearDecimal (); + SetIRQ (); + + Registers.PB = 0; + ICPU.ShiftedPB = 0; +#ifdef SA1_OPCODES + S9xSA1SetPCBase (Memory.FillRAM [0x2207] | + (Memory.FillRAM [0x2208] << 8)); +#else + if (Settings.SA1 && (Memory.FillRAM [0x2209] & 0x40)) + S9xSetPCBase (Memory.FillRAM [0x220e] | + (Memory.FillRAM [0x220f] << 8)); + else + S9xSetPCBase (S9xGetWord (0xFFEE)); +#endif +#ifdef VAR_CYCLES + CPU.Cycles += TWO_CYCLES; +#else +#ifndef SA1_OPCODES + CPU.Cycles += 8; +#endif +#endif + } + else + { + PushW (CPU.PC - CPU.PCBase); + S9xPackStatus (); + PushB (Registers.PL); + ClearDecimal (); + SetIRQ (); + + Registers.PB = 0; + ICPU.ShiftedPB = 0; +#ifdef SA1_OPCODES + S9xSA1SetPCBase (Memory.FillRAM [0x2207] | + (Memory.FillRAM [0x2208] << 8)); +#else + if (Settings.SA1 && (Memory.FillRAM [0x2209] & 0x40)) + S9xSetPCBase (Memory.FillRAM [0x220e] | + (Memory.FillRAM [0x220f] << 8)); + else + S9xSetPCBase (S9xGetWord (0xFFFE)); +#endif +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#else +#ifndef SA1_OPCODES + CPU.Cycles += 6; +#endif +#endif + } +} + +/**********************************************************************************************/ + +/* NMI *************************************************************************************** */ +void S9xOpcode_NMI (void) +{ +#ifdef DEBUGGER + if (CPU.Flags & TRACE_FLAG) + S9xTraceMessage ("*** NMI"); +#endif + if (!CheckEmulation()) + { + PushB (Registers.PB); + PushW (CPU.PC - CPU.PCBase); + S9xPackStatus (); + PushB (Registers.PL); + ClearDecimal (); + SetIRQ (); + + Registers.PB = 0; + ICPU.ShiftedPB = 0; +#ifdef SA1_OPCODES + S9xSA1SetPCBase (Memory.FillRAM [0x2205] | + (Memory.FillRAM [0x2206] << 8)); +#else + if (Settings.SA1 && (Memory.FillRAM [0x2209] & 0x20)) + S9xSetPCBase (Memory.FillRAM [0x220c] | + (Memory.FillRAM [0x220d] << 8)); + else + S9xSetPCBase (S9xGetWord (0xFFEA)); +#endif +#ifdef VAR_CYCLES + CPU.Cycles += TWO_CYCLES; +#else +#ifndef SA1_OPCODES + CPU.Cycles += 8; +#endif +#endif + } + else + { + PushW (CPU.PC - CPU.PCBase); + S9xPackStatus (); + PushB (Registers.PL); + ClearDecimal (); + SetIRQ (); + + Registers.PB = 0; + ICPU.ShiftedPB = 0; +#ifdef SA1_OPCODES + S9xSA1SetPCBase (Memory.FillRAM [0x2205] | + (Memory.FillRAM [0x2206] << 8)); +#else + if (Settings.SA1 && (Memory.FillRAM [0x2209] & 0x20)) + S9xSetPCBase (Memory.FillRAM [0x220c] | + (Memory.FillRAM [0x220d] << 8)); + else + S9xSetPCBase (S9xGetWord (0xFFFA)); +#endif +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#else +#ifndef SA1_OPCODES + CPU.Cycles += 6; +#endif +#endif + } +} +/**********************************************************************************************/ + +/* COP *************************************************************************************** */ +static void Op02 (void) +{ +#ifdef DEBUGGER + if (CPU.Flags & TRACE_FLAG) + S9xTraceMessage ("*** COP"); +#endif + if (!CheckEmulation()) + { + PushB (Registers.PB); + PushW (CPU.PC - CPU.PCBase + 1); + S9xPackStatus (); + PushB (Registers.PL); + ClearDecimal (); + SetIRQ (); + + Registers.PB = 0; + ICPU.ShiftedPB = 0; + S9xSetPCBase (S9xGetWord (0xFFE4)); +#ifdef VAR_CYCLES + CPU.Cycles += TWO_CYCLES; +#else +#ifndef SA1_OPCODES + CPU.Cycles += 8; +#endif +#endif + } + else + { + PushW (CPU.PC - CPU.PCBase); + S9xPackStatus (); + PushB (Registers.PL); + ClearDecimal (); + SetIRQ (); + + Registers.PB = 0; + ICPU.ShiftedPB = 0; + S9xSetPCBase (S9xGetWord (0xFFF4)); +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#else +#ifndef SA1_OPCODES + CPU.Cycles += 6; +#endif +#endif + } +} +/**********************************************************************************************/ + +/* JML *************************************************************************************** */ +static void OpDC (void) +{ + AbsoluteIndirectLong (); + Registers.PB = (uint8) (OpAddress >> 16); + ICPU.ShiftedPB = OpAddress & 0xff0000; + S9xSetPCBase (OpAddress); +#ifdef VAR_CYCLES + CPU.Cycles += TWO_CYCLES; +#endif +} + +static void Op5C (void) +{ + AbsoluteLong (); + Registers.PB = (uint8) (OpAddress >> 16); + ICPU.ShiftedPB = OpAddress & 0xff0000; + S9xSetPCBase (OpAddress); +} +/**********************************************************************************************/ + +/* JMP *************************************************************************************** */ +static void Op4C (void) +{ + Absolute (); + S9xSetPCBase (ICPU.ShiftedPB + (OpAddress & 0xffff)); +#if defined(CPU_SHUTDOWN) && defined(SA1_OPCODES) + CPUShutdown (); +#endif +} + +static void Op6C (void) +{ + AbsoluteIndirect (); + S9xSetPCBase (ICPU.ShiftedPB + (OpAddress & 0xffff)); +} + +static void Op7C (void) +{ + AbsoluteIndexedIndirect (); + S9xSetPCBase (ICPU.ShiftedPB + OpAddress); +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif +} +/**********************************************************************************************/ + +/* JSL/RTL *********************************************************************************** */ +static void Op22 (void) +{ + AbsoluteLong (); + PushB (Registers.PB); + PushW (CPU.PC - CPU.PCBase - 1); + Registers.PB = (uint8) (OpAddress >> 16); + ICPU.ShiftedPB = OpAddress & 0xff0000; + S9xSetPCBase (OpAddress); +} + +static void Op6B (void) +{ + PullW (Registers.PC); + PullB (Registers.PB); + ICPU.ShiftedPB = Registers.PB << 16; + S9xSetPCBase (ICPU.ShiftedPB + ((Registers.PC + 1) & 0xffff)); +#ifdef VAR_CYCLES + CPU.Cycles += TWO_CYCLES; +#endif +} +/**********************************************************************************************/ + +/* JSR/RTS *********************************************************************************** */ +static void Op20 (void) +{ + Absolute (); + PushW (CPU.PC - CPU.PCBase - 1); + S9xSetPCBase (ICPU.ShiftedPB + (OpAddress & 0xffff)); +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif +} + +static void OpFC (void) +{ + AbsoluteIndexedIndirect (); + PushW (CPU.PC - CPU.PCBase - 1); + S9xSetPCBase (ICPU.ShiftedPB + OpAddress); +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif +} + +static void Op60 (void) +{ + PullW (Registers.PC); + S9xSetPCBase (ICPU.ShiftedPB + ((Registers.PC + 1) & 0xffff)); +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE * 3; +#endif +} + +/**********************************************************************************************/ + +/* MVN/MVP *********************************************************************************** */ +static void Op54X1 (void) +{ + uint32 SrcBank; + +#ifdef VAR_CYCLES + CPU.Cycles += CPU.MemSpeedx2 + TWO_CYCLES; +#endif + + Registers.DB = *CPU.PC++; + ICPU.ShiftedDB = Registers.DB << 16; + SrcBank = *CPU.PC++; + + S9xSetByte (S9xGetByte ((SrcBank << 16) + Registers.X.W), + ICPU.ShiftedDB + Registers.Y.W); + + Registers.XL++; + Registers.YL++; + Registers.A.W--; + if (Registers.A.W != 0xffff) + CPU.PC -= 3; +} + +static void Op54X0 (void) +{ + uint32 SrcBank; + +#ifdef VAR_CYCLES + CPU.Cycles += CPU.MemSpeedx2 + TWO_CYCLES; +#endif + + Registers.DB = *CPU.PC++; + ICPU.ShiftedDB = Registers.DB << 16; + SrcBank = *CPU.PC++; + + S9xSetByte (S9xGetByte ((SrcBank << 16) + Registers.X.W), + ICPU.ShiftedDB + Registers.Y.W); + + Registers.X.W++; + Registers.Y.W++; + Registers.A.W--; + if (Registers.A.W != 0xffff) + CPU.PC -= 3; +} + +static void Op44X1 (void) +{ + uint32 SrcBank; + +#ifdef VAR_CYCLES + CPU.Cycles += CPU.MemSpeedx2 + TWO_CYCLES; +#endif + Registers.DB = *CPU.PC++; + ICPU.ShiftedDB = Registers.DB << 16; + SrcBank = *CPU.PC++; + S9xSetByte (S9xGetByte ((SrcBank << 16) + Registers.X.W), + ICPU.ShiftedDB + Registers.Y.W); + + Registers.XL--; + Registers.YL--; + Registers.A.W--; + if (Registers.A.W != 0xffff) + CPU.PC -= 3; +} + +static void Op44X0 (void) +{ + uint32 SrcBank; + +#ifdef VAR_CYCLES + CPU.Cycles += CPU.MemSpeedx2 + TWO_CYCLES; +#endif + Registers.DB = *CPU.PC++; + ICPU.ShiftedDB = Registers.DB << 16; + SrcBank = *CPU.PC++; + S9xSetByte (S9xGetByte ((SrcBank << 16) + Registers.X.W), + ICPU.ShiftedDB + Registers.Y.W); + + Registers.X.W--; + Registers.Y.W--; + Registers.A.W--; + if (Registers.A.W != 0xffff) + CPU.PC -= 3; +} + +/**********************************************************************************************/ + +/* REP/SEP *********************************************************************************** */ +static void OpC2 (void) +{ + Work8 = ~*CPU.PC++; + Registers.PL &= Work8; + ICPU._Carry &= Work8; + ICPU._Overflow &= (Work8 >> 6); + ICPU._Negative &= Work8; + ICPU._Zero |= ~Work8 & Zero; + +#ifdef VAR_CYCLES + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; +#endif + if (CheckEmulation()) + { + SetFlags (MemoryFlag | IndexFlag); + missing.emulate6502 = 1; + } + if (CheckIndex ()) + { + Registers.XH = 0; + Registers.YH = 0; + } + S9xFixCycles(); +/* CHECK_FOR_IRQ(); */ +} + +static void OpE2 (void) +{ + Work8 = *CPU.PC++; + Registers.PL |= Work8; + ICPU._Carry |= Work8 & 1; + ICPU._Overflow |= (Work8 >> 6) & 1; + ICPU._Negative |= Work8; + if (Work8 & Zero) + ICPU._Zero = 0; +#ifdef VAR_CYCLES + CPU.Cycles += CPU.MemSpeed + ONE_CYCLE; +#endif + if (CheckEmulation()) + { + SetFlags (MemoryFlag | IndexFlag); + missing.emulate6502 = 1; + } + if (CheckIndex ()) + { + Registers.XH = 0; + Registers.YH = 0; + } + S9xFixCycles(); +} +/**********************************************************************************************/ + +/* XBA *************************************************************************************** */ +static void OpEB (void) +{ + Work8 = Registers.AL; + Registers.AL = Registers.AH; + Registers.AH = Work8; + + SetZN8 (Registers.AL); +#ifdef VAR_CYCLES + CPU.Cycles += TWO_CYCLES; +#endif +} +/**********************************************************************************************/ + +/* RTI *************************************************************************************** */ +static void Op40 (void) +{ + PullB (Registers.PL); + S9xUnpackStatus (); + PullW (Registers.PC); + if (!CheckEmulation()) + { + PullB (Registers.PB); + ICPU.ShiftedPB = Registers.PB << 16; + } + else + { + SetFlags (MemoryFlag | IndexFlag); + missing.emulate6502 = 1; + } + S9xSetPCBase (ICPU.ShiftedPB + Registers.PC); + + if (CheckIndex ()) + { + Registers.XH = 0; + Registers.YH = 0; + } +#ifdef VAR_CYCLES + CPU.Cycles += TWO_CYCLES; +#endif + S9xFixCycles(); +/* CHECK_FOR_IRQ(); */ +} + +/**********************************************************************************************/ + +/* STP/WAI/DB ******************************************************************************** */ +// WAI +static void OpCB (void) +{ + if (CPU.IRQActive) + { +#ifdef VAR_CYCLES + CPU.Cycles += TWO_CYCLES; +#else +#ifndef SA1_OPCODES + CPU.Cycles += 2; +#endif +#endif + } + else + { + CPU.WaitingForInterrupt = TRUE; + CPU.PC--; +#ifdef CPU_SHUTDOWN +#ifndef SA1_OPCODES + if (Settings.Shutdown) + { + CPU.Cycles = CPU.NextEvent; + if (CPU.APU_APUExecuting) + { + ICPU.CPUExecuting = FALSE; + do + { + APU_EXECUTE1 (); + } while (CPU.APU_Cycles < CPU.NextEvent); + ICPU.CPUExecuting = TRUE; + } + } +#else + if (Settings.Shutdown) + { + SA1.CPUExecuting = FALSE; + SA1.Executing = FALSE; + } +#endif +#endif + } +} + +// STP +static void OpDB (void) +{ + CPU.PC--; + CPU.Flags |= DEBUG_MODE_FLAG; +} + +// Reserved S9xOpcode +static void Op42 (void) { +#ifndef SA1_OPCODES + uint8 b; + + CPU.WaitAddress = NULL; + if (Settings.SA1) S9xSA1ExecuteDuringSleep (); + + CPU.Cycles = CPU.NextEvent; + if (CPU.APU_APUExecuting) + { + ICPU.CPUExecuting = FALSE; + do + { + APU_EXECUTE1(); + } while (CPU.APU_Cycles < CPU.NextEvent); + ICPU.CPUExecuting = TRUE; + } + + //debug_log("toto"); + b=*CPU.PC++; + + //relative + s9xInt8=0xF0|(b&0xF); +#ifdef VAR_CYCLES + CPU.Cycles += CPU.MemSpeed; +#endif + OpAddress = ((int) (CPU.PC - CPU.PCBase) + s9xInt8) & 0xffff; + + switch (b&0xF0) { + case 0x10: //BPL + BranchCheck1 (); + if (!CheckNegative ()) { + CPU.PC = CPU.PCBase + OpAddress; +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#else +#ifndef SA1_OPCODES + CPU.Cycles++; +#endif +#endif + CPUShutdown (); + } + return; + case 0x30: //BMI + BranchCheck1 (); + if (CheckNegative ()) { + CPU.PC = CPU.PCBase + OpAddress; +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#else +#ifndef SA1_OPCODES + CPU.Cycles++; +#endif +#endif + CPUShutdown (); + } + return; + case 0x50: //BVC + BranchCheck0 (); + if (!CheckOverflow ()) { + CPU.PC = CPU.PCBase + OpAddress; +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#else +#ifndef SA1_OPCODES + CPU.Cycles++; +#endif +#endif + CPUShutdown (); + } + return; + case 0x70: //BVS + BranchCheck0 (); + if (CheckOverflow ()) { + CPU.PC = CPU.PCBase + OpAddress; +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#else +#ifndef SA1_OPCODES + CPU.Cycles++; +#endif +#endif + CPUShutdown (); + } + return; + case 0x80: //BRA + //op80 + CPU.PC = CPU.PCBase + OpAddress; +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#else +#ifndef SA1_OPCODES + CPU.Cycles++; +#endif +#endif + CPUShutdown (); + return; + case 0x90: //BCC + BranchCheck0 (); + if (!CheckCarry ()) { + CPU.PC = CPU.PCBase + OpAddress; +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#else +#ifndef SA1_OPCODES + CPU.Cycles++; +#endif +#endif + CPUShutdown (); + } + return; + case 0xB0: //BCS + BranchCheck0 (); + if (CheckCarry ()) { + CPU.PC = CPU.PCBase + OpAddress; +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#else +#ifndef SA1_OPCODES + CPU.Cycles++; +#endif +#endif + CPUShutdown (); + } + return; + case 0xD0: //BNE + BranchCheck1 (); + if (!CheckZero ()) { + CPU.PC = CPU.PCBase + OpAddress; +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#else +#ifndef SA1_OPCODES + CPU.Cycles++; +#endif +#endif + CPUShutdown (); + } + return; + case 0xF0: //BEQ + BranchCheck2 (); + if (CheckZero ()) { + CPU.PC = CPU.PCBase + OpAddress; +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; + #else + #ifndef SA1_OPCODES + CPU.Cycles++; + #endif + #endif + CPUShutdown (); + } + return; + } +#endif +} + +/**********************************************************************************************/ + +/**********************************************************************************************/ +/* CPU-S9xOpcodes Definitions */ +/**********************************************************************************************/ +struct SOpcodes S9xOpcodesM1X1[256] = +{ + {Op00}, {Op01M1}, {Op02}, {Op03M1}, {Op04M1}, + {Op05M1}, {Op06M1}, {Op07M1}, {Op08}, {Op09M1}, + {Op0AM1}, {Op0B}, {Op0CM1}, {Op0DM1}, {Op0EM1}, + {Op0FM1}, {Op10}, {Op11M1}, {Op12M1}, {Op13M1}, + {Op14M1}, {Op15M1}, {Op16M1}, {Op17M1}, {Op18}, + {Op19M1}, {Op1AM1}, {Op1B}, {Op1CM1}, {Op1DM1}, + {Op1EM1}, {Op1FM1}, {Op20}, {Op21M1}, {Op22}, + {Op23M1}, {Op24M1}, {Op25M1}, {Op26M1}, {Op27M1}, + {Op28}, {Op29M1}, {Op2AM1}, {Op2B}, {Op2CM1}, + {Op2DM1}, {Op2EM1}, {Op2FM1}, {Op30}, {Op31M1}, + {Op32M1}, {Op33M1}, {Op34M1}, {Op35M1}, {Op36M1}, + {Op37M1}, {Op38}, {Op39M1}, {Op3AM1}, {Op3B}, + {Op3CM1}, {Op3DM1}, {Op3EM1}, {Op3FM1}, {Op40}, + {Op41M1}, {Op42}, {Op43M1}, {Op44X1}, {Op45M1}, + {Op46M1}, {Op47M1}, {Op48M1}, {Op49M1}, {Op4AM1}, + {Op4B}, {Op4C}, {Op4DM1}, {Op4EM1}, {Op4FM1}, + {Op50}, {Op51M1}, {Op52M1}, {Op53M1}, {Op54X1}, + {Op55M1}, {Op56M1}, {Op57M1}, {Op58}, {Op59M1}, + {Op5AX1}, {Op5B}, {Op5C}, {Op5DM1}, {Op5EM1}, + {Op5FM1}, {Op60}, {Op61M1}, {Op62}, {Op63M1}, + {Op64M1}, {Op65M1}, {Op66M1}, {Op67M1}, {Op68M1}, + {Op69M1}, {Op6AM1}, {Op6B}, {Op6C}, {Op6DM1}, + {Op6EM1}, {Op6FM1}, {Op70}, {Op71M1}, {Op72M1}, + {Op73M1}, {Op74M1}, {Op75M1}, {Op76M1}, {Op77M1}, + {Op78}, {Op79M1}, {Op7AX1}, {Op7B}, {Op7C}, + {Op7DM1}, {Op7EM1}, {Op7FM1}, {Op80}, {Op81M1}, + {Op82}, {Op83M1}, {Op84X1}, {Op85M1}, {Op86X1}, + {Op87M1}, {Op88X1}, {Op89M1}, {Op8AM1}, {Op8B}, + {Op8CX1}, {Op8DM1}, {Op8EX1}, {Op8FM1}, {Op90}, + {Op91M1}, {Op92M1}, {Op93M1}, {Op94X1}, {Op95M1}, + {Op96X1}, {Op97M1}, {Op98M1}, {Op99M1}, {Op9A}, + {Op9BX1}, {Op9CM1}, {Op9DM1}, {Op9EM1}, {Op9FM1}, + {OpA0X1}, {OpA1M1}, {OpA2X1}, {OpA3M1}, {OpA4X1}, + {OpA5M1}, {OpA6X1}, {OpA7M1}, {OpA8X1}, {OpA9M1}, + {OpAAX1}, {OpAB}, {OpACX1}, {OpADM1}, {OpAEX1}, + {OpAFM1}, {OpB0}, {OpB1M1}, {OpB2M1}, {OpB3M1}, + {OpB4X1}, {OpB5M1}, {OpB6X1}, {OpB7M1}, {OpB8}, + {OpB9M1}, {OpBAX1}, {OpBBX1}, {OpBCX1}, {OpBDM1}, + {OpBEX1}, {OpBFM1}, {OpC0X1}, {OpC1M1}, {OpC2}, + {OpC3M1}, {OpC4X1}, {OpC5M1}, {OpC6M1}, {OpC7M1}, + {OpC8X1}, {OpC9M1}, {OpCAX1}, {OpCB}, {OpCCX1}, + {OpCDM1}, {OpCEM1}, {OpCFM1}, {OpD0}, {OpD1M1}, + {OpD2M1}, {OpD3M1}, {OpD4}, {OpD5M1}, {OpD6M1}, + {OpD7M1}, {OpD8}, {OpD9M1}, {OpDAX1}, {OpDB}, + {OpDC}, {OpDDM1}, {OpDEM1}, {OpDFM1}, {OpE0X1}, + {OpE1M1}, {OpE2}, {OpE3M1}, {OpE4X1}, {OpE5M1}, + {OpE6M1}, {OpE7M1}, {OpE8X1}, {OpE9M1}, {OpEA}, + {OpEB}, {OpECX1}, {OpEDM1}, {OpEEM1}, {OpEFM1}, + {OpF0}, {OpF1M1}, {OpF2M1}, {OpF3M1}, {OpF4}, + {OpF5M1}, {OpF6M1}, {OpF7M1}, {OpF8}, {OpF9M1}, + {OpFAX1}, {OpFB}, {OpFC}, {OpFDM1}, {OpFEM1}, + {OpFFM1} +}; + +struct SOpcodes S9xOpcodesM1X0[256] = +{ + {Op00}, {Op01M1}, {Op02}, {Op03M1}, {Op04M1}, + {Op05M1}, {Op06M1}, {Op07M1}, {Op08}, {Op09M1}, + {Op0AM1}, {Op0B}, {Op0CM1}, {Op0DM1}, {Op0EM1}, + {Op0FM1}, {Op10}, {Op11M1}, {Op12M1}, {Op13M1}, + {Op14M1}, {Op15M1}, {Op16M1}, {Op17M1}, {Op18}, + {Op19M1}, {Op1AM1}, {Op1B}, {Op1CM1}, {Op1DM1}, + {Op1EM1}, {Op1FM1}, {Op20}, {Op21M1}, {Op22}, + {Op23M1}, {Op24M1}, {Op25M1}, {Op26M1}, {Op27M1}, + {Op28}, {Op29M1}, {Op2AM1}, {Op2B}, {Op2CM1}, + {Op2DM1}, {Op2EM1}, {Op2FM1}, {Op30}, {Op31M1}, + {Op32M1}, {Op33M1}, {Op34M1}, {Op35M1}, {Op36M1}, + {Op37M1}, {Op38}, {Op39M1}, {Op3AM1}, {Op3B}, + {Op3CM1}, {Op3DM1}, {Op3EM1}, {Op3FM1}, {Op40}, + {Op41M1}, {Op42}, {Op43M1}, {Op44X0}, {Op45M1}, + {Op46M1}, {Op47M1}, {Op48M1}, {Op49M1}, {Op4AM1}, + {Op4B}, {Op4C}, {Op4DM1}, {Op4EM1}, {Op4FM1}, + {Op50}, {Op51M1}, {Op52M1}, {Op53M1}, {Op54X0}, + {Op55M1}, {Op56M1}, {Op57M1}, {Op58}, {Op59M1}, + {Op5AX0}, {Op5B}, {Op5C}, {Op5DM1}, {Op5EM1}, + {Op5FM1}, {Op60}, {Op61M1}, {Op62}, {Op63M1}, + {Op64M1}, {Op65M1}, {Op66M1}, {Op67M1}, {Op68M1}, + {Op69M1}, {Op6AM1}, {Op6B}, {Op6C}, {Op6DM1}, + {Op6EM1}, {Op6FM1}, {Op70}, {Op71M1}, {Op72M1}, + {Op73M1}, {Op74M1}, {Op75M1}, {Op76M1}, {Op77M1}, + {Op78}, {Op79M1}, {Op7AX0}, {Op7B}, {Op7C}, + {Op7DM1}, {Op7EM1}, {Op7FM1}, {Op80}, {Op81M1}, + {Op82}, {Op83M1}, {Op84X0}, {Op85M1}, {Op86X0}, + {Op87M1}, {Op88X0}, {Op89M1}, {Op8AM1}, {Op8B}, + {Op8CX0}, {Op8DM1}, {Op8EX0}, {Op8FM1}, {Op90}, + {Op91M1}, {Op92M1}, {Op93M1}, {Op94X0}, {Op95M1}, + {Op96X0}, {Op97M1}, {Op98M1}, {Op99M1}, {Op9A}, + {Op9BX0}, {Op9CM1}, {Op9DM1}, {Op9EM1}, {Op9FM1}, + {OpA0X0}, {OpA1M1}, {OpA2X0}, {OpA3M1}, {OpA4X0}, + {OpA5M1}, {OpA6X0}, {OpA7M1}, {OpA8X0}, {OpA9M1}, + {OpAAX0}, {OpAB}, {OpACX0}, {OpADM1}, {OpAEX0}, + {OpAFM1}, {OpB0}, {OpB1M1}, {OpB2M1}, {OpB3M1}, + {OpB4X0}, {OpB5M1}, {OpB6X0}, {OpB7M1}, {OpB8}, + {OpB9M1}, {OpBAX0}, {OpBBX0}, {OpBCX0}, {OpBDM1}, + {OpBEX0}, {OpBFM1}, {OpC0X0}, {OpC1M1}, {OpC2}, + {OpC3M1}, {OpC4X0}, {OpC5M1}, {OpC6M1}, {OpC7M1}, + {OpC8X0}, {OpC9M1}, {OpCAX0}, {OpCB}, {OpCCX0}, + {OpCDM1}, {OpCEM1}, {OpCFM1}, {OpD0}, {OpD1M1}, + {OpD2M1}, {OpD3M1}, {OpD4}, {OpD5M1}, {OpD6M1}, + {OpD7M1}, {OpD8}, {OpD9M1}, {OpDAX0}, {OpDB}, + {OpDC}, {OpDDM1}, {OpDEM1}, {OpDFM1}, {OpE0X0}, + {OpE1M1}, {OpE2}, {OpE3M1}, {OpE4X0}, {OpE5M1}, + {OpE6M1}, {OpE7M1}, {OpE8X0}, {OpE9M1}, {OpEA}, + {OpEB}, {OpECX0}, {OpEDM1}, {OpEEM1}, {OpEFM1}, + {OpF0}, {OpF1M1}, {OpF2M1}, {OpF3M1}, {OpF4}, + {OpF5M1}, {OpF6M1}, {OpF7M1}, {OpF8}, {OpF9M1}, + {OpFAX0}, {OpFB}, {OpFC}, {OpFDM1}, {OpFEM1}, + {OpFFM1} +}; + +struct SOpcodes S9xOpcodesM0X0[256] = +{ + {Op00}, {Op01M0}, {Op02}, {Op03M0}, {Op04M0}, + {Op05M0}, {Op06M0}, {Op07M0}, {Op08}, {Op09M0}, + {Op0AM0}, {Op0B}, {Op0CM0}, {Op0DM0}, {Op0EM0}, + {Op0FM0}, {Op10}, {Op11M0}, {Op12M0}, {Op13M0}, + {Op14M0}, {Op15M0}, {Op16M0}, {Op17M0}, {Op18}, + {Op19M0}, {Op1AM0}, {Op1B}, {Op1CM0}, {Op1DM0}, + {Op1EM0}, {Op1FM0}, {Op20}, {Op21M0}, {Op22}, + {Op23M0}, {Op24M0}, {Op25M0}, {Op26M0}, {Op27M0}, + {Op28}, {Op29M0}, {Op2AM0}, {Op2B}, {Op2CM0}, + {Op2DM0}, {Op2EM0}, {Op2FM0}, {Op30}, {Op31M0}, + {Op32M0}, {Op33M0}, {Op34M0}, {Op35M0}, {Op36M0}, + {Op37M0}, {Op38}, {Op39M0}, {Op3AM0}, {Op3B}, + {Op3CM0}, {Op3DM0}, {Op3EM0}, {Op3FM0}, {Op40}, + {Op41M0}, {Op42}, {Op43M0}, {Op44X0}, {Op45M0}, + {Op46M0}, {Op47M0}, {Op48M0}, {Op49M0}, {Op4AM0}, + {Op4B}, {Op4C}, {Op4DM0}, {Op4EM0}, {Op4FM0}, + {Op50}, {Op51M0}, {Op52M0}, {Op53M0}, {Op54X0}, + {Op55M0}, {Op56M0}, {Op57M0}, {Op58}, {Op59M0}, + {Op5AX0}, {Op5B}, {Op5C}, {Op5DM0}, {Op5EM0}, + {Op5FM0}, {Op60}, {Op61M0}, {Op62}, {Op63M0}, + {Op64M0}, {Op65M0}, {Op66M0}, {Op67M0}, {Op68M0}, + {Op69M0}, {Op6AM0}, {Op6B}, {Op6C}, {Op6DM0}, + {Op6EM0}, {Op6FM0}, {Op70}, {Op71M0}, {Op72M0}, + {Op73M0}, {Op74M0}, {Op75M0}, {Op76M0}, {Op77M0}, + {Op78}, {Op79M0}, {Op7AX0}, {Op7B}, {Op7C}, + {Op7DM0}, {Op7EM0}, {Op7FM0}, {Op80}, {Op81M0}, + {Op82}, {Op83M0}, {Op84X0}, {Op85M0}, {Op86X0}, + {Op87M0}, {Op88X0}, {Op89M0}, {Op8AM0}, {Op8B}, + {Op8CX0}, {Op8DM0}, {Op8EX0}, {Op8FM0}, {Op90}, + {Op91M0}, {Op92M0}, {Op93M0}, {Op94X0}, {Op95M0}, + {Op96X0}, {Op97M0}, {Op98M0}, {Op99M0}, {Op9A}, + {Op9BX0}, {Op9CM0}, {Op9DM0}, {Op9EM0}, {Op9FM0}, + {OpA0X0}, {OpA1M0}, {OpA2X0}, {OpA3M0}, {OpA4X0}, + {OpA5M0}, {OpA6X0}, {OpA7M0}, {OpA8X0}, {OpA9M0}, + {OpAAX0}, {OpAB}, {OpACX0}, {OpADM0}, {OpAEX0}, + {OpAFM0}, {OpB0}, {OpB1M0}, {OpB2M0}, {OpB3M0}, + {OpB4X0}, {OpB5M0}, {OpB6X0}, {OpB7M0}, {OpB8}, + {OpB9M0}, {OpBAX0}, {OpBBX0}, {OpBCX0}, {OpBDM0}, + {OpBEX0}, {OpBFM0}, {OpC0X0}, {OpC1M0}, {OpC2}, + {OpC3M0}, {OpC4X0}, {OpC5M0}, {OpC6M0}, {OpC7M0}, + {OpC8X0}, {OpC9M0}, {OpCAX0}, {OpCB}, {OpCCX0}, + {OpCDM0}, {OpCEM0}, {OpCFM0}, {OpD0}, {OpD1M0}, + {OpD2M0}, {OpD3M0}, {OpD4}, {OpD5M0}, {OpD6M0}, + {OpD7M0}, {OpD8}, {OpD9M0}, {OpDAX0}, {OpDB}, + {OpDC}, {OpDDM0}, {OpDEM0}, {OpDFM0}, {OpE0X0}, + {OpE1M0}, {OpE2}, {OpE3M0}, {OpE4X0}, {OpE5M0}, + {OpE6M0}, {OpE7M0}, {OpE8X0}, {OpE9M0}, {OpEA}, + {OpEB}, {OpECX0}, {OpEDM0}, {OpEEM0}, {OpEFM0}, + {OpF0}, {OpF1M0}, {OpF2M0}, {OpF3M0}, {OpF4}, + {OpF5M0}, {OpF6M0}, {OpF7M0}, {OpF8}, {OpF9M0}, + {OpFAX0}, {OpFB}, {OpFC}, {OpFDM0}, {OpFEM0}, + {OpFFM0} +}; + +struct SOpcodes S9xOpcodesM0X1[256] = +{ + {Op00}, {Op01M0}, {Op02}, {Op03M0}, {Op04M0}, + {Op05M0}, {Op06M0}, {Op07M0}, {Op08}, {Op09M0}, + {Op0AM0}, {Op0B}, {Op0CM0}, {Op0DM0}, {Op0EM0}, + {Op0FM0}, {Op10}, {Op11M0}, {Op12M0}, {Op13M0}, + {Op14M0}, {Op15M0}, {Op16M0}, {Op17M0}, {Op18}, + {Op19M0}, {Op1AM0}, {Op1B}, {Op1CM0}, {Op1DM0}, + {Op1EM0}, {Op1FM0}, {Op20}, {Op21M0}, {Op22}, + {Op23M0}, {Op24M0}, {Op25M0}, {Op26M0}, {Op27M0}, + {Op28}, {Op29M0}, {Op2AM0}, {Op2B}, {Op2CM0}, + {Op2DM0}, {Op2EM0}, {Op2FM0}, {Op30}, {Op31M0}, + {Op32M0}, {Op33M0}, {Op34M0}, {Op35M0}, {Op36M0}, + {Op37M0}, {Op38}, {Op39M0}, {Op3AM0}, {Op3B}, + {Op3CM0}, {Op3DM0}, {Op3EM0}, {Op3FM0}, {Op40}, + {Op41M0}, {Op42}, {Op43M0}, {Op44X1}, {Op45M0}, + {Op46M0}, {Op47M0}, {Op48M0}, {Op49M0}, {Op4AM0}, + {Op4B}, {Op4C}, {Op4DM0}, {Op4EM0}, {Op4FM0}, + {Op50}, {Op51M0}, {Op52M0}, {Op53M0}, {Op54X1}, + {Op55M0}, {Op56M0}, {Op57M0}, {Op58}, {Op59M0}, + {Op5AX1}, {Op5B}, {Op5C}, {Op5DM0}, {Op5EM0}, + {Op5FM0}, {Op60}, {Op61M0}, {Op62}, {Op63M0}, + {Op64M0}, {Op65M0}, {Op66M0}, {Op67M0}, {Op68M0}, + {Op69M0}, {Op6AM0}, {Op6B}, {Op6C}, {Op6DM0}, + {Op6EM0}, {Op6FM0}, {Op70}, {Op71M0}, {Op72M0}, + {Op73M0}, {Op74M0}, {Op75M0}, {Op76M0}, {Op77M0}, + {Op78}, {Op79M0}, {Op7AX1}, {Op7B}, {Op7C}, + {Op7DM0}, {Op7EM0}, {Op7FM0}, {Op80}, {Op81M0}, + {Op82}, {Op83M0}, {Op84X1}, {Op85M0}, {Op86X1}, + {Op87M0}, {Op88X1}, {Op89M0}, {Op8AM0}, {Op8B}, + {Op8CX1}, {Op8DM0}, {Op8EX1}, {Op8FM0}, {Op90}, + {Op91M0}, {Op92M0}, {Op93M0}, {Op94X1}, {Op95M0}, + {Op96X1}, {Op97M0}, {Op98M0}, {Op99M0}, {Op9A}, + {Op9BX1}, {Op9CM0}, {Op9DM0}, {Op9EM0}, {Op9FM0}, + {OpA0X1}, {OpA1M0}, {OpA2X1}, {OpA3M0}, {OpA4X1}, + {OpA5M0}, {OpA6X1}, {OpA7M0}, {OpA8X1}, {OpA9M0}, + {OpAAX1}, {OpAB}, {OpACX1}, {OpADM0}, {OpAEX1}, + {OpAFM0}, {OpB0}, {OpB1M0}, {OpB2M0}, {OpB3M0}, + {OpB4X1}, {OpB5M0}, {OpB6X1}, {OpB7M0}, {OpB8}, + {OpB9M0}, {OpBAX1}, {OpBBX1}, {OpBCX1}, {OpBDM0}, + {OpBEX1}, {OpBFM0}, {OpC0X1}, {OpC1M0}, {OpC2}, + {OpC3M0}, {OpC4X1}, {OpC5M0}, {OpC6M0}, {OpC7M0}, + {OpC8X1}, {OpC9M0}, {OpCAX1}, {OpCB}, {OpCCX1}, + {OpCDM0}, {OpCEM0}, {OpCFM0}, {OpD0}, {OpD1M0}, + {OpD2M0}, {OpD3M0}, {OpD4}, {OpD5M0}, {OpD6M0}, + {OpD7M0}, {OpD8}, {OpD9M0}, {OpDAX1}, {OpDB}, + {OpDC}, {OpDDM0}, {OpDEM0}, {OpDFM0}, {OpE0X1}, + {OpE1M0}, {OpE2}, {OpE3M0}, {OpE4X1}, {OpE5M0}, + {OpE6M0}, {OpE7M0}, {OpE8X1}, {OpE9M0}, {OpEA}, + {OpEB}, {OpECX1}, {OpEDM0}, {OpEEM0}, {OpEFM0}, + {OpF0}, {OpF1M0}, {OpF2M0}, {OpF3M0}, {OpF4}, + {OpF5M0}, {OpF6M0}, {OpF7M0}, {OpF8}, {OpF9M0}, + {OpFAX1}, {OpFB}, {OpFC}, {OpFDM0}, {OpFEM0}, + {OpFFM0} +}; diff --git a/src/snes4iphone_src/cpuops.h b/src/snes4iphone_src/cpuops.h new file mode 100755 index 0000000..542c9c7 --- /dev/null +++ b/src/snes4iphone_src/cpuops.h @@ -0,0 +1,50 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#ifndef _CPUOPS_H_ +#define _CPUOPS_H_ +void S9xOpcode_NMI (); +void S9xOpcode_IRQ (); + +#define CHECK_FOR_IRQ() \ +if (CPU.IRQActive && !CheckFlag (IRQ) && !Settings.DisableIRQ) \ + S9xOpcode_IRQ() + +#endif diff --git a/src/snes4iphone_src/data.cpp b/src/snes4iphone_src/data.cpp new file mode 100755 index 0000000..2a25eab --- /dev/null +++ b/src/snes4iphone_src/data.cpp @@ -0,0 +1,489 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#include "snes9x.h" +/* +uint8 add32_32 [32][32] = { +{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e, + 0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d, + 0x1e,0x1f}, +{ 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e, + 0x1f,0x1f}, +{ 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10, + 0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f, + 0x1f,0x1f}, +{ 0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11, + 0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f, + 0x1f,0x1f}, +{ 0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12, + 0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f, + 0x1f,0x1f}, +{ 0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13, + 0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f, + 0x1f,0x1f}, +{ 0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14, + 0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f, + 0x1f,0x1f}, +{ 0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15, + 0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, + 0x1f,0x1f}, +{ 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16, + 0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, + 0x1f,0x1f}, +{ 0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, + 0x1f,0x1f}, +{ 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18, + 0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, + 0x1f,0x1f}, +{ 0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19, + 0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, + 0x1f,0x1f}, +{ 0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a, + 0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, + 0x1f,0x1f}, +{ 0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b, + 0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, + 0x1f,0x1f}, +{ 0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c, + 0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, + 0x1f,0x1f}, +{ 0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d, + 0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, + 0x1f,0x1f}, +{ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e, + 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, + 0x1f,0x1f}, +{ 0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f, + 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, + 0x1f,0x1f}, +{ 0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f, + 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, + 0x1f,0x1f}, +{ 0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f, + 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, + 0x1f,0x1f}, +{ 0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f, + 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, + 0x1f,0x1f}, +{ 0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f, + 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, + 0x1f,0x1f}, +{ 0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, + 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, + 0x1f,0x1f}, +{ 0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, + 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, + 0x1f,0x1f}, +{ 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, + 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, + 0x1f,0x1f}, +{ 0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, + 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, + 0x1f,0x1f}, +{ 0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, + 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, + 0x1f,0x1f}, +{ 0x1b,0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, + 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, + 0x1f,0x1f}, +{ 0x1c,0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, + 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, + 0x1f,0x1f}, +{ 0x1d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, + 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, + 0x1f,0x1f}, +{ 0x1e,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, + 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, + 0x1f,0x1f}, +{ 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, + 0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f, + 0x1f,0x1f} +}; + +uint8 add32_32_half [32][32] = { +{ 0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07, + 0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e, + 0x0f,0x0f}, +{ 0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07, + 0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f, + 0x0f,0x10}, +{ 0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08, + 0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f, + 0x10,0x10}, +{ 0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08, + 0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10, + 0x10,0x11}, +{ 0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09, + 0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10, + 0x11,0x11}, +{ 0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09, + 0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11, + 0x11,0x12}, +{ 0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a, + 0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11, + 0x12,0x12}, +{ 0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a, + 0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12, + 0x12,0x13}, +{ 0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b, + 0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12, + 0x13,0x13}, +{ 0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b, + 0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13, + 0x13,0x14}, +{ 0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c, + 0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13, + 0x14,0x14}, +{ 0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c, + 0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14, + 0x14,0x15}, +{ 0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d, + 0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14, + 0x15,0x15}, +{ 0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d, + 0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15, + 0x15,0x16}, +{ 0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e, + 0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15, + 0x16,0x16}, +{ 0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e, + 0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15,0x16, + 0x16,0x17}, +{ 0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f, + 0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15,0x16,0x16, + 0x17,0x17}, +{ 0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f, + 0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15,0x16,0x16,0x17, + 0x17,0x18}, +{ 0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10, + 0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15,0x16,0x16,0x17,0x17, + 0x18,0x18}, +{ 0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10, + 0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15,0x16,0x16,0x17,0x17,0x18, + 0x18,0x19}, +{ 0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11, + 0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15,0x16,0x16,0x17,0x17,0x18,0x18, + 0x19,0x19}, +{ 0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11, + 0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15,0x16,0x16,0x17,0x17,0x18,0x18,0x19, + 0x19,0x1a}, +{ 0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12, + 0x12,0x13,0x13,0x14,0x14,0x15,0x15,0x16,0x16,0x17,0x17,0x18,0x18,0x19,0x19, + 0x1a,0x1a}, +{ 0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12, + 0x13,0x13,0x14,0x14,0x15,0x15,0x16,0x16,0x17,0x17,0x18,0x18,0x19,0x19,0x1a, + 0x1a,0x1b}, +{ 0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13, + 0x13,0x14,0x14,0x15,0x15,0x16,0x16,0x17,0x17,0x18,0x18,0x19,0x19,0x1a,0x1a, + 0x1b,0x1b}, +{ 0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13, + 0x14,0x14,0x15,0x15,0x16,0x16,0x17,0x17,0x18,0x18,0x19,0x19,0x1a,0x1a,0x1b, + 0x1b,0x1c}, +{ 0x0d,0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14, + 0x14,0x15,0x15,0x16,0x16,0x17,0x17,0x18,0x18,0x19,0x19,0x1a,0x1a,0x1b,0x1b, + 0x1c,0x1c}, +{ 0x0d,0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14, + 0x15,0x15,0x16,0x16,0x17,0x17,0x18,0x18,0x19,0x19,0x1a,0x1a,0x1b,0x1b,0x1c, + 0x1c,0x1d}, +{ 0x0e,0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15, + 0x15,0x16,0x16,0x17,0x17,0x18,0x18,0x19,0x19,0x1a,0x1a,0x1b,0x1b,0x1c,0x1c, + 0x1d,0x1d}, +{ 0x0e,0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15, + 0x16,0x16,0x17,0x17,0x18,0x18,0x19,0x19,0x1a,0x1a,0x1b,0x1b,0x1c,0x1c,0x1d, + 0x1d,0x1e}, +{ 0x0f,0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15,0x16, + 0x16,0x17,0x17,0x18,0x18,0x19,0x19,0x1a,0x1a,0x1b,0x1b,0x1c,0x1c,0x1d,0x1d, + 0x1e,0x1e}, +{ 0x0f,0x10,0x10,0x11,0x11,0x12,0x12,0x13,0x13,0x14,0x14,0x15,0x15,0x16,0x16, + 0x17,0x17,0x18,0x18,0x19,0x19,0x1a,0x1a,0x1b,0x1b,0x1c,0x1c,0x1d,0x1d,0x1e, + 0x1e,0x1f} +}; +uint8 sub32_32 [32][32] = { +{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e, + 0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d, + 0x1e,0x1f}, +{ 0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d, + 0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c, + 0x1d,0x1e}, +{ 0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c, + 0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b, + 0x1c,0x1d}, +{ 0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b, + 0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a, + 0x1b,0x1c}, +{ 0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a, + 0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19, + 0x1a,0x1b}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09, + 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18, + 0x19,0x1a}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08, + 0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17, + 0x18,0x19}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16, + 0x17,0x18}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06, + 0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15, + 0x16,0x17}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05, + 0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14, + 0x15,0x16}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04, + 0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13, + 0x14,0x15}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03, + 0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12, + 0x13,0x14}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02, + 0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11, + 0x12,0x13}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, + 0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10, + 0x11,0x12}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, + 0x10,0x11}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e, + 0x0f,0x10}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d, + 0x0e,0x0f}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c, + 0x0d,0x0e}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b, + 0x0c,0x0d}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a, + 0x0b,0x0c}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09, + 0x0a,0x0b}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08, + 0x09,0x0a}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x08,0x09}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06, + 0x07,0x08}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05, + 0x06,0x07}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04, + 0x05,0x06}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03, + 0x04,0x05}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02, + 0x03,0x04}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, + 0x02,0x03}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x02}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x01}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00} +}; + +uint8 sub32_32_half [32][32] = { +{ 0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07, + 0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e, + 0x0f,0x0f}, +{ 0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06, + 0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e, + 0x0e,0x0f}, +{ 0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06, + 0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d, + 0x0e,0x0e}, +{ 0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05, + 0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d, + 0x0d,0x0e}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05, + 0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c, + 0x0d,0x0d}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04, + 0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c, + 0x0c,0x0d}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04, + 0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b, + 0x0c,0x0c}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03, + 0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b, + 0x0b,0x0c}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03, + 0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a, + 0x0b,0x0b}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02, + 0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09,0x0a, + 0x0a,0x0b}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02, + 0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09,0x09, + 0x0a,0x0a}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01, + 0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08,0x09, + 0x09,0x0a}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, + 0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08,0x08, + 0x09,0x09}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07,0x08, + 0x08,0x09}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07, + 0x08,0x08}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07, + 0x07,0x08}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06, + 0x07,0x07}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06, + 0x06,0x07}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05, + 0x06,0x06}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05, + 0x05,0x06}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04, + 0x05,0x05}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04, + 0x04,0x05}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03, + 0x04,0x04}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02,0x03, + 0x03,0x04}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x02, + 0x03,0x03}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02, + 0x02,0x03}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01, + 0x02,0x02}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01, + 0x01,0x02}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x01}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00} +}; +*/ + +uint8 mul_brightness [16][32] = { +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00}, +{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x02,0x02,0x02,0x02,0x02,0x02, + 0x02,0x02}, +{ 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x02,0x02,0x02, + 0x02,0x02,0x02,0x02,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x04,0x04,0x04, + 0x04,0x04}, +{ 0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x02,0x02,0x02,0x02,0x02,0x03,0x03, + 0x03,0x03,0x03,0x04,0x04,0x04,0x04,0x04,0x05,0x05,0x05,0x05,0x05,0x06,0x06, + 0x06,0x06}, +{ 0x00,0x00,0x01,0x01,0x01,0x01,0x02,0x02,0x02,0x02,0x03,0x03,0x03,0x03,0x04, + 0x04,0x04,0x05,0x05,0x05,0x05,0x06,0x06,0x06,0x06,0x07,0x07,0x07,0x07,0x08, + 0x08,0x08}, +{ 0x00,0x00,0x01,0x01,0x01,0x02,0x02,0x02,0x03,0x03,0x03,0x04,0x04,0x04,0x05, + 0x05,0x05,0x06,0x06,0x06,0x07,0x07,0x07,0x08,0x08,0x08,0x09,0x09,0x09,0x0a, + 0x0a,0x0a}, +{ 0x00,0x00,0x01,0x01,0x02,0x02,0x02,0x03,0x03,0x04,0x04,0x04,0x05,0x05,0x06, + 0x06,0x06,0x07,0x07,0x08,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0a,0x0b,0x0b,0x0c, + 0x0c,0x0c}, +{ 0x00,0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07, + 0x07,0x07,0x08,0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e, + 0x0e,0x0e}, +{ 0x00,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x07, + 0x08,0x09,0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x0f, + 0x10,0x11}, +{ 0x00,0x01,0x01,0x02,0x02,0x03,0x04,0x04,0x05,0x05,0x06,0x07,0x07,0x08,0x08, + 0x09,0x0a,0x0a,0x0b,0x0b,0x0c,0x0d,0x0d,0x0e,0x0e,0x0f,0x10,0x10,0x11,0x11, + 0x12,0x13}, +{ 0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x05,0x05,0x06,0x07,0x07,0x08,0x09,0x09, + 0x0a,0x0b,0x0b,0x0c,0x0d,0x0d,0x0e,0x0f,0x0f,0x10,0x11,0x11,0x12,0x13,0x13, + 0x14,0x15}, +{ 0x00,0x01,0x01,0x02,0x03,0x04,0x04,0x05,0x06,0x07,0x07,0x08,0x09,0x0a,0x0a, + 0x0b,0x0c,0x0c,0x0d,0x0e,0x0f,0x0f,0x10,0x11,0x12,0x12,0x13,0x14,0x15,0x15, + 0x16,0x17}, +{ 0x00,0x01,0x02,0x02,0x03,0x04,0x05,0x06,0x06,0x07,0x08,0x09,0x0a,0x0a,0x0b, + 0x0c,0x0d,0x0e,0x0e,0x0f,0x10,0x11,0x12,0x12,0x13,0x14,0x15,0x16,0x16,0x17, + 0x18,0x19}, +{ 0x00,0x01,0x02,0x03,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0a,0x0b,0x0c, + 0x0d,0x0e,0x0f,0x10,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x17,0x18,0x19, + 0x1a,0x1b}, +{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d, + 0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b, + 0x1c,0x1d}, +{ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e, + 0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d, + 0x1e,0x1f} +}; + diff --git a/src/snes4iphone_src/debug.h b/src/snes4iphone_src/debug.h new file mode 100755 index 0000000..0b8cc79 --- /dev/null +++ b/src/snes4iphone_src/debug.h @@ -0,0 +1,63 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#ifndef _DEBUG_H_ +#define _DEBUG_H_ + +START_EXTERN_C +void S9xDoDebug (); +void S9xTrace (); +void S9xSA1Trace (); +void S9xTraceMessage (const char *); + +// Structures +struct SBreakPoint{ + bool8 Enabled; + uint8 Bank; + uint16 Address; +}; + +uint8 S9xOPrint( char *Line, uint8 Bank, uint16 Address); +uint8 S9xSA1OPrint( char *Line, uint8 Bank, uint16 Address); + +extern struct SBreakPoint S9xBreakpoint[ 6]; +extern char *S9xMnemonics[256]; +END_EXTERN_C +#endif diff --git a/src/snes4iphone_src/display.h b/src/snes4iphone_src/display.h new file mode 100755 index 0000000..753652b --- /dev/null +++ b/src/snes4iphone_src/display.h @@ -0,0 +1,86 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#ifndef _DISPLAY_H_ +#define _DISPLAY_H_ + +START_EXTERN_C +// Routines the port specific code has to implement +void S9xSetPalette (); +void S9xTextMode (); +void S9xGraphicsMode (); +char *S9xParseArgs (char **argv, int argc); +void S9xParseArg (char **argv, int &index, int argc); +void S9xExtraUsage (); +uint32 S9xReadJoypad (int which1_0_to_4); +bool8_32 S9xReadMousePosition (int which1_0_to_1, int &x, int &y, uint32 &buttons); +bool8_32 S9xReadSuperScopePosition (int &x, int &y, uint32 &buttons); + +void S9xUsage (); +void S9xInitDisplay (int argc, char **argv); +void S9xDeinitDisplay (); +void S9xInitInputDevices (); +void S9xSetTitle (const char *title); +void S9xProcessEvents (bool8_32 block); +void S9xPutImage (int width, int height); +void S9xParseDisplayArg (char **argv, int &index, int argc); +void S9xToggleSoundChannel (int channel); +void S9xSetInfoString (const char *string); +int S9xMinCommandLineArgs (); +void S9xNextController (); +bool8_32 S9xLoadROMImage (const char *string); +const char *S9xSelectFilename (const char *def, const char *dir, + const char *ext, const char *title); + +const char *S9xChooseFilename (bool8_32 read_only); +bool8_32 S9xOpenSnapshotFile (const char *base, bool8_32 read_only, STREAM *file); +void S9xCloseSnapshotFile (STREAM file); + +const char *S9xBasename (const char *filename); + +int S9xFStrcmp (FILE *, const char *); +const char *S9xGetHomeDirectory (); +const char *S9xGetSnapshotDirectory (); +const char *S9xGetROMDirectory (); +const char *S9xGetSRAMFilename (); +const char *S9xGetFilename (const char *extension); +END_EXTERN_C + +#endif diff --git a/src/snes4iphone_src/dma.cpp b/src/snes4iphone_src/dma.cpp new file mode 100755 index 0000000..f345c90 --- /dev/null +++ b/src/snes4iphone_src/dma.cpp @@ -0,0 +1,922 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#include "snes9x.h" + +#include "memmap.h" +#include "ppu.h" +#include "cpuexec.h" +#include "missing.h" +#include "dma.h" +#include "apu.h" +#include "gfx.h" +#ifdef USE_SA1 +#include "sa1.h" +#endif + +//SDD1 +#include "sdd1emu.h" +uint8 buffer[0x10000]; +//SDD1// + +extern int HDMA_ModeByteCounts [8]; +extern uint8 *HDMAMemPointers [8]; +extern uint8 *HDMABasePointers [8]; + +#if defined(__linux__) || defined(__WIN32__) || defined(__GP2X__) || defined(__IPHONE__) +static int S9xCompareSDD1IndexEntries (const void *p1, const void *p2) +{ + return (*(uint32 *) p1 - *(uint32 *) p2); +} +#endif + +/**********************************************************************************************/ +/* S9xDoDMA() */ +/* This function preforms the general dma transfer */ +/**********************************************************************************************/ +void S9xDoDMA (uint8 Channel) +{ + uint8 Work; + + if (Channel > 7 || CPU.InDMA) + return; + + CPU.InDMA = TRUE; + bool8 in_sa1_dma = FALSE; + uint8 *in_sdd1_dma = NULL; + SDMA *d = &DMA[Channel]; + + int count = d->TransferBytes; + + if (count == 0) + count = 0x10000; + + int inc = d->AAddressFixed ? 0 : (!d->AAddressDecrement ? 1 : -1); + + switch (d->BAddress) + { + case 0x18: + case 0x19: + if (IPPU.RenderThisFrame) + FLUSH_REDRAW (); + break; + } + + if (Settings.SDD1) + { + if (d->AAddressFixed && Memory.FillRAM [0x4801] > 0) + { + // Hacky support for pre-decompressed S-DD1 data + inc = !d->AAddressDecrement ? 1 : -1; + uint32 address = (((d->ABank << 16) | d->AAddress) & 0xfffff) << 4; + + address |= Memory.FillRAM [0x4804 + ((d->ABank - 0xc0) >> 4)]; + if(Settings.SDD1Pack) + { + uint8* in_ptr=GetBasePointer(((d->ABank << 16) | d->AAddress)); + in_ptr+=d->AAddress; + + SDD1_decompress(buffer,in_ptr,d->TransferBytes); + in_sdd1_dma=buffer; + } + else + { + #if defined (__GP2X__) || defined(__IPHONE__) + void *ptr = bsearch (&address, Memory.SDD1Index, + Memory.SDD1Entries, 12, S9xCompareSDD1IndexEntries); + if (ptr) + in_sdd1_dma = *(uint32 *) ((uint8 *) ptr + 4) + Memory.SDD1Data; + #else + uint8 *ptr = Memory.SDD1Index; + + for (uint32 e = 0; e < Memory.SDD1Entries; e++, ptr += 12) + { + if (address == *(uint32 *) ptr) + { + in_sdd1_dma = *(uint32 *) (ptr + 4) + Memory.SDD1Data; + break; + } + } + #endif + +/* if (!in_sdd1_dma) + { + // No matching decompressed data found. Must be some new + // graphics not encountered before. Log it if it hasn't been + // already. + uint8 *p = Memory.SDD1LoggedData; + bool8 found = FALSE; + uint8 SDD1Bank = Memory.FillRAM [0x4804 + ((d->ABank - 0xc0) >> 4)] | 0xf0; + + for (uint32 i = 0; i < Memory.SDD1LoggedDataCount; i++, p += 8) + { + if (*p == d->ABank || + *(p + 1) == (d->AAddress >> 8) && + *(p + 2) == (d->AAddress & 0xff) && + *(p + 3) == (count >> 8) && + *(p + 4) == (count & 0xff) && + *(p + 7) == SDD1Bank) + { + found = TRUE; + break; + } + } + if (!found && Memory.SDD1LoggedDataCount < MEMMAP_MAX_SDD1_LOGGED_ENTRIES) + { + *p = d->ABank; + *(p + 1) = d->AAddress >> 8; + *(p + 2) = d->AAddress & 0xff; + *(p + 3) = count >> 8; + *(p + 4) = count & 0xff; + *(p + 7) = SDD1Bank; + Memory.SDD1LoggedDataCount += 1; + } + } +*/ } + } + + Memory.FillRAM [0x4801] = 0; + } + +#ifdef USE_SA1 + if (d->BAddress == 0x18 && SA1.in_char_dma && (d->ABank & 0xf0) == 0x40) +#else + if (d->BAddress == 0x18 && (d->ABank & 0xf0) == 0x40) +#endif + { + // Perform packed bitmap to PPU character format conversion on the + // data before transmitting it to V-RAM via-DMA. + int num_chars = 1 << ((Memory.FillRAM [0x2231] >> 2) & 7); + int depth = (Memory.FillRAM [0x2231] & 3) == 0 ? 8 : + (Memory.FillRAM [0x2231] & 3) == 1 ? 4 : 2; + + int bytes_per_char = 8 * depth; + int bytes_per_line = depth * num_chars; + int char_line_bytes = bytes_per_char * num_chars; + uint32 addr = (d->AAddress / char_line_bytes) * char_line_bytes; + uint8 *base = GetBasePointer ((d->ABank << 16) + addr) + addr; + uint8 *buffer = &Memory.ROM [CMemory::MAX_ROM_SIZE - 0x10000]; + uint8 *p = buffer; + uint32 inc = char_line_bytes - (d->AAddress % char_line_bytes); + uint32 char_count = inc / bytes_per_char; + + in_sa1_dma = TRUE; + +//printf ("%08x,", base); fflush (stdout); +//printf ("depth = %d, count = %d, bytes_per_char = %d, bytes_per_line = %d, num_chars = %d, char_line_bytes = %d\n", +//depth, count, bytes_per_char, bytes_per_line, num_chars, char_line_bytes); + int i; + + switch (depth) + { + case 2: + for (i = 0; i < count; i += inc, base += char_line_bytes, + inc = char_line_bytes, char_count = num_chars) + { + uint8 *line = base + (num_chars - char_count) * 2; + for (uint32 j = 0; j < char_count && p - buffer < count; + j++, line += 2) + { + uint8 *q = line; + for (int l = 0; l < 8; l++, q += bytes_per_line) + { + for (int b = 0; b < 2; b++) + { + uint8 r = *(q + b); + *(p + 0) = (*(p + 0) << 1) | ((r >> 0) & 1); + *(p + 1) = (*(p + 1) << 1) | ((r >> 1) & 1); + *(p + 0) = (*(p + 0) << 1) | ((r >> 2) & 1); + *(p + 1) = (*(p + 1) << 1) | ((r >> 3) & 1); + *(p + 0) = (*(p + 0) << 1) | ((r >> 4) & 1); + *(p + 1) = (*(p + 1) << 1) | ((r >> 5) & 1); + *(p + 0) = (*(p + 0) << 1) | ((r >> 6) & 1); + *(p + 1) = (*(p + 1) << 1) | ((r >> 7) & 1); + } + p += 2; + } + } + } + break; + case 4: + for (i = 0; i < count; i += inc, base += char_line_bytes, + inc = char_line_bytes, char_count = num_chars) + { + uint8 *line = base + (num_chars - char_count) * 4; + for (uint32 j = 0; j < char_count && p - buffer < count; + j++, line += 4) + { + uint8 *q = line; + for (int l = 0; l < 8; l++, q += bytes_per_line) + { + for (int b = 0; b < 4; b++) + { + uint8 r = *(q + b); + *(p + 0) = (*(p + 0) << 1) | ((r >> 0) & 1); + *(p + 1) = (*(p + 1) << 1) | ((r >> 1) & 1); + *(p + 16) = (*(p + 16) << 1) | ((r >> 2) & 1); + *(p + 17) = (*(p + 17) << 1) | ((r >> 3) & 1); + *(p + 0) = (*(p + 0) << 1) | ((r >> 4) & 1); + *(p + 1) = (*(p + 1) << 1) | ((r >> 5) & 1); + *(p + 16) = (*(p + 16) << 1) | ((r >> 6) & 1); + *(p + 17) = (*(p + 17) << 1) | ((r >> 7) & 1); + } + p += 2; + } + p += 32 - 16; + } + } + break; + case 8: + for (i = 0; i < count; i += inc, base += char_line_bytes, + inc = char_line_bytes, char_count = num_chars) + { + uint8 *line = base + (num_chars - char_count) * 8; + for (uint32 j = 0; j < char_count && p - buffer < count; + j++, line += 8) + { + uint8 *q = line; + for (int l = 0; l < 8; l++, q += bytes_per_line) + { + for (int b = 0; b < 8; b++) + { + uint8 r = *(q + b); + *(p + 0) = (*(p + 0) << 1) | ((r >> 0) & 1); + *(p + 1) = (*(p + 1) << 1) | ((r >> 1) & 1); + *(p + 16) = (*(p + 16) << 1) | ((r >> 2) & 1); + *(p + 17) = (*(p + 17) << 1) | ((r >> 3) & 1); + *(p + 32) = (*(p + 32) << 1) | ((r >> 4) & 1); + *(p + 33) = (*(p + 33) << 1) | ((r >> 5) & 1); + *(p + 48) = (*(p + 48) << 1) | ((r >> 6) & 1); + *(p + 49) = (*(p + 49) << 1) | ((r >> 7) & 1); + } + p += 2; + } + p += 64 - 16; + } + } + break; + } + } + +#ifdef DEBUGGER + if (Settings.TraceDMA) + { + sprintf (String, "DMA[%d]: %s Mode: %d 0x%02X%04X->0x21%02X Bytes: %d (%s) V-Line:%ld", + Channel, d->TransferDirection ? "read" : "write", + d->TransferMode, d->ABank, d->AAddress, + d->BAddress, d->TransferBytes, + d->AAddressFixed ? "fixed" : + (d->AAddressDecrement ? "dec" : "inc"), + CPU.V_Counter); + if (d->BAddress == 0x18 || d->BAddress == 0x19) + sprintf (String, "%s VRAM: %04X (%d,%d) %s", String, + PPU.VMA.Address, + PPU.VMA.Increment, PPU.VMA.FullGraphicCount, + PPU.VMA.High ? "word" : "byte"); + else + if (d->BAddress == 0x22) + sprintf (String, "%s CGRAM: %02X (%x)", String, PPU.CGADD, + PPU.CGFLIP); + else + if (d->BAddress == 0x04) + sprintf (String, "%s OBJADDR: %04X", String, PPU.OAMAddr); + S9xMessage (S9X_TRACE, S9X_DMA_TRACE, String); + } +#endif + + if (!d->TransferDirection) + { +#ifdef VAR_CYCLES + CPU.Cycles += 8 * count; +#else + CPU.Cycles += count + (count >> 2); +#endif + uint8 *base = GetBasePointer ((d->ABank << 16) + d->AAddress); + uint16 p = d->AAddress; + + if (!base) + base = Memory.ROM; + + if (in_sa1_dma) + { + base = &Memory.ROM [CMemory::MAX_ROM_SIZE - 0x10000]; + p = 0; + } + + if (in_sdd1_dma) + { + base = in_sdd1_dma; + p = 0; + } + + if (inc > 0) + d->AAddress += count; + else + if (inc < 0) + d->AAddress -= count; + + if (d->TransferMode == 0 || d->TransferMode == 2) + { + switch (d->BAddress) + { + case 0x04: + do + { + Work = *(base + p); + REGISTER_2104(Work); + p += inc; + CHECK_SOUND(); + } while (--count > 0); + break; + case 0x18: + IPPU.FirstVRAMRead = TRUE; + if (!PPU.VMA.FullGraphicCount) + { + do + { + Work = *(base + p); + REGISTER_2118_linear(Work); + p += inc; + CHECK_SOUND(); + } while (--count > 0); + } + else + { + do + { + Work = *(base + p); + REGISTER_2118_tile(Work); + p += inc; + CHECK_SOUND(); + } while (--count > 0); + } + break; + case 0x19: + IPPU.FirstVRAMRead = TRUE; + if (!PPU.VMA.FullGraphicCount) + { + do + { + Work = *(base + p); + REGISTER_2119_linear(Work); + p += inc; + CHECK_SOUND(); + } while (--count > 0); + } + else + { + do + { + Work = *(base + p); + REGISTER_2119_tile(Work); + p += inc; + CHECK_SOUND(); + } while (--count > 0); + } + break; + case 0x22: + do + { + Work = *(base + p); + REGISTER_2122(Work); + p += inc; + CHECK_SOUND(); + } while (--count > 0); + break; + case 0x80: + do + { + Work = *(base + p); + REGISTER_2180(Work); + p += inc; + CHECK_SOUND(); + } while (--count > 0); + break; + default: + do + { + Work = *(base + p); + S9xSetPPU (Work, 0x2100 + d->BAddress); + p += inc; + CHECK_SOUND(); + } while (--count > 0); + break; + } + } + else + if (d->TransferMode == 1 || d->TransferMode == 5) + { + if (d->BAddress == 0x18) + { + // Write to V-RAM + IPPU.FirstVRAMRead = TRUE; + if (!PPU.VMA.FullGraphicCount) + { + while (count > 1) + { + Work = *(base + p); + REGISTER_2118_linear(Work); + p += inc; + + Work = *(base + p); + REGISTER_2119_linear(Work); + p += inc; + CHECK_SOUND(); + count -= 2; + } + if (count == 1) + { + Work = *(base + p); + REGISTER_2118_linear(Work); + p += inc; + } + } + else + { + while (count > 1) + { + Work = *(base + p); + REGISTER_2118_tile(Work); + p += inc; + + Work = *(base + p); + REGISTER_2119_tile(Work); + p += inc; + CHECK_SOUND(); + count -= 2; + } + if (count == 1) + { + Work = *(base + p); + REGISTER_2118_tile(Work); + p += inc; + } + } + } + else + { + // DMA mode 1 general case + while (count > 1) + { + Work = *(base + p); + S9xSetPPU (Work, 0x2100 + d->BAddress); + p += inc; + + Work = *(base + p); + S9xSetPPU (Work, 0x2101 + d->BAddress); + p += inc; + CHECK_SOUND(); + count -= 2; + } + if (count == 1) + { + Work = *(base + p); + S9xSetPPU (Work, 0x2100 + d->BAddress); + p += inc; + } + } + } + else + if (d->TransferMode == 3) + { + do + { + Work = *(base + p); + S9xSetPPU (Work, 0x2100 + d->BAddress); + p += inc; + if (count <= 1) + break; + + Work = *(base + p); + S9xSetPPU (Work, 0x2100 + d->BAddress); + p += inc; + if (count <= 2) + break; + + Work = *(base + p); + S9xSetPPU (Work, 0x2101 + d->BAddress); + p += inc; + if (count <= 3) + break; + + Work = *(base + p); + S9xSetPPU (Work, 0x2101 + d->BAddress); + p += inc; + CHECK_SOUND(); + count -= 4; + } while (count > 0); + } + else + if (d->TransferMode == 4) + { + do + { + Work = *(base + p); + S9xSetPPU (Work, 0x2100 + d->BAddress); + p += inc; + if (count <= 1) + break; + + Work = *(base + p); + S9xSetPPU (Work, 0x2101 + d->BAddress); + p += inc; + if (count <= 2) + break; + + Work = *(base + p); + S9xSetPPU (Work, 0x2102 + d->BAddress); + p += inc; + if (count <= 3) + break; + + Work = *(base + p); + S9xSetPPU (Work, 0x2103 + d->BAddress); + p += inc; + CHECK_SOUND(); + count -= 4; + } while (count > 0); + } + else + { +#ifdef DEBUGGER +// if (Settings.TraceDMA) + { + sprintf (String, "Unknown DMA transfer mode: %d on channel %d\n", + d->TransferMode, Channel); + S9xMessage (S9X_TRACE, S9X_DMA_TRACE, String); + } +#endif + } + } + else + { + do + { + switch (d->TransferMode) + { + case 0: + case 2: +#ifndef VAR_CYCLES + CPU.Cycles += 1; +#endif + Work = S9xGetPPU (0x2100 + d->BAddress); + S9xSetByte (Work, (d->ABank << 16) + d->AAddress); + d->AAddress += inc; + --count; + break; + + case 1: + case 5: +#ifndef VAR_CYCLES + CPU.Cycles += 3; +#endif + Work = S9xGetPPU (0x2100 + d->BAddress); + S9xSetByte (Work, (d->ABank << 16) + d->AAddress); + d->AAddress += inc; + if (!--count) + break; + + Work = S9xGetPPU (0x2101 + d->BAddress); + S9xSetByte (Work, (d->ABank << 16) + d->AAddress); + d->AAddress += inc; + count--; + break; + + case 3: +#ifndef VAR_CYCLES + CPU.Cycles += 6; +#endif + Work = S9xGetPPU (0x2100 + d->BAddress); + S9xSetByte (Work, (d->ABank << 16) + d->AAddress); + d->AAddress += inc; + if (!--count) + break; + + Work = S9xGetPPU (0x2100 + d->BAddress); + S9xSetByte (Work, (d->ABank << 16) + d->AAddress); + d->AAddress += inc; + if (!--count) + break; + + Work = S9xGetPPU (0x2101 + d->BAddress); + S9xSetByte (Work, (d->ABank << 16) + d->AAddress); + d->AAddress += inc; + if (!--count) + break; + + Work = S9xGetPPU (0x2101 + d->BAddress); + S9xSetByte (Work, (d->ABank << 16) + d->AAddress); + d->AAddress += inc; + count--; + break; + + case 4: +#ifndef VAR_CYCLES + CPU.Cycles += 6; +#endif + Work = S9xGetPPU (0x2100 + d->BAddress); + S9xSetByte (Work, (d->ABank << 16) + d->AAddress); + d->AAddress += inc; + if (!--count) + break; + + Work = S9xGetPPU (0x2101 + d->BAddress); + S9xSetByte (Work, (d->ABank << 16) + d->AAddress); + d->AAddress += inc; + if (!--count) + break; + + Work = S9xGetPPU (0x2102 + d->BAddress); + S9xSetByte (Work, (d->ABank << 16) + d->AAddress); + d->AAddress += inc; + if (!--count) + break; + + Work = S9xGetPPU (0x2103 + d->BAddress); + S9xSetByte (Work, (d->ABank << 16) + d->AAddress); + d->AAddress += inc; + count--; + break; + + default: +#ifdef DEBUGGER + if (1) //Settings.TraceDMA) + { + sprintf (String, "Unknown DMA transfer mode: %d on channel %d\n", + d->TransferMode, Channel); + S9xMessage (S9X_TRACE, S9X_DMA_TRACE, String); + } +#endif + count = 0; + break; + } + CHECK_SOUND(); + } while (count); + } + +#ifdef SPC700_C +#ifdef SPC700_SHUTDOWN + CPU.APU_APUExecuting = Settings.APUEnabled; +#endif + APU_EXECUTE(1); // execute but only in normal mode +#endif + while (CPU.Cycles > CPU.NextEvent) + S9xDoHBlankProcessing (); + + // Super Punch-Out requires that the A-BUS address be updated after the + // DMA transfer. + Memory.FillRAM[0x4302 + (Channel << 4)] = (uint8) d->AAddress; + Memory.FillRAM[0x4303 + (Channel << 4)] = d->AAddress >> 8; + + // Secret of the Mana requires that the DMA bytes transfer count be set to + // zero when DMA has completed. + Memory.FillRAM [0x4305 + (Channel << 4)] = 0; + Memory.FillRAM [0x4306 + (Channel << 4)] = 0; + + DMA[Channel].IndirectAddress = 0; + d->TransferBytes = 0; + + CPU.InDMA = FALSE; +} + +void S9xStartHDMA () +{ + if (Settings.DisableHDMA) + IPPU.HDMA = 0; + else + missing.hdma_this_frame = IPPU.HDMA = Memory.FillRAM [0x420c]; + + IPPU.HDMAStarted = TRUE; + + for (uint8 i = 0; i < 8; i++) + { + if (IPPU.HDMA & (1 << i)) + { + DMA [i].LineCount = 0; + DMA [i].FirstLine = TRUE; + DMA [i].Address = DMA [i].AAddress; + } + HDMAMemPointers [i] = NULL; + } +} + +#ifdef DEBUGGER +void S9xTraceSoundDSP (const char *s, int i1 = 0, int i2 = 0, int i3 = 0, + int i4 = 0, int i5 = 0, int i6 = 0, int i7 = 0); +#endif + + +uint8 S9xDoHDMA (uint8 byte) +{ + struct SDMA *p = &DMA [0]; + + int d = 0; + + for (uint8 mask = 1; mask; mask <<= 1, p++, d++) + { + if (byte & mask) + { + if (!p->LineCount) + { + uint8 line = S9xGetByte ((p->ABank << 16) + p->Address); + if (line == 0x80) + { + p->Repeat = TRUE; + p->LineCount = 128; + } + else + { + p->Repeat = !(line & 0x80); + p->LineCount = line & 0x7f; + } + + // Disable H-DMA'ing into V-RAM (register 2118) for Hook + if (!p->LineCount || p->BAddress == 0x18) + { + byte &= ~mask; + p->IndirectAddress += HDMAMemPointers [d] - HDMABasePointers [d]; + Memory.FillRAM [0x4305 + (d << 4)] = (uint8) p->IndirectAddress; + Memory.FillRAM [0x4306 + (d << 4)] = p->IndirectAddress >> 8; + continue; + } + + p->Address++; + p->FirstLine = 1; + if (p->HDMAIndirectAddressing) + { + p->IndirectBank = Memory.FillRAM [0x4307 + ((p - DMA) << 4)]; + p->IndirectAddress = S9xGetWord ((p->ABank << 16) + p->Address); + p->Address += 2; + } + else + { + p->IndirectBank = p->ABank; + p->IndirectAddress = p->Address; + } + HDMABasePointers [d] = HDMAMemPointers [d] = + S9xGetMemPointer ((p->IndirectBank << 16) + p->IndirectAddress); + } + if (!HDMAMemPointers [d]) + { + if (!(HDMABasePointers [d] = HDMAMemPointers [d] = + S9xGetMemPointer ((p->IndirectBank << 16) + p->IndirectAddress))) + { + byte &= ~mask; + continue; + } + // Uncommenting the following line breaks Punchout - it starts + // H-DMA during the frame. + //p->FirstLine = TRUE; + } + if (p->Repeat && !p->FirstLine) + { + p->LineCount--; + continue; + } + +#ifdef DEBUGGER + if (Settings.TraceSoundDSP && p->FirstLine && + p->BAddress >= 0x40 && p->BAddress <= 0x43) + S9xTraceSoundDSP ("Spooling data!!!\n"); + + if (Settings.TraceHDMA && p->FirstLine) + { + sprintf (String, "H-DMA[%d] (%d) 0x%02X%04X->0x21%02X %s, Count: %3d, Rep: %s, V-LINE: %3ld %02X%04X", + p-DMA, p->TransferMode, p->IndirectBank, + p->IndirectAddress, + p->BAddress, + p->HDMAIndirectAddressing ? "ind" : "abs", + p->LineCount, + p->Repeat ? "yes" : "no ", CPU.V_Counter, + p->ABank, p->Address); + S9xMessage (S9X_TRACE, S9X_HDMA_TRACE, String); + } +#endif + switch (p->TransferMode) + { + case 0: +#ifndef VAR_CYCLES + CPU.Cycles += 1; +#else + CPU.Cycles += 8; +#endif + S9xSetPPU (*HDMAMemPointers [d]++, 0x2100 + p->BAddress); + break; + case 1: + case 5: +#ifndef VAR_CYCLES + CPU.Cycles += 3; +#else + CPU.Cycles += 16; +#endif + S9xSetPPU (*(HDMAMemPointers [d] + 0), 0x2100 + p->BAddress); + S9xSetPPU (*(HDMAMemPointers [d] + 1), 0x2101 + p->BAddress); + HDMAMemPointers [d] += 2; + break; + case 2: + case 6: +#ifndef VAR_CYCLES + CPU.Cycles += 3; +#else + CPU.Cycles += 16; +#endif + S9xSetPPU (*(HDMAMemPointers [d] + 0), 0x2100 + p->BAddress); + S9xSetPPU (*(HDMAMemPointers [d] + 1), 0x2100 + p->BAddress); + HDMAMemPointers [d] += 2; + break; + case 3: + case 7: +#ifndef VAR_CYCLES + CPU.Cycles += 6; +#else + CPU.Cycles += 32; +#endif + S9xSetPPU (*(HDMAMemPointers [d] + 0), 0x2100 + p->BAddress); + S9xSetPPU (*(HDMAMemPointers [d] + 1), 0x2100 + p->BAddress); + S9xSetPPU (*(HDMAMemPointers [d] + 2), 0x2101 + p->BAddress); + S9xSetPPU (*(HDMAMemPointers [d] + 3), 0x2101 + p->BAddress); + HDMAMemPointers [d] += 4; + break; + case 4: +#ifndef VAR_CYCLES + CPU.Cycles += 6; +#else + CPU.Cycles += 32; +#endif + S9xSetPPU (*(HDMAMemPointers [d] + 0), 0x2100 + p->BAddress); + S9xSetPPU (*(HDMAMemPointers [d] + 1), 0x2101 + p->BAddress); + S9xSetPPU (*(HDMAMemPointers [d] + 2), 0x2102 + p->BAddress); + S9xSetPPU (*(HDMAMemPointers [d] + 3), 0x2103 + p->BAddress); + HDMAMemPointers [d] += 4; + break; + } + if (!p->HDMAIndirectAddressing) + p->Address += HDMA_ModeByteCounts [p->TransferMode]; + p->FirstLine = FALSE; + p->LineCount--; + } + } + return (byte); +} + +void S9xResetDMA () +{ + int d; + for (d = 0; d < 8; d++) + { + DMA [d].TransferDirection = FALSE; + DMA [d].HDMAIndirectAddressing = FALSE; + DMA [d].AAddressFixed = TRUE; + DMA [d].AAddressDecrement = FALSE; + DMA [d].TransferMode = 0xff; + DMA [d].ABank = 0xff; + DMA [d].AAddress = 0xffff; + DMA [d].Address = 0xffff; + DMA [d].BAddress = 0xff; + DMA [d].TransferBytes = 0xffff; + } + for (int c = 0x4300; c < 0x4380; c += 0x10) + { + for (d = c; d < c + 12; d++) + Memory.FillRAM [d] = 0xff; + + Memory.FillRAM [c + 0xf] = 0xff; + } +} diff --git a/src/snes4iphone_src/dma.h b/src/snes4iphone_src/dma.h new file mode 100755 index 0000000..c0277b9 --- /dev/null +++ b/src/snes4iphone_src/dma.h @@ -0,0 +1,51 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#ifndef _DMA_H_ +#define _DMA_H_ + +START_EXTERN_C +void S9xResetDMA (void); +uint8 S9xDoHDMA (uint8); +void S9xStartHDMA (); +void S9xDoDMA (uint8); +END_EXTERN_C + +#endif diff --git a/src/snes4iphone_src/dsp1.cpp b/src/snes4iphone_src/dsp1.cpp new file mode 100755 index 0000000..a5c1a62 --- /dev/null +++ b/src/snes4iphone_src/dsp1.cpp @@ -0,0 +1,1195 @@ +/******************************************************************************* + Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and + Jerremy Koot (jkoot@snes9x.com) + + (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net) + + (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net), + funkyass (funkyass@spam.shaw.ca), + Joel Yliluoma (http://iki.fi/bisqwit/) + Kris Bleakley (codeviolation@hotmail.com), + Matthew Kendora, + Nach (n-a-c-h@users.sourceforge.net), + Peter Bortas (peter@bortas.org) and + zones (kasumitokoduck@yahoo.com) + + C4 x86 assembler and some C emulation code + (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com), + _Demo_ (_demo_@zsnes.com), and Nach + + C4 C++ code + (c) Copyright 2003 Brad Jorsch + + DSP-1 emulator code + (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson, + John Weidman, neviksti (neviksti@hotmail.com), + Kris Bleakley, Andreas Naive + + DSP-2 emulator code + (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and + Lord Nightmare (lord_nightmare@users.sourceforge.net + + OBC1 emulator code + (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and + Kris Bleakley + Ported from x86 assembler to C by sanmaiwashi + + SPC7110 and RTC C++ emulator code + (c) Copyright 2002 Matthew Kendora with research by + zsKnight, John Weidman, and Dark Force + + S-DD1 C emulator code + (c) Copyright 2003 Brad Jorsch with research by + Andreas Naive and John Weidman + + S-RTC C emulator code + (c) Copyright 2001 John Weidman + + ST010 C++ emulator code + (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora + + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + + Super FX C emulator code + (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman + + + SH assembler code partly based on x86 assembler code + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + + + Specific ports contains the works of other authors. See headers in + individual files. + + Snes9x homepage: http://www.snes9x.com + + Permission to use, copy, modify and distribute Snes9x in both binary and + source form, for non-commercial purposes, is hereby granted without fee, + providing that this license information and copyright notice appear with + all copies and any derived work. + + This software is provided 'as-is', without any express or implied + warranty. In no event shall the authors be held liable for any damages + arising from the use of this software. + + Snes9x is freeware for PERSONAL USE only. Commercial users should + seek permission of the copyright holders first. Commercial use includes + charging money for Snes9x or software derived from Snes9x. + + The copyright holders request that bug fixes and improvements to the code + should be forwarded to them so everyone can benefit from the modifications + in future versions. + + Super NES and Super Nintendo Entertainment System are trademarks of + Nintendo Co., Limited and its subsidiary companies. +*******************************************************************************/ +#include "snes9x.h" +#include "dsp1.h" +#include "missing.h" +#include "memmap.h" +#include + +#include "dsp1emu.c" +#include "dsp2emu.c" +//#include "dsp3emu.cpp" + +void (*SetDSP)(uint8, uint16)=&DSP1SetByte; +uint8 (*GetDSP)(uint16)=&DSP1GetByte; + +void S9xInitDSP1 () +{ + static bool8 init = FALSE; + + if (!init) + { + InitDSP (); + init = TRUE; + } +} + +void S9xResetDSP1 () +{ + S9xInitDSP1 (); + + DSP1.waiting4command = TRUE; + DSP1.in_count = 0; + DSP1.out_count = 0; + DSP1.in_index = 0; + DSP1.out_index = 0; + DSP1.first_parameter = TRUE; +} + +uint8 S9xGetDSP (uint16 address) +{ + uint8 t; + +#ifdef DEBUGGER + if (Settings.TraceDSP) + { + sprintf (String, "DSP read: 0x%04X", address); + S9xMessage (S9X_TRACE, S9X_TRACE_DSP1, String); + } +#endif + + t=(*GetDSP)(address); + //DSP1GetByte(address); + return (t); +} + +void S9xSetDSP (uint8 byte, uint16 address) +{ +#ifdef DEBUGGER + missing.unknowndsp_write = address; + if (Settings.TraceDSP) + { + sprintf (String, "DSP write: 0x%04X=0x%02X", address, byte); + S9xMessage (S9X_TRACE, S9X_TRACE_DSP1, String); + } +#endif + (*SetDSP)(byte, address); + //DSP1SetByte(byte, address); +} + +void DSP1SetByte(uint8 byte, uint16 address) +{ + if( (address & 0xf000) == 0x6000 || (address & 0x7fff) < 0x4000 ) + { +// if ((address & 1) == 0) +// { + if((DSP1.command==0x0A||DSP1.command==0x1A)&&DSP1.out_count!=0) + { + DSP1.out_count--; + DSP1.out_index++; + return; + } + else if (DSP1.waiting4command) + { + DSP1.command = byte; + DSP1.in_index = 0; + DSP1.waiting4command = FALSE; + DSP1.first_parameter = TRUE; +// printf("Op%02X\n",byte); + // Mario Kart uses 0x00, 0x02, 0x06, 0x0c, 0x28, 0x0a + switch (byte) + { + case 0x00: DSP1.in_count = 2; break; + case 0x30: + case 0x10: DSP1.in_count = 2; break; + case 0x20: DSP1.in_count = 2; break; + case 0x24: + case 0x04: DSP1.in_count = 2; break; + case 0x08: DSP1.in_count = 3; break; + case 0x18: DSP1.in_count = 4; break; + case 0x28: DSP1.in_count = 3; break; + case 0x38: DSP1.in_count = 4; break; + case 0x2c: + case 0x0c: DSP1.in_count = 3; break; + case 0x3c: + case 0x1c: DSP1.in_count = 6; break; + case 0x32: + case 0x22: + case 0x12: + case 0x02: DSP1.in_count = 7; break; + case 0x0a: DSP1.in_count = 1; break; + case 0x3a: + case 0x2a: + case 0x1a: + DSP1. command =0x1a; + DSP1.in_count = 1; break; + case 0x16: + case 0x26: + case 0x36: + case 0x06: DSP1.in_count = 3; break; + case 0x1e: + case 0x2e: + case 0x3e: + case 0x0e: DSP1.in_count = 2; break; + case 0x05: + case 0x35: + case 0x31: + case 0x01: DSP1.in_count = 4; break; + case 0x15: + case 0x11: DSP1.in_count = 4; break; + case 0x25: + case 0x21: DSP1.in_count = 4; break; + case 0x09: + case 0x39: + case 0x3d: + case 0x0d: DSP1.in_count = 3; break; + case 0x19: + case 0x1d: DSP1.in_count = 3; break; + case 0x29: + case 0x2d: DSP1.in_count = 3; break; + case 0x33: + case 0x03: DSP1.in_count = 3; break; + case 0x13: DSP1.in_count = 3; break; + case 0x23: DSP1.in_count = 3; break; + case 0x3b: + case 0x0b: DSP1.in_count = 3; break; + case 0x1b: DSP1.in_count = 3; break; + case 0x2b: DSP1.in_count = 3; break; + case 0x34: + case 0x14: DSP1.in_count = 6; break; + case 0x07: + case 0x0f: DSP1.in_count = 1; break; + case 0x27: + case 0x2F: DSP1.in_count=1; break; + case 0x17: + case 0x37: + case 0x3F: + DSP1.command=0x1f; + case 0x1f: DSP1.in_count = 1; break; + // case 0x80: DSP1.in_count = 2; break; + default: + //printf("Op%02X\n",byte); + case 0x80: + DSP1.in_count = 0; + DSP1.waiting4command = TRUE; + DSP1.first_parameter = TRUE; + break; + } + DSP1.in_count<<=1; + } + else + { + DSP1.parameters [DSP1.in_index] = byte; + DSP1.first_parameter = FALSE; + DSP1.in_index++; + } + + if (DSP1.waiting4command || + (DSP1.first_parameter && byte == 0x80)) + { + DSP1.waiting4command = TRUE; + DSP1.first_parameter = FALSE; + } + else if(DSP1.first_parameter && (DSP1.in_count != 0 || (DSP1.in_count==0&&DSP1.in_index==0))) + { + } +// else if (DSP1.first_parameter) +// { +// } + else + { + if (DSP1.in_count) + { + //DSP1.parameters [DSP1.in_index] |= (byte << 8); + if (--DSP1.in_count == 0) + { + // Actually execute the command + DSP1.waiting4command = TRUE; + DSP1.out_index = 0; + switch (DSP1.command) + { + case 0x1f: + DSP1.out_count=2048; + break; + case 0x00: // Multiple + Op00Multiplicand = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); + Op00Multiplier = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); + + DSPOp00 (); + + DSP1.out_count = 2; + DSP1.output [0] = Op00Result&0xFF; + DSP1.output [1] = (Op00Result>>8)&0xFF; + break; + + case 0x20: // Multiple + Op20Multiplicand = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); + Op20Multiplier = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); + + DSPOp20 (); + + DSP1.out_count = 2; + DSP1.output [0] = Op20Result&0xFF; + DSP1.output [1] = (Op20Result>>8)&0xFF; + break; + + case 0x30: + case 0x10: // Inverse + Op10Coefficient = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); + Op10Exponent = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); + + DSPOp10 (); + + DSP1.out_count = 4; + DSP1.output [0] = (uint8) (((int16) Op10CoefficientR)&0xFF); + DSP1.output [1] = (uint8) ((((int16) Op10CoefficientR)>>8)&0xFF); + DSP1.output [2] = (uint8) (((int16) Op10ExponentR)&0xff); + DSP1.output [3] = (uint8) ((((int16) Op10ExponentR)>>8)&0xff); + break; + + case 0x24: + case 0x04: // Sin and Cos of angle + Op04Angle = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); + Op04Radius = (uint16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); + + DSPOp04 (); + + DSP1.out_count = 4; + DSP1.output [0] = (uint8) (Op04Sin&0xFF); + DSP1.output [1] = (uint8) ((Op04Sin>>8)&0xFF); + DSP1.output [2] = (uint8) (Op04Cos&0xFF); + DSP1.output [3] = (uint8) ((Op04Cos>>8)&0xFF); + break; + + case 0x08: // Radius + Op08X = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); + Op08Y = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); + Op08Z = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8)); + + DSPOp08 (); + + DSP1.out_count = 4; + DSP1.output [0] = (uint8) (((int16) Op08Ll)&0xFF); + DSP1.output [1] = (uint8) ((((int16) Op08Ll)>>8)&0xFF); + DSP1.output [2] = (uint8) (((int16) Op08Lh)&0xFF); + DSP1.output [3] = (uint8) ((((int16) Op08Lh)>>8)&0xFF); + break; + + case 0x18: // Range + + Op18X = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); + Op18Y = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); + Op18Z = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8)); + Op18R = (int16) (DSP1.parameters [6]|(DSP1.parameters[7]<<8)); + + DSPOp18 (); + + DSP1.out_count = 2; + DSP1.output [0] = (uint8) (Op18D&0xFF); + DSP1.output [1] = (uint8) ((Op18D>>8)&0xFF); + break; + + case 0x38: // Range + + Op38X = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); + Op38Y = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); + Op38Z = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8)); + Op38R = (int16) (DSP1.parameters [6]|(DSP1.parameters[7]<<8)); + + DSPOp38 (); + + DSP1.out_count = 2; + DSP1.output [0] = (uint8) (Op38D&0xFF); + DSP1.output [1] = (uint8) ((Op38D>>8)&0xFF); + break; + + case 0x28: // Distance (vector length) + Op28X = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); + Op28Y = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); + Op28Z = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8)); + + DSPOp28 (); + + DSP1.out_count = 2; + DSP1.output [0] = (uint8) (Op28R&0xFF); + DSP1.output [1] = (uint8) ((Op28R>>8)&0xFF); + break; + + case 0x2c: + case 0x0c: // Rotate (2D rotate) + Op0CA = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); + Op0CX1 = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); + Op0CY1 = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8)); + + DSPOp0C (); + + DSP1.out_count = 4; + DSP1.output [0] = (uint8) (Op0CX2&0xFF); + DSP1.output [1] = (uint8) ((Op0CX2>>8)&0xFF); + DSP1.output [2] = (uint8) (Op0CY2&0xFF); + DSP1.output [3] = (uint8) ((Op0CY2>>8)&0xFF); + break; + + case 0x3c: + case 0x1c: // Polar (3D rotate) + Op1CZ = (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); + //MK: reversed X and Y on neviksti and John's advice. + Op1CY = (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); + Op1CX = (DSP1.parameters [4]|(DSP1.parameters[5]<<8)); + Op1CXBR = (DSP1.parameters [6]|(DSP1.parameters[7]<<8)); + Op1CYBR = (DSP1.parameters [8]|(DSP1.parameters[9]<<8)); + Op1CZBR = (DSP1.parameters [10]|(DSP1.parameters[11]<<8)); + + DSPOp1C (); + + DSP1.out_count = 6; + DSP1.output [0] = (uint8) (Op1CXAR&0xFF); + DSP1.output [1] = (uint8) ((Op1CXAR>>8)&0xFF); + DSP1.output [2] = (uint8) (Op1CYAR&0xFF); + DSP1.output [3] = (uint8) ((Op1CYAR>>8)&0xFF); + DSP1.output [4] = (uint8) (Op1CZAR&0xFF); + DSP1.output [5] = (uint8) ((Op1CZAR>>8)&0xFF); + break; + + case 0x32: + case 0x22: + case 0x12: + case 0x02: // Parameter (Projection) + Op02FX = (short)(DSP1.parameters [0]|(DSP1.parameters[1]<<8)); + Op02FY = (short)(DSP1.parameters [2]|(DSP1.parameters[3]<<8)); + Op02FZ = (short)(DSP1.parameters [4]|(DSP1.parameters[5]<<8)); + Op02LFE = (short)(DSP1.parameters [6]|(DSP1.parameters[7]<<8)); + Op02LES = (short)(DSP1.parameters [8]|(DSP1.parameters[9]<<8)); + Op02AAS = (unsigned short)(DSP1.parameters [10]|(DSP1.parameters[11]<<8)); + Op02AZS = (unsigned short)(DSP1.parameters [12]|(DSP1.parameters[13]<<8)); + + DSPOp02 (); + + DSP1.out_count = 8; + DSP1.output [0] = (uint8) (Op02VOF&0xFF); + DSP1.output [1] = (uint8) ((Op02VOF>>8)&0xFF); + DSP1.output [2] = (uint8) (Op02VVA&0xFF); + DSP1.output [3] = (uint8) ((Op02VVA>>8)&0xFF); + DSP1.output [4] = (uint8) (Op02CX&0xFF); + DSP1.output [5] = (uint8) ((Op02CX>>8)&0xFF); + DSP1.output [6] = (uint8) (Op02CY&0xFF); + DSP1.output [7] = (uint8) ((Op02CY>>8)&0xFF); + break; + + case 0x3a: //1a Mirror + case 0x2a: //1a Mirror + case 0x1a: // Raster mode 7 matrix data + case 0x0a: + Op0AVS = (short)(DSP1.parameters [0]|(DSP1.parameters[1]<<8)); + + DSPOp0A (); + + DSP1.out_count = 8; + DSP1.output [0] = (uint8) (Op0AA&0xFF); + DSP1.output [2] = (uint8) (Op0AB&0xFF); + DSP1.output [4] = (uint8) (Op0AC&0xFF); + DSP1.output [6] = (uint8) (Op0AD&0xFF); + DSP1.output [1] = (uint8) ((Op0AA>>8)&0xFF); + DSP1.output [3] = (uint8) ((Op0AB>>8)&0xFF); + DSP1.output [5] = (uint8) ((Op0AC>>8)&0xFF); + DSP1.output [7] = (uint8) ((Op0AD>>8)&0xFF); + DSP1.in_index=0; + break; + + case 0x16: + case 0x26: + case 0x36: + case 0x06: // Project object + Op06X = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); + Op06Y = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); + Op06Z = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8)); + + DSPOp06 (); + + DSP1.out_count = 6; + DSP1.output [0] = (uint8) (Op06H&0xff); + DSP1.output [1] = (uint8) ((Op06H>>8)&0xFF); + DSP1.output [2] = (uint8) (Op06V&0xFF); + DSP1.output [3] = (uint8) ((Op06V>>8)&0xFF); + DSP1.output [4] = (uint8) (Op06S&0xFF); + DSP1.output [5] = (uint8) ((Op06S>>8)&0xFF); + break; + + case 0x1e: + case 0x2e: + case 0x3e: + case 0x0e: // Target + Op0EH = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); + Op0EV = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); + + DSPOp0E (); + + DSP1.out_count = 4; + DSP1.output [0] = (uint8) (Op0EX&0xFF); + DSP1.output [1] = (uint8) ((Op0EX>>8)&0xFF); + DSP1.output [2] = (uint8) (Op0EY&0xFF); + DSP1.output [3] = (uint8) ((Op0EY>>8)&0xFF); + break; + + // Extra commands used by Pilot Wings + case 0x05: + case 0x35: + case 0x31: + case 0x01: // Set attitude matrix A + Op01m = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); + Op01Zr = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); + Op01Yr = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8)); + Op01Xr = (int16) (DSP1.parameters [6]|(DSP1.parameters[7]<<8)); + + DSPOp01 (); + break; + + case 0x15: + case 0x11: // Set attitude matrix B + Op11m = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); + Op11Zr = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); + Op11Yr = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8)); + Op11Xr = (int16) (DSP1.parameters [7]|(DSP1.parameters[7]<<8)); + + DSPOp11 (); + break; + + case 0x25: + case 0x21: // Set attitude matrix C + Op21m = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); + Op21Zr = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); + Op21Yr = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8)); + Op21Xr = (int16) (DSP1.parameters [6]|(DSP1.parameters[7]<<8)); + + DSPOp21 (); + break; + + case 0x09: + case 0x39: + case 0x3d: + case 0x0d: // Objective matrix A + Op0DX = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); + Op0DY = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); + Op0DZ = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8)); + + DSPOp0D (); + + DSP1.out_count = 6; + DSP1.output [0] = (uint8) (Op0DF&0xFF); + DSP1.output [1] = (uint8) ((Op0DF>>8)&0xFF); + DSP1.output [2] = (uint8) (Op0DL&0xFF); + DSP1.output [3] = (uint8) ((Op0DL>>8)&0xFF); + DSP1.output [4] = (uint8) (Op0DU&0xFF); + DSP1.output [5] = (uint8) ((Op0DU>>8)&0xFF); + break; + + case 0x19: + case 0x1d: // Objective matrix B + Op1DX = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); + Op1DY = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); + Op1DZ = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8)); + + DSPOp1D (); + + DSP1.out_count = 6; + DSP1.output [0] = (uint8) (Op1DF&0xFF); + DSP1.output [1] = (uint8) ((Op1DF>>8)&0xFF); + DSP1.output [2] = (uint8) (Op1DL&0xFF); + DSP1.output [3] = (uint8) ((Op1DL>>8)&0xFF); + DSP1.output [4] = (uint8) (Op1DU&0xFF); + DSP1.output [5] = (uint8) ((Op1DU>>8)&0xFF); + break; + + case 0x29: + case 0x2d: // Objective matrix C + Op2DX = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); + Op2DY = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); + Op2DZ = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8)); + + DSPOp2D (); + + DSP1.out_count = 6; + DSP1.output [0] = (uint8) (Op2DF&0xFF); + DSP1.output [1] = (uint8) ((Op2DF>>8)&0xFF); + DSP1.output [2] = (uint8) (Op2DL&0xFF); + DSP1.output [3] = (uint8) ((Op2DL>>8)&0xFF); + DSP1.output [4] = (uint8) (Op2DU&0xFF); + DSP1.output [5] = (uint8) ((Op2DU>>8)&0xFF); + break; + + case 0x33: + case 0x03: // Subjective matrix A + Op03F = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); + Op03L = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); + Op03U = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8)); + + DSPOp03 (); + + DSP1.out_count = 6; + DSP1.output [0] = (uint8) (Op03X&0xFF); + DSP1.output [1] = (uint8) ((Op03X>>8)&0xFF); + DSP1.output [2] = (uint8) (Op03Y&0xFF); + DSP1.output [3] = (uint8) ((Op03Y>>8)&0xFF); + DSP1.output [4] = (uint8) (Op03Z&0xFF); + DSP1.output [5] = (uint8) ((Op03Z>>8)&0xFF); + break; + + case 0x13: // Subjective matrix B + Op13F = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); + Op13L = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); + Op13U = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8)); + + DSPOp13 (); + + DSP1.out_count = 6; + DSP1.output [0] = (uint8) (Op13X&0xFF); + DSP1.output [1] = (uint8) ((Op13X>>8)&0xFF); + DSP1.output [2] = (uint8) (Op13Y&0xFF); + DSP1.output [3] = (uint8) ((Op13Y>>8)&0xFF); + DSP1.output [4] = (uint8) (Op13Z&0xFF); + DSP1.output [5] = (uint8) ((Op13Z>>8)&0xFF); + break; + + case 0x23: // Subjective matrix C + Op23F = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); + Op23L = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); + Op23U = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8)); + + DSPOp23 (); + + DSP1.out_count = 6; + DSP1.output [0] = (uint8) (Op23X&0xFF); + DSP1.output [1] = (uint8) ((Op23X>>8)&0xFF); + DSP1.output [2] = (uint8) (Op23Y&0xFF); + DSP1.output [3] = (uint8) ((Op23Y>>8)&0xFF); + DSP1.output [4] = (uint8) (Op23Z&0xFF); + DSP1.output [5] = (uint8) ((Op23Z>>8)&0xFF); + break; + + case 0x3b: + case 0x0b: + Op0BX = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); + Op0BY = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); + Op0BZ = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8)); + + DSPOp0B (); + + DSP1.out_count = 2; + DSP1.output [0] = (uint8) (Op0BS&0xFF); + DSP1.output [1] = (uint8) ((Op0BS>>8)&0xFF); + break; + + case 0x1b: + Op1BX = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); + Op1BY = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); + Op1BZ = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8)); + + DSPOp1B (); + + DSP1.out_count = 2; + DSP1.output [0] = (uint8) (Op1BS&0xFF); + DSP1.output [1] = (uint8) ((Op1BS>>8)&0xFF); + break; + + case 0x2b: + Op2BX = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); + Op2BY = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); + Op2BZ = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8)); + + DSPOp2B (); + + DSP1.out_count = 2; + DSP1.output [0] = (uint8) (Op2BS&0xFF); + DSP1.output [1] = (uint8) ((Op2BS>>8)&0xFF); + break; + + case 0x34: + case 0x14: + Op14Zr = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); + Op14Xr = (int16) (DSP1.parameters [2]|(DSP1.parameters[3]<<8)); + Op14Yr = (int16) (DSP1.parameters [4]|(DSP1.parameters[5]<<8)); + Op14U = (int16) (DSP1.parameters [6]|(DSP1.parameters[7]<<8)); + Op14F = (int16) (DSP1.parameters [8]|(DSP1.parameters[9]<<8)); + Op14L = (int16) (DSP1.parameters [10]|(DSP1.parameters[11]<<8)); + + DSPOp14 (); + + DSP1.out_count = 6; + DSP1.output [0] = (uint8) (Op14Zrr&0xFF); + DSP1.output [1] = (uint8) ((Op14Zrr>>8)&0xFF); + DSP1.output [2] = (uint8) (Op14Xrr&0xFF); + DSP1.output [3] = (uint8) ((Op14Xrr>>8)&0xFF); + DSP1.output [4] = (uint8) (Op14Yrr&0xFF); + DSP1.output [5] = (uint8) ((Op14Yrr>>8)&0xFF); + break; + + case 0x27: + case 0x2F: + Op2FUnknown = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); + + DSPOp2F (); + + DSP1.out_count = 2; + DSP1.output [0] = (uint8)(Op2FSize&0xFF); + DSP1.output [1] = (uint8)((Op2FSize>>8)&0xFF); + break; + + + case 0x07: + case 0x0F: + Op0FRamsize = (int16) (DSP1.parameters [0]|(DSP1.parameters[1]<<8)); + + DSPOp0F (); + + DSP1.out_count = 2; + DSP1.output [0] = (uint8)(Op0FPass&0xFF); + DSP1.output [1] = (uint8)((Op0FPass>>8)&0xFF); + break; + + default: + break; + } + } + } + } + } +} + +uint8 DSP1GetByte(uint16 address) +{ + uint8 t; + if ((address & 0xf000) == 0x6000 || +// (address >= 0x8000 && address < 0xc000)) + (address&0x7fff) < 0x4000) + { + if (DSP1.out_count) + { + //if ((address & 1) == 0) + t = (uint8) DSP1.output [DSP1.out_index]; + //else + //{ + // t = (uint8) (DSP1.output [DSP1.out_index] >> 8); + DSP1.out_index++; + if (--DSP1.out_count == 0) + { + if (DSP1.command == 0x1a || DSP1.command == 0x0a) + { + DSPOp0A (); + DSP1.out_count = 8; + DSP1.out_index = 0; + DSP1.output [0] = (Op0AA&0xFF); + DSP1.output [1] = (Op0AA>>8)&0xFF; + DSP1.output [2] = (Op0AB&0xFF); + DSP1.output [3] = (Op0AB>>8)&0xFF; + DSP1.output [4] = (Op0AC&0xFF); + DSP1.output [5] = (Op0AC>>8)&0xFF; + DSP1.output [6] = (Op0AD&0xFF); + DSP1.output [7] = (Op0AD>>8)&0xFF; + } + if(DSP1.command==0x1f) + { + if((DSP1.out_index%2)!=0) + { + t=(uint8)DSP1ROM[DSP1.out_index>>1]; + } + else + { + t=DSP1ROM[DSP1.out_index>>1]>>8; + } + } + } + DSP1.waiting4command = TRUE; + //} + } + else + { + // Top Gear 3000 requires this value.... + // if(4==Settings.DSPVersion) + t = 0xff; + //Ballz3d requires this one: + // else t = 0x00; + } + } + else t = 0x80; + return t; +} + +void DSP2SetByte(uint8 byte, uint16 address) +{ + if ((address & 0xf000) == 0x6000 || + (address >= 0x8000 && address < 0xc000)) + { + if (DSP1.waiting4command) + { + DSP1.command = byte; + DSP1.in_index = 0; + DSP1.waiting4command = FALSE; +// DSP1.first_parameter = TRUE; +// printf("Op%02X\n",byte); + switch (byte) + { + case 0x01:DSP1.in_count=32;break; + case 0x03:DSP1.in_count=1;break; + case 0x05:DSP1.in_count=1;break; + case 0x09:DSP1.in_count=4;break; + case 0x06:DSP1.in_count=1;break; + case 0x0D:DSP1.in_count=2;break; + default: + printf("Op%02X\n",byte); + case 0x0f:DSP1.in_count=0;break; + } + } + else + { + DSP1.parameters [DSP1.in_index] = byte; +// DSP1.first_parameter = FALSE; + DSP1.in_index++; + } + + if (DSP1.in_count==DSP1.in_index) + { + //DSP1.parameters [DSP1.in_index] |= (byte << 8); + // Actually execute the command + DSP1.waiting4command = TRUE; + DSP1.out_index = 0; + switch (DSP1.command) + { + case 0x0D: + if(DSP2Op0DHasLen) + { + DSP2Op0DHasLen=false; + DSP1.out_count=DSP2Op0DOutLen; + //execute Op5 + DSP2_Op0D(); + } + else + { + DSP2Op0DInLen=DSP1.parameters[0]; + DSP2Op0DOutLen=DSP1.parameters[1]; + DSP1.in_index=0; + DSP1.in_count=(DSP2Op0DInLen+1)>>1; + DSP2Op0DHasLen=true; + if(byte) + DSP1.waiting4command=false; + } + break; + case 0x06: + if(DSP2Op06HasLen) + { + DSP2Op06HasLen=false; + DSP1.out_count=DSP2Op06Len; + //execute Op5 + DSP2_Op06(); + } + else + { + DSP2Op06Len=DSP1.parameters[0]; + DSP1.in_index=0; + DSP1.in_count=DSP2Op06Len; + DSP2Op06HasLen=true; + if(byte) + DSP1.waiting4command=false; + } + break; + case 0x01: + DSP1.out_count=32; + DSP2_Op01(); + break; + case 0x09: + // Multiply - don't yet know if this is signed or unsigned + DSP2Op09Word1 = DSP1.parameters[0] | (DSP1.parameters[1]<<8); + DSP2Op09Word2 = DSP1.parameters[2] | (DSP1.parameters[3]<<8); + DSP1.out_count=4; +#ifdef FAST_LSB_WORD_ACCESS + *(uint32 *)DSP1.output = DSP2Op09Word1 * DSP2Op09Word2; +#else + uint32 temp; + temp=DSP2Op09Word1 * DSP2Op09Word2; + DSP1.output[0]=temp&0xFF; + DSP1.output[1]=(temp>>8)&0xFF; + DSP1.output[2]=(temp>>16)&0xFF; + DSP1.output[3]=(temp>>24)&0xFF; +#endif + break; + case 0x05: + if(DSP2Op05HasLen) + { + DSP2Op05HasLen=false; + DSP1.out_count=DSP2Op05Len; + //execute Op5 + DSP2_Op05(); + } + else + { + DSP2Op05Len=DSP1.parameters[0]; + DSP1.in_index=0; + DSP1.in_count=2*DSP2Op05Len; + DSP2Op05HasLen=true; + if(byte) + DSP1.waiting4command=false; + } + break; + + case 0x03: + DSP2Op05Transparent= DSP1.parameters[0]; + //DSP2Op03(); + break; + case 0x0f: + default: + break; + } + } + } +} + +uint8 DSP2GetByte(uint16 address) +{ + uint8 t; + if ((address & 0xf000) == 0x6000 || + (address >= 0x8000 && address < 0xc000)) + { + if (DSP1.out_count) + { + t = (uint8) DSP1.output [DSP1.out_index]; + DSP1.out_index++; + if(DSP1.out_count==DSP1.out_index) + DSP1.out_count=0; + } + else + { + t = 0xff; + } + } + else t = 0x80; + return t; +} + +/*struct SDSP4 { + bool8 waiting4command; + bool8 half_command; + uint16 command; + uint32 in_count; + uint32 in_index; + uint32 out_count; + uint32 out_index; + uint8 parameters [512]; + uint8 output [512]; +}; + +SDSP4 DSP4; + +//#include "dsp4emu.cpp" + +bool DSP4_init=FALSE; + +void DSP4SetByte(uint8 byte, uint16 address) +{ + if(!DSP4_init) + { + // bootup + DSP4.waiting4command=1; + DSP4_init=TRUE; + } + + if ((address & 0xf000) == 0x6000 || + (address >= 0x8000 && address < 0xc000)) + { + if(DSP4.out_index>16); + } + break; + + // unknown: horizontal mapping command + case 0x0011: + { + int16 a,b,c,d,m; + + a = DSP4_READ_WORD(6); + b = DSP4_READ_WORD(4); + c = DSP4_READ_WORD(2); + d = DSP4_READ_WORD(0); + + DSP4_UnknownOP11(a,b,c,d,m); + + DSP4.out_count = 2; + DSP4_WRITE_WORD(0,m); + break; + } + + // track projection + case 0x0001: DSP4_Op01(); break; + + // track projection (pass 2) + case 0x0007: DSP4_Op07(); break; + + // zone projections (fuel/repair/lap/teleport/...) + case 0x0008: DSP4_Op08(); break; + + // sprite transformation + case 0x0009: DSP4_Op09(); break; + + // fast track projection + case 0x000D: DSP4_Op0D(); break; + + // single-player selection + case 0x0003: DSP4_Op03(); break; + + // clear OAM + case 0x0005: + { + op06_index = 0; + op06_offset = 0; + for( int lcv=0; lcv<32; lcv++ ) + op06_OAM[lcv] = 0; + break; + } + + // multi-player selection + case 0x000E: DSP4_Op0E(); break; + +#undef PRINT + + // transfer OAM + case 0x0006: + { + DSP4.out_count = 32; + for( int lcv=0; lcv<32; lcv++ ) + DSP4.output[lcv] = op06_OAM[lcv]; + } + break; + + // unknown + case 0x000A: + { + int16 in1a = DSP4_READ_WORD(0); + int16 in2a = DSP4_READ_WORD(2); + int16 in3a = DSP4_READ_WORD(4); + int16 out1a,out2a,out3a,out4a; + + // NOTE: Snes9x only! + // For some odd reason, the input nybbles are reversed + + DSP4_Op0A(in2a,out1a,out2a,out3a,out4a); + + DSP4.out_count=8; + + // Hack: Reverse the outputs for now to compensate + // Otherwise the AI gets really flaky + DSP4_WRITE_WORD(0,out2a); + DSP4_WRITE_WORD(2,out1a); + DSP4_WRITE_WORD(4,out4a); + DSP4_WRITE_WORD(6,out3a); + } + break; + + // set OAM + case 0x000B: + { + int16 sp_x = DSP4_READ_WORD(0); + int16 sp_y = DSP4_READ_WORD(2); + int16 oam = DSP4_READ_WORD(4); + + if ((sp_y < 0) || ((sp_y & 0x01ff) < 0x00eb)) + { + short Row = (sp_y >> 3) & 0x1f; + + if (RowCount[Row] < MaxTilesPerRow) + { + RowCount[Row]++; + + // yield OAM output + DSP4.out_count = 6; + DSP4_WRITE_WORD(0,1); + + // pack OAM data: x,y,name,attr + DSP4.output[2] = sp_x & 0xff; + DSP4.output[3] = sp_y & 0xff; + DSP4_WRITE_WORD(4,oam); + + // OAM: size,msb data + DSP4_Op06(0,0); + } + } + } + break; + + default: break; + } + } + } +} + +uint8 DSP4GetByte(uint16 address) +{ + uint8 t; + if ((address & 0xf000) == 0x6000 || + (address >= 0x8000 && address < 0xc000)) + { + if (DSP4.out_count) + { + t = (uint8) DSP4.output [DSP4.out_index]; + DSP4.out_index++; + if(DSP4.out_count==DSP4.out_index) + DSP4.out_count=0; + } + else + t = 0xff; + } + else + { + t = 0x80; + } + + return t; +} +*/ diff --git a/src/snes4iphone_src/dsp1.h b/src/snes4iphone_src/dsp1.h new file mode 100755 index 0000000..e036553 --- /dev/null +++ b/src/snes4iphone_src/dsp1.h @@ -0,0 +1,130 @@ +/******************************************************************************* + Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and + Jerremy Koot (jkoot@snes9x.com) + + (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net) + + (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net), + funkyass (funkyass@spam.shaw.ca), + Joel Yliluoma (http://iki.fi/bisqwit/) + Kris Bleakley (codeviolation@hotmail.com), + Matthew Kendora, + Nach (n-a-c-h@users.sourceforge.net), + Peter Bortas (peter@bortas.org) and + zones (kasumitokoduck@yahoo.com) + + C4 x86 assembler and some C emulation code + (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com), + _Demo_ (_demo_@zsnes.com), and Nach + + C4 C++ code + (c) Copyright 2003 Brad Jorsch + + DSP-1 emulator code + (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson, + John Weidman, neviksti (neviksti@hotmail.com), + Kris Bleakley, Andreas Naive + + DSP-2 emulator code + (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and + Lord Nightmare (lord_nightmare@users.sourceforge.net + + OBC1 emulator code + (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and + Kris Bleakley + Ported from x86 assembler to C by sanmaiwashi + + SPC7110 and RTC C++ emulator code + (c) Copyright 2002 Matthew Kendora with research by + zsKnight, John Weidman, and Dark Force + + S-DD1 C emulator code + (c) Copyright 2003 Brad Jorsch with research by + Andreas Naive and John Weidman + + S-RTC C emulator code + (c) Copyright 2001 John Weidman + + ST010 C++ emulator code + (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora + + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + + Super FX C emulator code + (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman + + + SH assembler code partly based on x86 assembler code + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + + + Specific ports contains the works of other authors. See headers in + individual files. + + Snes9x homepage: http://www.snes9x.com + + Permission to use, copy, modify and distribute Snes9x in both binary and + source form, for non-commercial purposes, is hereby granted without fee, + providing that this license information and copyright notice appear with + all copies and any derived work. + + This software is provided 'as-is', without any express or implied + warranty. In no event shall the authors be held liable for any damages + arising from the use of this software. + + Snes9x is freeware for PERSONAL USE only. Commercial users should + seek permission of the copyright holders first. Commercial use includes + charging money for Snes9x or software derived from Snes9x. + + The copyright holders request that bug fixes and improvements to the code + should be forwarded to them so everyone can benefit from the modifications + in future versions. + + Super NES and Super Nintendo Entertainment System are trademarks of + Nintendo Co., Limited and its subsidiary companies. +*******************************************************************************/ + +#ifndef _DSP1_H_ +#define _DSP1_H_ + +extern void (*SetDSP)(uint8, uint16); +extern uint8 (*GetDSP)(uint16); + +void DSP1SetByte(uint8 byte, uint16 address); +uint8 DSP1GetByte(uint16 address); + +void DSP2SetByte(uint8 byte, uint16 address); +uint8 DSP2GetByte(uint16 address); + +void DSP3SetByte(uint8 byte, uint16 address); +uint8 DSP3GetByte(uint16 address); +void DSP3_Reset(); + +void DSP4SetByte(uint8 byte, uint16 address); +uint8 DSP4GetByte(uint16 address); + +START_EXTERN_C +struct SDSP1 { + uint8 version; + bool8 waiting4command; + bool8 first_parameter; + uint8 command; + uint32 in_count; + uint32 in_index; + uint32 out_count; + uint32 out_index; + uint8 parameters [512]; + uint8 output [512]; +}; + +void S9xResetDSP1 (); +uint8 S9xGetDSP (uint16 Address); +void S9xSetDSP (uint8 Byte, uint16 Address); + +extern struct SDSP1 DSP1; +END_EXTERN_C + +#endif diff --git a/src/snes4iphone_src/dsp1_gp32.h b/src/snes4iphone_src/dsp1_gp32.h new file mode 100755 index 0000000..bd3ced1 --- /dev/null +++ b/src/snes4iphone_src/dsp1_gp32.h @@ -0,0 +1,244 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#ifndef _DSP1_H_ +#define _DSP1_H_ + +// Simple vector and matrix types +typedef double MATRIX[3][3]; +typedef double VECTOR[3]; + +enum AttitudeMatrix { MatrixA, MatrixB, MatrixC }; + +struct SDSP1 { + bool8 waiting4command; + bool8 first_parameter; + uint8 command; + uint32 in_count; + uint32 in_index; + uint32 out_count; + uint32 out_index; + uint16 parameters [10]; + uint16 output [10]; + + // Attitude matrices + MATRIX vMa; + MATRIX vMb; + MATRIX vMc; + + // Matrix and translaton vector for + // transforming a 3D position into the global coordinate system, + // from the view space coordinate system. + MATRIX vM; + VECTOR vT; + + // Focal distance + double vFov; + + // A precalculated value for optimization + double vPlaneD; + + // Raster position of horizon + double vHorizon; + + // Convert a 2D screen coordinate to a 3D ground coordinate in global coordinate system. + void ScreenToGround(VECTOR &v, double X2d, double Y2d); + + MATRIX &GetMatrix( AttitudeMatrix Matrix ); +}; + +///////////////// DSP Commands //////////////////// + +// DSP1 Command 02h +struct DSP1_Parameter +{ + DSP1_Parameter( int16 Fx, int16 Fy, int16 Fz, + uint16 Lfe, uint16 Les, + int8 Aas, int8 Azs ); + + // Raster number of imaginary center + int16 Vof; // -32768 ~ +32767 + + // Raster number representing + // horizontal line. + int16 Vva; // -32768 ~ +32767 + + // X,Y coordinate of the point + // projected on the center of the screen + // (ground coordinate) + int16 Cx; // -32768 ~ +32767 + int16 Cy; // -32768 ~ +32767 +}; + +// DSP1 Command 0Ah +struct DSP1_Raster +{ + DSP1_Raster( int16 Vs ); + + // Linear transformation matrix elements + // for each raster + int16 An; + int16 Bn; + int16 Cn; + int16 Dn; +}; + +// DSP1 Command 06h +struct DSP1_Project +{ + DSP1_Project( int16 x, int16 y, int16 z ); + + int16 H; + int16 V; + int16 M; +}; + +// DSP1 Command 0Eh +struct DSP1_Target +{ + DSP1_Target( int16 h, int16 v ); + + int16 X; + int16 Y; +}; + +// DSP1 Command 04h +struct DSP1_Triangle +{ + DSP1_Triangle (int16 Theta, int16 r ); + int16 S; + int16 C; +}; + +// DSP1 Command 08h +struct DSP1_Radius +{ + DSP1_Radius( int16 x, int16 y, int16 z ); + int16 Ll; + int16 Lh; +}; + +// DSP1 Command 18h +int16 DSP1_Range( int16 x, int16 y, int16 z, int16 r ); + +// DSP1 Command 28h +int16 DSP1_Distance( int16 x, int16 y, int16 z ); + +// DSP1 Command 0Ch +struct DSP1_Rotate +{ + DSP1_Rotate (int16 A, int16 x1, int16 y1); + + int16 x2; + int16 y2; +}; + +// DSP1 Command 1Ch +struct DSP1_Polar +{ + DSP1_Polar( int8 Za, int8 Xa, int8 Ya, int16 x, int16 y, int16 z ); + + int16 X; + int16 Y; + int16 Z; +}; + +// DSP1 Command 01h, 11h and 21h +void DSP1_Attitude( int16 m, int8 Za, int8 Xa, int8 Ya, AttitudeMatrix Matrix ); + +// DSP1 Command 0Dh, 1Dh and 2Dh +struct DSP1_Objective +{ + DSP1_Objective( int16 x, int16 y, int16 z, AttitudeMatrix Matrix ); + + int16 F; + int16 L; + int16 U; +}; + +// DSP1 Command 03h, 13h and 23h +struct DSP1_Subjective +{ + DSP1_Subjective( int16 F, int16 L, int16 U, AttitudeMatrix Matrix ); + + int16 X; + int16 Y; + int16 Z; +}; + +// DSP1 Command 0Bh, 1Bh and 2Bh +int16 DSP1_Scalar( int16 x, int16 y, int16 z, AttitudeMatrix Matrix ); + +// DSP1 Command 14h +struct DSP1_Gyrate +{ + DSP1_Gyrate( int8 Zi, int8 Xi, int8 Yi, + int8 dU, int8 dF, int8 dL ); + + int8 Z0; + int8 X0; + int8 Y0; +}; + +// DSP1 Command 00h +int16 DSP1_Multiply( int16 k, int16 I ); + +// DSP1 Command 10h +struct DSP1_Inverse +{ + DSP1_Inverse( int16 a, int16 b ); + + int16 A; + int16 B; +}; + +START_EXTERN_C +void S9xResetDSP1 (); +uint8 S9xGetDSP (uint16 Address); +void S9xSetDSP (uint8 Byte, uint16 Address); +END_EXTERN_C + +#ifndef __GP32__ +extern struct SDSP1 DSP1; +#else +extern "C" struct SDSP1 DSP1; +#endif + +#endif diff --git a/src/snes4iphone_src/dsp1emu.c b/src/snes4iphone_src/dsp1emu.c new file mode 100755 index 0000000..ea402a7 --- /dev/null +++ b/src/snes4iphone_src/dsp1emu.c @@ -0,0 +1,1451 @@ +//Copyright (C) 1997-2001 ZSNES Team ( zsknight@zsnes.com / _demo_@zsnes.com ) +// +//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 (at your option) any later +//version. +// +//This program 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 this program; if not, write to the Free Software +//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +//#define __ZSNES__ + +#if (defined __ZSNES__ && __LINUX__) +#include "../gblhdr.h" +#else +#endif + + +#include + + + +//#define DebugDSP1 + +// uncomment some lines to test +//#define printinfo +//#define debug02 +//#define debug0A +//#define debug06 + +#define __OPT__ +#define __OPT02__ +#define __OPT06__ + +#ifdef DebugDSP1 + +FILE * LogFile = NULL; + +void Log_Message (char *Message, ...) +{ + char Msg[400]; + va_list ap; + + va_start(ap,Message); + vsprintf(Msg,Message,ap ); + va_end(ap); + + strcat(Msg,"\r\n\0"); + fwrite(Msg,strlen(Msg),1,LogFile); + fflush (LogFile); +} + + +#endif + +const unsigned short DSP1ROM[1024] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, + 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, + 0x4000, 0x7fff, 0x4000, 0x2000, 0x1000, 0x0800, 0x0400, 0x0200, + 0x0100, 0x0080, 0x0040, 0x0020, 0x0001, 0x0008, 0x0004, 0x0002, + 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8000, 0xffe5, 0x0100, 0x7fff, 0x7f02, 0x7e08, + 0x7d12, 0x7c1f, 0x7b30, 0x7a45, 0x795d, 0x7878, 0x7797, 0x76ba, + 0x75df, 0x7507, 0x7433, 0x7361, 0x7293, 0x71c7, 0x70fe, 0x7038, + 0x6f75, 0x6eb4, 0x6df6, 0x6d3a, 0x6c81, 0x6bca, 0x6b16, 0x6a64, + 0x69b4, 0x6907, 0x685b, 0x67b2, 0x670b, 0x6666, 0x65c4, 0x6523, + 0x6484, 0x63e7, 0x634c, 0x62b3, 0x621c, 0x6186, 0x60f2, 0x6060, + 0x5fd0, 0x5f41, 0x5eb5, 0x5e29, 0x5d9f, 0x5d17, 0x5c91, 0x5c0c, + 0x5b88, 0x5b06, 0x5a85, 0x5a06, 0x5988, 0x590b, 0x5890, 0x5816, + 0x579d, 0x5726, 0x56b0, 0x563b, 0x55c8, 0x5555, 0x54e4, 0x5474, + 0x5405, 0x5398, 0x532b, 0x52bf, 0x5255, 0x51ec, 0x5183, 0x511c, + 0x50b6, 0x5050, 0x4fec, 0x4f89, 0x4f26, 0x4ec5, 0x4e64, 0x4e05, + 0x4da6, 0x4d48, 0x4cec, 0x4c90, 0x4c34, 0x4bda, 0x4b81, 0x4b28, + 0x4ad0, 0x4a79, 0x4a23, 0x49cd, 0x4979, 0x4925, 0x48d1, 0x487f, + 0x482d, 0x47dc, 0x478c, 0x473c, 0x46ed, 0x469f, 0x4651, 0x4604, + 0x45b8, 0x456c, 0x4521, 0x44d7, 0x448d, 0x4444, 0x43fc, 0x43b4, + 0x436d, 0x4326, 0x42e0, 0x429a, 0x4255, 0x4211, 0x41cd, 0x4189, + 0x4146, 0x4104, 0x40c2, 0x4081, 0x4040, 0x3fff, 0x41f7, 0x43e1, + 0x45bd, 0x478d, 0x4951, 0x4b0b, 0x4cbb, 0x4e61, 0x4fff, 0x5194, + 0x5322, 0x54a9, 0x5628, 0x57a2, 0x5914, 0x5a81, 0x5be9, 0x5d4a, + 0x5ea7, 0x5fff, 0x6152, 0x62a0, 0x63ea, 0x6530, 0x6672, 0x67b0, + 0x68ea, 0x6a20, 0x6b53, 0x6c83, 0x6daf, 0x6ed9, 0x6fff, 0x7122, + 0x7242, 0x735f, 0x747a, 0x7592, 0x76a7, 0x77ba, 0x78cb, 0x79d9, + 0x7ae5, 0x7bee, 0x7cf5, 0x7dfa, 0x7efe, 0x7fff, 0x0000, 0x0324, + 0x0647, 0x096a, 0x0c8b, 0x0fab, 0x12c8, 0x15e2, 0x18f8, 0x1c0b, + 0x1f19, 0x2223, 0x2528, 0x2826, 0x2b1f, 0x2e11, 0x30fb, 0x33de, + 0x36ba, 0x398c, 0x3c56, 0x3f17, 0x41ce, 0x447a, 0x471c, 0x49b4, + 0x4c3f, 0x4ebf, 0x5133, 0x539b, 0x55f5, 0x5842, 0x5a82, 0x5cb4, + 0x5ed7, 0x60ec, 0x62f2, 0x64e8, 0x66cf, 0x68a6, 0x6a6d, 0x6c24, + 0x6dca, 0x6f5f, 0x70e2, 0x7255, 0x73b5, 0x7504, 0x7641, 0x776c, + 0x7884, 0x798a, 0x7a7d, 0x7b5d, 0x7c29, 0x7ce3, 0x7d8a, 0x7e1d, + 0x7e9d, 0x7f09, 0x7f62, 0x7fa7, 0x7fd8, 0x7ff6, 0x7fff, 0x7ff6, + 0x7fd8, 0x7fa7, 0x7f62, 0x7f09, 0x7e9d, 0x7e1d, 0x7d8a, 0x7ce3, + 0x7c29, 0x7b5d, 0x7a7d, 0x798a, 0x7884, 0x776c, 0x7641, 0x7504, + 0x73b5, 0x7255, 0x70e2, 0x6f5f, 0x6dca, 0x6c24, 0x6a6d, 0x68a6, + 0x66cf, 0x64e8, 0x62f2, 0x60ec, 0x5ed7, 0x5cb4, 0x5a82, 0x5842, + 0x55f5, 0x539b, 0x5133, 0x4ebf, 0x4c3f, 0x49b4, 0x471c, 0x447a, + 0x41ce, 0x3f17, 0x3c56, 0x398c, 0x36ba, 0x33de, 0x30fb, 0x2e11, + 0x2b1f, 0x2826, 0x2528, 0x2223, 0x1f19, 0x1c0b, 0x18f8, 0x15e2, + 0x12c8, 0x0fab, 0x0c8b, 0x096a, 0x0647, 0x0324, 0x7fff, 0x7ff6, + 0x7fd8, 0x7fa7, 0x7f62, 0x7f09, 0x7e9d, 0x7e1d, 0x7d8a, 0x7ce3, + 0x7c29, 0x7b5d, 0x7a7d, 0x798a, 0x7884, 0x776c, 0x7641, 0x7504, + 0x73b5, 0x7255, 0x70e2, 0x6f5f, 0x6dca, 0x6c24, 0x6a6d, 0x68a6, + 0x66cf, 0x64e8, 0x62f2, 0x60ec, 0x5ed7, 0x5cb4, 0x5a82, 0x5842, + 0x55f5, 0x539b, 0x5133, 0x4ebf, 0x4c3f, 0x49b4, 0x471c, 0x447a, + 0x41ce, 0x3f17, 0x3c56, 0x398c, 0x36ba, 0x33de, 0x30fb, 0x2e11, + 0x2b1f, 0x2826, 0x2528, 0x2223, 0x1f19, 0x1c0b, 0x18f8, 0x15e2, + 0x12c8, 0x0fab, 0x0c8b, 0x096a, 0x0647, 0x0324, 0x0000, 0xfcdc, + 0xf9b9, 0xf696, 0xf375, 0xf055, 0xed38, 0xea1e, 0xe708, 0xe3f5, + 0xe0e7, 0xdddd, 0xdad8, 0xd7da, 0xd4e1, 0xd1ef, 0xcf05, 0xcc22, + 0xc946, 0xc674, 0xc3aa, 0xc0e9, 0xbe32, 0xbb86, 0xb8e4, 0xb64c, + 0xb3c1, 0xb141, 0xaecd, 0xac65, 0xaa0b, 0xa7be, 0xa57e, 0xa34c, + 0xa129, 0x9f14, 0x9d0e, 0x9b18, 0x9931, 0x975a, 0x9593, 0x93dc, + 0x9236, 0x90a1, 0x8f1e, 0x8dab, 0x8c4b, 0x8afc, 0x89bf, 0x8894, + 0x877c, 0x8676, 0x8583, 0x84a3, 0x83d7, 0x831d, 0x8276, 0x81e3, + 0x8163, 0x80f7, 0x809e, 0x8059, 0x8028, 0x800a, 0x6488, 0x0080, + 0x03ff, 0x0116, 0x0002, 0x0080, 0x4000, 0x3fd7, 0x3faf, 0x3f86, + 0x3f5d, 0x3f34, 0x3f0c, 0x3ee3, 0x3eba, 0x3e91, 0x3e68, 0x3e40, + 0x3e17, 0x3dee, 0x3dc5, 0x3d9c, 0x3d74, 0x3d4b, 0x3d22, 0x3cf9, + 0x3cd0, 0x3ca7, 0x3c7f, 0x3c56, 0x3c2d, 0x3c04, 0x3bdb, 0x3bb2, + 0x3b89, 0x3b60, 0x3b37, 0x3b0e, 0x3ae5, 0x3abc, 0x3a93, 0x3a69, + 0x3a40, 0x3a17, 0x39ee, 0x39c5, 0x399c, 0x3972, 0x3949, 0x3920, + 0x38f6, 0x38cd, 0x38a4, 0x387a, 0x3851, 0x3827, 0x37fe, 0x37d4, + 0x37aa, 0x3781, 0x3757, 0x372d, 0x3704, 0x36da, 0x36b0, 0x3686, + 0x365c, 0x3632, 0x3609, 0x35df, 0x35b4, 0x358a, 0x3560, 0x3536, + 0x350c, 0x34e1, 0x34b7, 0x348d, 0x3462, 0x3438, 0x340d, 0x33e3, + 0x33b8, 0x338d, 0x3363, 0x3338, 0x330d, 0x32e2, 0x32b7, 0x328c, + 0x3261, 0x3236, 0x320b, 0x31df, 0x31b4, 0x3188, 0x315d, 0x3131, + 0x3106, 0x30da, 0x30ae, 0x3083, 0x3057, 0x302b, 0x2fff, 0x2fd2, + 0x2fa6, 0x2f7a, 0x2f4d, 0x2f21, 0x2ef4, 0x2ec8, 0x2e9b, 0x2e6e, + 0x2e41, 0x2e14, 0x2de7, 0x2dba, 0x2d8d, 0x2d60, 0x2d32, 0x2d05, + 0x2cd7, 0x2ca9, 0x2c7b, 0x2c4d, 0x2c1f, 0x2bf1, 0x2bc3, 0x2b94, + 0x2b66, 0x2b37, 0x2b09, 0x2ada, 0x2aab, 0x2a7c, 0x2a4c, 0x2a1d, + 0x29ed, 0x29be, 0x298e, 0x295e, 0x292e, 0x28fe, 0x28ce, 0x289d, + 0x286d, 0x283c, 0x280b, 0x27da, 0x27a9, 0x2777, 0x2746, 0x2714, + 0x26e2, 0x26b0, 0x267e, 0x264c, 0x2619, 0x25e7, 0x25b4, 0x2581, + 0x254d, 0x251a, 0x24e6, 0x24b2, 0x247e, 0x244a, 0x2415, 0x23e1, + 0x23ac, 0x2376, 0x2341, 0x230b, 0x22d6, 0x229f, 0x2269, 0x2232, + 0x21fc, 0x21c4, 0x218d, 0x2155, 0x211d, 0x20e5, 0x20ad, 0x2074, + 0x203b, 0x2001, 0x1fc7, 0x1f8d, 0x1f53, 0x1f18, 0x1edd, 0x1ea1, + 0x1e66, 0x1e29, 0x1ded, 0x1db0, 0x1d72, 0x1d35, 0x1cf6, 0x1cb8, + 0x1c79, 0x1c39, 0x1bf9, 0x1bb8, 0x1b77, 0x1b36, 0x1af4, 0x1ab1, + 0x1a6e, 0x1a2a, 0x19e6, 0x19a1, 0x195c, 0x1915, 0x18ce, 0x1887, + 0x183f, 0x17f5, 0x17ac, 0x1761, 0x1715, 0x16c9, 0x167c, 0x162e, + 0x15df, 0x158e, 0x153d, 0x14eb, 0x1497, 0x1442, 0x13ec, 0x1395, + 0x133c, 0x12e2, 0x1286, 0x1228, 0x11c9, 0x1167, 0x1104, 0x109e, + 0x1036, 0x0fcc, 0x0f5f, 0x0eef, 0x0e7b, 0x0e04, 0x0d89, 0x0d0a, + 0x0c86, 0x0bfd, 0x0b6d, 0x0ad6, 0x0a36, 0x098d, 0x08d7, 0x0811, + 0x0736, 0x063e, 0x0519, 0x039a, 0x0000, 0x7fff, 0x0100, 0x0080, + 0x021d, 0x00c8, 0x00ce, 0x0048, 0x0a26, 0x277a, 0x00ce, 0x6488, + 0x14ac, 0x0001, 0x00f9, 0x00fc, 0x00ff, 0x00fc, 0x00f9, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}; + +/***************************************************************************\ +* Math tables * +\***************************************************************************/ + +#define INCR 2048 +#define Angle(x) (((x)/(65536/INCR)) & (INCR-1)) +#define Cos(x) ((float) CosTable2[x]) +#define Sin(x) ((float) SinTable2[x]) +#ifdef PI +#undef PI +#endif +#define PI 3.1415926535897932384626433832795 +float CosTable2[INCR]; +float SinTable2[INCR]; + +int32 CosTable2Fix[INCR];//=NULL; +int32 SinTable2Fix[INCR];//=NULL; + + +#define AngleFix(x) (((x)>>5) & (INCR-1)) +#define CosFix(x) (CosTable2Fix[x]) +#define SinFix(x) (SinTable2Fix[x]) + + +float Atan(float x) +{ + if ((x>=1) || (x<=1)) + return (x/(1+0.28*x*x)); + else + return (PI/2 - Atan(1/x)); +} + + +/***************************************************************************\ +* DSP1 code * +\***************************************************************************/ + +void InitDSP(void) +{ +#ifdef __OPT__ + unsigned int i; + +// CosTable2Fix = (int32 *) ljz_malloc(INCR*sizeof(int32)); +// SinTable2Fix = (int32 *) ljz_malloc(INCR*sizeof(int32)); + + for (i=0; i> 15; + + #ifdef DebugDSP1 + Log_Message("OP00 MULT %d*%d/32768=%d",Op00Multiplicand,Op00Multiplier,Op00Result); + #endif +} + +short Op20Multiplicand; +short Op20Multiplier; +short Op20Result; + +void DSPOp20() +{ + Op20Result= Op20Multiplicand * Op20Multiplier >> 15; + Op20Result++; + + #ifdef DebugDSP1 + Log_Message("OP20 MULT %d*%d/32768=%d",Op20Multiplicand,Op20Multiplier,Op20Result); + #endif +} + +signed short Op10Coefficient; +signed short Op10Exponent; +signed short Op10CoefficientR; +signed short Op10ExponentR; + +void DSP1_Inverse(short Coefficient, short Exponent, short *iCoefficient, short *iExponent) +{ + // Step One: Division by Zero + if (Coefficient == 0x0000) + { + *iCoefficient = 0x7fff; + *iExponent = 0x002f; + } + else + { + short Sign = 1; + + // Step Two: Remove Sign + if (Coefficient < 0) + { + if (Coefficient < -32767) Coefficient = -32767; + Coefficient = -Coefficient; + Sign = -1; + } + + // Step Three: Normalize + while (Coefficient < 0x4000) + { + Coefficient <<= 1; + Exponent--; + } + + // Step Four: Special Case + if (Coefficient == 0x4000) + if (Sign == 1) *iCoefficient = 0x7fff; + else { + *iCoefficient = -0x4000; + Exponent--; + } + else { + // Step Five: Initial Guess + short i = DSP1ROM[(((Coefficient - 0x4000) >> 7) + 0x0065)&1023]; + + // Step Six: Iterate "estimated" Newton's Method + i = (i + (-i * (Coefficient * i >> 15) >> 15)) << 1; + i = (i + (-i * (Coefficient * i >> 15) >> 15)) << 1; + + *iCoefficient = i * Sign; + } + + *iExponent = 1 - Exponent; + } +} + +void DSPOp10() +{ + DSP1_Inverse(Op10Coefficient, Op10Exponent, &Op10CoefficientR, &Op10ExponentR); + #ifdef DebugDSP1 + Log_Message("OP10 INV %d*2^%d = %d*2^%d", Op10Coefficient, Op10Exponent, Op10CoefficientR, Op10ExponentR); + #endif +} + +short Op04Angle; +short Op04Radius; +short Op04Sin; +short Op04Cos; + +const short DSP1_MulTable[256] = { + 0x0000, 0x0003, 0x0006, 0x0009, 0x000c, 0x000f, 0x0012, 0x0015, + 0x0019, 0x001c, 0x001f, 0x0022, 0x0025, 0x0028, 0x002b, 0x002f, + 0x0032, 0x0035, 0x0038, 0x003b, 0x003e, 0x0041, 0x0045, 0x0048, + 0x004b, 0x004e, 0x0051, 0x0054, 0x0057, 0x005b, 0x005e, 0x0061, + 0x0064, 0x0067, 0x006a, 0x006d, 0x0071, 0x0074, 0x0077, 0x007a, + 0x007d, 0x0080, 0x0083, 0x0087, 0x008a, 0x008d, 0x0090, 0x0093, + 0x0096, 0x0099, 0x009d, 0x00a0, 0x00a3, 0x00a6, 0x00a9, 0x00ac, + 0x00af, 0x00b3, 0x00b6, 0x00b9, 0x00bc, 0x00bf, 0x00c2, 0x00c5, + 0x00c9, 0x00cc, 0x00cf, 0x00d2, 0x00d5, 0x00d8, 0x00db, 0x00df, + 0x00e2, 0x00e5, 0x00e8, 0x00eb, 0x00ee, 0x00f1, 0x00f5, 0x00f8, + 0x00fb, 0x00fe, 0x0101, 0x0104, 0x0107, 0x010b, 0x010e, 0x0111, + 0x0114, 0x0117, 0x011a, 0x011d, 0x0121, 0x0124, 0x0127, 0x012a, + 0x012d, 0x0130, 0x0133, 0x0137, 0x013a, 0x013d, 0x0140, 0x0143, + 0x0146, 0x0149, 0x014d, 0x0150, 0x0153, 0x0156, 0x0159, 0x015c, + 0x015f, 0x0163, 0x0166, 0x0169, 0x016c, 0x016f, 0x0172, 0x0175, + 0x0178, 0x017c, 0x017f, 0x0182, 0x0185, 0x0188, 0x018b, 0x018e, + 0x0192, 0x0195, 0x0198, 0x019b, 0x019e, 0x01a1, 0x01a4, 0x01a8, + 0x01ab, 0x01ae, 0x01b1, 0x01b4, 0x01b7, 0x01ba, 0x01be, 0x01c1, + 0x01c4, 0x01c7, 0x01ca, 0x01cd, 0x01d0, 0x01d4, 0x01d7, 0x01da, + 0x01dd, 0x01e0, 0x01e3, 0x01e6, 0x01ea, 0x01ed, 0x01f0, 0x01f3, + 0x01f6, 0x01f9, 0x01fc, 0x0200, 0x0203, 0x0206, 0x0209, 0x020c, + 0x020f, 0x0212, 0x0216, 0x0219, 0x021c, 0x021f, 0x0222, 0x0225, + 0x0228, 0x022c, 0x022f, 0x0232, 0x0235, 0x0238, 0x023b, 0x023e, + 0x0242, 0x0245, 0x0248, 0x024b, 0x024e, 0x0251, 0x0254, 0x0258, + 0x025b, 0x025e, 0x0261, 0x0264, 0x0267, 0x026a, 0x026e, 0x0271, + 0x0274, 0x0277, 0x027a, 0x027d, 0x0280, 0x0284, 0x0287, 0x028a, + 0x028d, 0x0290, 0x0293, 0x0296, 0x029a, 0x029d, 0x02a0, 0x02a3, + 0x02a6, 0x02a9, 0x02ac, 0x02b0, 0x02b3, 0x02b6, 0x02b9, 0x02bc, + 0x02bf, 0x02c2, 0x02c6, 0x02c9, 0x02cc, 0x02cf, 0x02d2, 0x02d5, + 0x02d8, 0x02db, 0x02df, 0x02e2, 0x02e5, 0x02e8, 0x02eb, 0x02ee, + 0x02f1, 0x02f5, 0x02f8, 0x02fb, 0x02fe, 0x0301, 0x0304, 0x0307, + 0x030b, 0x030e, 0x0311, 0x0314, 0x0317, 0x031a, 0x031d, 0x0321}; + +const short DSP1_SinTable[256] = { + 0x0000, 0x0324, 0x0647, 0x096a, 0x0c8b, 0x0fab, 0x12c8, 0x15e2, + 0x18f8, 0x1c0b, 0x1f19, 0x2223, 0x2528, 0x2826, 0x2b1f, 0x2e11, + 0x30fb, 0x33de, 0x36ba, 0x398c, 0x3c56, 0x3f17, 0x41ce, 0x447a, + 0x471c, 0x49b4, 0x4c3f, 0x4ebf, 0x5133, 0x539b, 0x55f5, 0x5842, + 0x5a82, 0x5cb4, 0x5ed7, 0x60ec, 0x62f2, 0x64e8, 0x66cf, 0x68a6, + 0x6a6d, 0x6c24, 0x6dca, 0x6f5f, 0x70e2, 0x7255, 0x73b5, 0x7504, + 0x7641, 0x776c, 0x7884, 0x798a, 0x7a7d, 0x7b5d, 0x7c29, 0x7ce3, + 0x7d8a, 0x7e1d, 0x7e9d, 0x7f09, 0x7f62, 0x7fa7, 0x7fd8, 0x7ff6, + 0x7fff, 0x7ff6, 0x7fd8, 0x7fa7, 0x7f62, 0x7f09, 0x7e9d, 0x7e1d, + 0x7d8a, 0x7ce3, 0x7c29, 0x7b5d, 0x7a7d, 0x798a, 0x7884, 0x776c, + 0x7641, 0x7504, 0x73b5, 0x7255, 0x70e2, 0x6f5f, 0x6dca, 0x6c24, + 0x6a6d, 0x68a6, 0x66cf, 0x64e8, 0x62f2, 0x60ec, 0x5ed7, 0x5cb4, + 0x5a82, 0x5842, 0x55f5, 0x539b, 0x5133, 0x4ebf, 0x4c3f, 0x49b4, + 0x471c, 0x447a, 0x41ce, 0x3f17, 0x3c56, 0x398c, 0x36ba, 0x33de, + 0x30fb, 0x2e11, 0x2b1f, 0x2826, 0x2528, 0x2223, 0x1f19, 0x1c0b, + 0x18f8, 0x15e2, 0x12c8, 0x0fab, 0x0c8b, 0x096a, 0x0647, 0x0324, + -0x0000, -0x0324, -0x0647, -0x096a, -0x0c8b, -0x0fab, -0x12c8, -0x15e2, + -0x18f8, -0x1c0b, -0x1f19, -0x2223, -0x2528, -0x2826, -0x2b1f, -0x2e11, + -0x30fb, -0x33de, -0x36ba, -0x398c, -0x3c56, -0x3f17, -0x41ce, -0x447a, + -0x471c, -0x49b4, -0x4c3f, -0x4ebf, -0x5133, -0x539b, -0x55f5, -0x5842, + -0x5a82, -0x5cb4, -0x5ed7, -0x60ec, -0x62f2, -0x64e8, -0x66cf, -0x68a6, + -0x6a6d, -0x6c24, -0x6dca, -0x6f5f, -0x70e2, -0x7255, -0x73b5, -0x7504, + -0x7641, -0x776c, -0x7884, -0x798a, -0x7a7d, -0x7b5d, -0x7c29, -0x7ce3, + -0x7d8a, -0x7e1d, -0x7e9d, -0x7f09, -0x7f62, -0x7fa7, -0x7fd8, -0x7ff6, + -0x7fff, -0x7ff6, -0x7fd8, -0x7fa7, -0x7f62, -0x7f09, -0x7e9d, -0x7e1d, + -0x7d8a, -0x7ce3, -0x7c29, -0x7b5d, -0x7a7d, -0x798a, -0x7884, -0x776c, + -0x7641, -0x7504, -0x73b5, -0x7255, -0x70e2, -0x6f5f, -0x6dca, -0x6c24, + -0x6a6d, -0x68a6, -0x66cf, -0x64e8, -0x62f2, -0x60ec, -0x5ed7, -0x5cb4, + -0x5a82, -0x5842, -0x55f5, -0x539b, -0x5133, -0x4ebf, -0x4c3f, -0x49b4, + -0x471c, -0x447a, -0x41ce, -0x3f17, -0x3c56, -0x398c, -0x36ba, -0x33de, + -0x30fb, -0x2e11, -0x2b1f, -0x2826, -0x2528, -0x2223, -0x1f19, -0x1c0b, + -0x18f8, -0x15e2, -0x12c8, -0x0fab, -0x0c8b, -0x096a, -0x0647, -0x0324}; + +short DSP1_Sin(short Angle) +{ + if (Angle < 0) { + if (Angle == -32768) return 0; + return -DSP1_Sin(-Angle); + } + int S = DSP1_SinTable[Angle >> 8] + (DSP1_MulTable[Angle & 0xff] * DSP1_SinTable[0x40 + (Angle >> 8)] >> 15); + if (S > 32767) S = 32767; + return (short) S; +} + +short DSP1_Cos(short Angle) +{ + if (Angle < 0) { + if (Angle == -32768) return -32768; + Angle = -Angle; + } + int S = DSP1_SinTable[0x40 + (Angle >> 8)] - (DSP1_MulTable[Angle & 0xff] * DSP1_SinTable[Angle >> 8] >> 15); + if (S < -32768) S = -32767; + return (short) S; +} + +void DSP1_Normalize(short m, short *Coefficient, short *Exponent) +{ + short i = 0x4000; + short e = 0; + + if (m < 0) + while ((m & i) && i) { + i >>= 1; + e++; + } + else + while (!(m & i) && i) { + i >>= 1; + e++; + } + + if (e > 0) + *Coefficient = m * DSP1ROM[(0x21 + e)&1023] << 1; + else + *Coefficient = m; + + *Exponent -= e; +} + +void DSP1_Normalizefloat(int Product, short *Coefficient, short *Exponent) +{ + short n = Product & 0x7fff; + short m = Product >> 15; + short i = 0x4000; + short e = 0; + + if (m < 0) + while ((m & i) && i) { + i >>= 1; + e++; + } + else + while (!(m & i) && i) { + i >>= 1; + e++; + } + + if (e > 0) + { + *Coefficient = m * DSP1ROM[(0x0021 + e)&1023] << 1; + + if (e < 15) + *Coefficient += n * DSP1ROM[(0x0040 - e)&1023] >> 15; + else + { + i = 0x4000; + + if (m < 0) + while ((n & i) && i) { + i >>= 1; + e++; + } + else + while (!(n & i) && i) { + i >>= 1; + e++; + } + + if (e > 15) + *Coefficient = n * DSP1ROM[(0x0012 + e)&1023] << 1; + else + *Coefficient += n; + } + } + else + *Coefficient = m; + + *Exponent = e; +} + +void DSPOp04() +{ + Op04Sin = DSP1_Sin(Op04Angle) * Op04Radius >> 15; + Op04Cos = DSP1_Cos(Op04Angle) * Op04Radius >> 15; +} + +short Op0CA; +short Op0CX1; +short Op0CY1; +short Op0CX2; +short Op0CY2; + +void DSPOp0C() +{ + Op0CX2 = (Op0CY1 * DSP1_Sin(Op0CA) >> 15) + (Op0CX1 * DSP1_Cos(Op0CA) >> 15); + Op0CY2 = (Op0CY1 * DSP1_Cos(Op0CA) >> 15) - (Op0CX1 * DSP1_Sin(Op0CA) >> 15); +} + + +short Op02FX; +short Op02FY; +short Op02FZ; +short Op02LFE; +short Op02LES; +unsigned short Op02AAS; +unsigned short Op02AZS; +unsigned short Op02VOF; +unsigned short Op02VVA; + +short Op02CX; +short Op02CY; +float Op02CXF; +float Op02CYF; +float ViewerX0; +float ViewerY0; +float ViewerZ0; +float ViewerX1; +float ViewerY1; +float ViewerZ1; +float ViewerX; +float ViewerY; +float ViewerZ; +int ViewerAX; +int ViewerAY; +int ViewerAZ; +float NumberOfSlope; +float ScreenX; +float ScreenY; +float ScreenZ; +float TopLeftScreenX; +float TopLeftScreenY; +float TopLeftScreenZ; +float BottomRightScreenX; +float BottomRightScreenY; +float BottomRightScreenZ; +float Ready; +float RasterLX; +float RasterLY; +float RasterLZ; +float ScreenLX1; +float ScreenLY1; +float ScreenLZ1; +int ReversedLES; +short Op02LESb; +float NAzsB,NAasB; +float ViewerXc; +float ViewerYc; +float ViewerZc; +float CenterX,CenterY; +short Op02CYSup,Op02CXSup; +float CXdistance; + +#define VofAngle 0x3880 + +short TValDebug,TValDebug2; +short ScrDispl; + + +#ifdef __OPT02__ +void DSPOp02() +{ + ViewerZ1=-Cos(Angle(Op02AZS)); + ViewerX1=Sin(Angle(Op02AZS))*Sin(Angle(Op02AAS)); + ViewerY1=Sin(Angle(Op02AZS))*Cos(Angle(Op02AAS)); + + + #ifdef debug02 + printf("\nViewerX1 : %f ViewerY1 : %f ViewerZ1 : %f\n",ViewerX1,ViewerY1, + ViewerZ1); + getch(); + #endif + ViewerX=Op02FX-ViewerX1*Op02LFE; + ViewerY=Op02FY-ViewerY1*Op02LFE; + ViewerZ=Op02FZ-ViewerZ1*Op02LFE; + + ScreenX=Op02FX+ViewerX1*(Op02LES-Op02LFE); + ScreenY=Op02FY+ViewerY1*(Op02LES-Op02LFE); + ScreenZ=Op02FZ+ViewerZ1*(Op02LES-Op02LFE); + + #ifdef debug02 + printf("ViewerX : %f ViewerY : %f ViewerZ : %f\n",ViewerX,ViewerY,ViewerZ); + printf("Op02FX : %d Op02FY : %d Op02FZ : %d\n",Op02FX,Op02FY,Op02FZ); + printf("ScreenX : %f ScreenY : %f ScreenZ : %f\n",ScreenX,ScreenY,ScreenZ); + getch(); + #endif + if (ViewerZ1==0)ViewerZ1++; + NumberOfSlope=ViewerZ/-ViewerZ1; + + Op02CX=(short)(Op02CXF=ViewerX+ViewerX1*NumberOfSlope); + Op02CY=(short)(Op02CYF=ViewerY+ViewerY1*NumberOfSlope); + + Op02VOF=0x0000; + ReversedLES=0; + Op02LESb=Op02LES; + if ((Op02LES>=VofAngle+16384.0) && (Op02LES=VofAngle) && (Op02LESb<=VofAngle+0x4000)) { + Op02VOF= (short)(Op02LESb * tanf((Op02AZS-0x4000-VofAngle)*6.2832/65536.0)); + Op02VVA-=Op02VOF; + } + if (ReversedLES){ + Op02VOF=-Op02VOF; + } + + NAzsB = (Op02AZS-0x4000)*6.2832/65536.0; + NAasB = Op02AAS*6.2832/65536.0; + + if (tanf(NAzsB)==0) NAzsB=0.1; + + ScrDispl=0; + if (NAzsB>-0.15) {NAzsB=-0.15;ScrDispl=Op02VVA-0xFFDA;} + + CXdistance=1/tanf(NAzsB); + + ViewerXc=Op02FX; + ViewerYc=Op02FY; + ViewerZc=Op02FZ; + + CenterX = (-sinf(NAasB)*ViewerZc*CXdistance)+ViewerXc; + CenterY = (cosf(NAasB)*ViewerZc*CXdistance)+ViewerYc; + Op02CX = (short)CenterX; + Op02CY = (short)CenterY; + + ViewerXc=ViewerX;//-Op02FX); + ViewerYc=ViewerY;//-Op02FY); + ViewerZc=ViewerZ;//-Op02FZ); + + CenterX = (-sinf(NAasB)*ViewerZc*CXdistance)+ViewerXc; + if (CenterX<-32768) CenterX = -32768; if (CenterX>32767) CenterX=32767; + CenterY = (cosf(NAasB)*ViewerZc*CXdistance)+ViewerYc; + if (CenterY<-32768) CenterY = -32768; if (CenterY>32767) CenterY=32767; + + TValDebug = (short)((NAzsB*65536/6.28)); + TValDebug2 = ScrDispl; + +// if (Op02CY < 0) {Op02CYSup = Op02CY/256; Op02CY = 0;} +// if (Op02CX < 0) {Op02CXSup = Op02CX/256; Op02CX = 0;} + +// [4/15/2001] (ViewerX+ViewerX1*NumberOfSlope); +// [4/15/2001] (ViewerY+ViewerY1*NumberOfSlope); + +// if(Op02LFE==0x2200)Op02VVA=0xFECD; +// else Op02VVA=0xFFB2; + + + #ifdef DebugDSP1 + Log_Message("OP02 FX:%d FY:%d FZ:%d LFE:%d LES:%d",Op02FX,Op02FY,Op02FZ,Op02LFE,Op02LES); + Log_Message(" AAS:%d AZS:%d VOF:%d VVA:%d",Op02AAS,Op02AZS,Op02VOF,Op02VVA); + Log_Message(" VX:%d VY:%d VZ:%d",(short)ViewerX,(short)ViewerY,(short)ViewerZ); + #endif + +} +#else + +void DSPOp02() +{ + ViewerZ1=-cosf(Op02AZS*6.2832/65536.0); + ViewerX1=sinf(Op02AZS*6.2832/65536.0)*sinf(Op02AAS*6.2832/65536.0); + ViewerY1=sinf(Op02AZS*6.2832/65536.0)*cosf(-Op02AAS*6.2832/65536.0); + + #ifdef debug02 + printf("\nViewerX1 : %f ViewerY1 : %f ViewerZ1 : %f\n",ViewerX1,ViewerY1, + ViewerZ1); + getch(); + #endif + ViewerX=Op02FX-ViewerX1*Op02LFE; + ViewerY=Op02FY-ViewerY1*Op02LFE; + ViewerZ=Op02FZ-ViewerZ1*Op02LFE; + + ScreenX=Op02FX+ViewerX1*(Op02LES-Op02LFE); + ScreenY=Op02FY+ViewerY1*(Op02LES-Op02LFE); + ScreenZ=Op02FZ+ViewerZ1*(Op02LES-Op02LFE); + + #ifdef debug02 + printf("ViewerX : %f ViewerY : %f ViewerZ : %f\n",ViewerX,ViewerY,ViewerZ); + printf("Op02FX : %d Op02FY : %d Op02FZ : %d\n",Op02FX,Op02FY,Op02FZ); + printf("ScreenX : %f ScreenY : %f ScreenZ : %f\n",ScreenX,ScreenY,ScreenZ); + getch(); + #endif + if (ViewerZ1==0)ViewerZ1++; + NumberOfSlope=ViewerZ/-ViewerZ1; + + Op02CX=(short)(Op02CXF=ViewerX+ViewerX1*NumberOfSlope); + Op02CY=(short)(Op02CYF=ViewerY+ViewerY1*NumberOfSlope); + + ViewerXc=ViewerX;//-Op02FX); + ViewerYc=ViewerY;//-Op02FY); + ViewerZc=ViewerZ;//-Op02FZ); + + Op02VOF=0x0000; + ReversedLES=0; + Op02LESb=Op02LES; + if ((Op02LES>=VofAngle+16384.0) && (Op02LES=VofAngle) && (Op02LESb<=VofAngle+0x4000)) { + Op02VOF= (short)(Op02LESb * tanf((Op02AZS-0x4000-VofAngle)*6.2832/65536.0)); + Op02VVA-=Op02VOF; + } + if (ReversedLES){ + Op02VOF=-Op02VOF; + } + + NAzsB = (Op02AZS-0x4000)*6.2832/65536.0; + NAasB = Op02AAS*6.2832/65536.0; + + if (tanf(NAzsB)==0) NAzsB=0.1; + + ScrDispl=0; + if (NAzsB>-0.15) {NAzsB=-0.15;ScrDispl=Op02VVA-0xFFDA;} + + CXdistance=1/tanf(NAzsB); + + CenterX = (-sinf(NAasB)*ViewerZc*CXdistance)+ViewerXc; + if (CenterX<-32768) CenterX = -32768; if (CenterX>32767) CenterX=32767; + Op02CX = (short)CenterX; + CenterY = (cosf(NAasB)*ViewerZc*CXdistance)+ViewerYc; + if (CenterY<-32768) CenterY = -32768; if (CenterY>32767) CenterY=32767; + Op02CY = (short)CenterY; + + TValDebug = (NAzsB*65536/6.28); + TValDebug2 = ScrDispl; + +// if (Op02CY < 0) {Op02CYSup = Op02CY/256; Op02CY = 0;} +// if (Op02CX < 0) {Op02CXSup = Op02CX/256; Op02CX = 0;} + +// [4/15/2001] (ViewerX+ViewerX1*NumberOfSlope); +// [4/15/2001] (ViewerY+ViewerY1*NumberOfSlope); + +// if(Op02LFE==0x2200)Op02VVA=0xFECD; +// else Op02VVA=0xFFB2; + + + #ifdef DebugDSP1 + Log_Message("OP02 FX:%d FY:%d FZ:%d LFE:%d LES:%d",Op02FX,Op02FY,Op02FZ,Op02LFE,Op02LES); + Log_Message(" AAS:%d AZS:%d VOF:%d VVA:%d",Op02AAS,Op02AZS,Op02VOF,Op02VVA); + Log_Message(" VX:%d VY:%d VZ:%d",(short)ViewerX,(short)ViewerY,(short)ViewerZ); + #endif + +} +#endif + +short Op0AVS; +short Op0AA; +short Op0AB; +short Op0AC; +short Op0AD; + +float RasterRX; +float RasterRY; +float RasterRZ; +float RasterLSlopeX; +float RasterLSlopeY; +float RasterLSlopeZ; +float RasterRSlopeX; +float RasterRSlopeY; +float RasterRSlopeZ; +float GroundLX; +float GroundLY; +float GroundRX; +float GroundRY; +float Distance; + +float NAzs,NAas; +float RVPos,RHPos,RXRes,RYRes; + + +void GetRXYPos(){ + float scalar; + + if (Op02LES==0) return; + + + NAzs = NAzsB - Atan((RVPos) / (float)Op02LES); + NAas = NAasB;// + Atan(RHPos) / (float)Op02LES); + + if (cosf(NAzs)==0) NAzs+=0.001; + if (tanf(NAzs)==0) NAzs+=0.001; + + RXRes = (-sinf(NAas)*ViewerZc/(tanf(NAzs))+ViewerXc); + RYRes = (cosf(NAas)*ViewerZc/(tanf(NAzs))+ViewerYc); + scalar = ((ViewerZc/sinf(NAzs))/(float)Op02LES); + RXRes += scalar*-sinf(NAas+PI/2)*RHPos; + RYRes += scalar*cosf(NAas+PI/2)*RHPos; +} + +void DSPOp0A() +{ + float x2,y2,x3,y3,x4,y4,m,ypos; + + + if(Op0AVS==0) {Op0AVS++; return;} + ypos=Op0AVS-ScrDispl; + // CenterX,CenterX = Center (x1,y1) + // Get (0,Vs) coords (x2,y2) + RVPos = ypos; RHPos = 0; + GetRXYPos(); x2 = RXRes; y2 = RYRes; + // Get (-128,Vs) coords (x3,y3) + RVPos = ypos; RHPos = -128; + GetRXYPos(); x3 = RXRes; y3 = RYRes; + // Get (127,Vs) coords (x4,y4) + RVPos = ypos; RHPos = 127; + GetRXYPos(); x4 = RXRes; y4 = RYRes; + + // A = (x4-x3)/256 + m = (x4-x3)/256*256; if (m>32767) m=32767; if (m<-32768) m=-32768; + Op0AA = (short)(m); + // C = (y4-y3)/256 + m = (y4-y3)/256*256; if (m>32767) m=32767; if (m<-32768) m=-32768; + Op0AC = (short)(m); + if (ypos==0){ + Op0AB = 0; + Op0AD = 0; + } + else { + // B = (x2-x1)/Vs + m = (x2-CenterX)/ypos*256; if (m>32767) m=32767; if (m<-32768) m=-32768; + Op0AB = (short)(m); + // D = (y2-y1)/Vs + m = (y2-CenterY)/ypos*256; if (m>32767) m=32767; if (m<-32768) m=-32768; + Op0AD = (short)(m); + } + + Op0AVS+=1; +} + +short Op06X; +short Op06Y; +short Op06Z; +short Op06H; +short Op06V; +unsigned short Op06S; + +/*float ObjPX; +float ObjPY; +float ObjPZ; +float ObjPX1; +float ObjPY1; +float ObjPZ1; +float ObjPX2; +float ObjPY2; +float ObjPZ2;*/ +int32 ObjPX; +int32 ObjPY; +int32 ObjPZ; +int32 ObjPX1; +int32 ObjPY1; +int32 ObjPZ1; +int32 ObjPX2; +int32 ObjPY2; +int32 ObjPZ2; + +float DivideOp06; +int Temp; +int tanval2; + +#define SADDMULT1616(res,a,b,c,d) res=((int64)a*(int64)b+(int64)c*(int64)d)>>16; + +#ifdef __OPT06__ +void DSPOp06() +{ + + ObjPX=Op06X-Op02FX; + ObjPY=Op06Y-Op02FY; + ObjPZ=Op06Z-Op02FZ; + + // rotate around Z +/* tanval2 = Angle(-Op02AAS+32768); +// tanval2 = (-Op02AAS+32768)/(65536/INCR); + ObjPX1=(ObjPX*Cos(tanval2)+ObjPY*-Sin(tanval2)); + ObjPY1=(ObjPX*Sin(tanval2)+ObjPY*Cos(tanval2)); + ObjPZ1=ObjPZ;*/ + tanval2 = AngleFix(-Op02AAS+32768); + SADDMULT1616(ObjPX1,ObjPX,CosFix(tanval2),ObjPY,-SinFix(tanval2)) + SADDMULT1616(ObjPY1,ObjPX,SinFix(tanval2),ObjPY,CosFix(tanval2)) + ObjPZ1=ObjPZ; + + + // rotate around X +// tanval2 = (-Op02AZS/(65536/INCR)) & 1023; +/* tanval2 = Angle(-Op02AZS); +// tanval2 = (-Op02AZS)/256; + ObjPX2=ObjPX1; + ObjPY2=(ObjPY1*Cos(tanval2)+ObjPZ1*-Sin(tanval2)); + ObjPZ2=(ObjPY1*Sin(tanval2)+ObjPZ1*Cos(tanval2));*/ + tanval2 = AngleFix(-Op02AZS); + ObjPX2=ObjPX1; + SADDMULT1616(ObjPY2,ObjPY1,CosFix(tanval2),ObjPZ1,-SinFix(tanval2)) + SADDMULT1616(ObjPZ2,ObjPY1,SinFix(tanval2),ObjPZ1,CosFix(tanval2)) + + #ifdef debug06 + Log_Message("ObjPX2: %f ObjPY2: %f ObjPZ2: %f\n",ObjPX2,ObjPY2,ObjPZ2); + #endif + + ObjPZ2=ObjPZ2-Op02LFE; + + if (ObjPZ2<0) + { + //float d; + int32 d; + Op06H=(short)(-ObjPX2*Op02LES/-(ObjPZ2)); //-ObjPX2*256/-ObjPZ2; + Op06V=(short)(-ObjPY2*Op02LES/-(ObjPZ2)); //-ObjPY2*256/-ObjPZ2; + /*d=(float)Op02LES; + d*=256.0; + d/=(-ObjPZ2); + if(d>65535.0) + d=65535.0; + else if(d<0.0) + d=0.0;*/ + d=(((int32)Op02LES)<<8)/(-ObjPZ2); + if (d>65535) d=65535; + if (d<0) d=0; + Op06S=(unsigned short)d; + //Op06S=(unsigned short)(256*(float)Op02LES/-ObjPZ2); + //Op06S=(unsigned short)((float)(256.0*((float)Op02LES)/(-ObjPZ2))); + } + else + { + Op06H=0; + Op06V=14*16; + Op06S=0xFFFF; + } + + + #ifdef DebugDSP1 + Log_Message("OP06 X:%d Y:%d Z:%d",Op06X,Op06Y,Op06Z); + Log_Message("OP06 H:%d V:%d S:%d",Op06H,Op06V,Op06S); + #endif +} +#else + +void DSPOp06() +{ + ObjPX=Op06X-Op02FX; + ObjPY=Op06Y-Op02FY; + ObjPZ=Op06Z-Op02FZ; + + // rotate around Z + tanval = (-Op02AAS+32768)/65536.0*6.2832; + ObjPX1=(ObjPX*cosf(tanval)+ObjPY*-sinf(tanval)); + ObjPY1=(ObjPX*sinf(tanval)+ObjPY*cosf(tanval)); + ObjPZ1=ObjPZ; + + #ifdef debug06 + Log_Message("Angle : %f", tanval); + Log_Message("ObjPX1: %f ObjPY1: %f ObjPZ1: %f\n",ObjPX1,ObjPY1,ObjPZ1); + Log_Message("cos(tanval) : %f sin(tanval) : %f", cosf(tanval), sinf(tanval)); + #endif + + // rotate around X + tanval = (-Op02AZS)/65536.0*6.2832; + ObjPX2=ObjPX1; + ObjPY2=(ObjPY1*cosf(tanval)+ObjPZ1*-sinf(tanval)); + ObjPZ2=(ObjPY1*sinf(tanval)+ObjPZ1*cosf(tanval)); + + #ifdef debug06 + Log_Message("ObjPX2: %f ObjPY2: %f ObjPZ2: %f\n",ObjPX2,ObjPY2,ObjPZ2); + #endif + + ObjPZ2=ObjPZ2-Op02LFE; + + if (ObjPZ2<0) + { + Op06H=(short)(-ObjPX2*Op02LES/-(ObjPZ2)); //-ObjPX2*256/-ObjPZ2; + Op06V=(short)(-ObjPY2*Op02LES/-(ObjPZ2)); //-ObjPY2*256/-ObjPZ2; + float d=(float)Op02LES; + d*=256.0; + d/=(-ObjPZ2); + if(d>65535.0) + d=65535.0; + else if(d<0.0) + d=0.0; + Op06S=(unsigned short)d; +// Op06S=(unsigned short)(256*(float)Op02LES/-ObjPZ2); + } + else + { + Op06H=0; + Op06V=14*16; + Op06S=0xFFFF; + } + + #ifdef DebugDSP1 + Log_Message("OP06 X:%d Y:%d Z:%d",Op06X,Op06Y,Op06Z); + Log_Message("OP06 H:%d V:%d S:%d",Op06H,Op06V,Op06S); + #endif +} +#endif + + +short matrixC[3][3]; +short matrixB[3][3]; +short matrixA[3][3]; + +short Op01m; +short Op01Zr; +short Op01Xr; +short Op01Yr; +short Op11m; +short Op11Zr; +short Op11Xr; +short Op11Yr; +short Op21m; +short Op21Zr; +short Op21Xr; +short Op21Yr; + +void DSPOp01() +{ + short SinAz = DSP1_Sin(Op01Zr); + short CosAz = DSP1_Cos(Op01Zr); + short SinAy = DSP1_Sin(Op01Yr); + short CosAy = DSP1_Cos(Op01Yr); + short SinAx = DSP1_Sin(Op01Xr); + short CosAx = DSP1_Cos(Op01Xr); + + Op01m >>= 1; + + matrixA[0][0] = (Op01m * CosAz >> 15) * CosAy >> 15; + matrixA[0][1] = -((Op01m * SinAz >> 15) * CosAy >> 15); + matrixA[0][2] = Op01m * SinAy >> 15; + + matrixA[1][0] = ((Op01m * SinAz >> 15) * CosAx >> 15) + (((Op01m * CosAz >> 15) * SinAx >> 15) * SinAy >> 15); + matrixA[1][1] = ((Op01m * CosAz >> 15) * CosAx >> 15) - (((Op01m * SinAz >> 15) * SinAx >> 15) * SinAy >> 15); + matrixA[1][2] = -((Op01m * SinAx >> 15) * CosAy >> 15); + + matrixA[2][0] = ((Op01m * SinAz >> 15) * SinAx >> 15) - (((Op01m * CosAz >> 15) * CosAx >> 15) * SinAy >> 15); + matrixA[2][1] = ((Op01m * CosAz >> 15) * SinAx >> 15) + (((Op01m * SinAz >> 15) * CosAx >> 15) * SinAy >> 15); + matrixA[2][2] = (Op01m * CosAx >> 15) * CosAy >> 15; +} + +void DSPOp11() +{ + short SinAz = DSP1_Sin(Op11Zr); + short CosAz = DSP1_Cos(Op11Zr); + short SinAy = DSP1_Sin(Op11Yr); + short CosAy = DSP1_Cos(Op11Yr); + short SinAx = DSP1_Sin(Op11Xr); + short CosAx = DSP1_Cos(Op11Xr); + + Op11m >>= 1; + + matrixB[0][0] = (Op11m * CosAz >> 15) * CosAy >> 15; + matrixB[0][1] = -((Op11m * SinAz >> 15) * CosAy >> 15); + matrixB[0][2] = Op11m * SinAy >> 15; + + matrixB[1][0] = ((Op11m * SinAz >> 15) * CosAx >> 15) + (((Op11m * CosAz >> 15) * SinAx >> 15) * SinAy >> 15); + matrixB[1][1] = ((Op11m * CosAz >> 15) * CosAx >> 15) - (((Op11m * SinAz >> 15) * SinAx >> 15) * SinAy >> 15); + matrixB[1][2] = -((Op11m * SinAx >> 15) * CosAy >> 15); + + matrixB[2][0] = ((Op11m * SinAz >> 15) * SinAx >> 15) - (((Op11m * CosAz >> 15) * CosAx >> 15) * SinAy >> 15); + matrixB[2][1] = ((Op11m * CosAz >> 15) * SinAx >> 15) + (((Op11m * SinAz >> 15) * CosAx >> 15) * SinAy >> 15); + matrixB[2][2] = (Op11m * CosAx >> 15) * CosAy >> 15; +} + +void DSPOp21() +{ + short SinAz = DSP1_Sin(Op21Zr); + short CosAz = DSP1_Cos(Op21Zr); + short SinAy = DSP1_Sin(Op21Yr); + short CosAy = DSP1_Cos(Op21Yr); + short SinAx = DSP1_Sin(Op21Xr); + short CosAx = DSP1_Cos(Op21Xr); + + Op21m >>= 1; + + matrixC[0][0] = (Op21m * CosAz >> 15) * CosAy >> 15; + matrixC[0][1] = -((Op21m * SinAz >> 15) * CosAy >> 15); + matrixC[0][2] = Op21m * SinAy >> 15; + + matrixC[1][0] = ((Op21m * SinAz >> 15) * CosAx >> 15) + (((Op21m * CosAz >> 15) * SinAx >> 15) * SinAy >> 15); + matrixC[1][1] = ((Op21m * CosAz >> 15) * CosAx >> 15) - (((Op21m * SinAz >> 15) * SinAx >> 15) * SinAy >> 15); + matrixC[1][2] = -((Op21m * SinAx >> 15) * CosAy >> 15); + + matrixC[2][0] = ((Op21m * SinAz >> 15) * SinAx >> 15) - (((Op21m * CosAz >> 15) * CosAx >> 15) * SinAy >> 15); + matrixC[2][1] = ((Op21m * CosAz >> 15) * SinAx >> 15) + (((Op21m * SinAz >> 15) * CosAx >> 15) * SinAy >> 15); + matrixC[2][2] = (Op21m * CosAx >> 15) * CosAy >> 15; +} + +short Op0DX; +short Op0DY; +short Op0DZ; +short Op0DF; +short Op0DL; +short Op0DU; +short Op1DX; +short Op1DY; +short Op1DZ; +short Op1DF; +short Op1DL; +short Op1DU; +short Op2DX; +short Op2DY; +short Op2DZ; +short Op2DF; +short Op2DL; +short Op2DU; + +void DSPOp0D() +{ + Op0DF = (Op0DX * matrixA[0][0] >> 15) + (Op0DY * matrixA[0][1] >> 15) + (Op0DZ * matrixA[0][2] >> 15); + Op0DL = (Op0DX * matrixA[1][0] >> 15) + (Op0DY * matrixA[1][1] >> 15) + (Op0DZ * matrixA[1][2] >> 15); + Op0DU = (Op0DX * matrixA[2][0] >> 15) + (Op0DY * matrixA[2][1] >> 15) + (Op0DZ * matrixA[2][2] >> 15); + + #ifdef DebugDSP1 + Log_Message("OP0D X: %d Y: %d Z: %d / F: %d L: %d U: %d",Op0DX,Op0DY,Op0DZ,Op0DF,Op0DL,Op0DU); + #endif +} + +void DSPOp1D() +{ + Op1DF = (Op1DX * matrixB[0][0] >> 15) + (Op1DY * matrixB[0][1] >> 15) + (Op1DZ * matrixB[0][2] >> 15); + Op1DL = (Op1DX * matrixB[1][0] >> 15) + (Op1DY * matrixB[1][1] >> 15) + (Op1DZ * matrixB[1][2] >> 15); + Op1DU = (Op1DX * matrixB[2][0] >> 15) + (Op1DY * matrixB[2][1] >> 15) + (Op1DZ * matrixB[2][2] >> 15); + + #ifdef DebugDSP1 + Log_Message("OP1D X: %d Y: %d Z: %d / F: %d L: %d U: %d",Op1DX,Op1DY,Op1DZ,Op1DF,Op1DL,Op1DU); + #endif +} + +void DSPOp2D() +{ + Op2DF = (Op2DX * matrixC[0][0] >> 15) + (Op2DY * matrixC[0][1] >> 15) + (Op2DZ * matrixC[0][2] >> 15); + Op2DL = (Op2DX * matrixC[1][0] >> 15) + (Op2DY * matrixC[1][1] >> 15) + (Op2DZ * matrixC[1][2] >> 15); + Op2DU = (Op2DX * matrixC[2][0] >> 15) + (Op2DY * matrixC[2][1] >> 15) + (Op2DZ * matrixC[2][2] >> 15); + + #ifdef DebugDSP1 + Log_Message("OP2D X: %d Y: %d Z: %d / F: %d L: %d U: %d",Op2DX,Op2DY,Op2DZ,Op2DF,Op2DL,Op2DU); + #endif +} + +short Op03F; +short Op03L; +short Op03U; +short Op03X; +short Op03Y; +short Op03Z; +short Op13F; +short Op13L; +short Op13U; +short Op13X; +short Op13Y; +short Op13Z; +short Op23F; +short Op23L; +short Op23U; +short Op23X; +short Op23Y; +short Op23Z; + +void DSPOp03() +{ + Op03X = (Op03F * matrixA[0][0] >> 15) + (Op03L * matrixA[1][0] >> 15) + (Op03U * matrixA[2][0] >> 15); + Op03Y = (Op03F * matrixA[0][1] >> 15) + (Op03L * matrixA[1][1] >> 15) + (Op03U * matrixA[2][1] >> 15); + Op03Z = (Op03F * matrixA[0][2] >> 15) + (Op03L * matrixA[1][2] >> 15) + (Op03U * matrixA[2][2] >> 15); + + #ifdef DebugDSP1 + Log_Message("OP03 F: %d L: %d U: %d / X: %d Y: %d Z: %d",Op03F,Op03L,Op03U,Op03X,Op03Y,Op03Z); + #endif +} + +void DSPOp13() +{ + Op13X = (Op13F * matrixB[0][0] >> 15) + (Op13L * matrixB[1][0] >> 15) + (Op13U * matrixB[2][0] >> 15); + Op13Y = (Op13F * matrixB[0][1] >> 15) + (Op13L * matrixB[1][1] >> 15) + (Op13U * matrixB[2][1] >> 15); + Op13Z = (Op13F * matrixB[0][2] >> 15) + (Op13L * matrixB[1][2] >> 15) + (Op13U * matrixB[2][2] >> 15); + + #ifdef DebugDSP1 + Log_Message("OP13 F: %d L: %d U: %d / X: %d Y: %d Z: %d",Op13F,Op13L,Op13U,Op13X,Op13Y,Op13Z); + #endif +} + +void DSPOp23() +{ + Op23X = (Op23F * matrixC[0][0] >> 15) + (Op23L * matrixC[1][0] >> 15) + (Op23U * matrixC[2][0] >> 15); + Op23Y = (Op23F * matrixC[0][1] >> 15) + (Op23L * matrixC[1][1] >> 15) + (Op23U * matrixC[2][1] >> 15); + Op23Z = (Op23F * matrixC[0][2] >> 15) + (Op23L * matrixC[1][2] >> 15) + (Op23U * matrixC[2][2] >> 15); + + #ifdef DebugDSP1 + Log_Message("OP23 F: %d L: %d U: %d / X: %d Y: %d Z: %d",Op23F,Op23L,Op23U,Op23X,Op23Y,Op23Z); + #endif +} + +short Op14Zr; +short Op14Xr; +short Op14Yr; +short Op14U; +short Op14F; +short Op14L; +short Op14Zrr; +short Op14Xrr; +short Op14Yrr; + +void DSPOp14() +{ + short CSec, ESec, CTan, CSin, C, E; + + DSP1_Inverse(DSP1_Cos(Op14Xr), 0, &CSec, &ESec); + + // Rotation Around Z + DSP1_Normalizefloat(Op14U * DSP1_Cos(Op14Yr) - Op14F * DSP1_Sin(Op14Yr), &C, &E); + + E = ESec - E; + + DSP1_Normalize(C * CSec >> 15, &C, &E); + + if (E > 0) { + if (C > 0) C = 32767; else if (C < 0) C = -32767; + } else { + if (E < 0) C = C * DSP1ROM[(0x31 + E)&1023] >> 15; + } + + Op14Zrr = Op14Zr + C; + + // Rotation Around X + Op14Xrr = Op14Xr + (Op14U * DSP1_Sin(Op14Yr) >> 15) + (Op14F * DSP1_Cos(Op14Yr) >> 15); + + // Rotation Around Y + DSP1_Normalizefloat(Op14U * DSP1_Cos(Op14Yr) + Op14F * DSP1_Sin(Op14Yr), &C, &E); + + E = ESec - E; + + DSP1_Normalize(DSP1_Sin(Op14Xr), &CSin, &E); + + CTan = CSec * CSin >> 15; + + DSP1_Normalize(-(C * CTan >> 15), &C, &E); + + if (E > 0) { + if (C > 0) C = 32767; else if (C < 0) C = -32767; + } else { + if (E < 0) C = C * DSP1ROM[(0x31 + E)&1023] >> 15; + } + + Op14Yrr = Op14Yr + C + Op14L; +} + +short Op0EH; +short Op0EV; +short Op0EX; +short Op0EY; + +void DSPOp0E() +{ + // screen Directions UP + RVPos = Op0EV; + RHPos = Op0EH; + GetRXYPos(); + Op0EX = (short)(RXRes); + Op0EY = (short)(RYRes); + + #ifdef DebugDSP1 + Log_Message("OP0E COORDINATE H:%d V:%d X:%d Y:%d",Op0EH,Op0EV,Op0EX,Op0EY); + #endif +} + +short Op0BX; +short Op0BY; +short Op0BZ; +short Op0BS; +short Op1BX; +short Op1BY; +short Op1BZ; +short Op1BS; +short Op2BX; +short Op2BY; +short Op2BZ; +short Op2BS; + +void DSPOp0B() +{ + Op0BS = (Op0BX * matrixA[0][0] + Op0BY * matrixA[0][1] + Op0BZ * matrixA[0][2]) >> 15; + + #ifdef DebugDSP1 + Log_Message("OP0B"); + #endif +} + +void DSPOp1B() +{ + Op1BS = (Op1BX * matrixB[0][0] + Op1BY * matrixB[0][1] + Op1BZ * matrixB[0][2]) >> 15; + + #ifdef DebugDSP1 + Log_Message("OP1B X: %d Y: %d Z: %d S: %d",Op1BX,Op1BY,Op1BZ,Op1BS); + Log_Message(" MX: %d MY: %d MZ: %d Scale: %d",(short)(matrixB[0][0]*100),(short)(matrixB[0][1]*100),(short)(matrixB[0][2]*100),(short)(sc2*100)); + #endif +} + +void DSPOp2B() +{ + Op2BS = (Op2BX * matrixC[0][0] + Op2BY * matrixC[0][1] + Op2BZ * matrixC[0][2]) >> 15; + + #ifdef DebugDSP1 + Log_Message("OP2B"); + #endif +} + +short Op08X,Op08Y,Op08Z,Op08Ll,Op08Lh; + +void DSPOp08() +{ + int Op08Size = (Op08X * Op08X + Op08Y * Op08Y + Op08Z * Op08Z) << 1; + Op08Ll = Op08Size & 0xffff; + Op08Lh = (Op08Size >> 16) & 0xffff; + + #ifdef DebugDSP1 + Log_Message("OP08 %d,%d,%d",Op08X,Op08Y,Op08Z); + Log_Message("OP08 ((Op08X^2)+(Op08Y^2)+(Op08X^2))=%x",Op08Size ); + #endif +} + +short Op18X,Op18Y,Op18Z,Op18R,Op18D; + +void DSPOp18() +{ + Op18D = (Op18X * Op18X + Op18Y * Op18Y + Op18Z * Op18Z - Op18R * Op18R) >> 15; + + #ifdef DebugDSP1 + Log_Message("Op18 X: %d Y: %d Z: %d R: %D DIFF %d",Op18X,Op18Y,Op38Z,Op18D); + #endif +} + +short Op38X,Op38Y,Op38Z,Op38R,Op38D; + +void DSPOp38() +{ + Op38D = (Op38X * Op38X + Op38Y * Op38Y + Op38Z * Op38Z - Op38R * Op38R) >> 15; + Op38D++; + + #ifdef DebugDSP1 + Log_Message("OP38 X: %d Y: %d Z: %d R: %D DIFF %d",Op38X,Op38Y,Op38Z,Op38D); + #endif +} + +short Op28X; +short Op28Y; +short Op28Z; +short Op28R; + +void DSPOp28() +{ + int Radius = Op28X * Op28X + Op28Y * Op28Y + Op28Z * Op28Z; + + if (Radius == 0) Op28R = 0; + else + { + short C, E; + DSP1_Normalizefloat(Radius, &C, &E); + if (E & 1) C = C * 0x4000 >> 15; + + short Pos = C * 0x0040 >> 15; + + short Node1 = DSP1ROM[(0x00d5 + Pos)&1023]; + short Node2 = DSP1ROM[(0x00d6 + Pos)&1023]; + + Op28R = ((Node2 - Node1) * (C & 0x1ff) >> 9) + Node1; + Op28R >>= (E >> 1); + } + + #ifdef DebugDSP1 + Log_Message("OP28 X:%d Y:%d Z:%d",Op28X,Op28Y,Op28Z); + Log_Message("OP28 Vector Length %d",Op28R); + #endif +} + +short Op1CX,Op1CY,Op1CZ; +short Op1CXBR,Op1CYBR,Op1CZBR,Op1CXAR,Op1CYAR,Op1CZAR; +short Op1CX1; +short Op1CY1; +short Op1CZ1; +short Op1CX2; +short Op1CY2; +short Op1CZ2; + +void DSPOp1C() +{ + + // Rotate Around Op1CZ1 + Op1CX1 = (Op1CYBR * DSP1_Sin(Op1CZ) >> 15) + (Op1CXBR * DSP1_Cos(Op1CZ) >> 15); + Op1CY1 = (Op1CYBR * DSP1_Cos(Op1CZ) >> 15) - (Op1CXBR * DSP1_Sin(Op1CZ) >> 15); + Op1CXBR = Op1CX1; Op1CYBR = Op1CY1; + + // Rotate Around Op1CY1 + Op1CZ1 = (Op1CXBR * DSP1_Sin(Op1CY) >> 15) + (Op1CZBR * DSP1_Cos(Op1CY) >> 15); + Op1CX1 = (Op1CXBR * DSP1_Cos(Op1CY) >> 15) - (Op1CZBR * DSP1_Sin(Op1CY) >> 15); + Op1CXAR = Op1CX1; Op1CZBR = Op1CZ1; + + // Rotate Around Op1CX1 + Op1CY1 = (Op1CZBR * DSP1_Sin(Op1CX) >> 15) + (Op1CYBR * DSP1_Cos(Op1CX) >> 15); + Op1CZ1 = (Op1CZBR * DSP1_Cos(Op1CX) >> 15) - (Op1CYBR * DSP1_Sin(Op1CX) >> 15); + Op1CYAR = Op1CY1; Op1CZAR = Op1CZ1; + + #ifdef DebugDSP1 + Log_Message("OP1C Apply Matrix CX:%d CY:%d CZ",Op1CXAR,Op1CYAR,Op1CZAR); + #endif +} + +unsigned short Op0FRamsize; +unsigned short Op0FPass; + +void DSPOp0F() +{ + Op0FPass = 0x0000; + + #ifdef DebugDSP1 + Log_Message("OP0F RAM Test Pass:%d", Op0FPass); + #endif +} + +short Op2FUnknown; +short Op2FSize; + +void DSPOp2F() +{ + Op2FSize=0x100; +} diff --git a/src/snes4iphone_src/dsp1emu_fixed.c b/src/snes4iphone_src/dsp1emu_fixed.c new file mode 100755 index 0000000..91204a4 --- /dev/null +++ b/src/snes4iphone_src/dsp1emu_fixed.c @@ -0,0 +1,1691 @@ +//Copyright (C) 1997-2001 ZSNES Team ( zsknight@zsnes.com / _demo_@zsnes.com ) +// +//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 (at your option) any later +//version. +// +//This program 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 this program; if not, write to the Free Software +//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +#ifndef __GP32__ +#include +#include +#endif +#include + +#ifndef __GP32__ +#include +#include +#endif +//#define DebugDSP1 + +#define funcSADDMULT1616(a,b,c,d) (((int64)a*(int64)b+(int64)c*(int64)d)>>16); + +#define SADDMULT1616(res,a,b,c,d) {\ + res=funcSADDMULT1616(a,b,c,d);\ + } +#define SMULT1616(res,a,b) {\ + res=funcSADDMULT1616(a,b,0,0);\ + } + +// uncomment some lines to test +//#define printinfo +//#define debug02 +//#define debug0A +//#define debug06 + +//#ifdef __GP32__ +//for the SMUL1616 & UMUL1616 +//#include "gp32_func.h" +//#endif + +#define __OPT__ +#define __OPT01__ +#define __OPT02__ +#define __OPT04__ +#define __OPT06__ +#define __OPT0C__ // this optimisation may break pilotwings +#define __OPT11__ +#define __OPT21__ +#define __OPT1C__ + +#ifdef DebugDSP1 + +FILE * LogFile = NULL; + +void Log_Message (char *Message, ...) +{ + char Msg[400]; + va_list ap; + + va_start(ap,Message); + vsprintf(Msg,Message,ap ); + va_end(ap); + + strcat(Msg,"\r\n\0"); + fwrite(Msg,strlen(Msg),1,LogFile); + fflush (LogFile); +} + +void Start_Log (void) +{ + char LogFileName[255]; +// [4/15/2001] char *p; + + strcpy(LogFileName,"dsp1emu.log\0"); + + LogFile = fopen(LogFileName,"wb"); +} + +void Stop_Log (void) +{ + if (LogFile) + { + fclose(LogFile); + LogFile = NULL; + } +} + +#endif + +const unsigned short DSP1ROM[1024] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, + 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, + 0x4000, 0x7fff, 0x4000, 0x2000, 0x1000, 0x0800, 0x0400, 0x0200, + 0x0100, 0x0080, 0x0040, 0x0020, 0x0001, 0x0008, 0x0004, 0x0002, + 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x8000, 0xffe5, 0x0100, 0x7fff, 0x7f02, 0x7e08, + 0x7d12, 0x7c1f, 0x7b30, 0x7a45, 0x795d, 0x7878, 0x7797, 0x76ba, + 0x75df, 0x7507, 0x7433, 0x7361, 0x7293, 0x71c7, 0x70fe, 0x7038, + 0x6f75, 0x6eb4, 0x6df6, 0x6d3a, 0x6c81, 0x6bca, 0x6b16, 0x6a64, + 0x69b4, 0x6907, 0x685b, 0x67b2, 0x670b, 0x6666, 0x65c4, 0x6523, + 0x6484, 0x63e7, 0x634c, 0x62b3, 0x621c, 0x6186, 0x60f2, 0x6060, + 0x5fd0, 0x5f41, 0x5eb5, 0x5e29, 0x5d9f, 0x5d17, 0x5c91, 0x5c0c, + 0x5b88, 0x5b06, 0x5a85, 0x5a06, 0x5988, 0x590b, 0x5890, 0x5816, + 0x579d, 0x5726, 0x56b0, 0x563b, 0x55c8, 0x5555, 0x54e4, 0x5474, + 0x5405, 0x5398, 0x532b, 0x52bf, 0x5255, 0x51ec, 0x5183, 0x511c, + 0x50b6, 0x5050, 0x4fec, 0x4f89, 0x4f26, 0x4ec5, 0x4e64, 0x4e05, + 0x4da6, 0x4d48, 0x4cec, 0x4c90, 0x4c34, 0x4bda, 0x4b81, 0x4b28, + 0x4ad0, 0x4a79, 0x4a23, 0x49cd, 0x4979, 0x4925, 0x48d1, 0x487f, + 0x482d, 0x47dc, 0x478c, 0x473c, 0x46ed, 0x469f, 0x4651, 0x4604, + 0x45b8, 0x456c, 0x4521, 0x44d7, 0x448d, 0x4444, 0x43fc, 0x43b4, + 0x436d, 0x4326, 0x42e0, 0x429a, 0x4255, 0x4211, 0x41cd, 0x4189, + 0x4146, 0x4104, 0x40c2, 0x4081, 0x4040, 0x3fff, 0x41f7, 0x43e1, + 0x45bd, 0x478d, 0x4951, 0x4b0b, 0x4cbb, 0x4e61, 0x4fff, 0x5194, + 0x5322, 0x54a9, 0x5628, 0x57a2, 0x5914, 0x5a81, 0x5be9, 0x5d4a, + 0x5ea7, 0x5fff, 0x6152, 0x62a0, 0x63ea, 0x6530, 0x6672, 0x67b0, + 0x68ea, 0x6a20, 0x6b53, 0x6c83, 0x6daf, 0x6ed9, 0x6fff, 0x7122, + 0x7242, 0x735f, 0x747a, 0x7592, 0x76a7, 0x77ba, 0x78cb, 0x79d9, + 0x7ae5, 0x7bee, 0x7cf5, 0x7dfa, 0x7efe, 0x7fff, 0x0000, 0x0324, + 0x0647, 0x096a, 0x0c8b, 0x0fab, 0x12c8, 0x15e2, 0x18f8, 0x1c0b, + 0x1f19, 0x2223, 0x2528, 0x2826, 0x2b1f, 0x2e11, 0x30fb, 0x33de, + 0x36ba, 0x398c, 0x3c56, 0x3f17, 0x41ce, 0x447a, 0x471c, 0x49b4, + 0x4c3f, 0x4ebf, 0x5133, 0x539b, 0x55f5, 0x5842, 0x5a82, 0x5cb4, + 0x5ed7, 0x60ec, 0x62f2, 0x64e8, 0x66cf, 0x68a6, 0x6a6d, 0x6c24, + 0x6dca, 0x6f5f, 0x70e2, 0x7255, 0x73b5, 0x7504, 0x7641, 0x776c, + 0x7884, 0x798a, 0x7a7d, 0x7b5d, 0x7c29, 0x7ce3, 0x7d8a, 0x7e1d, + 0x7e9d, 0x7f09, 0x7f62, 0x7fa7, 0x7fd8, 0x7ff6, 0x7fff, 0x7ff6, + 0x7fd8, 0x7fa7, 0x7f62, 0x7f09, 0x7e9d, 0x7e1d, 0x7d8a, 0x7ce3, + 0x7c29, 0x7b5d, 0x7a7d, 0x798a, 0x7884, 0x776c, 0x7641, 0x7504, + 0x73b5, 0x7255, 0x70e2, 0x6f5f, 0x6dca, 0x6c24, 0x6a6d, 0x68a6, + 0x66cf, 0x64e8, 0x62f2, 0x60ec, 0x5ed7, 0x5cb4, 0x5a82, 0x5842, + 0x55f5, 0x539b, 0x5133, 0x4ebf, 0x4c3f, 0x49b4, 0x471c, 0x447a, + 0x41ce, 0x3f17, 0x3c56, 0x398c, 0x36ba, 0x33de, 0x30fb, 0x2e11, + 0x2b1f, 0x2826, 0x2528, 0x2223, 0x1f19, 0x1c0b, 0x18f8, 0x15e2, + 0x12c8, 0x0fab, 0x0c8b, 0x096a, 0x0647, 0x0324, 0x7fff, 0x7ff6, + 0x7fd8, 0x7fa7, 0x7f62, 0x7f09, 0x7e9d, 0x7e1d, 0x7d8a, 0x7ce3, + 0x7c29, 0x7b5d, 0x7a7d, 0x798a, 0x7884, 0x776c, 0x7641, 0x7504, + 0x73b5, 0x7255, 0x70e2, 0x6f5f, 0x6dca, 0x6c24, 0x6a6d, 0x68a6, + 0x66cf, 0x64e8, 0x62f2, 0x60ec, 0x5ed7, 0x5cb4, 0x5a82, 0x5842, + 0x55f5, 0x539b, 0x5133, 0x4ebf, 0x4c3f, 0x49b4, 0x471c, 0x447a, + 0x41ce, 0x3f17, 0x3c56, 0x398c, 0x36ba, 0x33de, 0x30fb, 0x2e11, + 0x2b1f, 0x2826, 0x2528, 0x2223, 0x1f19, 0x1c0b, 0x18f8, 0x15e2, + 0x12c8, 0x0fab, 0x0c8b, 0x096a, 0x0647, 0x0324, 0x0000, 0xfcdc, + 0xf9b9, 0xf696, 0xf375, 0xf055, 0xed38, 0xea1e, 0xe708, 0xe3f5, + 0xe0e7, 0xdddd, 0xdad8, 0xd7da, 0xd4e1, 0xd1ef, 0xcf05, 0xcc22, + 0xc946, 0xc674, 0xc3aa, 0xc0e9, 0xbe32, 0xbb86, 0xb8e4, 0xb64c, + 0xb3c1, 0xb141, 0xaecd, 0xac65, 0xaa0b, 0xa7be, 0xa57e, 0xa34c, + 0xa129, 0x9f14, 0x9d0e, 0x9b18, 0x9931, 0x975a, 0x9593, 0x93dc, + 0x9236, 0x90a1, 0x8f1e, 0x8dab, 0x8c4b, 0x8afc, 0x89bf, 0x8894, + 0x877c, 0x8676, 0x8583, 0x84a3, 0x83d7, 0x831d, 0x8276, 0x81e3, + 0x8163, 0x80f7, 0x809e, 0x8059, 0x8028, 0x800a, 0x6488, 0x0080, + 0x03ff, 0x0116, 0x0002, 0x0080, 0x4000, 0x3fd7, 0x3faf, 0x3f86, + 0x3f5d, 0x3f34, 0x3f0c, 0x3ee3, 0x3eba, 0x3e91, 0x3e68, 0x3e40, + 0x3e17, 0x3dee, 0x3dc5, 0x3d9c, 0x3d74, 0x3d4b, 0x3d22, 0x3cf9, + 0x3cd0, 0x3ca7, 0x3c7f, 0x3c56, 0x3c2d, 0x3c04, 0x3bdb, 0x3bb2, + 0x3b89, 0x3b60, 0x3b37, 0x3b0e, 0x3ae5, 0x3abc, 0x3a93, 0x3a69, + 0x3a40, 0x3a17, 0x39ee, 0x39c5, 0x399c, 0x3972, 0x3949, 0x3920, + 0x38f6, 0x38cd, 0x38a4, 0x387a, 0x3851, 0x3827, 0x37fe, 0x37d4, + 0x37aa, 0x3781, 0x3757, 0x372d, 0x3704, 0x36da, 0x36b0, 0x3686, + 0x365c, 0x3632, 0x3609, 0x35df, 0x35b4, 0x358a, 0x3560, 0x3536, + 0x350c, 0x34e1, 0x34b7, 0x348d, 0x3462, 0x3438, 0x340d, 0x33e3, + 0x33b8, 0x338d, 0x3363, 0x3338, 0x330d, 0x32e2, 0x32b7, 0x328c, + 0x3261, 0x3236, 0x320b, 0x31df, 0x31b4, 0x3188, 0x315d, 0x3131, + 0x3106, 0x30da, 0x30ae, 0x3083, 0x3057, 0x302b, 0x2fff, 0x2fd2, + 0x2fa6, 0x2f7a, 0x2f4d, 0x2f21, 0x2ef4, 0x2ec8, 0x2e9b, 0x2e6e, + 0x2e41, 0x2e14, 0x2de7, 0x2dba, 0x2d8d, 0x2d60, 0x2d32, 0x2d05, + 0x2cd7, 0x2ca9, 0x2c7b, 0x2c4d, 0x2c1f, 0x2bf1, 0x2bc3, 0x2b94, + 0x2b66, 0x2b37, 0x2b09, 0x2ada, 0x2aab, 0x2a7c, 0x2a4c, 0x2a1d, + 0x29ed, 0x29be, 0x298e, 0x295e, 0x292e, 0x28fe, 0x28ce, 0x289d, + 0x286d, 0x283c, 0x280b, 0x27da, 0x27a9, 0x2777, 0x2746, 0x2714, + 0x26e2, 0x26b0, 0x267e, 0x264c, 0x2619, 0x25e7, 0x25b4, 0x2581, + 0x254d, 0x251a, 0x24e6, 0x24b2, 0x247e, 0x244a, 0x2415, 0x23e1, + 0x23ac, 0x2376, 0x2341, 0x230b, 0x22d6, 0x229f, 0x2269, 0x2232, + 0x21fc, 0x21c4, 0x218d, 0x2155, 0x211d, 0x20e5, 0x20ad, 0x2074, + 0x203b, 0x2001, 0x1fc7, 0x1f8d, 0x1f53, 0x1f18, 0x1edd, 0x1ea1, + 0x1e66, 0x1e29, 0x1ded, 0x1db0, 0x1d72, 0x1d35, 0x1cf6, 0x1cb8, + 0x1c79, 0x1c39, 0x1bf9, 0x1bb8, 0x1b77, 0x1b36, 0x1af4, 0x1ab1, + 0x1a6e, 0x1a2a, 0x19e6, 0x19a1, 0x195c, 0x1915, 0x18ce, 0x1887, + 0x183f, 0x17f5, 0x17ac, 0x1761, 0x1715, 0x16c9, 0x167c, 0x162e, + 0x15df, 0x158e, 0x153d, 0x14eb, 0x1497, 0x1442, 0x13ec, 0x1395, + 0x133c, 0x12e2, 0x1286, 0x1228, 0x11c9, 0x1167, 0x1104, 0x109e, + 0x1036, 0x0fcc, 0x0f5f, 0x0eef, 0x0e7b, 0x0e04, 0x0d89, 0x0d0a, + 0x0c86, 0x0bfd, 0x0b6d, 0x0ad6, 0x0a36, 0x098d, 0x08d7, 0x0811, + 0x0736, 0x063e, 0x0519, 0x039a, 0x0000, 0x7fff, 0x0100, 0x0080, + 0x021d, 0x00c8, 0x00ce, 0x0048, 0x0a26, 0x277a, 0x00ce, 0x6488, + 0x14ac, 0x0001, 0x00f9, 0x00fc, 0x00ff, 0x00fc, 0x00f9, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, + 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff}; + + + +/***************************************************************************\ +* Math tables * +\***************************************************************************/ + +#define INCR 2048 //<<11 +#define INCR_SHIFT 5 //16-11 coz (>>INCR_SHIFT) = (*INCR/65536) +#define _FIX_SHIFT_ 16 +//double *CosTable2; +int32 CosTable2[INCR]; +//double *SinTable2; +int32 SinTable2[INCR]; + +//#define Angle(x) (((x)/(65536/INCR)) & (INCR-1)) +#define Angle(x) (((int32)(x)>>INCR_SHIFT) & (INCR-1) ) +//#define Cos(x) ((double) CosTable2[x]) +#define Cos(x) ((int32) CosTable2[x]) +//#define Sin(x) ((double) SinTable2[x]) +#define Sin(x) ((int32) SinTable2[x]) +//#define PI 3.14159265358979323846264338327 +#define PI_float 3.14159265358979323846264338327f +#define PI 205887 //3.14159265358979323846264338327 << _FIX_SHIFT_ + +//double Atan(double x) +int32 Atan(int32 x) +{ +// if ((x>=1) || (x<=1)) //stupid ? + if ((x>=(1<<_FIX_SHIFT_)) || (x<=(1<<_FIX_SHIFT_))) //stupid ? + //return (x/(1+0.28*x*x)); + {int32 t;SMULT1616(t,x,x) + return ( ( (int64)x<<_FIX_SHIFT_ ) /(1+0.28f*t) );} + else + //return ( PI/2 - Atan(1/x)); + return ( PI/2 - Atan( ((int64)1<<(_FIX_SHIFT_*2))/x) ); +} + +/***************************************************************************\ +* DSP1 code * +\***************************************************************************/ + + +void InitDSP(void) +{ +#ifdef __OPT__ + unsigned int i; + //CosTable2 = (double *) malloc(INCR*sizeof(double)); + //CosTable2 = (int32 *) malloc(INCR*sizeof(int32)); + //SinTable2 = (double *) malloc(INCR*sizeof(double)); + //SinTable2 = (int32 *) malloc(INCR*sizeof(int32)); + for (i=0; i>15; + #ifdef DebugDSP1 + Log_Message("OP00 MULT %d*%d/32768=%d",Op00Multiplicand,Op00Multiplier,Op00Result); + #endif +} + +short Op20Multiplicand; +short Op20Multiplier; +short Op20Result; + +void DSPOp20() +{ + Op20Result= Op20Multiplicand * Op20Multiplier >> 15; + Op20Result++; + + #ifdef DebugDSP1 + Log_Message("OP20 MULT %d*%d/32768=%d",Op20Multiplicand,Op20Multiplier,Op20Result); + #endif +} + + +signed short Op10Coefficient; +signed short Op10Exponent; +signed short Op10CoefficientR; +signed short Op10ExponentR; +//float Op10Temp; +int32 Op10Temp; + +void DSPOp10() +{ + Op10ExponentR=-Op10Exponent; + //Op10Temp = Op10Coefficient / 32768.0; + Op10Temp = (Op10Coefficient<<(_FIX_SHIFT_-15)); + if (Op10Temp == 0) { + Op10CoefficientR = 0; + } else + //Op10Temp = 1/Op10Temp; + Op10Temp = ((int64)(1)<<(_FIX_SHIFT_*2)) /Op10Temp ; + if (Op10Temp > 0) + //while (Op10Temp>=1.0) { + while (Op10Temp>=(1<<_FIX_SHIFT_)) { + //Op10Temp=Op10Temp/2.0; + Op10Temp=Op10Temp>>1; + Op10ExponentR++; + } + else + //while (Op10Temp<-1.0) { + while (Op10Temp<-(1<<_FIX_SHIFT_)) { + //Op10Temp=Op10Temp/2.0; + Op10Temp=Op10Temp>>1; + Op10ExponentR++; + } + //Op10CoefficientR = Op10Temp*32768; + Op10CoefficientR = Op10Temp>>(_FIX_SHIFT_-15); + #ifdef DebugDSP1 + Log_Message("OP10 INV %d*2^%d = %d*2^%d", Op10Coefficient, Op10Exponent, Op10CoefficientR, Op10ExponentR); + #endif +} + + +short Op04Angle; +unsigned short Op04Radius; +short Op04Sin; +short Op04Cos; + +#ifdef __OPT04__ + +void DSPOp04() +{ + int angle; + + angle = Angle(Op04Angle); + + //Op04Sin = Sin(angle) * Op04Radius; + //Op04Cos = Cos(angle) * Op04Radius; + SMULT1616(Op04Sin,Sin(angle),Op04Radius) + SMULT1616(Op04Cos,Cos(angle),Op04Radius) + + #ifdef DebugDSP1 + Log_Message("OP04 Angle:%d Radius:%d",(Op04Angle/256)&255,Op04Radius); + Log_Message("OP04 SIN:%d COS:%d",Op04Sin,Op04Cos); + #endif +} +#else + +void DSPOp04() +{ + double angle; + + angle = Op04Angle*2*PI/65536.0; + + Op04Sin = sin(angle) * Op04Radius; + Op04Cos = cos(angle) * Op04Radius; + + #ifdef DebugDSP1 + Log_Message("OP04 Angle:%d Radius:%d",(Op04Angle/256)&255,Op04Radius); + Log_Message("OP04 SIN:%d COS:%d",Op04Sin,Op04Cos); + #endif +} +#endif + +unsigned short Op0CA; +short Op0CX1; +short Op0CY1; +short Op0CX2; +short Op0CY2; + +#ifdef __OPT0C__ +void DSPOp0C() +{ + //Op0CX2=Op0CX1*Cos(Angle(Op0CA))+Op0CY1*Sin(Angle(Op0CA)); + //Op0CY2=Op0CX1*-Sin(Angle(Op0CA))+Op0CY1*Cos(Angle(Op0CA)); + Op0CX2=((int32)Op0CX1*Cos(Angle(Op0CA))+(int32)Op0CY1*Sin(Angle(Op0CA)))>>_FIX_SHIFT_; + Op0CY2=((int32)Op0CX1*-Sin(Angle(Op0CA))+(int32)Op0CY1*Cos(Angle(Op0CA)))>>_FIX_SHIFT_; + + #ifdef DebugDSP1 + Log_Message("OP0C Angle:%d X:%d Y:%d CX:%d CY:%d",(Op0CA/256)&255,Op0CX1,Op0CY1,Op0CX2,Op0CY2); + #endif +} +#else +void DSPOp0C() +{ + + Op0CX2=(Op0CX1*cos(Op0CA*2*PI/65536.0)+Op0CY1*sin(Op0CA*2*PI/65536.0)); + Op0CY2=(Op0CX1*-sin(Op0CA*2*PI/65536.0)+Op0CY1*cos(Op0CA*2*PI/65536.0)); + #ifdef DebugDSP1 + Log_Message("OP0C Angle:%d X:%d Y:%d CX:%d CY:%d",(Op0CA/256)&255,Op0CX1,Op0CY1,Op0CX2,Op0CY2); + #endif +} + +#endif + +short Op02FX; +short Op02FY; +short Op02FZ; +short Op02LFE; +short Op02LES; +unsigned short Op02AAS; +unsigned short Op02AZS; +unsigned short Op02VOF; +unsigned short Op02VVA; + +short Op02CX; +short Op02CY; +/*double Op02CXF; +double Op02CYF; +double ViewerX0; +double ViewerY0; +double ViewerZ0; +double ViewerX1; +double ViewerY1; +double ViewerZ1; +double ViewerX; +double ViewerY; +double ViewerZ;*/ +int32 Op02CXF; +int32 Op02CYF; +int32 ViewerX0; +int32 ViewerY0; +int32 ViewerZ0; +int32 ViewerX1; +int32 ViewerY1; +int32 ViewerZ1; +int32 ViewerX; +int32 ViewerY; +int32 ViewerZ; +int ViewerAX; +int ViewerAY; +int ViewerAZ; +/*double NumberOfSlope; +double ScreenX; +double ScreenY; +double ScreenZ; +double TopLeftScreenX; +double TopLeftScreenY; +double TopLeftScreenZ; +double BottomRightScreenX; +double BottomRightScreenY; +double BottomRightScreenZ; +double Ready; +double RasterLX; +double RasterLY; +double RasterLZ; +double ScreenLX1; +double ScreenLY1; +double ScreenLZ1;*/ +int32 NumberOfSlope; +int32 ScreenX; +int32 ScreenY; +int32 ScreenZ; +int32 TopLeftScreenX; +int32 TopLeftScreenY; +int32 TopLeftScreenZ; +int32 BottomRightScreenX; +int32 BottomRightScreenY; +int32 BottomRightScreenZ; +int32 Ready; +int32 RasterLX; +int32 RasterLY; +int32 RasterLZ; +int32 ScreenLX1; +int32 ScreenLY1; +int32 ScreenLZ1; +int ReversedLES; +short Op02LESb; +/*double NAzsB,NAasB; +double ViewerXc; +double ViewerYc; +double ViewerZc; +double CenterX,CenterY;*/ +int32 NAzsB,NAasB; +int32 ViewerXc; +int32 ViewerYc; +int32 ViewerZc; +int32 CenterX,CenterY; +short Op02CYSup,Op02CXSup; +//double CXdistance; +int32 CXdistance; + +#define VofAngle 0x3880 + +short TValDebug,TValDebug2; +short ScrDispl; + + +#ifdef __OPT02__ +void DSPOp02() +{ + ViewerZ1=-Cos(Angle(Op02AZS)); +/* ViewerX1=Sin(Angle(Op02AZS))*Sin(Angle(Op02AAS)); + ViewerY1=Sin(Angle(Op02AZS))*Cos(Angle(Op02AAS));*/ + SMULT1616(ViewerX1,Sin(Angle(Op02AZS)),Sin(Angle(Op02AAS))) + SMULT1616(ViewerY1,Sin(Angle(Op02AZS)),Cos(Angle(Op02AAS))) + + + #ifdef debug02 + printf("\nViewerX1 : %f ViewerY1 : %f ViewerZ1 : %f\n",ViewerX1,ViewerY1, + ViewerZ1); + getch(); + #endif + /*ViewerX=Op02FX-ViewerX1*Op02LFE; + ViewerY=Op02FY-ViewerY1*Op02LFE; + ViewerZ=Op02FZ-ViewerZ1*Op02LFE; + + ScreenX=Op02FX+ViewerX1*(Op02LES-Op02LFE); + ScreenY=Op02FY+ViewerY1*(Op02LES-Op02LFE); + ScreenZ=Op02FZ+ViewerZ1*(Op02LES-Op02LFE);*/ + ViewerX=((int32)Op02FX<<_FIX_SHIFT_)-ViewerX1*(int32)Op02LFE; + ViewerY=((int32)Op02FY<<_FIX_SHIFT_)-ViewerY1*(int32)Op02LFE; + ViewerZ=((int32)Op02FZ<<_FIX_SHIFT_)-ViewerZ1*(int32)Op02LFE; + + ScreenX=((int32)Op02FX<<_FIX_SHIFT_)+ViewerX1*(int32)(Op02LES-Op02LFE); + ScreenY=((int32)Op02FY<<_FIX_SHIFT_)+ViewerY1*(int32)(Op02LES-Op02LFE); + ScreenZ=((int32)Op02FZ<<_FIX_SHIFT_)+ViewerZ1*(int32)(Op02LES-Op02LFE); + + #ifdef debug02 + printf("ViewerX : %f ViewerY : %f ViewerZ : %f\n",ViewerX,ViewerY,ViewerZ); + printf("Op02FX : %d Op02FY : %d Op02FZ : %d\n",Op02FX,Op02FY,Op02FZ); + printf("ScreenX : %f ScreenY : %f ScreenZ : %f\n",ScreenX,ScreenY,ScreenZ); + getch(); + #endif + if (ViewerZ1==0)ViewerZ1++; + NumberOfSlope=((int64)ViewerZ<<_FIX_SHIFT_)/(-ViewerZ1); + + //Op02CX=(short)(Op02CXF=ViewerX+ViewerX1*NumberOfSlope); + //Op02CY=(short)(Op02CYF=ViewerY+ViewerY1*NumberOfSlope); + int32 t; + SMULT1616(t,ViewerX1,NumberOfSlope) + Op02CX=(short)(Op02CXF=(ViewerX+t)>>_FIX_SHIFT_); + SMULT1616(t,ViewerY1,NumberOfSlope) + Op02CY=(short)(Op02CYF=(ViewerY+t)>>_FIX_SHIFT_); + + Op02VOF=0x0000; + ReversedLES=0; + Op02LESb=Op02LES; + //if ((Op02LES>=VofAngle+16384.0) && (Op02LES=VofAngle+16384) && (Op02LES=VofAngle) && (Op02LESb<=VofAngle+0x4000)) { + Op02VOF= (short)(Op02LESb * tan((Op02AZS-0x4000-VofAngle)*6.2832/65536.0)); + Op02VVA-=Op02VOF; + } + if (ReversedLES){ + Op02VOF=-Op02VOF; + } + + //NAzsB = (Op02AZS-0x4000)*6.2832/65536.0; + NAzsB = (int32)(Op02AZS-0x4000); + //NAasB = Op02AAS*6.2832/65536.0; + NAasB = (int32)(Op02AAS); + + //if (tan(NAzsB)==0) NAzsB=0.1; + if (Sin(Angle(NAzsB))==0) NAzsB=1043; //0.1*65536/(2*pi) + + ScrDispl=0; + //if (NAzsB>-0.15) {NAzsB=-0.15;ScrDispl=Op02VVA-0xFFDA;} + if (NAzsB>-1565 /*0.15*65536/2/pi*/) {NAzsB=-1565;ScrDispl=Op02VVA-0xFFDA;} + + //CXdistance=1/tan(NAzsB); + CXdistance=((int64)Cos(Angle(NAzsB))<<_FIX_SHIFT_)/Sin(Angle((NAzsB))); + + + ViewerXc=(int32)Op02FX<<_FIX_SHIFT_; + ViewerYc=(int32)Op02FY<<_FIX_SHIFT_; + ViewerZc=(int32)Op02FZ<<_FIX_SHIFT_; + + //CenterX = (-sin(NAasB)*ViewerZc*CXdistance)+ViewerXc; + //CenterY = (cos(NAasB)*ViewerZc*CXdistance)+ViewerYc; + //Op02CX = (short)CenterX; + //Op02CY = (short)CenterY; + SMULT1616(t,-Sin(Angle(NAasB)),ViewerZc) + SMULT1616(t,t,CXdistance) + CenterX = t+ViewerXc; + SMULT1616(t,Cos(Angle(NAasB)),ViewerZc) + SMULT1616(t,t,CXdistance) + CenterY = t+ViewerYc; + Op02CX=CenterX>>_FIX_SHIFT_; + Op02CY=CenterY>>_FIX_SHIFT_; + + ViewerXc=ViewerX;//-Op02FX); + ViewerYc=ViewerY;//-Op02FY); + ViewerZc=ViewerZ;//-Op02FZ); + + //CenterX = (-sin(NAasB)*ViewerZc*CXdistance)+ViewerXc; + SMULT1616(t,-Sin(Angle(NAasB)),ViewerZc) + SMULT1616(t,t,CXdistance) + CenterX = t+ViewerXc; + + /*if (CenterX<-32768) CenterX = -32768; if (CenterX>32767) CenterX=32767; + CenterY = (cos(NAasB)*ViewerZc*CXdistance)+ViewerYc; + if (CenterY<-32768) CenterY = -32768; if (CenterY>32767) CenterY=32767;*/ + + //BUG en puissance : overflow + if (CenterX<(-32768<<_FIX_SHIFT_)) CenterX = (-32768<<_FIX_SHIFT_); if (CenterX>(32767<<_FIX_SHIFT_)) CenterX=(32767<<_FIX_SHIFT_); + SMULT1616(t,Cos(Angle(NAasB)),ViewerZc) + SMULT1616(t,t,CXdistance) + CenterY = t+ViewerYc; + if (CenterY<(-32768<<_FIX_SHIFT_)) CenterY = (-32768<<_FIX_SHIFT_); if (CenterY>(32767<<_FIX_SHIFT_)) CenterY=(32767<<_FIX_SHIFT_); + +// TValDebug = (NAzsB*65536/6.28); + // TValDebug2 = ScrDispl; + +// if (Op02CY < 0) {Op02CYSup = Op02CY/256; Op02CY = 0;} +// if (Op02CX < 0) {Op02CXSup = Op02CX/256; Op02CX = 0;} + +// [4/15/2001] (ViewerX+ViewerX1*NumberOfSlope); +// [4/15/2001] (ViewerY+ViewerY1*NumberOfSlope); + +// if(Op02LFE==0x2200)Op02VVA=0xFECD; +// else Op02VVA=0xFFB2; + + + #ifdef DebugDSP1 + Log_Message("OP02 FX:%d FY:%d FZ:%d LFE:%d LES:%d",Op02FX,Op02FY,Op02FZ,Op02LFE,Op02LES); + Log_Message(" AAS:%d AZS:%d VOF:%d VVA:%d",Op02AAS,Op02AZS,Op02VOF,Op02VVA); + Log_Message(" VX:%d VY:%d VZ:%d",(short)ViewerX,(short)ViewerY,(short)ViewerZ); + #endif + +} +#else + +void DSPOp02() +{ + ViewerZ1=-cos(Op02AZS*6.2832/65536.0); + ViewerX1=sin(Op02AZS*6.2832/65536.0)*sin(Op02AAS*6.2832/65536.0); + ViewerY1=sin(Op02AZS*6.2832/65536.0)*cos(-Op02AAS*6.2832/65536.0); + + #ifdef debug02 + printf("\nViewerX1 : %f ViewerY1 : %f ViewerZ1 : %f\n",ViewerX1,ViewerY1, + ViewerZ1); + getch(); + #endif + ViewerX=Op02FX-ViewerX1*Op02LFE; + ViewerY=Op02FY-ViewerY1*Op02LFE; + ViewerZ=Op02FZ-ViewerZ1*Op02LFE; + + ScreenX=Op02FX+ViewerX1*(Op02LES-Op02LFE); + ScreenY=Op02FY+ViewerY1*(Op02LES-Op02LFE); + ScreenZ=Op02FZ+ViewerZ1*(Op02LES-Op02LFE); + + #ifdef debug02 + printf("ViewerX : %f ViewerY : %f ViewerZ : %f\n",ViewerX,ViewerY,ViewerZ); + printf("Op02FX : %d Op02FY : %d Op02FZ : %d\n",Op02FX,Op02FY,Op02FZ); + printf("ScreenX : %f ScreenY : %f ScreenZ : %f\n",ScreenX,ScreenY,ScreenZ); + getch(); + #endif + if (ViewerZ1==0)ViewerZ1++; + NumberOfSlope=ViewerZ/-ViewerZ1; + + Op02CX=(short)(Op02CXF=ViewerX+ViewerX1*NumberOfSlope); + Op02CY=(short)(Op02CYF=ViewerY+ViewerY1*NumberOfSlope); + + ViewerXc=ViewerX;//-Op02FX); + ViewerYc=ViewerY;//-Op02FY); + ViewerZc=ViewerZ;//-Op02FZ); + + Op02VOF=0x0000; + ReversedLES=0; + Op02LESb=Op02LES; + if ((Op02LES>=VofAngle+16384.0) && (Op02LES=VofAngle) && (Op02LESb<=VofAngle+0x4000)) { + Op02VOF= (short)(Op02LESb * tan((Op02AZS-0x4000-VofAngle)*6.2832/65536.0)); + Op02VVA-=Op02VOF; + } + if (ReversedLES){ + Op02VOF=-Op02VOF; + } + + NAzsB = (Op02AZS-0x4000)*6.2832/65536.0; + NAasB = Op02AAS*6.2832/65536.0; + + if (tan(NAzsB)==0) NAzsB=0.1; + + ScrDispl=0; + if (NAzsB>-0.15) {NAzsB=-0.15;ScrDispl=Op02VVA-0xFFDA;} + + CXdistance=1/tan(NAzsB); + + CenterX = (-sin(NAasB)*ViewerZc*CXdistance)+ViewerXc; + if (CenterX<-32768) CenterX = -32768; if (CenterX>32767) CenterX=32767; + Op02CX = (short)CenterX; + CenterY = (cos(NAasB)*ViewerZc*CXdistance)+ViewerYc; + if (CenterY<-32768) CenterY = -32768; if (CenterY>32767) CenterY=32767; + Op02CY = (short)CenterY; + +// TValDebug = (NAzsB*65536/6.28); + // TValDebug2 = ScrDispl; + +// if (Op02CY < 0) {Op02CYSup = Op02CY/256; Op02CY = 0;} +// if (Op02CX < 0) {Op02CXSup = Op02CX/256; Op02CX = 0;} + +// [4/15/2001] (ViewerX+ViewerX1*NumberOfSlope); +// [4/15/2001] (ViewerY+ViewerY1*NumberOfSlope); + +// if(Op02LFE==0x2200)Op02VVA=0xFECD; +// else Op02VVA=0xFFB2; + + + #ifdef DebugDSP1 + Log_Message("OP02 FX:%d FY:%d FZ:%d LFE:%d LES:%d",Op02FX,Op02FY,Op02FZ,Op02LFE,Op02LES); + Log_Message(" AAS:%d AZS:%d VOF:%d VVA:%d",Op02AAS,Op02AZS,Op02VOF,Op02VVA); + Log_Message(" VX:%d VY:%d VZ:%d",(short)ViewerX,(short)ViewerY,(short)ViewerZ); + #endif + +} +#endif + +short Op0AVS; +short Op0AA; +short Op0AB; +short Op0AC; +short Op0AD; + +/*double RasterRX; +double RasterRY; +double RasterRZ; +double RasterLSlopeX; +double RasterLSlopeY; +double RasterLSlopeZ; +double RasterRSlopeX; +double RasterRSlopeY; +double RasterRSlopeZ; +double GroundLX; +double GroundLY; +double GroundRX; +double GroundRY; +double Distance; + +double NAzs,NAas; +double RVPos,RHPos,RXRes,RYRes;*/ + +int32 RasterRX; +int32 RasterRY; +int32 RasterRZ; +int32 RasterLSlopeX; +int32 RasterLSlopeY; +int32 RasterLSlopeZ; +int32 RasterRSlopeX; +int32 RasterRSlopeY; +int32 RasterRSlopeZ; +int32 GroundLX; +int32 GroundLY; +int32 GroundRX; +int32 GroundRY; +int32 Distance; + +int32 NAzs,NAas; +int32 RVPos,RHPos,RXRes,RYRes; + + + +void GetRXYPos(){ + int32 scalar; + + if (Op02LES==0) return; + + + NAzs = NAzsB - Atan((RVPos) / (int32)Op02LES); + NAas = NAasB;// + Atan(RHPos) / (double)Op02LES); + + /* if (cos(NAzs)==0) NAzs+=0.001; + if (tan(NAzs)==0) NAzs+=0.001;*/ + if (Cos(Angle(NAzs))==0) NAzs+=10; + if (Sin(Angle(NAzs))==0) NAzs+=10; + + /*RXRes = (-sin(NAas)*ViewerZc/(tan(NAzs))+ViewerXc); + RYRes = (cos(NAas)*ViewerZc/(tan(NAzs))+ViewerYc); + scalar = ((ViewerZc/sin(NAzs))/(double)Op02LES); + RXRes += scalar*-sin(NAas+PI_float/2)*RHPos; + RYRes += scalar*cos(NAas+PI_float/2)*RHPos;*/ + RXRes = ((int64)-Sin(Angle(NAas))*(int64)ViewerZc/ ((int64)(Sin(Angle(NAzs))<<_FIX_SHIFT_)/(int64)Cos(Angle(NAzs)) )+ViewerXc); + RYRes = ((int64)Cos(Angle(NAas))*(int64)ViewerZc/ ((int64)(Sin(Angle(NAzs))<<_FIX_SHIFT_)/(int64)Cos(Angle(NAzs)) )+ViewerYc); + scalar = ((ViewerZc/Sin(Angle(NAzs)))/(int32)Op02LES); + int32 t; + SMULT1616(t,-Sin(Angle(NAas+PI/2)),RHPos) + RXRes += scalar*t; + SMULT1616(t,Cos(Angle(NAas+PI/2)),RHPos) + RYRes += scalar*t; +} + +void DSPOp0A() +{ + //double x2,y2,x3,y3,x4,y4,m,ypos; + int32 x2,y2,x3,y3,x4,y4,m,ypos; + + + if(Op0AVS==0) {Op0AVS++; return;} + ypos=(int32)(Op0AVS-ScrDispl)<<_FIX_SHIFT_; + // CenterX,CenterX = Center (x1,y1) + // Get (0,Vs) coords (x2,y2) + RVPos = ypos; RHPos = 0; + GetRXYPos(); x2 = RXRes; y2 = RYRes; + // Get (-128,Vs) coords (x3,y3) + RVPos = ypos; RHPos = -128<<_FIX_SHIFT_; + GetRXYPos(); x3 = RXRes; y3 = RYRes; + // Get (127,Vs) coords (x4,y4) + RVPos = ypos; RHPos = 127<<_FIX_SHIFT_; + GetRXYPos(); x4 = RXRes; y4 = RYRes; + + // A = (x4-x3)/256 + //m = (x4-x3)/256*256; if (m>32767) m=32767; if (m<-32768) m=-32768; + m = (x4-x3)>>16; if (m>32767) m=32767; if (m<-32768) m=-32768; + Op0AA = (short)(m); + // C = (y4-y3)/256 + //m = (y4-y3)/256*256; if (m>32767) m=32767; if (m<-32768) m=-32768; + m = (y4-y3)>>16; if (m>32767) m=32767; if (m<-32768) m=-32768; + Op0AC = (short)(m); + if (ypos==0){ + Op0AB = 0; + Op0AD = 0; + } + else { + // B = (x2-x1)/Vs + m = (x2-CenterX)/ypos*256; if (m>32767) m=32767; if (m<-32768) m=-32768; + Op0AB = (short)(m); + // D = (y2-y1)/Vs + m = (y2-CenterY)/ypos*256; if (m>32767) m=32767; if (m<-32768) m=-32768; + Op0AD = (short)(m); + } + + Op0AVS+=1; +} + +short Op06X; +short Op06Y; +short Op06Z; +short Op06H; +short Op06V; +unsigned short Op06S; + +/*double ObjPX; +double ObjPY; +double ObjPZ; +double ObjPX1; +double ObjPY1; +double ObjPZ1; +double ObjPX2; +double ObjPY2; +double ObjPZ2; +double DivideOp06;*/ +int32 ObjPX; +int32 ObjPY; +int32 ObjPZ; +int32 ObjPX1; +int32 ObjPY1; +int32 ObjPZ1; +int32 ObjPX2; +int32 ObjPY2; +int32 ObjPZ2; +int32 DivideOp06; +int Temp; +int tanval2; + +#ifdef __OPT06__ +void DSPOp06() +{ + + ObjPX=Op06X-Op02FX; + ObjPY=Op06Y-Op02FY; + ObjPZ=Op06Z-Op02FZ; + + + + // rotate around Z + tanval2 = Angle(-Op02AAS+32768); +// tanval2 = (-Op02AAS+32768)/(65536/INCR); + //ObjPX1=(ObjPX*Cos(tanval2)+ObjPY*-Sin(tanval2)); + SADDMULT1616(ObjPX1,ObjPX,Cos(tanval2),ObjPY,-Sin(tanval2)) + //ObjPY1=(ObjPX*Sin(tanval2)+ObjPY*Cos(tanval2)); + SADDMULT1616(ObjPY1,ObjPX,Sin(tanval2),ObjPY,Cos(tanval2)) + ObjPZ1=ObjPZ; + + + // rotate around X +// tanval2 = (-Op02AZS/(65536/INCR)) & 1023; + tanval2 = Angle(-Op02AZS); +// tanval2 = (-Op02AZS)/256; + ObjPX2=ObjPX1; + //ObjPY2=(ObjPY1*Cos(tanval2)+ObjPZ1*-Sin(tanval2)); + SADDMULT1616(ObjPY2,ObjPY1,Cos(tanval2),ObjPZ1,-Sin(tanval2)) + //ObjPZ2=(ObjPY1*Sin(tanval2)+ObjPZ1*Cos(tanval2)); + SADDMULT1616(ObjPZ2,ObjPY1,Sin(tanval2),ObjPZ1,Cos(tanval2)) + + #ifdef debug06 + Log_Message("ObjPX2: %f ObjPY2: %f ObjPZ2: %f\n",ObjPX2,ObjPY2,ObjPZ2); + #endif + + ObjPZ2=ObjPZ2-Op02LFE; + + if (ObjPZ2<0) + { + Op06H=(short)(-(int64)ObjPX2*(int64)Op02LES/-(ObjPZ2)); //-ObjPX2*256/-ObjPZ2; + Op06V=(short)(-(int64)ObjPY2*(int64)Op02LES/-(ObjPZ2)); //-ObjPY2*256/-ObjPZ2; + Op06S=(unsigned short)(256*(int64)(Op02LES<<_FIX_SHIFT_)/-ObjPZ2); + } + else + { + Op06H=0; + Op06V=14*16; + Op06S=0xFFFF; + } + + + #ifdef DebugDSP1 + Log_Message("OP06 X:%d Y:%d Z:%d",Op06X,Op06Y,Op06Z); + Log_Message("OP06 H:%d V:%d S:%d",Op06H,Op06V,Op06S); + #endif +} +#else + +void DSPOp06() +{ + ObjPX=Op06X-Op02FX; + ObjPY=Op06Y-Op02FY; + ObjPZ=Op06Z-Op02FZ; + + // rotate around Z + tanval = (-Op02AAS+32768)/65536.0*6.2832; + ObjPX1=(ObjPX*cos(tanval)+ObjPY*-sin(tanval)); + ObjPY1=(ObjPX*sin(tanval)+ObjPY*cos(tanval)); + ObjPZ1=ObjPZ; + + #ifdef debug06 + Log_Message("Angle : %f", tanval); + Log_Message("ObjPX1: %f ObjPY1: %f ObjPZ1: %f\n",ObjPX1,ObjPY1,ObjPZ1); + Log_Message("cos(tanval) : %f sin(tanval) : %f", cos(tanval), sin(tanval)); + #endif + + // rotate around X + tanval = (-Op02AZS)/65536.0*6.2832; + ObjPX2=ObjPX1; + ObjPY2=(ObjPY1*cos(tanval)+ObjPZ1*-sin(tanval)); + ObjPZ2=(ObjPY1*sin(tanval)+ObjPZ1*cos(tanval)); + + #ifdef debug06 + Log_Message("ObjPX2: %f ObjPY2: %f ObjPZ2: %f\n",ObjPX2,ObjPY2,ObjPZ2); + #endif + + ObjPZ2=ObjPZ2-Op02LFE; + + if (ObjPZ2<0) + { + Op06H=(short)(-ObjPX2*Op02LES/-(ObjPZ2)); //-ObjPX2*256/-ObjPZ2; + Op06V=(short)(-ObjPY2*Op02LES/-(ObjPZ2)); //-ObjPY2*256/-ObjPZ2; + Op06S=(unsigned short)(256*(double)Op02LES/-ObjPZ2); + } + else + { + Op06H=0; + Op06V=14*16; + Op06S=0xFFFF; + } + + + #ifdef DebugDSP1 + Log_Message("OP06 X:%d Y:%d Z:%d",Op06X,Op06Y,Op06Z); + Log_Message("OP06 H:%d V:%d S:%d",Op06H,Op06V,Op06S); + #endif +} +#endif + + + +/*double matrixB[3][3]; +double matrixB2[3][3]; +double matrixB3[3][3]; + +double matrixA[3][3]; +double matrixA2[3][3]; +double matrixA3[3][3];*/ +int32 matrixB[3][3]; +int32 matrixB2[3][3]; +int32 matrixB3[3][3]; + +int32 matrixA[3][3]; +int32 matrixA2[3][3]; +int32 matrixA3[3][3]; + + +void MultMatrixB(int32 result[3][3],int32 mat1[3][3],int32 mat2[3][3]) +{ + result[0][0]=(mat1[0][0]*mat2[0][0]+mat1[0][1]*mat2[1][0]+mat1[0][2]*mat2[2][0])>>_FIX_SHIFT_; + result[0][1]=(mat1[0][0]*mat2[0][1]+mat1[0][1]*mat2[1][1]+mat1[0][2]*mat2[2][1])>>_FIX_SHIFT_; + result[0][2]=(mat1[0][0]*mat2[0][2]+mat1[0][1]*mat2[1][2]+mat1[0][2]*mat2[2][2])>>_FIX_SHIFT_; + + result[1][0]=(mat1[1][0]*mat2[0][0]+mat1[1][1]*mat2[1][0]+mat1[1][2]*mat2[2][0])>>_FIX_SHIFT_; + result[1][1]=(mat1[1][0]*mat2[0][1]+mat1[1][1]*mat2[1][1]+mat1[1][2]*mat2[2][1])>>_FIX_SHIFT_; + result[1][2]=(mat1[1][0]*mat2[0][2]+mat1[1][1]*mat2[1][2]+mat1[1][2]*mat2[2][2])>>_FIX_SHIFT_; + + result[2][0]=(mat1[2][0]*mat2[0][0]+mat1[2][1]*mat2[1][0]+mat1[2][2]*mat2[2][0])>>_FIX_SHIFT_; + result[2][1]=(mat1[2][0]*mat2[0][1]+mat1[2][1]*mat2[1][1]+mat1[2][2]*mat2[2][1])>>_FIX_SHIFT_; + result[2][2]=(mat1[2][0]*mat2[0][2]+mat1[2][1]*mat2[1][2]+mat1[2][2]*mat2[2][2])>>_FIX_SHIFT_; + +} + + +short Op01m; +short Op01Zr; +short Op01Xr; +short Op01Yr; +short Op11m; +short Op11Zr; +short Op11Xr; +short Op11Yr; +short Op21m; +short Op21Zr; +short Op21Xr; +short Op21Yr; +//double sc,sc2,sc3; +int32 sc,sc2,sc3; + + + +#ifdef __OPT01__ +void DSPOp01() +{ + unsigned short zr,yr,xr; + + zr = Angle(Op01Zr); + xr = Angle(Op01Yr); + yr = Angle(Op01Xr); + + matrixB[0][0]=1; matrixB[0][1]=0; matrixB[0][2]=0; + matrixB[1][0]=0; matrixB[1][1]=Cos(xr); matrixB[1][2]=-Sin(xr); + matrixB[2][0]=0; matrixB[2][1]=Sin(xr); matrixB[2][2]=Cos(xr); + + matrixB2[0][0]=Cos(yr); matrixB2[0][1]=0; matrixB2[0][2]=Sin(yr); + matrixB2[1][0]=0; matrixB2[1][1]=1; matrixB2[1][2]=0; + matrixB2[2][0]=-Sin(yr); matrixB2[2][1]=0; matrixB2[2][2]=Cos(yr); + + MultMatrixB(matrixB3,matrixB,matrixB2); + + matrixB2[0][0]=Cos(zr); matrixB2[0][1]=-Sin(zr); matrixB2[0][2]=0; + matrixB2[1][0]=Sin(zr); matrixB2[1][1]=Cos(zr); matrixB2[1][2]=0; + matrixB2[2][0]=0; matrixB2[2][1]=0; matrixB2[2][2]=1; + + MultMatrixB(matrixB,matrixB3,matrixB2); + + sc = ((double)Op01m)/32768.0; + + matrixA[0][0]=matrixB[0][0]; matrixA[0][1]=matrixB[0][1]; matrixA[0][2]=matrixB[0][2]; + matrixA[1][0]=matrixB[1][0]; matrixA[1][1]=matrixB[1][1]; matrixA[1][2]=matrixB[1][2]; + matrixA[2][0]=matrixB[2][0]; matrixA[2][1]=matrixB[2][1]; matrixA[2][2]=matrixB[2][2]; + + #ifdef DebugDSP1 + Log_Message("OP01 ZR: %d XR: %d YR: %d",Op01Zr,Op01Xr,Op01Yr); + #endif +} + +#else + +void DSPOp01() +{ + double zr,yr,xr; + + zr = ((double)Op01Zr)*6.2832/65536; + xr = ((double)Op01Yr)*6.2832/65536; + yr = ((double)Op01Xr)*6.2832/65536; + + matrixB[0][0]=1; matrixB[0][1]=0; matrixB[0][2]=0; + matrixB[1][0]=0; matrixB[1][1]=cos(xr); matrixB[1][2]=-sin(xr); + matrixB[2][0]=0; matrixB[2][1]=sin(xr); matrixB[2][2]=cos(xr); + + matrixB2[0][0]=cos(yr); matrixB2[0][1]=0; matrixB2[0][2]=sin(yr); + matrixB2[1][0]=0; matrixB2[1][1]=1; matrixB2[1][2]=0; + matrixB2[2][0]=-sin(yr); matrixB2[2][1]=0; matrixB2[2][2]=cos(yr); + + MultMatrixB(matrixB3,matrixB,matrixB2); + + matrixB2[0][0]=cos(zr); matrixB2[0][1]=-sin(zr); matrixB2[0][2]=0; + matrixB2[1][0]=sin(zr); matrixB2[1][1]=cos(zr); matrixB2[1][2]=0; + matrixB2[2][0]=0; matrixB2[2][1]=0; matrixB2[2][2]=1; + + MultMatrixB(matrixB,matrixB3,matrixB2); + + sc = ((double)Op01m)/32768.0; + + matrixA[0][0]=matrixB[0][0]; matrixA[0][1]=matrixB[0][1]; matrixA[0][2]=matrixB[0][2]; + matrixA[1][0]=matrixB[1][0]; matrixA[1][1]=matrixB[1][1]; matrixA[1][2]=matrixB[1][2]; + matrixA[2][0]=matrixB[2][0]; matrixA[2][1]=matrixB[2][1]; matrixA[2][2]=matrixB[2][2]; + + #ifdef DebugDSP1 + Log_Message("OP01 ZR: %d XR: %d YR: %d",Op01Zr,Op01Xr,Op01Yr); + #endif +} +#endif + + +#ifdef __OPT11__ +void DSPOp11() +{ + short zr,yr,xr; + + zr = Angle(Op11Zr); + xr = Angle(Op11Yr); + yr = Angle(Op11Xr); + + matrixB[0][0]=1; matrixB[0][1]=0; matrixB[0][2]=0; + matrixB[1][0]=0; matrixB[1][1]=Cos(xr); matrixB[1][2]=-Sin(xr); + matrixB[2][0]=0; matrixB[2][1]=Sin(xr); matrixB[2][2]=Cos(xr); + + matrixB2[0][0]=Cos(yr); matrixB2[0][1]=0; matrixB2[0][2]=Sin(yr); + matrixB2[1][0]=0; matrixB2[1][1]=1; matrixB2[1][2]=0; + matrixB2[2][0]=-Sin(yr); matrixB2[2][1]=0; matrixB2[2][2]=Cos(yr); + + MultMatrixB(matrixB3,matrixB,matrixB2); + + matrixB2[0][0]=Cos(zr); matrixB2[0][1]=-Sin(zr); matrixB2[0][2]=0; + matrixB2[1][0]=Sin(zr); matrixB2[1][1]=Cos(zr); matrixB2[1][2]=0; + matrixB2[2][0]=0; matrixB2[2][1]=0; matrixB2[2][2]=1; + + MultMatrixB(matrixB,matrixB3,matrixB2); + + sc2 = ((double)Op11m)/32768.0; + + matrixA2[0][0]=matrixB[0][0]; matrixA2[0][1]=matrixB[0][1]; matrixA2[0][2]=matrixB[0][2]; + matrixA2[1][0]=matrixB[1][0]; matrixA2[1][1]=matrixB[1][1]; matrixA2[1][2]=matrixB[1][2]; + matrixA2[2][0]=matrixB[2][0]; matrixA2[2][1]=matrixB[2][1]; matrixA2[2][2]=matrixB[2][2]; + #ifdef DebugDSP1 + Log_Message("OP11 ZR: %d XR: %d YR: %d SC: %d",Op11Zr,Op11Xr,Op11Yr,Op11m); + #endif +} +#else + +void DSPOp11() +{ + double zr,yr,xr; + + zr = ((double)Op11Zr)*6.2832/65536; + xr = ((double)Op11Yr)*6.2832/65536; + yr = ((double)Op11Xr)*6.2832/65536; + + matrixB[0][0]=1; matrixB[0][1]=0; matrixB[0][2]=0; + matrixB[1][0]=0; matrixB[1][1]=cos(xr); matrixB[1][2]=-sin(xr); + matrixB[2][0]=0; matrixB[2][1]=sin(xr); matrixB[2][2]=cos(xr); + + matrixB2[0][0]=cos(yr); matrixB2[0][1]=0; matrixB2[0][2]=sin(yr); + matrixB2[1][0]=0; matrixB2[1][1]=1; matrixB2[1][2]=0; + matrixB2[2][0]=-sin(yr); matrixB2[2][1]=0; matrixB2[2][2]=cos(yr); + + MultMatrixB(matrixB3,matrixB,matrixB2); + + matrixB2[0][0]=cos(zr); matrixB2[0][1]=-sin(zr); matrixB2[0][2]=0; + matrixB2[1][0]=sin(zr); matrixB2[1][1]=cos(zr); matrixB2[1][2]=0; + matrixB2[2][0]=0; matrixB2[2][1]=0; matrixB2[2][2]=1; + + MultMatrixB(matrixB,matrixB3,matrixB2); + + sc2 = ((double)Op11m)/32768.0; + + matrixA2[0][0]=matrixB[0][0]; matrixA2[0][1]=matrixB[0][1]; matrixA2[0][2]=matrixB[0][2]; + matrixA2[1][0]=matrixB[1][0]; matrixA2[1][1]=matrixB[1][1]; matrixA2[1][2]=matrixB[1][2]; + matrixA2[2][0]=matrixB[2][0]; matrixA2[2][1]=matrixB[2][1]; matrixA2[2][2]=matrixB[2][2]; + #ifdef DebugDSP1 + Log_Message("OP11 ZR: %d XR: %d YR: %d SC: %d",Op11Zr,Op11Xr,Op11Yr,Op11m); + #endif +} +#endif + + +#ifdef __OPT21__ +void DSPOp21() +{ + short zr,yr,xr; + + zr = Angle(Op21Zr); + xr = Angle(Op21Yr); + yr = Angle(Op21Xr); + + + matrixB[0][0]=1; matrixB[0][1]=0; matrixB[0][2]=0; + matrixB[1][0]=0; matrixB[1][1]=Cos(xr); matrixB[1][2]=-Sin(xr); + matrixB[2][0]=0; matrixB[2][1]=Sin(xr); matrixB[2][2]=Cos(xr); + + matrixB2[0][0]=Cos(yr); matrixB2[0][1]=0; matrixB2[0][2]=Sin(yr); + matrixB2[1][0]=0; matrixB2[1][1]=1; matrixB2[1][2]=0; + matrixB2[2][0]=-Sin(yr); matrixB2[2][1]=0; matrixB2[2][2]=Cos(yr); + + MultMatrixB(matrixB3,matrixB,matrixB2); + + matrixB2[0][0]=Cos(zr); matrixB2[0][1]=-Sin(zr); matrixB2[0][2]=0; + matrixB2[1][0]=Sin(zr); matrixB2[1][1]=Cos(zr); matrixB2[1][2]=0; + matrixB2[2][0]=0; matrixB2[2][1]=0; matrixB2[2][2]=1; + + MultMatrixB(matrixB,matrixB3,matrixB2); + + sc3 = ((double)Op21m)/32768.0; + + matrixA3[0][0]=matrixB[0][0]; matrixA3[0][1]=matrixB[0][1]; matrixA3[0][2]=matrixB[0][2]; + matrixA3[1][0]=matrixB[1][0]; matrixA3[1][1]=matrixB[1][1]; matrixA3[1][2]=matrixB[1][2]; + matrixA3[2][0]=matrixB[2][0]; matrixA3[2][1]=matrixB[2][1]; matrixA3[2][2]=matrixB[2][2]; + #ifdef DebugDSP1 + Log_Message("OP21 ZR: %d XR: %d YR: %d",Op21Zr,Op21Xr,Op21Yr); + #endif +} +#else + +void DSPOp21() +{ + double zr,yr,xr; + + zr = ((double)Op21Zr)*6.2832/65536; + xr = ((double)Op21Yr)*6.2832/65536; + yr = ((double)Op21Xr)*6.2832/65536; + + matrixB[0][0]=1; matrixB[0][1]=0; matrixB[0][2]=0; + matrixB[1][0]=0; matrixB[1][1]=cos(xr); matrixB[1][2]=-sin(xr); + matrixB[2][0]=0; matrixB[2][1]=sin(xr); matrixB[2][2]=cos(xr); + + matrixB2[0][0]=cos(yr); matrixB2[0][1]=0; matrixB2[0][2]=sin(yr); + matrixB2[1][0]=0; matrixB2[1][1]=1; matrixB2[1][2]=0; + matrixB2[2][0]=-sin(yr); matrixB2[2][1]=0; matrixB2[2][2]=cos(yr); + + MultMatrixB(matrixB3,matrixB,matrixB2); + + matrixB2[0][0]=cos(zr); matrixB2[0][1]=-sin(zr); matrixB2[0][2]=0; + matrixB2[1][0]=sin(zr); matrixB2[1][1]=cos(zr); matrixB2[1][2]=0; + matrixB2[2][0]=0; matrixB2[2][1]=0; matrixB2[2][2]=1; + + MultMatrixB(matrixB,matrixB3,matrixB2); + + sc3 = ((double)Op21m)/32768.0; + + matrixA3[0][0]=matrixB[0][0]; matrixA3[0][1]=matrixB[0][1]; matrixA3[0][2]=matrixB[0][2]; + matrixA3[1][0]=matrixB[1][0]; matrixA3[1][1]=matrixB[1][1]; matrixA3[1][2]=matrixB[1][2]; + matrixA3[2][0]=matrixB[2][0]; matrixA3[2][1]=matrixB[2][1]; matrixA3[2][2]=matrixB[2][2]; + #ifdef DebugDSP1 + Log_Message("OP21 ZR: %d XR: %d YR: %d",Op21Zr,Op21Xr,Op21Yr); + #endif +} +#endif + +short Op0DX; +short Op0DY; +short Op0DZ; +short Op0DF; +short Op0DL; +short Op0DU; +short Op1DX; +short Op1DY; +short Op1DZ; +short Op1DF; +short Op1DL; +short Op1DU; +short Op2DX; +short Op2DY; +short Op2DZ; +short Op2DF; +short Op2DL; +short Op2DU; + +#define swap(a,b) temp=a;a=b;b=temp; + +void DSPOp0D() +{ + double a,b,c,d,e,f,g,h,i,det,temp; + double a2,b2,c2,d2,e2,f2,g2,h2,i2,x,y,z; + + a = matrixA[0][0]; b=matrixA[0][1]; c=matrixA[0][2]; + d = matrixA[1][0]; e=matrixA[1][1]; f=matrixA[1][2]; + g = matrixA[2][0]; h=matrixA[2][1]; i=matrixA[2][2]; + //abc + //def + //ghi + det = a*e*i+b*f*g+c*d*h-g*e*c-h*f*a-i*d*b; + if (det==0) { + Op0DF=Op0DX; + Op0DL=Op0DY; + Op0DU=Op0DZ; + #ifdef DebugDSP1 + Log_Message("OP0D Error! Det == 0"); + #endif + return; + } + swap(d,b); swap(g,c); swap(h,f); + b=-b; d=-d; f=-f; h=-h; + a2=(e*i-h*f)/det; b2=(d*i-g*f)/det; c2=(d*h-g*e)/det; + d2=(b*i-h*c)/det; e2=(a*i-g*c)/det; f2=(a*h-g*b)/det; + g2=(b*f-e*c)/det; h2=(a*f-d*c)/det; i2=(a*e-d*b)/det; + x=Op0DX; y=Op0DY; z=Op0DZ; + Op0DF=(short)((x*a2+y*d2+z*g2)/2*sc); + Op0DL=(short)((x*b2+y*e2+z*h2)/2*sc); + Op0DU=(short)((x*c2+y*f2+z*i2)/2*sc); + + #ifdef DebugDSP1 + Log_Message("OP0D X: %d Y: %d Z: %d / F: %d L: %d U: %d",Op0DX,Op0DY,Op0DZ,Op0DF,Op0DL,Op0DU); + #endif +} + +void DSPOp1D() +{ + double a,b,c,d,e,f,g,h,i,det,temp; + double a2,b2,c2,d2,e2,f2,g2,h2,i2,x,y,z; + a = matrixA2[0][0]; b=matrixA2[0][1]; c=matrixA2[0][2]; + d = matrixA2[1][0]; e=matrixA2[1][1]; f=matrixA2[1][2]; + g = matrixA2[2][0]; h=matrixA2[2][1]; i=matrixA2[2][2]; + //abc + //def + //ghi + det = a*e*i+b*f*g+c*d*h-g*e*c-h*f*a-i*d*b; + if (det==0) { + Op1DF=0; Op1DL=0; Op1DU=0; + return; + } + swap(d,b); swap(g,c); swap(h,f); + b=-b; d=-d; f=-f; h=-h; + a2=(e*i-h*f)/det; b2=(d*i-g*f)/det; c2=(d*h-g*e)/det; + d2=(b*i-h*c)/det; e2=(a*i-g*c)/det; f2=(a*h-g*b)/det; + g2=(b*f-e*c)/det; h2=(a*f-d*c)/det; i2=(a*e-d*b)/det; + x=Op1DX; y=Op1DY; z=Op1DZ; + Op1DF=(short)((x*a2+y*d2+z*g2)/2*sc2); + Op1DL=(short)((x*b2+y*e2+z*h2)/2*sc2); + Op1DU=(short)((x*c2+y*f2+z*i2)/2*sc2); + #ifdef DebugDSP1 + Log_Message("OP1D X: %d Y: %d Z: %d / F: %d L: %d U: %d",Op1DX,Op1DY,Op1DZ,Op1DF,Op1DL,Op1DU); + #endif +} + +void DSPOp2D() +{ + double a,b,c,d,e,f,g,h,i,det,temp; + double a2,b2,c2,d2,e2,f2,g2,h2,i2,x,y,z; + a = matrixA3[0][0]; b=matrixA3[0][1]; c=matrixA3[0][2]; + d = matrixA3[1][0]; e=matrixA3[1][1]; f=matrixA3[1][2]; + g = matrixA3[2][0]; h=matrixA3[2][1]; i=matrixA3[2][2]; + //abc + //def + //ghi + det = a*e*i+b*f*g+c*d*h-g*e*c-h*f*a-i*d*b; + if (det==0) { + Op2DF=0; Op2DL=0; Op2DU=0; + return; + } + swap(d,b); swap(g,c); swap(h,f); + b=-b; d=-d; f=-f; h=-h; + a2=(e*i-h*f)/det; b2=(d*i-g*f)/det; c2=(d*h-g*e)/det; + d2=(b*i-h*c)/det; e2=(a*i-g*c)/det; f2=(a*h-g*b)/det; + g2=(b*f-e*c)/det; h2=(a*f-d*c)/det; i2=(a*e-d*b)/det; + x=Op2DX; y=Op2DY; z=Op2DZ; + Op2DF=(short)((x*a2+y*d2+z*g2)/2*sc3); + Op2DL=(short)((x*b2+y*e2+z*h2)/2*sc3); + Op2DU=(short)((x*c2+y*f2+z*i2)/2*sc3); + #ifdef DebugDSP1 + Log_Message("OP2D X: %d Y: %d Z: %d / F: %d L: %d U: %d",Op2DX,Op2DY,Op2DZ,Op2DF,Op2DL,Op2DU); + #endif +} + +short Op03F; +short Op03L; +short Op03U; +short Op03X; +short Op03Y; +short Op03Z; +short Op13F; +short Op13L; +short Op13U; +short Op13X; +short Op13Y; +short Op13Z; +short Op23F; +short Op23L; +short Op23U; +short Op23X; +short Op23Y; +short Op23Z; + +void DSPOp03() +{ + double F,L,U; + + F=Op03F; L=Op03L; U=Op03U; + Op03X=(short)((F*matrixA[0][0]+L*matrixA[1][0]+U*matrixA[2][0])/2*sc); + Op03Y=(short)((F*matrixA[0][1]+L*matrixA[1][1]+U*matrixA[2][1])/2*sc); + Op03Z=(short)((F*matrixA[0][2]+L*matrixA[1][2]+U*matrixA[2][2])/2*sc); + + #ifdef DebugDSP1 + Log_Message("OP03 F: %d L: %d U: %d / X: %d Y: %d Z: %d",Op03F,Op03L,Op03U,Op03X,Op03Y,Op03Z); + #endif +} + +void DSPOp13() +{ + double F,L,U; + F=Op13F; L=Op13L; U=Op13U; + Op13X=(short)((F*matrixA2[0][0]+L*matrixA2[1][0]+U*matrixA2[2][0])/2*sc2); + Op13Y=(short)((F*matrixA2[0][1]+L*matrixA2[1][1]+U*matrixA2[2][1])/2*sc2); + Op13Z=(short)((F*matrixA2[0][2]+L*matrixA2[1][2]+U*matrixA2[2][2])/2*sc2); + #ifdef DebugDSP1 + Log_Message("OP13 F: %d L: %d U: %d / X: %d Y: %d Z: %d",Op13F,Op13L,Op13U,Op13X,Op13Y,Op13Z); + #endif +} + +void DSPOp23() +{ + double F,L,U; + F=Op23F; L=Op23L; U=Op23U; + Op23X=(short)((F*matrixA3[0][0]+L*matrixA3[1][0]+U*matrixA3[2][0])/2*sc3); + Op23Y=(short)((F*matrixA3[0][1]+L*matrixA3[1][1]+U*matrixA3[2][1])/2*sc3); + Op23Z=(short)((F*matrixA3[0][2]+L*matrixA3[1][2]+U*matrixA3[2][2])/2*sc3); + #ifdef DebugDSP1 + Log_Message("OP23 F: %d L: %d U: %d / X: %d Y: %d Z: %d",Op23F,Op23L,Op23U,Op23X,Op23Y,Op23Z); + #endif +} + +short Op14Zr; +short Op14Xr; +short Op14Yr; +short Op14U; +short Op14F; +short Op14L; +short Op14Zrr; +short Op14Xrr; +short Op14Yrr; + +//double Op14Temp; +int32 Op14Temp; +void DSPOp14() +{ +//TODO + Op14Temp=(Op14Zr*6.2832/65536.0)+(1/cos(Op14Xr*6.2832/65536.0))*((Op14U*6.2832/65536.0)*cos(Op14Yr*6.2832/65536.0)-(Op14F*6.2832/65536.0)*sin(Op14Yr*6.2832/65536.0)); + Op14Zrr=(short)(Op14Temp*65536.0/6.2832); + Op14Temp=(Op14Xr*6.2832/65536.0)+((Op14U*6.2832/65536.0)*sin(Op14Yr*6.2832/65536.0)+(Op14F*6.2832/65536.0)*cos(Op14Yr*6.2832/65536.0)); + Op14Xrr=(short)(Op14Temp*65536.0/6.2832); + Op14Temp=(Op14Yr*6.2832/65536.0)-tan(Op14Xr*6.2832/65536.0)*((Op14U*6.2832/65536.0)*cos(Op14Yr*6.2832/65536.0)+(Op14F*6.2832/65536.0)*sin(Op14Yr*6.2832/65536.0))+(Op14L*6.2832/65536.0); + Op14Yrr=(short)(Op14Temp*65536.0/6.2832); + + + #ifdef DebugDSP1 + Log_Message("OP14 X:%d Y%d Z:%D U:%d F:%d L:%d",Op14Xr,Op14Yr,Op14Zr,Op14U,Op14F,Op14L); + Log_Message("OP14 X:%d Y%d Z:%D",Op14Xrr,Op14Yrr,Op14Zrr); + #endif +} + +short Op0EH; +short Op0EV; +short Op0EX; +short Op0EY; + +void DSPOp0E() +{ + + // screen Directions UP + //RVPos = Op0EV; + RVPos = Op0EV<<_FIX_SHIFT_; + //RHPos = Op0EH; + RHPos = Op0EH<<_FIX_SHIFT_; + GetRXYPos(); + //Op0EX = RXRes; + Op0EX = RXRes>>_FIX_SHIFT_; + //Op0EY = RYRes; + Op0EY = RYRes>>_FIX_SHIFT_; + + #ifdef DebugDSP1 + Log_Message("OP0E COORDINATE H:%d V:%d X:%d Y:%d",Op0EH,Op0EV,Op0EX,Op0EY); + #endif +} + +short Op0BX; +short Op0BY; +short Op0BZ; +short Op0BS; +short Op1BX; +short Op1BY; +short Op1BZ; +short Op1BS; +short Op2BX; +short Op2BY; +short Op2BZ; +short Op2BS; + +void DSPOp0B() +{ + //Op0BS = (Op0BX*matrixA[0][0]+Op0BY*matrixA2[0][1]+Op0BZ*matrixA2[0][2]); + Op0BS = (Op0BX*matrixA[0][0]+Op0BY*matrixA2[0][1]+Op0BZ*matrixA2[0][2])>>_FIX_SHIFT_; +#ifdef DebugDSP1 + Log_Message("OP0B"); +#endif +} + +void DSPOp1B() +{ + //Op1BS = (Op1BX*matrixA2[0][0]+Op1BY*matrixA2[0][1]+Op1BZ*matrixA2[0][2]); + Op1BS = (Op1BX*matrixA2[0][0]+Op1BY*matrixA2[0][1]+Op1BZ*matrixA2[0][2])>>_FIX_SHIFT_; +#ifdef DebugDSP1 + Log_Message("OP1B X: %d Y: %d Z: %d S: %d",Op1BX,Op1BY,Op1BZ,Op1BS); + Log_Message(" MX: %d MY: %d MZ: %d Scale: %d",(short)(matrixA2[0][0]*100),(short)(matrixA2[0][1]*100),(short)(matrixA2[0][2]*100),(short)(sc2*100)); +#endif + +} + +void DSPOp2B() +{ + //Op2BS = (Op2BX*matrixA3[0][0]+Op2BY*matrixA3[0][1]+Op2BZ*matrixA3[0][2]); + Op2BS = (Op2BX*matrixA3[0][0]+Op2BY*matrixA3[0][1]+Op2BZ*matrixA3[0][2])>>_FIX_SHIFT_; +#ifdef DebugDSP1 + Log_Message("OP2B"); +#endif +} + +short Op08X,Op08Y,Op08Z,Op08Ll,Op08Lh; +long Op08Size; + +void DSPOp08() +{ + Op08Size=(Op08X*Op08X+Op08Y*Op08Y+Op08Z*Op08Z)*2; + Op08Ll = Op08Size&0xFFFF; + Op08Lh = (Op08Size>>16) & 0xFFFF; + #ifdef DebugDSP1 + Log_Message("OP08 %d,%d,%d",Op08X,Op08Y,Op08Z); + Log_Message("OP08 ((Op08X^2)+(Op08Y^2)+(Op08X^2))=%x",Op08Size ); + #endif +} + +short Op18X,Op18Y,Op18Z,Op18R,Op18D; + +void DSPOp18() +{ + //double x,y,z,r; + int32 x,y,z,r; + x=Op18X; y=Op18Y; z=Op18Z; r=Op18R; + r = (x*x+y*y+z*z-r*r); + if (r>32767) r=32767; + if (r<-32768) r=-32768; + Op18D=(short)r; + #ifdef DebugDSP1 + Log_Message("OP18 X: %d Y: %d Z: %d R: %D DIFF %d",Op18X,Op18Y,Op18Z,Op18D); + #endif +} + +short Op38X,Op38Y,Op38Z,Op38R,Op38D; + +void DSPOp38() +{ + Op38D = (Op38X * Op38X + Op38Y * Op38Y + Op38Z * Op38Z - Op38R * Op38R) >> 15; + Op38D++; + + #ifdef DebugDSP1 + Log_Message("OP38 X: %d Y: %d Z: %d R: %D DIFF %d",Op38X,Op38Y,Op38Z,Op38D); + #endif +} + + +short Op28X; +short Op28Y; +short Op28Z; +short Op28R; + +void DSPOp28() +{ + //to optimize... sqrt + Op28R=(short)sqrt((double)(Op28X*Op28X+Op28Y*Op28Y+Op28Z*Op28Z)); + #ifdef DebugDSP1 + Log_Message("OP28 X:%d Y:%d Z:%d",Op28X,Op28Y,Op28Z); + Log_Message("OP28 Vector Length %d",Op28R); + #endif +} + +short Op1CAZ; +unsigned short Op1CX,Op1CY,Op1CZ; +short Op1CXBR,Op1CYBR,Op1CZBR,Op1CXAR,Op1CYAR,Op1CZAR; +short Op1CX1; +short Op1CY1; +short Op1CZ1; +short Op1CX2; +short Op1CY2; +short Op1CZ2; + +#ifdef __OPT1C__ +void DSPOp1C() +{ + short ya,xa,za; + ya = Angle(Op1CX); + xa = Angle(Op1CY); + za = Angle(Op1CZ); + + // rotate around Z + //Op1CX1=(Op1CXBR*Cos(za)+Op1CYBR*Sin(za)); + Op1CX1=(Op1CXBR*Cos(za)+Op1CYBR*Sin(za))>>_FIX_SHIFT_; + //Op1CY1=(Op1CXBR*-Sin(za)+Op1CYBR*Cos(za)); + Op1CY1=(Op1CXBR*-Sin(za)+Op1CYBR*Cos(za))>>_FIX_SHIFT_; + Op1CZ1=Op1CZBR; + // rotate around Y + //Op1CX2=(Op1CX1*Cos(ya)+Op1CZ1*-Sin(ya)); + Op1CX2=(Op1CX1*Cos(ya)+Op1CZ1*-Sin(ya))>>_FIX_SHIFT_; + Op1CY2=Op1CY1; + //Op1CZ2=(Op1CX1*Sin(ya)+Op1CZ1*Cos(ya)); + Op1CZ2=(Op1CX1*Sin(ya)+Op1CZ1*Cos(ya))>>_FIX_SHIFT_; + // rotate around X + Op1CXAR=Op1CX2; + //Op1CYAR=(Op1CY2*Cos(xa)+Op1CZ2*Sin(xa)); + Op1CYAR=(Op1CY2*Cos(xa)+Op1CZ2*Sin(xa))>>_FIX_SHIFT_; + //Op1CZAR=(Op1CY2*-Sin(xa)+Op1CZ2*Cos(xa)); + Op1CZAR=(Op1CY2*-Sin(xa)+Op1CZ2*Cos(xa))>>_FIX_SHIFT_; + + #ifdef DebugDSP1 + Log_Message("OP1C Apply Matrix CX:%d CY:%d CZ",Op1CXAR,Op1CYAR,Op1CZAR); + #endif +} +#else +void DSPOp1C() +{ + double ya,xa,za; + ya = Op1CX/65536.0*PI*2; + xa = Op1CY/65536.0*PI*2; + za = Op1CZ/65536.0*PI*2; + // rotate around Z + Op1CX1=(Op1CXBR*cos(za)+Op1CYBR*sin(za)); + Op1CY1=(Op1CXBR*-sin(za)+Op1CYBR*cos(za)); + Op1CZ1=Op1CZBR; + // rotate around Y + Op1CX2=(Op1CX1*cos(ya)+Op1CZ1*-sin(ya)); + Op1CY2=Op1CY1; + Op1CZ2=(Op1CX1*sin(ya)+Op1CZ1*cos(ya)); + // rotate around X + Op1CXAR=Op1CX2; + Op1CYAR=(Op1CY2*cos(xa)+Op1CZ2*sin(xa)); + Op1CZAR=(Op1CY2*-sin(xa)+Op1CZ2*cos(xa)); + + #ifdef DebugDSP1 + Log_Message("OP1C Apply Matrix CX:%d CY:%d CZ",Op1CXAR,Op1CYAR,Op1CZAR); + #endif +} + +#endif + +unsigned short Op0FRamsize; +unsigned short Op0FPass; + +void DSPOp0F() +{ + Op0FPass = 0x0000; + + #ifdef DebugDSP1 + Log_Message("OP0F RAM Test Pass:%d", Op0FPass); + #endif +} + + +short Op2FUnknown; +short Op2FSize; + +void DSPOp2F() +{ + Op2FSize=0x100; +} diff --git a/src/snes4iphone_src/dsp1emu_yo.c b/src/snes4iphone_src/dsp1emu_yo.c new file mode 100755 index 0000000..4b4e579 --- /dev/null +++ b/src/snes4iphone_src/dsp1emu_yo.c @@ -0,0 +1,1423 @@ +//Copyright (C) 1997-2001 ZSNES Team ( zsknight@zsnes.com / _demo_@zsnes.com ) +// +//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 (at your option) any later +//version. +// +//This program 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 this program; if not, write to the Free Software +//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +#ifndef __GP32__ +#include +#include +#endif +#include + +#ifndef __GP32__ +#include +#include +#endif + +#ifdef __GP32__ +#include "gp32_func.h" +#endif +//#define DebugDSP1 + +// uncomment some lines to test +//#define printinfo +//#define debug02 +//#define debug0A +//#define debug06 + +#define __OPT__ +#define __OPT01__ +#define __OPT02__ +#define __OPT04__ //was commented on original source (yoyo) +#define __OPT06__ +#define __OPT0C__ // this optimisation may break pilotwings +#define __OPT11__ +#define __OPT21__ +#define __OPT1C__ + +#ifdef DebugDSP1 + +FILE * LogFile = NULL; + +void Log_Message (char *Message, ...) +{ + char Msg[400]; + va_list ap; + + va_start(ap,Message); + vsprintf(Msg,Message,ap ); + va_end(ap); + + strcat(Msg,"\r\n\0"); + fwrite(Msg,strlen(Msg),1,LogFile); + fflush (LogFile); +} + +void Start_Log (void) +{ + char LogFileName[255]; +// [4/15/2001] char *p; + + strcpy(LogFileName,"dsp1emu.log\0"); + + LogFile = fopen(LogFileName,"wb"); +} + +void Stop_Log (void) +{ + if (LogFile) + { + fclose(LogFile); + LogFile = NULL; + } +} + +#endif + + +/***************************************************************************\ +* Math tables * +\***************************************************************************/ + +double *CosTable2; +double *SinTable2; + +int32 *CosTable2Fix; +int32 *SinTable2Fix; + +#define INCR 2048 +#define Angle(x) (((x)/(65536/INCR)) & (INCR-1)) + +#define AngleFix(x) (((x)>>5) & (INCR-1)) + +#define Cos(x) ((double) CosTable2[x]) +#define Sin(x) ((double) SinTable2[x]) + +#define CosFix(x) (CosTable2Fix[x]) +#define SinFix(x) (SinTable2Fix[x]) + +#define PI 3.14159265358979323846264338327 + +double Atan(double x) +{ + if ((x>=1) || (x<=1)) + return (x/(1+0.28*x*x)); + else + return (PI/2 - Atan(1/x)); +} + + +/***************************************************************************\ +* DSP1 code * +\***************************************************************************/ + + +void InitDSP(void) +{ +#ifdef __OPT__ + unsigned int i; + CosTable2 = (double *) malloc(INCR*sizeof(double)); + SinTable2 = (double *) malloc(INCR*sizeof(double)); + + CosTable2Fix = (int32 *) malloc(INCR*sizeof(int32)); + SinTable2Fix = (int32 *) malloc(INCR*sizeof(int32)); + for (i=0; i 0) + while (Op10Temp>=1.0) { + Op10Temp=Op10Temp/2.0; + Op10ExponentR++; + } + else + while (Op10Temp<-1.0) { + Op10Temp=Op10Temp/2.0; + Op10ExponentR++; + } + Op10CoefficientR = Op10Temp*32768; + #ifdef DebugDSP1 + Log_Message("OP10 INV %d*2^%d = %d*2^%d", Op10Coefficient, Op10Exponent, Op10CoefficientR, Op10ExponentR); + #endif +} + + +short Op04Angle; +unsigned short Op04Radius; +short Op04Sin; +short Op04Cos; + +#ifdef __OPT04__ + +void DSPOp04() +{ + dsp_opcode[0x04]++; + + int32 angle; + //angle = Angle(Op04Angle); + angle = AngleFix(Op04Angle); + + //Op04Sin = Sin(angle) * Op04Radius; + SMULT1616(Op04Sin,SinFix(angle),(int32)Op04Radius) + //Op04Cos = Cos(angle) * Op04Radius; + SMULT1616(Op04Cos,CosFix(angle),(int32)Op04Radius); + + #ifdef DebugDSP1 + Log_Message("OP04 Angle:%d Radius:%d",(Op04Angle/256)&255,Op04Radius); + Log_Message("OP04 SIN:%d COS:%d",Op04Sin,Op04Cos); + #endif +} +#else + +void DSPOp04() +{ + double angle; + + angle = Op04Angle*2*PI/65536.0; + + Op04Sin = sin(angle) * Op04Radius; + Op04Cos = cos(angle) * Op04Radius; + + #ifdef DebugDSP1 + Log_Message("OP04 Angle:%d Radius:%d",(Op04Angle/256)&255,Op04Radius); + Log_Message("OP04 SIN:%d COS:%d",Op04Sin,Op04Cos); + #endif +} +#endif + +unsigned short Op0CA; +short Op0CX1; +short Op0CY1; +short Op0CX2; +short Op0CY2; + +#ifdef __OPT0C__ +void DSPOp0C() +{ +dsp_opcode[0x0C]++; + + Op0CX2=(Op0CX1*Cos(Angle(Op0CA))+Op0CY1*Sin(Angle(Op0CA))); + Op0CY2=(Op0CX1*-Sin(Angle(Op0CA))+Op0CY1*Cos(Angle(Op0CA))); + #ifdef DebugDSP1 + Log_Message("OP0C Angle:%d X:%d Y:%d CX:%d CY:%d",(Op0CA/256)&255,Op0CX1,Op0CY1,Op0CX2,Op0CY2); + #endif +} +#else +void DSPOp0C() +{ + + Op0CX2=(Op0CX1*cos(Op0CA*2*PI/65536.0)+Op0CY1*sin(Op0CA*2*PI/65536.0)); + Op0CY2=(Op0CX1*-sin(Op0CA*2*PI/65536.0)+Op0CY1*cos(Op0CA*2*PI/65536.0)); + #ifdef DebugDSP1 + Log_Message("OP0C Angle:%d X:%d Y:%d CX:%d CY:%d",(Op0CA/256)&255,Op0CX1,Op0CY1,Op0CX2,Op0CY2); + #endif +} + +#endif + +short Op02FX; +short Op02FY; +short Op02FZ; +short Op02LFE; +short Op02LES; +unsigned short Op02AAS; +unsigned short Op02AZS; +unsigned short Op02VOF; +unsigned short Op02VVA; + +short Op02CX; +short Op02CY; +double Op02CXF; +double Op02CYF; +double ViewerX0; +double ViewerY0; +double ViewerZ0; +double ViewerX1; +double ViewerY1; +double ViewerZ1; +double ViewerX; +double ViewerY; +double ViewerZ; +int ViewerAX; +int ViewerAY; +int ViewerAZ; +double NumberOfSlope; +double ScreenX; +double ScreenY; +double ScreenZ; +double TopLeftScreenX; +double TopLeftScreenY; +double TopLeftScreenZ; +double BottomRightScreenX; +double BottomRightScreenY; +double BottomRightScreenZ; +double Ready; +double RasterLX; +double RasterLY; +double RasterLZ; +double ScreenLX1; +double ScreenLY1; +double ScreenLZ1; +int ReversedLES; +short Op02LESb; +double NAzsB,NAasB; +double ViewerXc; +double ViewerYc; +double ViewerZc; +double CenterX,CenterY; +short Op02CYSup,Op02CXSup; +double CXdistance; + +#define VofAngle 0x3880 + +short TValDebug,TValDebug2; +short ScrDispl; + + +#ifdef __OPT02__ +void DSPOp02() +{ +dsp_opcode[0x02]++; + + ViewerZ1=-Cos(Angle(Op02AZS)); + ViewerX1=Sin(Angle(Op02AZS))*Sin(Angle(Op02AAS)); + ViewerY1=Sin(Angle(Op02AZS))*Cos(Angle(Op02AAS)); + + + #ifdef debug02 + printf("\nViewerX1 : %f ViewerY1 : %f ViewerZ1 : %f\n",ViewerX1,ViewerY1, + ViewerZ1); + getch(); + #endif + ViewerX=Op02FX-ViewerX1*Op02LFE; + ViewerY=Op02FY-ViewerY1*Op02LFE; + ViewerZ=Op02FZ-ViewerZ1*Op02LFE; + + ScreenX=Op02FX+ViewerX1*(Op02LES-Op02LFE); + ScreenY=Op02FY+ViewerY1*(Op02LES-Op02LFE); + ScreenZ=Op02FZ+ViewerZ1*(Op02LES-Op02LFE); + + #ifdef debug02 + printf("ViewerX : %f ViewerY : %f ViewerZ : %f\n",ViewerX,ViewerY,ViewerZ); + printf("Op02FX : %d Op02FY : %d Op02FZ : %d\n",Op02FX,Op02FY,Op02FZ); + printf("ScreenX : %f ScreenY : %f ScreenZ : %f\n",ScreenX,ScreenY,ScreenZ); + getch(); + #endif + if (ViewerZ1==0)ViewerZ1++; + NumberOfSlope=ViewerZ/-ViewerZ1; + + Op02CX=(short)(Op02CXF=ViewerX+ViewerX1*NumberOfSlope); + Op02CY=(short)(Op02CYF=ViewerY+ViewerY1*NumberOfSlope); + + Op02VOF=0x0000; + ReversedLES=0; + Op02LESb=Op02LES; + if ((Op02LES>=VofAngle+16384.0) && (Op02LES=VofAngle) && (Op02LESb<=VofAngle+0x4000)) { + Op02VOF= (short)(Op02LESb * tan((Op02AZS-0x4000-VofAngle)*6.2832/65536.0)); + Op02VVA-=Op02VOF; + } + if (ReversedLES){ + Op02VOF=-Op02VOF; + } + + NAzsB = (Op02AZS-0x4000)*6.2832/65536.0; + NAasB = Op02AAS*6.2832/65536.0; + + if (tan(NAzsB)==0) NAzsB=0.1; + + ScrDispl=0; + if (NAzsB>-0.15) {NAzsB=-0.15;ScrDispl=Op02VVA-0xFFDA;} + + CXdistance=1/tan(NAzsB); + + ViewerXc=Op02FX; + ViewerYc=Op02FY; + ViewerZc=Op02FZ; + + CenterX = (-sin(NAasB)*ViewerZc*CXdistance)+ViewerXc; + CenterY = (cos(NAasB)*ViewerZc*CXdistance)+ViewerYc; + Op02CX = (short)CenterX; + Op02CY = (short)CenterY; + + ViewerXc=ViewerX;//-Op02FX); + ViewerYc=ViewerY;//-Op02FY); + ViewerZc=ViewerZ;//-Op02FZ); + + CenterX = (-sin(NAasB)*ViewerZc*CXdistance)+ViewerXc; + if (CenterX<-32768) CenterX = -32768; if (CenterX>32767) CenterX=32767; + CenterY = (cos(NAasB)*ViewerZc*CXdistance)+ViewerYc; + if (CenterY<-32768) CenterY = -32768; if (CenterY>32767) CenterY=32767; + + TValDebug = (NAzsB*65536/6.28); + TValDebug2 = ScrDispl; + +// if (Op02CY < 0) {Op02CYSup = Op02CY/256; Op02CY = 0;} +// if (Op02CX < 0) {Op02CXSup = Op02CX/256; Op02CX = 0;} + +// [4/15/2001] (ViewerX+ViewerX1*NumberOfSlope); +// [4/15/2001] (ViewerY+ViewerY1*NumberOfSlope); + +// if(Op02LFE==0x2200)Op02VVA=0xFECD; +// else Op02VVA=0xFFB2; + + + #ifdef DebugDSP1 + Log_Message("OP02 FX:%d FY:%d FZ:%d LFE:%d LES:%d",Op02FX,Op02FY,Op02FZ,Op02LFE,Op02LES); + Log_Message(" AAS:%d AZS:%d VOF:%d VVA:%d",Op02AAS,Op02AZS,Op02VOF,Op02VVA); + Log_Message(" VX:%d VY:%d VZ:%d",(short)ViewerX,(short)ViewerY,(short)ViewerZ); + #endif + +} +#else + +void DSPOp02() +{ + ViewerZ1=-cos(Op02AZS*6.2832/65536.0); + ViewerX1=sin(Op02AZS*6.2832/65536.0)*sin(Op02AAS*6.2832/65536.0); + ViewerY1=sin(Op02AZS*6.2832/65536.0)*cos(-Op02AAS*6.2832/65536.0); + + #ifdef debug02 + printf("\nViewerX1 : %f ViewerY1 : %f ViewerZ1 : %f\n",ViewerX1,ViewerY1, + ViewerZ1); + getch(); + #endif + ViewerX=Op02FX-ViewerX1*Op02LFE; + ViewerY=Op02FY-ViewerY1*Op02LFE; + ViewerZ=Op02FZ-ViewerZ1*Op02LFE; + + ScreenX=Op02FX+ViewerX1*(Op02LES-Op02LFE); + ScreenY=Op02FY+ViewerY1*(Op02LES-Op02LFE); + ScreenZ=Op02FZ+ViewerZ1*(Op02LES-Op02LFE); + + #ifdef debug02 + printf("ViewerX : %f ViewerY : %f ViewerZ : %f\n",ViewerX,ViewerY,ViewerZ); + printf("Op02FX : %d Op02FY : %d Op02FZ : %d\n",Op02FX,Op02FY,Op02FZ); + printf("ScreenX : %f ScreenY : %f ScreenZ : %f\n",ScreenX,ScreenY,ScreenZ); + getch(); + #endif + if (ViewerZ1==0)ViewerZ1++; + NumberOfSlope=ViewerZ/-ViewerZ1; + + Op02CX=(short)(Op02CXF=ViewerX+ViewerX1*NumberOfSlope); + Op02CY=(short)(Op02CYF=ViewerY+ViewerY1*NumberOfSlope); + + ViewerXc=ViewerX;//-Op02FX); + ViewerYc=ViewerY;//-Op02FY); + ViewerZc=ViewerZ;//-Op02FZ); + + Op02VOF=0x0000; + ReversedLES=0; + Op02LESb=Op02LES; + if ((Op02LES>=VofAngle+16384.0) && (Op02LES=VofAngle) && (Op02LESb<=VofAngle+0x4000)) { + Op02VOF= (short)(Op02LESb * tan((Op02AZS-0x4000-VofAngle)*6.2832/65536.0)); + Op02VVA-=Op02VOF; + } + if (ReversedLES){ + Op02VOF=-Op02VOF; + } + + NAzsB = (Op02AZS-0x4000)*6.2832/65536.0; + NAasB = Op02AAS*6.2832/65536.0; + + if (tan(NAzsB)==0) NAzsB=0.1; + + ScrDispl=0; + if (NAzsB>-0.15) {NAzsB=-0.15;ScrDispl=Op02VVA-0xFFDA;} + + CXdistance=1/tan(NAzsB); + + CenterX = (-sin(NAasB)*ViewerZc*CXdistance)+ViewerXc; + if (CenterX<-32768) CenterX = -32768; if (CenterX>32767) CenterX=32767; + Op02CX = (short)CenterX; + CenterY = (cos(NAasB)*ViewerZc*CXdistance)+ViewerYc; + if (CenterY<-32768) CenterY = -32768; if (CenterY>32767) CenterY=32767; + Op02CY = (short)CenterY; + + TValDebug = (NAzsB*65536/6.28); + TValDebug2 = ScrDispl; + +// if (Op02CY < 0) {Op02CYSup = Op02CY/256; Op02CY = 0;} +// if (Op02CX < 0) {Op02CXSup = Op02CX/256; Op02CX = 0;} + +// [4/15/2001] (ViewerX+ViewerX1*NumberOfSlope); +// [4/15/2001] (ViewerY+ViewerY1*NumberOfSlope); + +// if(Op02LFE==0x2200)Op02VVA=0xFECD; +// else Op02VVA=0xFFB2; + + + #ifdef DebugDSP1 + Log_Message("OP02 FX:%d FY:%d FZ:%d LFE:%d LES:%d",Op02FX,Op02FY,Op02FZ,Op02LFE,Op02LES); + Log_Message(" AAS:%d AZS:%d VOF:%d VVA:%d",Op02AAS,Op02AZS,Op02VOF,Op02VVA); + Log_Message(" VX:%d VY:%d VZ:%d",(short)ViewerX,(short)ViewerY,(short)ViewerZ); + #endif + +} +#endif + +short Op0AVS; +short Op0AA; +short Op0AB; +short Op0AC; +short Op0AD; + +double RasterRX; +double RasterRY; +double RasterRZ; +double RasterLSlopeX; +double RasterLSlopeY; +double RasterLSlopeZ; +double RasterRSlopeX; +double RasterRSlopeY; +double RasterRSlopeZ; +double GroundLX; +double GroundLY; +double GroundRX; +double GroundRY; +double Distance; + +double NAzs,NAas; +double RVPos,RHPos,RXRes,RYRes; + + +void GetRXYPos(){ + double scalar; + + if (Op02LES==0) return; + + + NAzs = NAzsB - Atan((RVPos) / (double)Op02LES); + NAas = NAasB;// + Atan(RHPos) / (double)Op02LES); + + if (cos(NAzs)==0) NAzs+=0.001; + if (tan(NAzs)==0) NAzs+=0.001; + + RXRes = (-sin(NAas)*ViewerZc/(tan(NAzs))+ViewerXc); + RYRes = (cos(NAas)*ViewerZc/(tan(NAzs))+ViewerYc); + scalar = ((ViewerZc/sin(NAzs))/(double)Op02LES); + RXRes += scalar*-sin(NAas+PI/2)*RHPos; + RYRes += scalar*cos(NAas+PI/2)*RHPos; +} + +void DSPOp0A() +{ +dsp_opcode[0x0A]++; + + double x2,y2,x3,y3,x4,y4,m,ypos; + + + if(Op0AVS==0) {Op0AVS++; return;} + ypos=Op0AVS-ScrDispl; + // CenterX,CenterX = Center (x1,y1) + // Get (0,Vs) coords (x2,y2) + RVPos = ypos; RHPos = 0; + GetRXYPos(); x2 = RXRes; y2 = RYRes; + // Get (-128,Vs) coords (x3,y3) + RVPos = ypos; RHPos = -128; + GetRXYPos(); x3 = RXRes; y3 = RYRes; + // Get (127,Vs) coords (x4,y4) + RVPos = ypos; RHPos = 127; + GetRXYPos(); x4 = RXRes; y4 = RYRes; + + // A = (x4-x3)/256 + m = (x4-x3)/256*256; if (m>32767) m=32767; if (m<-32768) m=-32768; + Op0AA = (short)(m); + // C = (y4-y3)/256 + m = (y4-y3)/256*256; if (m>32767) m=32767; if (m<-32768) m=-32768; + Op0AC = (short)(m); + if (ypos==0){ + Op0AB = 0; + Op0AD = 0; + } + else { + // B = (x2-x1)/Vs + m = (x2-CenterX)/ypos*256; if (m>32767) m=32767; if (m<-32768) m=-32768; + Op0AB = (short)(m); + // D = (y2-y1)/Vs + m = (y2-CenterY)/ypos*256; if (m>32767) m=32767; if (m<-32768) m=-32768; + Op0AD = (short)(m); + } + + Op0AVS+=1; +} + +short Op06X; +short Op06Y; +short Op06Z; +short Op06H; +short Op06V; +unsigned short Op06S; + +/*double ObjPX; +double ObjPY; +double ObjPZ; +double ObjPX1; +double ObjPY1; +double ObjPZ1; +double ObjPX2; +double ObjPY2; +double ObjPZ2;*/ +int32 ObjPX; +int32 ObjPY; +int32 ObjPZ; +int32 ObjPX1; +int32 ObjPY1; +int32 ObjPZ1; +int32 ObjPX2; +int32 ObjPY2; +int32 ObjPZ2; +double DivideOp06; +int Temp; +int tanval2; + +#ifdef __OPT06__ +void DSPOp06() +{ + + dsp_opcode[0x06]++; + + ObjPX=Op06X-Op02FX; + ObjPY=Op06Y-Op02FY; + ObjPZ=Op06Z-Op02FZ; + + + + // rotate around Z + //tanval2 = Angle(-Op02AAS+32768); +// tanval2 = (-Op02AAS+32768)/(65536/INCR); + //ObjPX1=(ObjPX*Cos(tanval2)+ObjPY*-Sin(tanval2)); + //ObjPY1=(ObjPX*Sin(tanval2)+ObjPY*Cos(tanval2)); + //ObjPZ1=ObjPZ; + tanval2 = AngleFix(-Op02AAS+32768); + SADDMULT1616(ObjPX1,ObjPX,CosFix(tanval2),ObjPY,-SinFix(tanval2)) + SADDMULT1616(ObjPY1,ObjPX,SinFix(tanval2),ObjPY,CosFix(tanval2)) + ObjPZ1=ObjPZ; + + + // rotate around X +// tanval2 = (-Op02AZS/(65536/INCR)) & 1023; + //tanval2 = Angle(-Op02AZS); +// tanval2 = (-Op02AZS)/256; + /*ObjPX2=ObjPX1; + ObjPY2=(ObjPY1*Cos(tanval2)+ObjPZ1*-Sin(tanval2)); + ObjPZ2=(ObjPY1*Sin(tanval2)+ObjPZ1*Cos(tanval2));*/ + tanval2 = AngleFix(-Op02AZS); + ObjPX2=ObjPX1; + SADDMULT1616(ObjPY2,ObjPY1,CosFix(tanval2),ObjPZ1,-SinFix(tanval2)) + SADDMULT1616(ObjPZ2,ObjPY1,SinFix(tanval2),ObjPZ1,CosFix(tanval2)) + + #ifdef debug06 + Log_Message("ObjPX2: %f ObjPY2: %f ObjPZ2: %f\n",ObjPX2,ObjPY2,ObjPZ2); + #endif + + ObjPZ2=ObjPZ2-Op02LFE; + + if (ObjPZ2<0) + { + Op06H=(short)(-ObjPX2*Op02LES/-(ObjPZ2)); //-ObjPX2*256/-ObjPZ2; + Op06V=(short)(-ObjPY2*Op02LES/-(ObjPZ2)); //-ObjPY2*256/-ObjPZ2; + //Op06S=(unsigned short)(256*(double)Op02LES/-ObjPZ2); + Op06S=(unsigned short)(256*(int32)Op02LES/-ObjPZ2); + } + else + { + Op06H=0; + Op06V=14*16; + Op06S=0xFFFF; + } + + + #ifdef DebugDSP1 + Log_Message("OP06 X:%d Y:%d Z:%d",Op06X,Op06Y,Op06Z); + Log_Message("OP06 H:%d V:%d S:%d",Op06H,Op06V,Op06S); + #endif +} +#else + +void DSPOp06() +{ + ObjPX=Op06X-Op02FX; + ObjPY=Op06Y-Op02FY; + ObjPZ=Op06Z-Op02FZ; + + // rotate around Z + tanval = (-Op02AAS+32768)/65536.0*6.2832; + ObjPX1=(ObjPX*cos(tanval)+ObjPY*-sin(tanval)); + ObjPY1=(ObjPX*sin(tanval)+ObjPY*cos(tanval)); + ObjPZ1=ObjPZ; + + #ifdef debug06 + Log_Message("Angle : %f", tanval); + Log_Message("ObjPX1: %f ObjPY1: %f ObjPZ1: %f\n",ObjPX1,ObjPY1,ObjPZ1); + Log_Message("cos(tanval) : %f sin(tanval) : %f", cos(tanval), sin(tanval)); + #endif + + // rotate around X + tanval = (-Op02AZS)/65536.0*6.2832; + ObjPX2=ObjPX1; + ObjPY2=(ObjPY1*cos(tanval)+ObjPZ1*-sin(tanval)); + ObjPZ2=(ObjPY1*sin(tanval)+ObjPZ1*cos(tanval)); + + #ifdef debug06 + Log_Message("ObjPX2: %f ObjPY2: %f ObjPZ2: %f\n",ObjPX2,ObjPY2,ObjPZ2); + #endif + + ObjPZ2=ObjPZ2-Op02LFE; + + if (ObjPZ2<0) + { + Op06H=(short)(-ObjPX2*Op02LES/-(ObjPZ2)); //-ObjPX2*256/-ObjPZ2; + Op06V=(short)(-ObjPY2*Op02LES/-(ObjPZ2)); //-ObjPY2*256/-ObjPZ2; + Op06S=(unsigned short)(256*(double)Op02LES/-ObjPZ2); + } + else + { + Op06H=0; + Op06V=14*16; + Op06S=0xFFFF; + } + + + #ifdef DebugDSP1 + Log_Message("OP06 X:%d Y:%d Z:%d",Op06X,Op06Y,Op06Z); + Log_Message("OP06 H:%d V:%d S:%d",Op06H,Op06V,Op06S); + #endif +} +#endif + + + +double matrixB[3][3]; +double matrixB2[3][3]; +double matrixB3[3][3]; + +double matrixA[3][3]; +double matrixA2[3][3]; +double matrixA3[3][3]; + +void MultMatrixB(double result[3][3],double mat1[3][3],double mat2[3][3]) +{ + result[0][0]=(mat1[0][0]*mat2[0][0]+mat1[0][1]*mat2[1][0]+mat1[0][2]*mat2[2][0]); + result[0][1]=(mat1[0][0]*mat2[0][1]+mat1[0][1]*mat2[1][1]+mat1[0][2]*mat2[2][1]); + result[0][2]=(mat1[0][0]*mat2[0][2]+mat1[0][1]*mat2[1][2]+mat1[0][2]*mat2[2][2]); + + result[1][0]=(mat1[1][0]*mat2[0][0]+mat1[1][1]*mat2[1][0]+mat1[1][2]*mat2[2][0]); + result[1][1]=(mat1[1][0]*mat2[0][1]+mat1[1][1]*mat2[1][1]+mat1[1][2]*mat2[2][1]); + result[1][2]=(mat1[1][0]*mat2[0][2]+mat1[1][1]*mat2[1][2]+mat1[1][2]*mat2[2][2]); + + result[2][0]=(mat1[2][0]*mat2[0][0]+mat1[2][1]*mat2[1][0]+mat1[2][2]*mat2[2][0]); + result[2][1]=(mat1[2][0]*mat2[0][1]+mat1[2][1]*mat2[1][1]+mat1[2][2]*mat2[2][1]); + result[2][2]=(mat1[2][0]*mat2[0][2]+mat1[2][1]*mat2[1][2]+mat1[2][2]*mat2[2][2]); + +} + + +short Op01m; +short Op01Zr; +short Op01Xr; +short Op01Yr; +short Op11m; +short Op11Zr; +short Op11Xr; +short Op11Yr; +short Op21m; +short Op21Zr; +short Op21Xr; +short Op21Yr; +double sc,sc2,sc3; + + + +#ifdef __OPT01__ +void DSPOp01() +{ +dsp_opcode[0x01]++; + + unsigned short zr,yr,xr; + + zr = Angle(Op01Zr); + xr = Angle(Op01Yr); + yr = Angle(Op01Xr); + + matrixB[0][0]=1; matrixB[0][1]=0; matrixB[0][2]=0; + matrixB[1][0]=0; matrixB[1][1]=Cos(xr); matrixB[1][2]=-Sin(xr); + matrixB[2][0]=0; matrixB[2][1]=Sin(xr); matrixB[2][2]=Cos(xr); + + matrixB2[0][0]=Cos(yr); matrixB2[0][1]=0; matrixB2[0][2]=Sin(yr); + matrixB2[1][0]=0; matrixB2[1][1]=1; matrixB2[1][2]=0; + matrixB2[2][0]=-Sin(yr); matrixB2[2][1]=0; matrixB2[2][2]=Cos(yr); + + MultMatrixB(matrixB3,matrixB,matrixB2); + + matrixB2[0][0]=Cos(zr); matrixB2[0][1]=-Sin(zr); matrixB2[0][2]=0; + matrixB2[1][0]=Sin(zr); matrixB2[1][1]=Cos(zr); matrixB2[1][2]=0; + matrixB2[2][0]=0; matrixB2[2][1]=0; matrixB2[2][2]=1; + + MultMatrixB(matrixB,matrixB3,matrixB2); + + sc = ((double)Op01m)/32768.0; + + matrixA[0][0]=matrixB[0][0]; matrixA[0][1]=matrixB[0][1]; matrixA[0][2]=matrixB[0][2]; + matrixA[1][0]=matrixB[1][0]; matrixA[1][1]=matrixB[1][1]; matrixA[1][2]=matrixB[1][2]; + matrixA[2][0]=matrixB[2][0]; matrixA[2][1]=matrixB[2][1]; matrixA[2][2]=matrixB[2][2]; + + #ifdef DebugDSP1 + Log_Message("OP01 ZR: %d XR: %d YR: %d",Op01Zr,Op01Xr,Op01Yr); + #endif +} + +#else + +void DSPOp01() +{ + double zr,yr,xr; + + zr = ((double)Op01Zr)*6.2832/65536; + xr = ((double)Op01Yr)*6.2832/65536; + yr = ((double)Op01Xr)*6.2832/65536; + + matrixB[0][0]=1; matrixB[0][1]=0; matrixB[0][2]=0; + matrixB[1][0]=0; matrixB[1][1]=cos(xr); matrixB[1][2]=-sin(xr); + matrixB[2][0]=0; matrixB[2][1]=sin(xr); matrixB[2][2]=cos(xr); + + matrixB2[0][0]=cos(yr); matrixB2[0][1]=0; matrixB2[0][2]=sin(yr); + matrixB2[1][0]=0; matrixB2[1][1]=1; matrixB2[1][2]=0; + matrixB2[2][0]=-sin(yr); matrixB2[2][1]=0; matrixB2[2][2]=cos(yr); + + MultMatrixB(matrixB3,matrixB,matrixB2); + + matrixB2[0][0]=cos(zr); matrixB2[0][1]=-sin(zr); matrixB2[0][2]=0; + matrixB2[1][0]=sin(zr); matrixB2[1][1]=cos(zr); matrixB2[1][2]=0; + matrixB2[2][0]=0; matrixB2[2][1]=0; matrixB2[2][2]=1; + + MultMatrixB(matrixB,matrixB3,matrixB2); + + sc = ((double)Op01m)/32768.0; + + matrixA[0][0]=matrixB[0][0]; matrixA[0][1]=matrixB[0][1]; matrixA[0][2]=matrixB[0][2]; + matrixA[1][0]=matrixB[1][0]; matrixA[1][1]=matrixB[1][1]; matrixA[1][2]=matrixB[1][2]; + matrixA[2][0]=matrixB[2][0]; matrixA[2][1]=matrixB[2][1]; matrixA[2][2]=matrixB[2][2]; + + #ifdef DebugDSP1 + Log_Message("OP01 ZR: %d XR: %d YR: %d",Op01Zr,Op01Xr,Op01Yr); + #endif +} +#endif + + +#ifdef __OPT11__ +void DSPOp11() +{ +dsp_opcode[0x11]++; + + short zr,yr,xr; + + zr = Angle(Op11Zr); + xr = Angle(Op11Yr); + yr = Angle(Op11Xr); + + matrixB[0][0]=1; matrixB[0][1]=0; matrixB[0][2]=0; + matrixB[1][0]=0; matrixB[1][1]=Cos(xr); matrixB[1][2]=-Sin(xr); + matrixB[2][0]=0; matrixB[2][1]=Sin(xr); matrixB[2][2]=Cos(xr); + + matrixB2[0][0]=Cos(yr); matrixB2[0][1]=0; matrixB2[0][2]=Sin(yr); + matrixB2[1][0]=0; matrixB2[1][1]=1; matrixB2[1][2]=0; + matrixB2[2][0]=-Sin(yr); matrixB2[2][1]=0; matrixB2[2][2]=Cos(yr); + + MultMatrixB(matrixB3,matrixB,matrixB2); + + matrixB2[0][0]=Cos(zr); matrixB2[0][1]=-Sin(zr); matrixB2[0][2]=0; + matrixB2[1][0]=Sin(zr); matrixB2[1][1]=Cos(zr); matrixB2[1][2]=0; + matrixB2[2][0]=0; matrixB2[2][1]=0; matrixB2[2][2]=1; + + MultMatrixB(matrixB,matrixB3,matrixB2); + + sc2 = ((double)Op11m)/32768.0; + + matrixA2[0][0]=matrixB[0][0]; matrixA2[0][1]=matrixB[0][1]; matrixA2[0][2]=matrixB[0][2]; + matrixA2[1][0]=matrixB[1][0]; matrixA2[1][1]=matrixB[1][1]; matrixA2[1][2]=matrixB[1][2]; + matrixA2[2][0]=matrixB[2][0]; matrixA2[2][1]=matrixB[2][1]; matrixA2[2][2]=matrixB[2][2]; + #ifdef DebugDSP1 + Log_Message("OP11 ZR: %d XR: %d YR: %d SC: %d",Op11Zr,Op11Xr,Op11Yr,Op11m); + #endif +} +#else + +void DSPOp11() +{ + double zr,yr,xr; + + zr = ((double)Op11Zr)*6.2832/65536; + xr = ((double)Op11Yr)*6.2832/65536; + yr = ((double)Op11Xr)*6.2832/65536; + + matrixB[0][0]=1; matrixB[0][1]=0; matrixB[0][2]=0; + matrixB[1][0]=0; matrixB[1][1]=cos(xr); matrixB[1][2]=-sin(xr); + matrixB[2][0]=0; matrixB[2][1]=sin(xr); matrixB[2][2]=cos(xr); + + matrixB2[0][0]=cos(yr); matrixB2[0][1]=0; matrixB2[0][2]=sin(yr); + matrixB2[1][0]=0; matrixB2[1][1]=1; matrixB2[1][2]=0; + matrixB2[2][0]=-sin(yr); matrixB2[2][1]=0; matrixB2[2][2]=cos(yr); + + MultMatrixB(matrixB3,matrixB,matrixB2); + + matrixB2[0][0]=cos(zr); matrixB2[0][1]=-sin(zr); matrixB2[0][2]=0; + matrixB2[1][0]=sin(zr); matrixB2[1][1]=cos(zr); matrixB2[1][2]=0; + matrixB2[2][0]=0; matrixB2[2][1]=0; matrixB2[2][2]=1; + + MultMatrixB(matrixB,matrixB3,matrixB2); + + sc2 = ((double)Op11m)/32768.0; + + matrixA2[0][0]=matrixB[0][0]; matrixA2[0][1]=matrixB[0][1]; matrixA2[0][2]=matrixB[0][2]; + matrixA2[1][0]=matrixB[1][0]; matrixA2[1][1]=matrixB[1][1]; matrixA2[1][2]=matrixB[1][2]; + matrixA2[2][0]=matrixB[2][0]; matrixA2[2][1]=matrixB[2][1]; matrixA2[2][2]=matrixB[2][2]; + #ifdef DebugDSP1 + Log_Message("OP11 ZR: %d XR: %d YR: %d SC: %d",Op11Zr,Op11Xr,Op11Yr,Op11m); + #endif +} +#endif + + +#ifdef __OPT21__ +void DSPOp21() +{ +dsp_opcode[0x21]++; + + short zr,yr,xr; + + zr = Angle(Op21Zr); + xr = Angle(Op21Yr); + yr = Angle(Op21Xr); + + + matrixB[0][0]=1; matrixB[0][1]=0; matrixB[0][2]=0; + matrixB[1][0]=0; matrixB[1][1]=Cos(xr); matrixB[1][2]=-Sin(xr); + matrixB[2][0]=0; matrixB[2][1]=Sin(xr); matrixB[2][2]=Cos(xr); + + matrixB2[0][0]=Cos(yr); matrixB2[0][1]=0; matrixB2[0][2]=Sin(yr); + matrixB2[1][0]=0; matrixB2[1][1]=1; matrixB2[1][2]=0; + matrixB2[2][0]=-Sin(yr); matrixB2[2][1]=0; matrixB2[2][2]=Cos(yr); + + MultMatrixB(matrixB3,matrixB,matrixB2); + + matrixB2[0][0]=Cos(zr); matrixB2[0][1]=-Sin(zr); matrixB2[0][2]=0; + matrixB2[1][0]=Sin(zr); matrixB2[1][1]=Cos(zr); matrixB2[1][2]=0; + matrixB2[2][0]=0; matrixB2[2][1]=0; matrixB2[2][2]=1; + + MultMatrixB(matrixB,matrixB3,matrixB2); + + sc3 = ((double)Op21m)/32768.0; + + matrixA3[0][0]=matrixB[0][0]; matrixA3[0][1]=matrixB[0][1]; matrixA3[0][2]=matrixB[0][2]; + matrixA3[1][0]=matrixB[1][0]; matrixA3[1][1]=matrixB[1][1]; matrixA3[1][2]=matrixB[1][2]; + matrixA3[2][0]=matrixB[2][0]; matrixA3[2][1]=matrixB[2][1]; matrixA3[2][2]=matrixB[2][2]; + #ifdef DebugDSP1 + Log_Message("OP21 ZR: %d XR: %d YR: %d",Op21Zr,Op21Xr,Op21Yr); + #endif +} +#else + +void DSPOp21() +{ + double zr,yr,xr; + + zr = ((double)Op21Zr)*6.2832/65536; + xr = ((double)Op21Yr)*6.2832/65536; + yr = ((double)Op21Xr)*6.2832/65536; + + matrixB[0][0]=1; matrixB[0][1]=0; matrixB[0][2]=0; + matrixB[1][0]=0; matrixB[1][1]=cos(xr); matrixB[1][2]=-sin(xr); + matrixB[2][0]=0; matrixB[2][1]=sin(xr); matrixB[2][2]=cos(xr); + + matrixB2[0][0]=cos(yr); matrixB2[0][1]=0; matrixB2[0][2]=sin(yr); + matrixB2[1][0]=0; matrixB2[1][1]=1; matrixB2[1][2]=0; + matrixB2[2][0]=-sin(yr); matrixB2[2][1]=0; matrixB2[2][2]=cos(yr); + + MultMatrixB(matrixB3,matrixB,matrixB2); + + matrixB2[0][0]=cos(zr); matrixB2[0][1]=-sin(zr); matrixB2[0][2]=0; + matrixB2[1][0]=sin(zr); matrixB2[1][1]=cos(zr); matrixB2[1][2]=0; + matrixB2[2][0]=0; matrixB2[2][1]=0; matrixB2[2][2]=1; + + MultMatrixB(matrixB,matrixB3,matrixB2); + + sc3 = ((double)Op21m)/32768.0; + + matrixA3[0][0]=matrixB[0][0]; matrixA3[0][1]=matrixB[0][1]; matrixA3[0][2]=matrixB[0][2]; + matrixA3[1][0]=matrixB[1][0]; matrixA3[1][1]=matrixB[1][1]; matrixA3[1][2]=matrixB[1][2]; + matrixA3[2][0]=matrixB[2][0]; matrixA3[2][1]=matrixB[2][1]; matrixA3[2][2]=matrixB[2][2]; + #ifdef DebugDSP1 + Log_Message("OP21 ZR: %d XR: %d YR: %d",Op21Zr,Op21Xr,Op21Yr); + #endif +} +#endif + +short Op0DX; +short Op0DY; +short Op0DZ; +short Op0DF; +short Op0DL; +short Op0DU; +short Op1DX; +short Op1DY; +short Op1DZ; +short Op1DF; +short Op1DL; +short Op1DU; +short Op2DX; +short Op2DY; +short Op2DZ; +short Op2DF; +short Op2DL; +short Op2DU; + +#define swap(a,b) temp=a;a=b;b=temp; + +void DSPOp0D() +{ +dsp_opcode[0x0D]++; + + double a,b,c,d,e,f,g,h,i,det,temp; + double a2,b2,c2,d2,e2,f2,g2,h2,i2,x,y,z; + + a = matrixA[0][0]; b=matrixA[0][1]; c=matrixA[0][2]; + d = matrixA[1][0]; e=matrixA[1][1]; f=matrixA[1][2]; + g = matrixA[2][0]; h=matrixA[2][1]; i=matrixA[2][2]; + //abc + //def + //ghi + det = a*e*i+b*f*g+c*d*h-g*e*c-h*f*a-i*d*b; + if (det==0) { + Op0DF=Op0DX; + Op0DL=Op0DY; + Op0DU=Op0DZ; + #ifdef DebugDSP1 + Log_Message("OP0D Error! Det == 0"); + #endif + return; + } + swap(d,b); swap(g,c); swap(h,f); + b=-b; d=-d; f=-f; h=-h; + a2=(e*i-h*f)/det; b2=(d*i-g*f)/det; c2=(d*h-g*e)/det; + d2=(b*i-h*c)/det; e2=(a*i-g*c)/det; f2=(a*h-g*b)/det; + g2=(b*f-e*c)/det; h2=(a*f-d*c)/det; i2=(a*e-d*b)/det; + x=Op0DX; y=Op0DY; z=Op0DZ; + Op0DF=(short)((x*a2+y*d2+z*g2)/2*sc); + Op0DL=(short)((x*b2+y*e2+z*h2)/2*sc); + Op0DU=(short)((x*c2+y*f2+z*i2)/2*sc); + + #ifdef DebugDSP1 + Log_Message("OP0D X: %d Y: %d Z: %d / F: %d L: %d U: %d",Op0DX,Op0DY,Op0DZ,Op0DF,Op0DL,Op0DU); + #endif +} + +void DSPOp1D() +{ +dsp_opcode[0x1D]++; + + double a,b,c,d,e,f,g,h,i,det,temp; + double a2,b2,c2,d2,e2,f2,g2,h2,i2,x,y,z; + a = matrixA2[0][0]; b=matrixA2[0][1]; c=matrixA2[0][2]; + d = matrixA2[1][0]; e=matrixA2[1][1]; f=matrixA2[1][2]; + g = matrixA2[2][0]; h=matrixA2[2][1]; i=matrixA2[2][2]; + //abc + //def + //ghi + det = a*e*i+b*f*g+c*d*h-g*e*c-h*f*a-i*d*b; + if (det==0) { + Op1DF=0; Op1DL=0; Op1DU=0; + return; + } + swap(d,b); swap(g,c); swap(h,f); + b=-b; d=-d; f=-f; h=-h; + a2=(e*i-h*f)/det; b2=(d*i-g*f)/det; c2=(d*h-g*e)/det; + d2=(b*i-h*c)/det; e2=(a*i-g*c)/det; f2=(a*h-g*b)/det; + g2=(b*f-e*c)/det; h2=(a*f-d*c)/det; i2=(a*e-d*b)/det; + x=Op1DX; y=Op1DY; z=Op1DZ; + Op1DF=(short)((x*a2+y*d2+z*g2)/2*sc2); + Op1DL=(short)((x*b2+y*e2+z*h2)/2*sc2); + Op1DU=(short)((x*c2+y*f2+z*i2)/2*sc2); + #ifdef DebugDSP1 + Log_Message("OP1D X: %d Y: %d Z: %d / F: %d L: %d U: %d",Op1DX,Op1DY,Op1DZ,Op1DF,Op1DL,Op1DU); + #endif +} + +void DSPOp2D() +{ +dsp_opcode[0x2D]++; + + double a,b,c,d,e,f,g,h,i,det,temp; + double a2,b2,c2,d2,e2,f2,g2,h2,i2,x,y,z; + a = matrixA3[0][0]; b=matrixA3[0][1]; c=matrixA3[0][2]; + d = matrixA3[1][0]; e=matrixA3[1][1]; f=matrixA3[1][2]; + g = matrixA3[2][0]; h=matrixA3[2][1]; i=matrixA3[2][2]; + //abc + //def + //ghi + det = a*e*i+b*f*g+c*d*h-g*e*c-h*f*a-i*d*b; + if (det==0) { + Op2DF=0; Op2DL=0; Op2DU=0; + return; + } + swap(d,b); swap(g,c); swap(h,f); + b=-b; d=-d; f=-f; h=-h; + a2=(e*i-h*f)/det; b2=(d*i-g*f)/det; c2=(d*h-g*e)/det; + d2=(b*i-h*c)/det; e2=(a*i-g*c)/det; f2=(a*h-g*b)/det; + g2=(b*f-e*c)/det; h2=(a*f-d*c)/det; i2=(a*e-d*b)/det; + x=Op2DX; y=Op2DY; z=Op2DZ; + Op2DF=(short)((x*a2+y*d2+z*g2)/2*sc3); + Op2DL=(short)((x*b2+y*e2+z*h2)/2*sc3); + Op2DU=(short)((x*c2+y*f2+z*i2)/2*sc3); + #ifdef DebugDSP1 + Log_Message("OP2D X: %d Y: %d Z: %d / F: %d L: %d U: %d",Op2DX,Op2DY,Op2DZ,Op2DF,Op2DL,Op2DU); + #endif +} + +short Op03F; +short Op03L; +short Op03U; +short Op03X; +short Op03Y; +short Op03Z; +short Op13F; +short Op13L; +short Op13U; +short Op13X; +short Op13Y; +short Op13Z; +short Op23F; +short Op23L; +short Op23U; +short Op23X; +short Op23Y; +short Op23Z; + +void DSPOp03() +{ +dsp_opcode[0x03]++; + + double F,L,U; + + F=Op03F; L=Op03L; U=Op03U; + Op03X=(short)((F*matrixA[0][0]+L*matrixA[1][0]+U*matrixA[2][0])/2*sc); + Op03Y=(short)((F*matrixA[0][1]+L*matrixA[1][1]+U*matrixA[2][1])/2*sc); + Op03Z=(short)((F*matrixA[0][2]+L*matrixA[1][2]+U*matrixA[2][2])/2*sc); + + #ifdef DebugDSP1 + Log_Message("OP03 F: %d L: %d U: %d / X: %d Y: %d Z: %d",Op03F,Op03L,Op03U,Op03X,Op03Y,Op03Z); + #endif +} + +void DSPOp13() +{ +dsp_opcode[0x13]++; + + double F,L,U; + F=Op13F; L=Op13L; U=Op13U; + Op13X=(short)((F*matrixA2[0][0]+L*matrixA2[1][0]+U*matrixA2[2][0])/2*sc2); + Op13Y=(short)((F*matrixA2[0][1]+L*matrixA2[1][1]+U*matrixA2[2][1])/2*sc2); + Op13Z=(short)((F*matrixA2[0][2]+L*matrixA2[1][2]+U*matrixA2[2][2])/2*sc2); + #ifdef DebugDSP1 + Log_Message("OP13 F: %d L: %d U: %d / X: %d Y: %d Z: %d",Op13F,Op13L,Op13U,Op13X,Op13Y,Op13Z); + #endif +} + +void DSPOp23() +{ +dsp_opcode[0x23]++; + + double F,L,U; + F=Op23F; L=Op23L; U=Op23U; + Op23X=(short)((F*matrixA3[0][0]+L*matrixA3[1][0]+U*matrixA3[2][0])/2*sc3); + Op23Y=(short)((F*matrixA3[0][1]+L*matrixA3[1][1]+U*matrixA3[2][1])/2*sc3); + Op23Z=(short)((F*matrixA3[0][2]+L*matrixA3[1][2]+U*matrixA3[2][2])/2*sc3); + #ifdef DebugDSP1 + Log_Message("OP23 F: %d L: %d U: %d / X: %d Y: %d Z: %d",Op23F,Op23L,Op23U,Op23X,Op23Y,Op23Z); + #endif +} + +short Op14Zr; +short Op14Xr; +short Op14Yr; +short Op14U; +short Op14F; +short Op14L; +short Op14Zrr; +short Op14Xrr; +short Op14Yrr; + +double Op14Temp; +void DSPOp14() +{ +dsp_opcode[0x14]++; + + Op14Temp=(Op14Zr*6.2832/65536.0)+(1/cos(Op14Xr*6.2832/65536.0))*((Op14U*6.2832/65536.0)*cos(Op14Yr*6.2832/65536.0)-(Op14F*6.2832/65536.0)*sin(Op14Yr*6.2832/65536.0)); + Op14Zrr=(short)(Op14Temp*65536.0/6.2832); + Op14Temp=(Op14Xr*6.2832/65536.0)+((Op14U*6.2832/65536.0)*sin(Op14Yr*6.2832/65536.0)+(Op14F*6.2832/65536.0)*cos(Op14Yr*6.2832/65536.0)); + Op14Xrr=(short)(Op14Temp*65536.0/6.2832); + Op14Temp=(Op14Yr*6.2832/65536.0)-tan(Op14Xr*6.2832/65536.0)*((Op14U*6.2832/65536.0)*cos(Op14Yr*6.2832/65536.0)+(Op14F*6.2832/65536.0)*sin(Op14Yr*6.2832/65536.0))+(Op14L*6.2832/65536.0); + Op14Yrr=(short)(Op14Temp*65536.0/6.2832); + #ifdef DebugDSP1 + Log_Message("OP14 X:%d Y%d Z:%D U:%d F:%d L:%d",Op14Xr,Op14Yr,Op14Zr,Op14U,Op14F,Op14L); + Log_Message("OP14 X:%d Y%d Z:%D",Op14Xrr,Op14Yrr,Op14Zrr); + #endif +} + +short Op0EH; +short Op0EV; +short Op0EX; +short Op0EY; + +void DSPOp0E() +{ +dsp_opcode[0x0E]++; + + // screen Directions UP + RVPos = Op0EV; + RHPos = Op0EH; + GetRXYPos(); + Op0EX = RXRes; + Op0EY = RYRes; + + #ifdef DebugDSP1 + Log_Message("OP0E COORDINATE H:%d V:%d X:%d Y:%d",Op0EH,Op0EV,Op0EX,Op0EY); + #endif +} + +short Op0BX; +short Op0BY; +short Op0BZ; +short Op0BS; +short Op1BX; +short Op1BY; +short Op1BZ; +short Op1BS; +short Op2BX; +short Op2BY; +short Op2BZ; +short Op2BS; + +void DSPOp0B() +{ +dsp_opcode[0x0B]++; + + Op0BS = (Op0BX*matrixA[0][0]+Op0BY*matrixA2[0][1]+Op0BZ*matrixA2[0][2]); +#ifdef DebugDSP1 + Log_Message("OP0B"); +#endif +} + +void DSPOp1B() +{ +dsp_opcode[0x1B]++; + + Op1BS = (Op1BX*matrixA2[0][0]+Op1BY*matrixA2[0][1]+Op1BZ*matrixA2[0][2]); +#ifdef DebugDSP1 + Log_Message("OP1B X: %d Y: %d Z: %d S: %d",Op1BX,Op1BY,Op1BZ,Op1BS); + Log_Message(" MX: %d MY: %d MZ: %d Scale: %d",(short)(matrixA2[0][0]*100),(short)(matrixA2[0][1]*100),(short)(matrixA2[0][2]*100),(short)(sc2*100)); +#endif + +} + +void DSPOp2B() +{ +dsp_opcode[0x2B]++; + + Op2BS = (Op2BX*matrixA3[0][0]+Op2BY*matrixA3[0][1]+Op2BZ*matrixA3[0][2]); +#ifdef DebugDSP1 + Log_Message("OP2B"); +#endif +} + +short Op08X,Op08Y,Op08Z,Op08Ll,Op08Lh; +long Op08Size; + +void DSPOp08() +{ +dsp_opcode[0x08]++; + + Op08Size=(Op08X*Op08X+Op08Y*Op08Y+Op08Z*Op08Z)*2; + Op08Ll = Op08Size&0xFFFF; + Op08Lh = (Op08Size>>16) & 0xFFFF; + #ifdef DebugDSP1 + Log_Message("OP08 %d,%d,%d",Op08X,Op08Y,Op08Z); + Log_Message("OP08 ((Op08X^2)+(Op08Y^2)+(Op08X^2))=%x",Op08Size ); + #endif +} + +short Op18X,Op18Y,Op18Z,Op18R,Op18D; + +void DSPOp18() +{ +dsp_opcode[0x18]++; + + double x,y,z,r; + x=Op18X; y=Op18Y; z=Op18Z; r=Op18R; + r = (x*x+y*y+z*z-r*r); + if (r>32767) r=32767; + if (r<-32768) r=-32768; + Op18D=(short)r; + #ifdef DebugDSP1 + Log_Message("OP18 X: %d Y: %d Z: %d R: %D DIFF %d",Op18X,Op18Y,Op18Z,Op18D); + #endif +} + +short Op28X; +short Op28Y; +short Op28Z; +short Op28R; + +int32 fixed_sqrt(int32 r) +{ + int32 t,b,c=0; + + for (b=0x10000000;b!=0;b>>=2) { + t = c + b; + c >>= 1; + if (t <= r) { + r -= t; + c += b; + } + } + return(c); +} + + +void DSPOp28() +{ +dsp_opcode[0x28]++; + +// Op28R=(short)sqrt((double)(Op28X*Op28X+Op28Y*Op28Y+Op28Z*Op28Z)); + Op28R=(short)fixed_sqrt((int32)(Op28X*Op28X+Op28Y*Op28Y+Op28Z*Op28Z)); + #ifdef DebugDSP1 + Log_Message("OP28 X:%d Y:%d Z:%d",Op28X,Op28Y,Op28Z); + Log_Message("OP28 Vector Length %d",Op28R); + #endif +} + +short Op1CAZ; +unsigned short Op1CX,Op1CY,Op1CZ; +short Op1CXBR,Op1CYBR,Op1CZBR,Op1CXAR,Op1CYAR,Op1CZAR; +short Op1CX1; +short Op1CY1; +short Op1CZ1; +short Op1CX2; +short Op1CY2; +short Op1CZ2; + +#ifdef __OPT1C__ +void DSPOp1C() +{ +dsp_opcode[0x1C]++; + + short ya,xa,za; + ya = Angle(Op1CX); + xa = Angle(Op1CY); + za = Angle(Op1CZ); + + // rotate around Z + Op1CX1=(Op1CXBR*Cos(za)+Op1CYBR*Sin(za)); + Op1CY1=(Op1CXBR*-Sin(za)+Op1CYBR*Cos(za)); + Op1CZ1=Op1CZBR; + // rotate around Y + Op1CX2=(Op1CX1*Cos(ya)+Op1CZ1*-Sin(ya)); + Op1CY2=Op1CY1; + Op1CZ2=(Op1CX1*Sin(ya)+Op1CZ1*Cos(ya)); + // rotate around X + Op1CXAR=Op1CX2; + Op1CYAR=(Op1CY2*Cos(xa)+Op1CZ2*Sin(xa)); + Op1CZAR=(Op1CY2*-Sin(xa)+Op1CZ2*Cos(xa)); + + #ifdef DebugDSP1 + Log_Message("OP1C Apply Matrix CX:%d CY:%d CZ",Op1CXAR,Op1CYAR,Op1CZAR); + #endif +} +#else +void DSPOp1C() +{ + double ya,xa,za; + ya = Op1CX/65536.0*PI*2; + xa = Op1CY/65536.0*PI*2; + za = Op1CZ/65536.0*PI*2; + // rotate around Z + Op1CX1=(Op1CXBR*cos(za)+Op1CYBR*sin(za)); + Op1CY1=(Op1CXBR*-sin(za)+Op1CYBR*cos(za)); + Op1CZ1=Op1CZBR; + // rotate around Y + Op1CX2=(Op1CX1*cos(ya)+Op1CZ1*-sin(ya)); + Op1CY2=Op1CY1; + Op1CZ2=(Op1CX1*sin(ya)+Op1CZ1*cos(ya)); + // rotate around X + Op1CXAR=Op1CX2; + Op1CYAR=(Op1CY2*cos(xa)+Op1CZ2*sin(xa)); + Op1CZAR=(Op1CY2*-sin(xa)+Op1CZ2*cos(xa)); + + #ifdef DebugDSP1 + Log_Message("OP1C Apply Matrix CX:%d CY:%d CZ",Op1CXAR,Op1CYAR,Op1CZAR); + #endif +} + +#endif diff --git a/src/snes4iphone_src/dsp2emu.c b/src/snes4iphone_src/dsp2emu.c new file mode 100755 index 0000000..1eeb021 --- /dev/null +++ b/src/snes4iphone_src/dsp2emu.c @@ -0,0 +1,341 @@ +/******************************************************************************* + Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and + Jerremy Koot (jkoot@snes9x.com) + + (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net) + + (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net), + funkyass (funkyass@spam.shaw.ca), + Joel Yliluoma (http://iki.fi/bisqwit/) + Kris Bleakley (codeviolation@hotmail.com), + Matthew Kendora, + Nach (n-a-c-h@users.sourceforge.net), + Peter Bortas (peter@bortas.org) and + zones (kasumitokoduck@yahoo.com) + + C4 x86 assembler and some C emulation code + (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com), + _Demo_ (_demo_@zsnes.com), and Nach + + C4 C++ code + (c) Copyright 2003 Brad Jorsch + + DSP-1 emulator code + (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson, + John Weidman, neviksti (neviksti@hotmail.com), + Kris Bleakley, Andreas Naive + + DSP-2 emulator code + (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and + Lord Nightmare (lord_nightmare@users.sourceforge.net + + OBC1 emulator code + (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and + Kris Bleakley + Ported from x86 assembler to C by sanmaiwashi + + SPC7110 and RTC C++ emulator code + (c) Copyright 2002 Matthew Kendora with research by + zsKnight, John Weidman, and Dark Force + + S-DD1 C emulator code + (c) Copyright 2003 Brad Jorsch with research by + Andreas Naive and John Weidman + + S-RTC C emulator code + (c) Copyright 2001 John Weidman + + ST010 C++ emulator code + (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora + + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + + Super FX C emulator code + (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman + + + SH assembler code partly based on x86 assembler code + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + + + Specific ports contains the works of other authors. See headers in + individual files. + + Snes9x homepage: http://www.snes9x.com + + Permission to use, copy, modify and distribute Snes9x in both binary and + source form, for non-commercial purposes, is hereby granted without fee, + providing that this license information and copyright notice appear with + all copies and any derived work. + + This software is provided 'as-is', without any express or implied + warranty. In no event shall the authors be held liable for any damages + arising from the use of this software. + + Snes9x is freeware for PERSONAL USE only. Commercial users should + seek permission of the copyright holders first. Commercial use includes + charging money for Snes9x or software derived from Snes9x. + + The copyright holders request that bug fixes and improvements to the code + should be forwarded to them so everyone can benefit from the modifications + in future versions. + + Super NES and Super Nintendo Entertainment System are trademarks of + Nintendo Co., Limited and its subsidiary companies. +*******************************************************************************/ + + +uint16 DSP2Op09Word1=0; +uint16 DSP2Op09Word2=0; +bool DSP2Op05HasLen=false; +int DSP2Op05Len=0; +bool DSP2Op06HasLen=false; +int DSP2Op06Len=0; +uint8 DSP2Op05Transparent=0; + +void DSP2_Op05 () +{ + uint8 color; + // Overlay bitmap with transparency. + // Input: + // + // Bitmap 1: i[0] <=> i[size-1] + // Bitmap 2: i[size] <=> i[2*size-1] + // + // Output: + // + // Bitmap 3: o[0] <=> o[size-1] + // + // Processing: + // + // Process all 4-bit pixels (nibbles) in the bitmap + // + // if ( BM2_pixel == transparent_color ) + // pixelout = BM1_pixel + // else + // pixelout = BM2_pixel + + // The max size bitmap is limited to 255 because the size parameter is a byte + // I think size=0 is an error. The behavior of the chip on size=0 is to + // return the last value written to DR if you read DR on Op05 with + // size = 0. I don't think it's worth implementing this quirk unless it's + // proven necessary. + + int n; + unsigned char c1; + unsigned char c2; + unsigned char *p1 = DSP1.parameters; + unsigned char *p2 = &DSP1.parameters[DSP2Op05Len]; + unsigned char *p3 = DSP1.output; + + color = DSP2Op05Transparent&0x0f; + + for( n = 0; n < DSP2Op05Len; n++ ) + { + c1 = *p1++; + c2 = *p2++; + *p3++ = ( ((c2 >> 4) == color ) ? c1 & 0xf0: c2 & 0xf0 ) | + ( ((c2 & 0x0f)==color) ? c1 & 0x0f: c2 & 0x0f ); + } +} + +void DSP2_Op01 () +{ + // Op01 size is always 32 bytes input and output. + // The hardware does strange things if you vary the size. + + int j; + unsigned char c0, c1, c2, c3; + unsigned char *p1 = DSP1.parameters; + unsigned char *p2a = DSP1.output; + unsigned char *p2b = &DSP1.output[16]; // halfway + + // Process 8 blocks of 4 bytes each + + for ( j = 0; j < 8; j++ ) + { + c0 = *p1++; + c1 = *p1++; + c2 = *p1++; + c3 = *p1++; + + *p2a++ = (c0 & 0x10) << 3 | + (c0 & 0x01) << 6 | + (c1 & 0x10) << 1 | + (c1 & 0x01) << 4 | + (c2 & 0x10) >> 1 | + (c2 & 0x01) << 2 | + (c3 & 0x10) >> 3 | + (c3 & 0x01); + + *p2a++ = (c0 & 0x20) << 2 | + (c0 & 0x02) << 5 | + (c1 & 0x20) | + (c1 & 0x02) << 3 | + (c2 & 0x20) >> 2 | + (c2 & 0x02) << 1 | + (c3 & 0x20) >> 4 | + (c3 & 0x02) >> 1; + + *p2b++ = (c0 & 0x40) << 1 | + (c0 & 0x04) << 4 | + (c1 & 0x40) >> 1 | + (c1 & 0x04) << 2 | + (c2 & 0x40) >> 3 | + (c2 & 0x04) | + (c3 & 0x40) >> 5 | + (c3 & 0x04) >> 2; + + + *p2b++ = (c0 & 0x80) | + (c0 & 0x08) << 3 | + (c1 & 0x80) >> 2 | + (c1 & 0x08) << 1 | + (c2 & 0x80) >> 4 | + (c2 & 0x08) >> 1 | + (c3 & 0x80) >> 6 | + (c3 & 0x08) >> 3; + } + return; +} + +void DSP2_Op06 () +{ + // Input: + // size + // bitmap + + int i, j; + + for ( i = 0, j = DSP2Op06Len - 1; i < DSP2Op06Len; i++, j-- ) + { + DSP1.output[j] = (DSP1.parameters[i] << 4) | (DSP1.parameters[i] >> 4); + } +} + +bool DSP2Op0DHasLen=false; +int DSP2Op0DOutLen=0; +int DSP2Op0DInLen=0; + +#ifndef DSP2_BIT_ACCURRATE_CODE + +// Scale bitmap based on input length out output length + +void DSP2_Op0D() +{ + // Overload's algorithm - use this unless doing hardware testing + + // One note: the HW can do odd byte scaling but since we divide + // by two to get the count of bytes this won't work well for + // odd byte scaling (in any of the current algorithm implementations). + // So far I haven't seen Dungeon Master use it. + // If it does we can adjust the parameters and code to work with it + + int i; + int pixel_offset; + uint8 pixelarray[512]; + + for(i=0; i>1] >> 4; + else + pixelarray[i] = DSP1.parameters[pixel_offset>>1] & 0x0f; + } + + for ( i=0; i < DSP2Op0DOutLen; i++ ) + DSP1.output[i] = ( pixelarray[i<<1] << 4 ) | pixelarray[(i<<1)+1]; +} + +#else + +void DSP2_Op0D() +{ + // Bit accurate hardware algorithm - uses fixed point math + // This should match the DSP2 Op0D output exactly + // I wouldn't recommend using this unless you're doing hardware debug. + // In some situations it has small visual artifacts that + // are not readily apparent on a TV screen but show up clearly + // on a monitor. Use Overload's scaling instead. + // This is for hardware verification testing. + // + // One note: the HW can do odd byte scaling but since we divide + // by two to get the count of bytes this won't work well for + // odd byte scaling (in any of the current algorithm implementations). + // So far I haven't seen Dungeon Master use it. + // If it does we can adjust the parameters and code to work with it + + + uint32 multiplier; // Any size int >= 32-bits + uint32 pixloc; // match size of multiplier + int i, j; + uint8 pixelarray[512]; + + if (DSP2Op0DInLen <= DSP2Op0DOutLen) + multiplier = 0x10000; // In our self defined fixed point 0x10000 == 1 + else + multiplier = (DSP2Op0DInLen << 17) / ((DSP2Op0DOutLen<<1) + 1); + + pixloc = 0; + for ( i=0; i < DSP2Op0DOutLen * 2; i++ ) + { + j = pixloc >> 16; + + if ( j & 1 ) + pixelarray[i] = DSP1.parameters[j>>1] & 0x0f; + else + pixelarray[i] = (DSP1.parameters[j>>1] & 0xf0) >> 4; + + pixloc += multiplier; + } + + for ( i=0; i < DSP2Op0DOutLen; i++ ) + DSP1.output[i] = ( pixelarray[i<<1] << 4 ) | pixelarray[(i<<1)+1]; +} + +#endif + +#if 0 // Probably no reason to use this code - it's not quite bit accurate and it doesn't look as good as Overload's algorithm + +void DSP2_Op0D() +{ + // Float implementation of Neviksti's algorithm + // This is the right algorithm to match the DSP2 bits but the precision + // of the PC float does not match the precision of the fixed point math + // on the DSP2 causing occasional one off data mismatches (which should + // be no problem because its just a one pixel difference in a scaled image + // to be displayed). + + float multiplier; + float pixloc; + int i, j; + uint8 pixelarray[512]; + + if (DSP2Op0DInLen <= DSP2Op0DOutLen) + multiplier = (float) 1.0; + else + multiplier = (float) ((DSP2Op0DInLen * 2.0) / (DSP2Op0DOutLen * 2.0 + 1.0)); + + pixloc = 0.0; + for ( i=0; i < DSP2Op0DOutLen * 2; i++ ) + { + // j = (int)(i * multiplier); + j = (int) pixloc; + + if ( j & 1 ) + pixelarray[i] = DSP1.parameters[j>>1] & 0x0f; + else + pixelarray[i] = (DSP1.parameters[j>>1] & 0xf0) >> 4; + + pixloc += multiplier; // use an add in the loop instead of multiply to increase loop speed + } + + for ( i=0; i < DSP2Op0DOutLen; i++ ) + DSP1.output[i] = ( pixelarray[i<<1] << 4 ) | pixelarray[(i<<1)+1]; +} + +#endif \ No newline at end of file diff --git a/src/snes4iphone_src/dspMixer.s b/src/snes4iphone_src/dspMixer.s new file mode 100755 index 0000000..8fda1f4 --- /dev/null +++ b/src/snes4iphone_src/dspMixer.s @@ -0,0 +1,837 @@ + .TEXT + .ARM + .ALIGN + +#include "mixrate.h" + +@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@ Function called with: +@ r0 - Raw brr data (s8*) +@ r1 - Decoded sample data (s16*) +@ r2 - DspChannel *channel +@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@ Function Data: +@ r4 - r4 +@ r5 - r5 +@ r6,r7 - tmp +@ r8 - shift amount +@ r9 - number of iterations left +@ r10 - 0xf +@ r11 - low clip +@ r12 - high clip + + +.GLOBAL brrHash +brrHash: +.word 0 + +.GLOBAL DecodeSampleBlockAsm +DecodeSampleBlockAsm: + stmfd sp!, {r4-r12,r14} + + @ Save the channel pointer + mov r14, r2 + +/* @ Hash the block, and skip the decode if we can + ldmia r0, {r4-r7} + ldr r8, =0x050C5D1F @ (2166136261 * 16777619) + ldr r9, =16777619 + eor r8, r8, r4 + mul r8, r9, r8 + eor r8, r8, r5 + mul r8, r9, r8 + eor r8, r8, r6 + + @ r8 is the hashed value + + ldr r4, brrHash + + @ Compute the actual brr location minus the apu ram base + ldr r6, =APU_MEM + ldr r6, [r6] + sub r6, r0, r6 + + @ Compute the address of the cached samples in brrHash + add r3, r4, #0x8000 + mov r6, r6, lsr #3 + add r3, r3, r6, lsl #5 + + @ Load the previous hash value + ldr r5, [r4, r6, lsl #2] + str r8, [r4, r6, lsl #2] + cmp r5, r8 + bne doDecode + + @ Load the cached samples + ldmia r3, {r4-r11} + stmia r1!, {r4-r11} + + ldrsh r2, [r1, #-2] + ldrsh r3, [r1, #-4] + + b doneDecodeCached + +doDecode: + stmfd sp!, {r3} +*/ + @ Load r2 and r3 + ldrsh r2, [r14, #62] + ldrsh r3, [r14, #64] + + ldrb r4, [r0], #1 + @ Compute the index into the brrTab to load the bytes from + mov r9, r4, lsr #4 + ldr r8, =brrTab + add r8, r8, r9, lsl #5 @ brrTabPtr = brrTab + (r4 * 32) + + mov r10, #0xf << 1 + ldr r11, =0xffff8000 + ldr r12, =0x7fff + + @ 16 samples to decode, but do two at a time + mov r9, #8 + @ Figure out the type of decode filter + mov r4, r4, lsr #2 + and r4, r4, #3 + ldr pc, [pc, r4, lsl #2] + nop +.word case0 +.word case1 +.word case2 +.word case3 +case0: + ldrb r4, [r0], #1 + and r5, r10, r4, lsl #1 + ldrsh r5, [r8, r5] + and r4, r10, r4, lsr #3 + ldrsh r4, [r8, r4] + + mov r4, r4, lsl #1 + mov r5, r5, lsl #1 + strh r4, [r1], #2 + strh r5, [r1], #2 + + subs r9, r9, #1 + bne case0 + + @ Set up r2 and r3 + ldrsh r2, [r1, #-2] + ldrsh r3, [r1, #-4] + + b doneDecode + +case1: + ldrb r4, [r0], #1 + and r5, r10, r4, lsl #1 + ldrsh r5, [r8, r5] + and r4, r10, r4, lsr #3 + ldrsh r4, [r8, r4] + + @ r3 = r4 + (last1 >> 1) - (last1 >> 5) + add r3, r4, r2, asr #1 + sub r3, r3, r2, asr #5 + + cmp r3, r12 + movgt r3, r12 + cmp r3, r11 + movlt r3, r11 + + mov r3, r3, lsl #1 + strh r3, [r1], #2 + ldrsh r3, [r1, #-2] + + @ same for r2 now + add r2, r5, r3, asr #1 + sub r2, r2, r3, asr #5 + + cmp r2, r12 + movgt r2, r12 + cmp r2, r11 + movlt r2, r11 + + mov r2, r2, lsl #1 + strh r2, [r1], #2 + ldrsh r2, [r1, #-2] + + subs r9, r9, #1 + bne case1 + + b doneDecode + +case2: + ldrb r4, [r0], #1 + and r5, r10, r4, lsl #1 + ldrsh r5, [r8, r5] + and r4, r10, r4, lsr #3 + ldrsh r4, [r8, r4] + + @ Sample 1 + mov r6, r3, asr #1 + rsb r6, r6, r3, asr #5 + mov r3, r2 + add r7, r2, r2, asr #1 + rsb r7, r7, #0 + add r6, r6, r7, asr #5 + add r7, r4, r2 + add r2, r6, r7 + + cmp r2, r12 + movgt r2, r12 + cmp r2, r11 + movlt r2, r11 + mov r2, r2, lsl #1 + strh r2, [r1], #2 + ldrsh r2, [r1, #-2] + + @ Sample 2 + mov r6, r3, asr #1 + rsb r6, r6, r3, asr #5 + mov r3, r2 + add r7, r2, r2, asr #1 + rsb r7, r7, #0 + add r6, r6, r7, asr #5 + add r7, r5, r2 + add r2, r6, r7 + + cmp r2, r12 + movgt r2, r12 + cmp r2, r11 + movlt r2, r11 + mov r2, r2, lsl #1 + strh r2, [r1], #2 + ldrsh r2, [r1, #-2] + + subs r9, r9, #1 + bne case2 + + b doneDecode + +case3: + ldrb r4, [r0], #1 + and r5, r10, r4, lsl #1 + ldrsh r5, [r8, r5] + and r4, r10, r4, lsr #3 + ldrsh r4, [r8, r4] + + @ Sample 1 + add r6, r3, r3, asr #1 + mov r6, r6, asr #4 + sub r6, r6, r3, asr #1 + mov r3, r2 + add r7, r2, r2, lsl #2 + add r7, r7, r2, lsl #3 + rsb r7, r7, #0 + add r6, r6, r7, asr #7 + add r6, r6, r2 + add r2, r4, r6 + + cmp r2, r12 + movgt r2, r12 + cmp r2, r11 + movlt r2, r11 + mov r2, r2, lsl #1 + strh r2, [r1], #2 + ldrsh r2, [r1, #-2] + + @ Sample 2 + add r6, r3, r3, asr #1 + mov r6, r6, asr #4 + sub r6, r6, r3, asr #1 + mov r3, r2 + add r7, r2, r2, lsl #2 + add r7, r7, r2, lsl #3 + rsb r7, r7, #0 + add r6, r6, r7, asr #7 + add r6, r6, r2 + add r2, r5, r6 + + cmp r2, r12 + movgt r2, r12 + cmp r2, r11 + movlt r2, r11 + mov r2, r2, lsl #1 + strh r2, [r1], #2 + ldrsh r2, [r1, #-2] + + subs r9, r9, #1 + bne case3 + +doneDecode: +/* sub r1, r1, #32 + ldmia r1, {r4-r11} + ldmfd sp!, {r1} + stmia r1, {r4-r11}*/ + +doneDecodeCached: + @ Store r2 and r3 + strh r2, [r14, #62] + strh r3, [r14, #64] + + ldmfd sp!, {r4-r12,r14} + bx lr + +#define ENVSTATE_INCREASE 6 +#define ENVSTATE_BENTLINE 7 +#define ENVSTATE_DECREASE 8 +#define ENVSTATE_DECEXP 9 + +@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@ Function called with: +@ r0 - int Number of samples to mix +@ r1 - u16* mix buffer (left first, right is always 4000 * 4 bytes ahead +@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + +#define PREVDECODE_OFFSET 16 +#define BLOCKPOS_OFFSET 66 +#define KEYWAIT_OFFSET 76 + +@ r0 - channel structure base +@ r1 - mix buffer +@ r2 - echo buffer ptr +@ r3 - numSamples +@ r4 - sampleSpeed +@ r5 - samplePos +@ r6 - envCount +@ r7 - envSpeed +@ r8 - sampleValue (value of the current sample) +@ r9 - tmp +@ r10 - leftCalcVol +@ r11 - rightCalcVol +@ r12 - tmp +@ r13 - tmp +@ r14 - tmp + +.GLOBAL DspMixSamplesStereo +.FUNC DspMixSamplesStereo +DspMixSamplesStereo: + stmfd sp!, {r4-r12, lr} + + mov r3, #0 + strb r3, channelNum + str r0, numSamples + + @ Store the original mix buffer for use later + stmfd sp!, {r1} + + @ Clear the left and right mix buffers, saving their initial positions + ldr r1, =r1 + ldr r2, =echoBuffer + mov r3, #0 + mov r4, #0 + mov r5, #0 + mov r6, #0 +clearLoop: + stmia r1!, {r3-r6} + stmia r1!, {r3-r6} + stmia r2!, {r3-r6} + stmia r2!, {r3-r6} + subs r0, r0, #4 + cmp r0, #0 + bgt clearLoop + + @ Load the initial mix buffer and echo position + ldr r1, =r1 + ldr r2, =echoBuffer + + ldr r0, =channels +channelLoopback: + @ Check if active == 0, then next + ldrb r3, [r0, #77] + cmps r3, #0 + beq nextChannelNothingDone + + @ Save the start position of the mix buffer & echo buffer + stmfd sp!, {r1,r2} + + @ Get echo enabled, then replace the opcode there if it's enabled + ldrb r14, [r0, #79] + cmp r14, #1 + ldr r3, =0x01A00000 @ mov r0, r0 + streq r3, branchLocation + + ldrb r3, numSamples + @ Load the important variables into registers + ldmia r0, {r4-r7} + ldrsh r10, [r0, #68] + ldrsh r11, [r0, #70] + +mixLoopback: + + @ Commence the mixing + subs r6, r6, r7 + bpl noEnvelopeUpdate + + @ Update envelope + mov r6, #0x7800 + + ldrsh r9, [r0, #60] + ldrb r12, [r0, #72] + + ldr pc, [pc, r12, lsl #2] + nop +@ Jump table for envelope handling +.word noEnvelopeUpdate +.word envStateAttack +.word envStateDecay +.word envStateSustain +.word envStateRelease +.word noEnvelopeUpdate @ Actually direct, but we don't need to do anything +.word envStateIncrease +.word envStateBentline +.word envStateDecrease +.word envStateSustain @ Actually decrease exponential, but it's the same code + +envStateAttack: + add r9, r9, #4 << 8 + + cmp r9, #0x7f00 + ble storeEnvx + @ envx = 0x7f, state = decay, speed = decaySpeed + mov r9, #0x7f00 + mov r12, #2 + strb r12, [r0, #72] + ldrh r7, [r0, #56] + b storeEnvx + +envStateDecay: + rsb r9, r9, r9, lsl #8 + mov r9, r9, asr #8 + + ldrb r12, [r0, #73] + cmp r9, r12, lsl #8 + bge storeEnvx + @ state = sustain, speed = sustainSpeed + mov r12, #3 + strb r12, [r0, #72] + ldrh r7, [r0, #58] + + @ Make sure envx > 0 + cmp r9, #0 + bge storeEnvx + + @ If not, end channel, then go to next channel + stmfd sp!, {r0-r3, r14} + ldrb r0, channelNum + bl DspSetEndOfSample + ldmfd sp!, {r0-r3, r14} + b nextChannel + +envStateSustain: + rsb r9, r9, r9, lsl #8 + mov r9, r9, asr #8 + + @ Make sure envx > 0 + cmp r9, #0 + bge storeEnvx + + @ If not, end channel, then go to next channel + stmfd sp!, {r0-r3,r14} + ldrb r0, channelNum + bl DspSetEndOfSample + ldmfd sp!, {r0-r3,r14} + b nextChannel + +envStateRelease: + sub r9, r9, #1 << 8 + + @ Make sure envx > 0 + cmp r9, #0 + bge storeEnvx + + @ If not, end channel, then go to next channel + stmfd sp!, {r0-r3,r14} + ldrb r0, channelNum + bl DspSetEndOfSample + ldmfd sp!, {r0-r3,r14} + b nextChannel + +envStateIncrease: + add r9, r9, #4 << 8 + + cmp r9, #0x7f00 + ble storeEnvx + @ envx = 0x7f, state = direct, speed = 0 + mov r9, #0x7f00 + mov r12, #5 + strb r12, [r0, #72] + mov r7, #0 + b storeEnvx + +envStateBentline: + cmp r9, #0x5f << 8 + addgt r9, r9, #1 << 8 + addle r9, r9, #4 << 8 + + cmp r9, #0x7f00 + blt storeEnvx + @ envx = 0x7f, state = direct, speed = 0 + mov r9, #0x7f00 + mov r12, #5 + strb r12, [r0, #72] + mov r7, #0 + b storeEnvx + +envStateDecrease: + sub r9, r9, #4 << 8 + + @ Make sure envx > 0 + cmp r9, #0 + bge storeEnvx + + @ If not, end channel, then go to next channel + stmfd sp!, {r0-r3,r14} + ldrb r0, channelNum + bl DspSetEndOfSample + ldmfd sp!, {r0-r3,r14} + b nextChannel + +storeEnvx: + strh r9, [r0, #60] + + @ Recalculate leftCalcVol and rightCalcVol + ldrsb r10, [r0, #74] + mul r10, r9, r10 + mov r10, r10, asr #7 + + ldrsb r11, [r0, #75] + mul r11, r9, r11 + mov r11, r11, asr #7 + +noEnvelopeUpdate: + add r5, r5, r4 + cmp r5, #16 << 12 + blo noSampleUpdate + + @ Decode next 16 bytes... + sub r5, r5, #16 << 12 + + @ Decode the sample block, r0 = DspChannel* + stmfd sp!, {r0-r3, r14} + bl DecodeSampleBlock + cmps r0, #1 + ldmfd sp!, {r0-r3, r14} + beq nextChannel + +noSampleUpdate: + @ This is really a >> 12 then << 1, but since samplePos bit 0 will never be set, it's safe. + @ Must ensure that sampleSpeed bit 0 is never set, and samplePos is never set to anything but 0 + @ TODO - The speed up hack doesn't work. Find out why + mov r12, r5, lsr #12 + add r12, r0, r12, lsl #1 + ldrsh r8, [r12, #24] + +branchLocation: + b mixEchoDisabled + +mixEchoEnabled: + @ Echo mixing + ldr r9, [r2] + mla r9, r8, r10, r9 + str r9, [r2], #4 + + ldr r9, [r2] + mla r9, r8, r11, r9 + str r9, [r2], #4 + +mixEchoDisabled: + ldr r9, [r1] + mla r9, r8, r10, r9 + str r9, [r1], #4 + + ldr r9, [r1] + mla r9, r8, r11, r9 + str r9, [r1], #4 + + subs r3, r3, #1 + bne mixLoopback + +nextChannel: + + @ Set ENVX and OUTX + ldrb r3, channelNum + ldr r12, =DSP_MEM + add r12, r12, r3, lsl #4 + + @ Set ENVX + ldrsh r9, [r0, #60] + mov r9, r9, asr #8 + strb r9, [r12, #0x8] + + @ Set OUTX + mul r9, r8, r9 + mov r9, r9, asr #15 + strb r9, [r12, #0x9] + + strh r10, [r0, #68] + strh r11, [r0, #70] + + @ Store changing values + stmia r0, {r4-r7} + + @ Reload mix&echo buffer position + ldmfd sp!, {r1,r2} + +nextChannelNothingDone: + @ Move to next channel + add r0, r0, #80 + + @ Increment channelNum + ldrb r3, channelNum + add r3, r3, #1 + strb r3, channelNum + cmps r3, #8 + blt channelLoopback + +@ This is the end of normal mixing + +#ifdef NEVER + @ Store the original mix & echo buffers, cause we trash these regs + stmfd sp!, {r1, r2} + + @ r0 - + @ r1 - + @ r2 - + @ r3 - + @ r4 - + @ r5 - echo volume (right) + @ r6 - numSamples + @ r7 - echo in apu ram (r/w) + @ r8 - echo mix buffer (r/w) + @ r9 - end of echo in apu ram + @ r10 - echo volume (left) + @ r11 - echo feedback + @ r12 - FIR coefficients in DSP ram + @ r13 - FIR table base + @ r14 - FIR offset + +@ Process the echo filter stuff +echoMixSetup: + mov r8, r2 + + ldr r0, =DSP_MEM + + ldrsb r10, [r0, #0x2C] @ Get left echo volume + mov r10, r10, lsl #7 + ldrsb r5, [r0, #0x3C] @ Get right echo volume + mov r5, r5, lsl #7 + + @ Get echo feedback + ldrsb r11, [r0, #0x0D] + + @ Check if echo is enabled + ldrb r1, [r0, #0x6C] + strb r1, echoEnabled + @ Get echo base (APU_MEM + DSP_ESA << 8) + ldr r7, =echoBase + ldr r7, [r7] + str r7, echoBufferStart + @ Set up end of echo delay area in r8 + ldr r0, =echoDelay + ldrh r0, [r0] + add r9, r7, r0 + + @ Set up current echo cursor location + ldr r0, =echoCursor + ldrh r0, [r0] + add r7, r7, r0 + +@ str r13, tmpSp + + ldr r14, =firOffset + ldrb r14, [r14] + + @ Offset firTable to start at FIR #7 + ldr r12, =DSP_MEM + add r12, r12, #0x7F + + ldr r6, numSamples + +echoMixLoopback: + @ Load the old echo value (l,r) + ldrsh r0, [r7] + ldrsh r1, [r7, #2] + +/* @ Increment and wrap firOffset + add r14, r14, #2 + and r14, r14, #(8 * 2) - 1 + + @ Get &firTable[firOffset + 8] into r13 + ldr r13, =firTable + ((8 * 2) * 4) + add r13, r13, r14, lsl #2 + + @ Store the computed samples in the FIR ring buffer + str r0, [r13] + str r1, [r13, #4] + str r0, [r13, #-8 * 2 * 4] + str r1, [r13, #(-8 * 2 * 4) + 4] + + @ Process FIR sample 0 (special) + ldr r2, [r13], #4 + ldr r3, [r13], #-12 + ldrsb r4, [r12], #-0x10 + mul r0, r2, r4 + mul r1, r3, r4 + +.MACRO processFir + ldr r2, [r13], #4 + ldr r3, [r13], #-12 + ldrsb r4, [r12], #-0x10 + mla r0, r2, r4, r0 + mla r1, r3, r4, r1 +.ENDM + processFir + processFir + processFir + processFir + processFir + processFir + + @ Last FIR sample (special) + ldr r2, [r13], #4 + ldr r3, [r13], #-12 + ldrsb r4, [r12], #0x70 + + mla r0, r2, r4, r0 + mla r1, r3, r4, r1 + + @ Get rid of volume multiplication stuff + mov r0, r0, asr #7 + mov r1, r1, asr #7*/ + + @ r0,r1 contains the filtered samples + ldr r2, [r8] + @ Left channel = (feedback * filtered) >> 7 + mla r2, r11, r0, r2 + mov r2, r2, asr #15 + + ldr r3, [r8, #4] + @ Right channel = (feedback * filtered) >> 7 + mla r3, r11, r1, r3 + mov r3, r3, asr #15 + + @ Store (filtered * echoFB) + echobuffer into echobuffer + ldrb r5, echoEnabled + tst r5, #0x20 + streqh r2, [r7], #2 + streqh r3, [r7], #2 + cmp r7, r9 + ldrge r7, echoBufferStart + + @ Store (filtered * echoVol) into echomix + mul r2, r10, r0 + str r2, [r8], #4 + mul r2, r5, r1 + str r2, [r8], #4 + + subs r6, r6, #1 + bne echoMixLoopback + +doneEchoMix: + +/* ldr r13, tmpSp + + @ Store changed values + ldr r0, =firOffset + strb r14, [r0]*/ + + ldr r3, echoBufferStart + sub r7, r7, r3 + ldr r0, =echoCursor + strh r7, [r0] + + @ Reload mix buffer & echo positions + ldmfd sp!, {r1, r2} + +#endif + +clipAndMix: + @ Put the original output buffer into r3 + ldmfd sp!, {r3} + + @ Set up the preamp & overall volume + ldr r8, =dspPreamp + ldrh r8, [r8] + + ldr r9, =DSP_MEM + ldrsb r4, [r9, #0x0C] @ Main left volume + ldrsb r6, [r9, #0x1C] @ Main right volume + + mul r4, r8, r4 + mov r4, r4, asr #7 + mul r6, r8, r6 + mov r6, r6, asr #7 + + @ r0 - numSamples + @ r1 - mix buffer + @ r2 - echo buffer + @ r3 - output buffer + @ r4 - left volume + @ r5 - TMP (assigned to sample value) + @ r6 - right volume + @ r7 - TMP + @ r8 - preamp + @ r9 - + @ r10 - + @ r11 - + @ r12 - + @ r14 - + + @ Do volume multiplication, mix in echo buffer and clipping here + ldr r0, numSamples + +mixClipLoop: + @ Load and scale by volume (LEFT) + ldr r5, [r1], #4 + mov r5, r5, asr #15 + mul r5, r4, r5 + ldr r7, [r2], #4 + add r5, r5, r7, asr #7 + mov r5, r5, asr #7 + + @ Clip and store + cmp r5, #0x7f00 + movgt r5, #0x7f00 + cmn r5, #0x7f00 + movlt r5, #0x8100 + strh r5, [r3] + add r3, r3, #4000 * 4 + + @ Load and scale by volume (RIGHT) + ldr r5, [r1], #4 + mov r5, r5, asr #15 + mul r5, r6, r5 + ldr r7, [r2], #4 + add r5, r5, r7, asr #7 + mov r5, r5, asr #7 + + @ Clip and store + cmp r5, #0x7f00 + movgt r5, #0x7f00 + cmn r5, #0x7f00 + movlt r5, #0x8100 + strh r5, [r3], #2 + sub r3, r3, #4000 * 4 + + subs r0, r0, #1 + bne mixClipLoop + +doneMix: + ldmfd sp!, {r4-r12, lr} + bx lr +.ENDFUNC + +.GLOBAL channelNum + +tmpSp: +.word 0 +echoBufferStart: +.word 0 +numSamples: +.word 0 +channelNum: +.byte 0 +echoEnabled: +.byte 0 + +.align +.pool diff --git a/src/snes4iphone_src/font.h b/src/snes4iphone_src/font.h new file mode 100755 index 0000000..8fde4c2 --- /dev/null +++ b/src/snes4iphone_src/font.h @@ -0,0 +1,99 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +static char *font[] = { +" . . . . .. . . ", +" .#. .#.#. . . ... .#. . . .##. .#. .#. . . . . ", +" .#. .#.#. .#.#. .###. .#..#. .#. .#. .#. .#. .#.#. .#. .#. ", +" .#. .#.#. .#####. .#.#. ..#. .#.#. .#. .#. .#. .#. ..#.. .... .#. ", +" .#. . . .#.#. .###. .#.. .#. . .#. .#. .###. .#####. .. .####. .. .#. ", +" . .#####. .#.#. .#..#. .#.#. .#. .#. .#. ..#.. .##. .... .##. .#. ", +" .#. .#.#. .###. . .#. .#.#. .#. .#. .#.#. .#. .#. .##. . ", +" . . . ... . . . . . . . . .#. .. ", +" . ", +" . . .. .... . .... .. .... .. .. . ", +" .#. .#. .##. .####. .#. .####. .##. .####. .##. .##. .. .. . . .#. ", +".#.#. .##. .#..#. ...#. .##. .#... .#.. ...#. .#..#. .#..#. .##. .##. .#. .... .#. .#.#. ", +".#.#. .#. . .#. .##. .#.#. .###. .###. .#. .##. .#..#. .##. .##. .#. .####. .#. ..#. ", +".#.#. .#. .#. ...#. .####. ...#. .#..#. .#. .#..#. .###. .. .. .#. .... .#. .#. ", +".#.#. .#. .#.. .#..#. ..#. .#..#. .#..#. .#. .#..#. ..#. .##. .##. .#. .####. .#. . ", +" .#. .###. .####. .##. .#. .##. .##. .#. .##. .##. .##. .#. .#. .... .#. .#. ", +" . ... .... .. . .. .. . .. .. .. .#. . . . ", +" . ", +" .. .. ... .. ... .... .... .. . . ... . . . . . . . . .. ", +" .##. .##. .###. .##. .###. .####. .####. .##. .#..#. .###. .#. .#..#. .#. .#. .#. .#. .#. .##. ", +".#..#. .#..#. .#..#. .#..#. .#..#. .#... .#... .#..#. .#..#. .#. .#. .#.#. .#. .##.##. .##..#. .#..#. ", +".#.##. .#..#. .###. .#. . .#..#. .###. .###. .#... .####. .#. .#. .##. .#. .#.#.#. .#.#.#. .#..#. ", +".#.##. .####. .#..#. .#. . .#..#. .#.. .#.. .#.##. .#..#. .#. . .#. .##. .#. .#...#. .#.#.#. .#..#. ", +".#... .#..#. .#..#. .#..#. .#..#. .#... .#. .#..#. .#..#. .#. .#..#. .#.#. .#... .#. .#. .#..##. .#..#. ", +" .##. .#..#. .###. .##. .###. .####. .#. .###. .#..#. .###. .##. .#..#. .####. .#. .#. .#. .#. .##. ", +" .. . . ... .. ... .... . ... . . ... .. . . .... . . . . .. ", +" ", +" ... .. ... .. ... . . . . . . . . . . .... ... ... . ", +".###. .##. .###. .##. .###. .#. .#. .#. .#. .#. .#. .#..#. .#.#. .####. .###. . .###. .#. ", +".#..#. .#..#. .#..#. .#..#. .#. .#. .#. .#. .#. .#...#. .#..#. .#.#. ...#. .#.. .#. ..#. .#.#. ", +".#..#. .#..#. .#..#. .#.. .#. .#. .#. .#. .#. .#.#.#. .##. .#.#. .#. .#. .#. .#. . . ", +".###. .#..#. .###. ..#. .#. .#. .#. .#. .#. .#.#.#. .#..#. .#. .#. .#. .#. .#. ", +".#.. .##.#. .#.#. .#..#. .#. .#...#. .#.#. .##.##. .#..#. .#. .#... .#.. .#. ..#. .... ", +".#. .##. .#..#. .##. .#. .###. .#. .#. .#. .#..#. .#. .####. .###. . .###. .####. ", +" . ..#. . . .. . ... . . . . . . .... ... ... .... ", +" . ", +" .. . . . . . . . .. ", +".##. .#. .#. .#. .#. .#. .#. .#. .##. ", +" .#. ... .#.. .. ..#. .. .#.#. ... .#.. .. . .#.. .#. .. .. ... .. ", +" .#. .###. .###. .##. .###. .##. .#.. .###. .###. .##. .#. .#.#. .#. .##.##. .###. .##. ", +" . .#..#. .#..#. .#.. .#..#. .#.##. .###. .#..#. .#..#. .#. .#. .##. .#. .#.#.#. .#..#. .#..#. ", +" .#.##. .#..#. .#.. .#..#. .##.. .#. .##. .#..#. .#. ..#. .#.#. .#. .#...#. .#..#. .#..#. ", +" .#.#. .###. .##. .###. .##. .#. .#... .#..#. .###. .#.#. .#..#. .###. .#. .#. .#..#. .##. ", +" . . ... .. ... .. . .###. . . ... .#. . . ... . . . . .. ", +" ... . ", +" . . . . . . ", +" .#. .#. .#. .#. .#.#. ", +" ... ... ... ... .#. . . . . . . . . . . .... .#. .#. .#. .#.#. ", +".###. .###. .###. .###. .###. .#..#. .#.#. .#...#. .#..#. .#..#. .####. .##. .#. .##. . . ", +".#..#. .#..#. .#..#. .##.. .#. .#..#. .#.#. .#.#.#. .##. .#..#. ..#. .#. .#. .#. ", +".#..#. .#..#. .#. . ..##. .#.. .#..#. .#.#. .#.#.#. .##. .#.#. .#.. .#. .#. .#. ", +".###. .###. .#. .###. .##. .###. .#. .#.#. .#..#. .#. .####. .#. .#. .#. ", +".#.. ..#. . ... .. ... . . . . . .#. .... . . . ", +" . . . ", +}; + +static int font_width = 8; +static int font_height = 9; diff --git a/src/snes4iphone_src/frame_skip.cpp b/src/snes4iphone_src/frame_skip.cpp new file mode 100755 index 0000000..d656a0d --- /dev/null +++ b/src/snes4iphone_src/frame_skip.cpp @@ -0,0 +1,99 @@ +#include +#include +#include +#include +#include "frame_skip.h" +#include "memmap.h" + +#ifndef uclock_t +#define uclock_t unsigned int +#endif + +#define TICKS_PER_SEC 1000000UL +//#define CPU_FPS 60 +static int CPU_FPS=60; +static uclock_t F; + +#define MAX_FRAMESKIP 10 + + +static char init_frame_skip = 1; +char skip_next_frame = 0; +static struct timeval init_tv = { 0, 0 }; + + +void reset_frame_skip(void) +{ + //static Uint8 init=0; + + init_tv.tv_usec = 0; + init_tv.tv_sec = 0; + skip_next_frame = 0; + init_frame_skip = 1; + CPU_FPS=Memory.ROMFramesPerSecond; + + F = (uclock_t) ((double) TICKS_PER_SEC / CPU_FPS); +} + +uclock_t get_ticks(void) +{ + struct timeval tv; + + gettimeofday(&tv, 0); + if (init_tv.tv_sec == 0) + init_tv = tv; + return (tv.tv_sec - init_tv.tv_sec) * TICKS_PER_SEC + tv.tv_usec - + init_tv.tv_usec; + + +} + +int frame_skip(void) +{ + static int f2skip; + static uclock_t sec = 0; + static uclock_t rfd; + static uclock_t target; + static int nbFrame = 0; + static int skpFrm = 0; + + if (init_frame_skip) { + init_frame_skip = 0; + target = get_ticks(); + nbFrame = 0; + //f2skip=0; + //skpFrm=0; + sec = 0; + return 0; + } + + target += F; + if (f2skip > 0) { + f2skip--; + skpFrm++; + return 1; + } else + skpFrm = 0; + + + rfd = get_ticks(); + + if (rfd < target && f2skip == 0) { + while (get_ticks() < target); + } else { + f2skip = (rfd - target) / (double) F; + if (f2skip > MAX_FRAMESKIP) { + f2skip = MAX_FRAMESKIP; + reset_frame_skip(); + } + // printf("Skip %d frame(s) %lu %lu\n",f2skip,target,rfd); + } + + + nbFrame++; + if (get_ticks() - sec >= TICKS_PER_SEC) { + nbFrame = 0; + sec = get_ticks(); + } + return 0; +} diff --git a/src/snes4iphone_src/frame_skip.h b/src/snes4iphone_src/frame_skip.h new file mode 100755 index 0000000..0e3627f --- /dev/null +++ b/src/snes4iphone_src/frame_skip.h @@ -0,0 +1,9 @@ +#ifndef _FRAME_SKIP_H +#define _FRAME_SKIP_H + + +void reset_frame_skip(void); +int frame_skip(void); + + +#endif diff --git a/src/snes4iphone_src/fxdbg.cpp b/src/snes4iphone_src/fxdbg.cpp new file mode 100755 index 0000000..71549cb --- /dev/null +++ b/src/snes4iphone_src/fxdbg.cpp @@ -0,0 +1,360 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ + +#include "fxemu.h" +#include "fxinst.h" +#include +#include + +extern const char *fx_apvMnemonicTable[]; +extern struct FxRegs_s GSU; + + +/* + When printing a line from the pipe, it could look like this: + + 01:8006 f4 fb 86 iwt r4,#$86fb + + The values are: + program bank: 01 + adress: 8006 + values at memory address 8006: f4 fb 86 + instruction in the pipe: iwt r4,#$86fb + + Note! If the instruction has more than one byte (like in 'iwt') + and the instruction is in a delay slot, the second and third + byte displayed will not be the same as those used. + Since the instrction is in a delay slot, the first byte + of the instruction will be taken from the pipe at the address + after the branch instruction, and the next one or two bytes + will be taken from the address that the branch points to. + This is a bit complicated, but I've taken this into account, + in this debug function. (See the diffrence of how the values + vPipe1 and vPipe2 are read, compared to the values vByte1 and + vByte2) + + */ +void FxPipeString(char * pvString) +{ + char *p; + uint32 vOpcode = (GSU.vStatusReg & 0x300) | ((uint32)PIPE); + const char *m = fx_apvMnemonicTable[vOpcode]; + uint8 vPipe1,vPipe2,vByte1,vByte2; + uint8 vPipeBank = GSU.vPipeAdr >> 16; + + /* The next two bytes after the pipe's address */ + vPipe1 = GSU.apvRomBank[vPipeBank][USEX16(GSU.vPipeAdr+1)]; + vPipe2 = GSU.apvRomBank[vPipeBank][USEX16(GSU.vPipeAdr+2)]; + + /* The actual next two bytes to be read */ + vByte1 = PRGBANK(USEX16(R15)); + vByte2 = PRGBANK(USEX16(R15+1)); + + /* Print ROM address of the pipe */ + sprintf(pvString, "%02x:%04x %02x ", + USEX8(vPipeBank), USEX16(GSU.vPipeAdr), USEX8(PIPE)); + p = &pvString[strlen(pvString)]; + + /* Check if it's a branch instruction */ + if( PIPE >= 0x05 && PIPE <= 0x0f ) + { + sprintf(&pvString[11], "%02x ", USEX8(vPipe1)); +#ifdef BRANCH_DELAY_RELATIVE + sprintf(p, m, USEX16(R15 + SEX8(vByte1) + 1 ) ); +#else + sprintf(p, m, USEX16(R15 + SEX8(vByte1) - 1 ) ); +#endif + } + /* Check for 'move' instruction */ + else if( PIPE >= 0x10 && PIPE <= 0x1f && TF(B) ) + sprintf(p, "move r%d,r%d", USEX8(PIPE & 0x0f), GSU.pvSreg - GSU.avReg); + /* Check for 'ibt', 'lms' or 'sms' */ + else if( PIPE >= 0xa0 && PIPE <= 0xaf ) + { + sprintf(&pvString[11], "%02x ", USEX8(vPipe1)); + if( (GSU.vStatusReg & 0x300) == 0x100 || (GSU.vStatusReg & 0x300) == 0x200 ) + sprintf(p, m, USEX16(vByte1) << 1 ); + else + sprintf(p, m, USEX16(vByte1) ); + } + /* Check for 'moves' */ + else if( PIPE >= 0xb0 && PIPE <= 0xbf && TF(B) ) + sprintf(p, "moves r%d,r%d", GSU.pvDreg - GSU.avReg, USEX8(PIPE & 0x0f) ); + /* Check for 'iwt', 'lm' or 'sm' */ + else if( PIPE >= 0xf0 ) + { + sprintf(&pvString[11], "%02x %02x ", USEX8(vPipe1), USEX8(vPipe2)); + sprintf(p, m, USEX8(vByte1) | (USEX16(vByte2)<<8) ); + } + /* Normal instruction */ + else + strcpy(p, m); +} + +const char *fx_apvMnemonicTable[] = +{ + /* + * ALT0 Table + */ + /* 00 - 0f */ + "stop", "nop", "cache", "lsr", "rol", "bra $%04x","blt $%04x","bge $%04x", + "bne $%04x","beq $%04x","bpl $%04x","bmi $%04x","bcc $%04x","bcs $%04x","bvc $%04x","bvs $%04x", + /* 10 - 1f */ + "to r0", "to r1", "to r2", "to r3", "to r4", "to r5", "to r6", "to r7", + "to r8", "to r9", "to r10", "to r11", "to r12", "to r13", "to r14", "to r15", + /* 20 - 2f */ + "with r0", "with r1", "with r2", "with r3", "with r4", "with r5", "with r6", "with r7", + "with r8", "with r9", "with r10", "with r11", "with r12", "with r13", "with r14", "with r15", + /* 30 - 3f */ + "stw (r0)","stw (r1)","stw (r2)", "stw (r3)", "stw (r4)", "stw (r5)", "stw (r6)", "stw (r7)", + "stw (r8)","stw (r9)","stw (r10)","stw (r11)","loop", "alt1", "alt2", "alt3", + /* 40 - 4f */ + "ldw (r0)","ldw (r1)","ldw (r2)", "ldw (r3)", "ldw (r4)", "ldw (r5)", "ldw (r6)", "ldw (r7)", + "ldw (r8)","ldw (r9)","ldw (r10)","ldw (r11)","plot", "swap", "color", "not", + /* 50 - 5f */ + "add r0", "add r1", "add r2", "add r3", "add r4", "add r5", "add r6", "add r7", + "add r8", "add r9", "add r10", "add r11", "add r12", "add r13", "add r14", "add r15", + /* 60 - 6f */ + "sub r0", "sub r1", "sub r2", "sub r3", "sub r4", "sub r5", "sub r6", "sub r7", + "sub r8", "sub r9", "sub r10", "sub r11", "sub r12", "sub r13", "sub r14", "sub r15", + /* 70 - 7f */ + "merge", "and r1", "and r2", "and r3", "and r4", "and r5", "and r6", "and r7", + "and r8", "and r9", "and r10", "and r11", "and r12", "and r13", "and r14", "and r15", + /* 80 - 8f */ + "mult r0", "mult r1", "mult r2", "mult r3", "mult r4", "mult r5", "mult r6", "mult r7", + "mult r8", "mult r9", "mult r10", "mult r11", "mult r12", "mult r13", "mult r14", "mult r15", + /* 90 - 9f */ + "sbk", "link #1", "link #2", "link #3", "link #4", "sex", "asr", "ror", + "jmp (r8)","jmp (r9)","jmp (r10)","jmp (r11)","jmp (r12)","jmp (r13)","lob", "fmult", + /* a0 - af */ + "ibt r0,#$%02x", "ibt r1,#$%02x", "ibt r2,#$%02x", "ibt r3,#$%02x", + "ibt r4,#$%02x", "ibt r5,#$%02x", "ibt r6,#$%02x", "ibt r7,#$%02x", + "ibt r8,#$%02x", "ibt r9,#$%02x", "ibt r10,#$%02x", "ibt r11,#$%02x", + "ibt r12,#$%02x", "ibt r13,#$%02x", "ibt r14,#$%02x", "ibt r15,#$%02x", + /* b0 - bf */ + "from r0", "from r1", "from r2", "from r3", "from r4", "from r5", "from r6", "from r7", + "from r8", "from r9", "from r10", "from r11", "from r12", "from r13", "from r14", "from r15", + /* c0 - cf */ + "hib", "or r1", "or r2", "or r3", "or r4", "or r5", "or r6", "or r7", + "or r8", "or r9", "or r10", "or r11", "or r12", "or r13", "or r14", "or r15", + /* d0 - df */ + "inc r0", "inc r1", "inc r2", "inc r3", "inc r4", "inc r5", "inc r6", "inc r7", + "inc r8", "inc r9", "inc r10", "inc r11", "inc r12", "inc r13", "inc r14", "getc", + /* e0 - ef */ + "dec r0", "dec r1", "dec r2", "dec r3", "dec r4", "dec r5", "dec r6", "dec r7", + "dec r8", "dec r9", "dec r10", "dec r11", "dec r12", "dec r13", "dec r14", "getb", + /* f0 - ff */ + "iwt r0,#$%04x", "iwt r1,#$%04x", "iwt r2,#$%04x", "iwt r3,#$%04x", + "iwt r4,#$%04x", "iwt r5,#$%04x", "iwt r6,#$%04x", "iwt r7,#$%04x", + "iwt r8,#$%04x", "iwt r9,#$%04x", "iwt r10,#$%04x", "iwt r11,#$%04x", + "iwt r12,#$%04x", "iwt r13,#$%04x", "iwt r14,#$%04x", "iwt r15,#$%04x", + + /* + * ALT1 Table + */ + + /* 00 - 0f */ + "stop", "nop", "cache", "lsr", "rol", "bra $%04x","blt $%04x","bge $%04x", + "bne $%04x","beq $%04x","bpl $%04x","bmi $%04x","bcc $%04x","bcs $%04x","bvc $%04x","bvs $%04x", + /* 10 - 1f */ + "to r0", "to r1", "to r2", "to r3", "to r4", "to r5", "to r6", "to r7", + "to r8", "to r9", "to r10", "to r11", "to r12", "to r13", "to r14", "to r15", + /* 20 - 2f */ + "with r0", "with r1", "with r2", "with r3", "with r4", "with r5", "with r6", "with r7", + "with r8", "with r9", "with r10", "with r11", "with r12", "with r13", "with r14", "with r15", + /* 30 - 3f */ + "stb (r0)","stb (r1)","stb (r2)", "stb (r3)", "stb (r4)", "stb (r5)", "stb (r6)", "stb (r7)", + "stb (r8)","stb (r9)","stb (r10)","stb (r11)","loop", "alt1", "alt2", "alt3", + /* 40 - 4f */ + "ldb (r0)","ldb (r1)","ldb (r2)", "ldb (r3)", "ldb (r4)", "ldb (r5)", "ldb (r6)", "ldb (r7)", + "ldb (r8)","ldb (r9)","ldb (r10)","ldb (r11)","rpix", "swap", "cmode", "not", + /* 50 - 5f */ + "adc r0", "adc r1", "adc r2", "adc r3", "adc r4", "adc r5", "adc r6", "adc r7", + "adc r8", "adc r9", "adc r10", "adc r11", "adc r12", "adc r13", "adc r14", "adc r15", + /* 60 - 6f */ + "sbc r0", "sbc r1", "sbc r2", "sbc r3", "sbc r4", "sbc r5", "sbc r6", "sbc r7", + "sbc r8", "sbc r9", "sbc r10", "sbc r11", "sbc r12", "sbc r13", "sbc r14", "sbc r15", + /* 70 - 7f */ + "merge", "bic r1", "bic r2", "bic r3", "bic r4", "bic r5", "bic r6", "bic r7", + "bic r8", "bic r9", "bic r10", "bic r11", "bic r12", "bic r13", "bic r14", "bic r15", + /* 80 - 8f */ + "umult r0","umult r1","umult r2", "umult r3", "umult r4", "umult r5", "umult r6", "umult r7", + "umult r8","umult r9","umult r10","umult r11","umult r12","umult r13","umult r14","umult r15", + /* 90 - 9f */ + "sbk", "link #1", "link #2", "link #3", "link #4", "sex", "div2", "ror", + "ljmp (r8)","ljmp (r9)","ljmp (r10)","ljmp (r11)", "ljmp (r12)", "ljmp (r13)", "lob", "lmult", + /* a0 - af */ + "lms r0,($%04x)", "lms r1,($%04x)", "lms r2,($%04x)", "lms r3,($%04x)", + "lms r4,($%04x)", "lms r5,($%04x)", "lms r6,($%04x)", "lms r7,($%04x)", + "lms r8,($%04x)", "lms r9,($%04x)", "lms r10,($%04x)", "lms r11,($%04x)", + "lms r12,($%04x)", "lms r13,($%04x)", "lms r14,($%04x)", "lms r15,($%04x)", + /* b0 - bf */ + "from r0", "from r1", "from r2", "from r3", "from r4", "from r5", "from r6", "from r7", + "from r8", "from r9", "from r10", "from r11", "from r12", "from r13", "from r14", "from r15", + /* c0 - cf */ + "hib", "xor r1", "xor r2", "xor r3", "xor r4", "xor r5", "xor r6", "xor r7", + "xor r8", "xor r9", "xor r10", "xor r11", "xor r12", "xor r13", "xor r14", "xor r15", + /* d0 - df */ + "inc r0", "inc r1", "inc r2", "inc r3", "inc r4", "inc r5", "inc r6", "inc r7", + "inc r8", "inc r9", "inc r10", "inc r11", "inc r12", "inc r13", "inc r14", "getc", + /* e0 - ef */ + "dec r0", "dec r1", "dec r2", "dec r3", "dec r4", "dec r5", "dec r6", "dec r7", + "dec r8", "dec r9", "dec r10", "dec r11", "dec r12", "dec r13", "dec r14", "getbh", + /* f0 - ff */ + "lm r0,($%04x)", "lm r1,($%04x)", "lm r2,($%04x)", "lm r3,($%04x)", + "lm r4,($%04x)", "lm r5,($%04x)", "lm r6,($%04x)", "lm r7,($%04x)", + "lm r8,($%04x)", "lm r9,($%04x)", "lm r10,($%04x)", "lm r11,($%04x)", + "lm r12,($%04x)", "lm r13,($%04x)", "lm r14,($%04x)", "lm r15,($%04x)", + + /* + * ALT2 Table + */ + + /* 00 - 0f */ + "stop", "nop", "cache", "lsr", "rol", "bra $%04x","blt $%04x","bge $%04x", + "bne $%04x","beq $%04x","bpl $%04x","bmi $%04x","bcc $%04x","bcs $%04x","bvc $%04x","bvs $%04x", + /* 10 - 1f */ + "to r0", "to r1", "to r2", "to r3", "to r4", "to r5", "to r6", "to r7", + "to r8", "to r9", "to r10", "to r11", "to r12", "to r13", "to r14", "to r15", + /* 20 - 2f */ + "with r0", "with r1", "with r2", "with r3", "with r4", "with r5", "with r6", "with r7", + "with r8", "with r9", "with r10", "with r11", "with r12", "with r13", "with r14", "with r15", + /* 30 - 3f */ + "stw (r0)","stw (r1)","stw (r2)", "stw (r3)", "stw (r4)", "stw (r5)", "stw (r6)", "stw (r7)", + "stw (r8)","stw (r9)","stw (r10)","stw (r11)","loop", "alt1", "alt2", "alt3", + /* 40 - 4f */ + "ldw (r0)","ldw (r1)","ldw (r2)", "ldw (r3)", "ldw (r4)", "ldw (r5)", "ldw (r6)", "ldw (r7)", + "ldw (r8)","ldw (r9)","ldw (r10)","ldw (r11)","plot", "swap", "color", "not", + /* 50 - 5f */ + "add #0", "add #1", "add #2", "add #3", "add #4", "add #5", "add #6", "add #7", + "add #8", "add #9", "add #10", "add #11", "add #12", "add #13", "add #14", "add #15", + /* 60 - 6f */ + "sub #0", "sub #1", "sub #2", "sub #3", "sub #4", "sub #5", "sub #6", "sub #7", + "sub #8", "sub #9", "sub #10", "sub #11", "sub #12", "sub #13", "sub #14", "sub #15", + /* 70 - 7f */ + "merge", "and #1", "and #2", "and #3", "and #4", "and #5", "and #6", "and #7", + "and #8", "and #9", "and #10", "and #11", "and #12", "and #13", "and #14", "and #15", + /* 80 - 8f */ + "mult #0", "mult #1", "mult #2", "mult #3", "mult #4", "mult #5", "mult #6", "mult #7", + "mult #8", "mult #9", "mult #10", "mult #11", "mult #12", "mult #13", "mult #14", "mult #15", + /* 90 - 9f */ + "sbk", "link #1", "link #2", "link #3", "link #4", "sex", "asr", "ror", + "jmp (r8)","jmp (r9)","jmp (r10)","jmp (r11)","jmp (r12)","jmp (r13)","lob", "fmult", + /* a0 - af */ + "sms ($%04x),r0", "sms ($%04x),r1", "sms ($%04x),r2", "sms ($%04x),r3", + "sms ($%04x),r4", "sms ($%04x),r5", "sms ($%04x),r6", "sms ($%04x),r7", + "sms ($%04x),r8", "sms ($%04x),r9", "sms ($%04x),r10", "sms ($%04x),r11", + "sms ($%04x),r12", "sms ($%04x),r13", "sms ($%04x),r14", "sms ($%04x),r15", + /* b0 - bf */ + "from r0", "from r1", "from r2", "from r3", "from r4", "from r5", "from r6", "from r7", + "from r8", "from r9", "from r10", "from r11", "from r12", "from r13", "from r14", "from r15", + /* c0 - cf */ + "hib", "or #1", "or #2", "or #3", "or #4", "or #5", "or #6", "or #7", + "or #8", "or #9", "or #10", "or #11", "or #12", "or #13", "or #14", "or #15", + /* d0 - df */ + "inc r0", "inc r1", "inc r2", "inc r3", "inc r4", "inc r5", "inc r6", "inc r7", + "inc r8", "inc r9", "inc r10", "inc r11", "inc r12", "inc r13", "inc r14", "ramb", + /* e0 - ef */ + "dec r0", "dec r1", "dec r2", "dec r3", "dec r4", "dec r5", "dec r6", "dec r7", + "dec r8", "dec r9", "dec r10", "dec r11", "dec r12", "dec r13", "dec r14", "getbl", + /* f0 - ff */ + "sm ($%04x),r0", "sm ($%04x),r1", "sm ($%04x),r2", "sm ($%04x),r3", + "sm ($%04x),r4", "sm ($%04x),r5", "sm ($%04x),r6", "sm ($%04x),r7", + "sm ($%04x),r8", "sm ($%04x),r9", "sm ($%04x),r10", "sm ($%04x),r11", + "sm ($%04x),r12", "sm ($%04x),r13", "sm ($%04x),r14", "sm ($%04x),r15", + + /* + * ALT3 Table + */ + + /* 00 - 0f */ + "stop", "nop", "cache", "lsr", "rol", "bra $%04x","blt $%04x","bge $%04x", + "bne $%04x","beq $%04x","bpl $%04x","bmi $%04x","bcc $%04x","bcs $%04x","bvc $%04x","bvs $%04x", + /* 10 - 1f */ + "to r0", "to r1", "to r2", "to r3", "to r4", "to r5", "to r6", "to r7", + "to r8", "to r9", "to r10", "to r11", "to r12", "to r13", "to r14", "to r15", + /* 20 - 2f */ + "with r0", "with r1", "with r2", "with r3", "with r4", "with r5", "with r6", "with r7", + "with r8", "with r9", "with r10", "with r11", "with r12", "with r13", "with r14", "with r15", + /* 30 - 3f */ + "stb (r0)","stb (r1)","stb (r2)", "stb (r3)", "stb (r4)", "stb (r5)", "stb (r6)", "stb (r7)", + "stb (r8)","stb (r9)","stb (r10)","stb (r11)","loop", "alt1", "alt2", "alt3", + /* 40 - 4f */ + "ldb (r0)","ldb (r1)","ldb (r2)", "ldb (r3)", "ldb (r4)", "ldb (r5)", "ldb (r6)", "ldb (r7)", + "ldb (r8)","ldb (r9)","ldb (r10)","ldb (r11)","rpix", "swap", "cmode", "not", + /* 50 - 5f */ + "adc #0", "adc #1", "adc #2", "adc #3", "adc #4", "adc #5", "adc #6", "adc #7", + "adc #8", "adc #9", "adc #10", "adc #11", "adc #12", "adc #13", "adc #14", "adc #15", + /* 60 - 6f */ + "cmp r0", "cmp r1", "cmp r2", "cmp r3", "cmp r4", "cmp r5", "cmp r6", "cmp r7", + "cmp r8", "cmp r9", "cmp r10", "cmp r11", "cmp r12", "cmp r13", "cmp r14", "cmp r15", + /* 70 - 7f */ + "merge", "bic #1", "bic #2", "bic #3", "bic #4", "bic #5", "bic #6", "bic #7", + "bic #8", "bic #9", "bic #10", "bic #11", "bic #12", "bic #13", "bic #14", "bic #15", + /* 80 - 8f */ + "umult #0","umult #1","umult #2", "umult #3", "umult #4", "umult #5", "umult #6", "umult #7", + "umult #8","umult #9","umult #10","umult #11","umult #12","umult #13","umult #14","umult #15", + /* 90 - 9f */ + "sbk", "link #1", "link #2", "link #3", "link #4", "sex", "div2", "ror", + "ljmp (r8)","ljmp (r9)","ljmp (r10)","ljmp (r11)", "ljmp (r12)", "ljmp (r13)", "lob", "lmult", + /* a0 - af */ + "lms r0,($%04x)", "lms r1,($%04x)", "lms r2,($%04x)", "lms r3,($%04x)", + "lms r4,($%04x)", "lms r5,($%04x)", "lms r6,($%04x)", "lms r7,($%04x)", + "lms r8,($%04x)", "lms r9,($%04x)", "lms r10,($%04x)", "lms r11,($%04x)", + "lms r12,($%04x)", "lms r13,($%04x)", "lms r14,($%04x)", "lms r15,($%04x)", + /* b0 - bf */ + "from r0", "from r1", "from r2", "from r3", "from r4", "from r5", "from r6", "from r7", + "from r8", "from r9", "from r10", "from r11", "from r12", "from r13", "from r14", "from r15", + /* c0 - cf */ + "hib", "xor #1", "xor #2", "xor #3", "xor #4", "xor #5", "xor #6", "xor #7", + "xor #8", "xor #9", "xor #10", "xor #11", "xor #12", "xor #13", "xor #14", "xor #15", + /* d0 - df */ + "inc r0", "inc r1", "inc r2", "inc r3", "inc r4", "inc r5", "inc r6", "inc r7", + "inc r8", "inc r9", "inc r10", "inc r11", "inc r12", "inc r13", "inc r14", "romb", + /* e0 - ef */ + "dec r0", "dec r1", "dec r2", "dec r3", "dec r4", "dec r5", "dec r6", "dec r7", + "dec r8", "dec r9", "dec r10", "dec r11", "dec r12", "dec r13", "dec r14", "getbs", + /* f0 - ff */ + "lm r0,($%04x)", "lm r1,($%04x)", "lm r2,($%04x)", "lm r3,($%04x)", + "lm r4,($%04x)", "lm r5,($%04x)", "lm r6,($%04x)", "lm r7,($%04x)", + "lm r8,($%04x)", "lm r9,($%04x)", "lm r10,($%04x)", "lm r11,($%04x)", + "lm r12,($%04x)", "lm r13,($%04x)", "lm r14,($%04x)", "lm r15,($%04x)", +}; diff --git a/src/snes4iphone_src/fxemu.cpp b/src/snes4iphone_src/fxemu.cpp new file mode 100755 index 0000000..a048b76 --- /dev/null +++ b/src/snes4iphone_src/fxemu.cpp @@ -0,0 +1,660 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#include "fxemu.h" +#include "fxinst.h" +#include +#include +#include + +/* The FxChip Emulator's internal variables */ +struct FxRegs_s GSU = {0}; + +uint32 (**fx_ppfFunctionTable)(uint32) = 0; +void (**fx_ppfPlotTable)() = 0; +void (**fx_ppfOpcodeTable)() = 0; + +#if 0 +void fx_setCache() +{ + uint32 c; + GSU.bCacheActive = TRUE; + GSU.pvRegisters[0x3e] &= 0xf0; + c = (uint32)GSU.pvRegisters[0x3e]; + c |= ((uint32)GSU.pvRegisters[0x3f])<<8; + if(c == GSU.vCacheBaseReg) + return; + GSU.vCacheBaseReg = c; + GSU.vCacheFlags = 0; + if(c < (0x10000-512)) + { + uint8 const* t = &ROM(c); + memcpy(GSU.pvCache,t,512); + } + else + { + uint8 const* t1; + uint8 const* t2; + uint32 i = 0x10000 - c; + t1 = &ROM(c); + t2 = &ROM(0); + memcpy(GSU.pvCache,t1,i); + memcpy(&GSU.pvCache[i],t2,512-i); + } +} +#endif + +void FxCacheWriteAccess(uint16 vAddress) +{ +#if 0 + if(!GSU.bCacheActive) + { + uint8 v = GSU.pvCache[GSU.pvCache[vAddress&0x1ff]; + fx_setCache(); + GSU.pvCache[GSU.pvCache[vAddress&0x1ff] = v; + } +#endif + if((vAddress & 0x00f) == 0x00f) + GSU.vCacheFlags |= 1 << ((vAddress&0x1f0) >> 4); +} + +void FxFlushCache() +{ + GSU.vCacheFlags = 0; + GSU.vCacheBaseReg = 0; + GSU.bCacheActive = FALSE; +// GSU.vPipe = 0x1; +} + +static void fx_backupCache() +{ +#if 0 + uint32 i; + uint32 v = GSU.vCacheFlags; + uint32 c = USEX16(GSU.vCacheBaseReg); + if(v) + for(i=0; i<32; i++) + { + if(v&1) + { + if(c < (0x10000-16)) + { + uint8 * t = &GSU.pvPrgBank[c]; + memcpy(&GSU.avCacheBackup[i<<4],t,16); + memcpy(t,&GSU.pvCache[i<<4],16); + } + else + { + uint8 * t1; + uint8 * t2; + uint32 a = 0x10000 - c; + t1 = &GSU.pvPrgBank[c]; + t2 = &GSU.pvPrgBank[0]; + memcpy(&GSU.avCacheBackup[i<<4],t1,a); + memcpy(t1,&GSU.pvCache[i<<4],a); + memcpy(&GSU.avCacheBackup[(i<<4)+a],t2,16-a); + memcpy(t2,&GSU.pvCache[(i<<4)+a],16-a); + } + } + c = USEX16(c+16); + v >>= 1; + } +#endif +} + +static void fx_restoreCache() +{ +#if 0 + uint32 i; + uint32 v = GSU.vCacheFlags; + uint32 c = USEX16(GSU.vCacheBaseReg); + if(v) + for(i=0; i<32; i++) + { + if(v&1) + { + if(c < (0x10000-16)) + { + uint8 * t = &GSU.pvPrgBank[c]; + memcpy(t,&GSU.avCacheBackup[i<<4],16); + memcpy(&GSU.pvCache[i<<4],t,16); + } + else + { + uint8 * t1; + uint8 * t2; + uint32 a = 0x10000 - c; + t1 = &GSU.pvPrgBank[c]; + t2 = &GSU.pvPrgBank[0]; + memcpy(t1,&GSU.avCacheBackup[i<<4],a); + memcpy(&GSU.pvCache[i<<4],t1,a); + memcpy(t2,&GSU.avCacheBackup[(i<<4)+a],16-a); + memcpy(&GSU.pvCache[(i<<4)+a],t2,16-a); + } + } + c = USEX16(c+16); + v >>= 1; + } +#endif +} + +void fx_flushCache() +{ + fx_restoreCache(); + GSU.vCacheFlags = 0; + GSU.bCacheActive = FALSE; +} + +static void fx_readRegisterSpace() +{ + int i; + uint8 *p; + static uint32 avHeight[] = { 128, 160, 192, 256 }; + static uint32 avMult[] = { 16, 32, 32, 64 }; + + GSU.vErrorCode = 0; + + /* Update R0-R15 */ + p = GSU.pvRegisters; + for(i=0; i<16; i++) + { + GSU.avReg[i] = *p++; + GSU.avReg[i] += ((uint32)(*p++)) << 8; + } + + /* Update other registers */ + p = GSU.pvRegisters; + GSU.vStatusReg = (uint32)p[GSU_SFR]; + GSU.vStatusReg |= ((uint32)p[GSU_SFR+1]) << 8; + GSU.vPrgBankReg = (uint32)p[GSU_PBR]; + GSU.vRomBankReg = (uint32)p[GSU_ROMBR]; + GSU.vRamBankReg = ((uint32)p[GSU_RAMBR]) & (FX_RAM_BANKS-1); + GSU.vCacheBaseReg = (uint32)p[GSU_CBR]; + GSU.vCacheBaseReg |= ((uint32)p[GSU_CBR+1]) << 8; + + /* Update status register variables */ + GSU.vZero = !(GSU.vStatusReg & FLG_Z); + GSU.vSign = (GSU.vStatusReg & FLG_S) << 12; + GSU.vOverflow = (GSU.vStatusReg & FLG_OV) << 16; + GSU.vCarry = (GSU.vStatusReg & FLG_CY) >> 2; + + /* Set bank pointers */ + GSU.pvRamBank = GSU.apvRamBank[GSU.vRamBankReg & 0x3]; + GSU.pvRomBank = GSU.apvRomBank[GSU.vRomBankReg]; + GSU.pvPrgBank = GSU.apvRomBank[GSU.vPrgBankReg]; + + /* Set screen pointers */ + GSU.pvScreenBase = &GSU.pvRam[ USEX8(p[GSU_SCBR]) << 10 ]; + i = (int)(!!(p[GSU_SCMR] & 0x04)); + i |= ((int)(!!(p[GSU_SCMR] & 0x20))) << 1; + GSU.vScreenHeight = GSU.vScreenRealHeight = avHeight[i]; + GSU.vMode = p[GSU_SCMR] & 0x03; +#if 0 + if(GSU.vMode == 2) + error illegal color depth GSU.vMode; +#endif + if(i == 3) + GSU.vScreenSize = (256/8) * (256/8) * 32; + else + GSU.vScreenSize = (GSU.vScreenHeight/8) * (256/8) * avMult[GSU.vMode]; + if (GSU.vPlotOptionReg & 0x10) + { + /* OBJ Mode (for drawing into sprites) */ + GSU.vScreenHeight = 256; + } +#if 0 + if(GSU.pvScreenBase + GSU.vScreenSize > GSU.pvRam + (GSU.nRamBanks * 65536)) + error illegal address for screen base register +#else + if(GSU.pvScreenBase + GSU.vScreenSize > GSU.pvRam + (GSU.nRamBanks * 65536)) + GSU.pvScreenBase = GSU.pvRam + (GSU.nRamBanks * 65536) - GSU.vScreenSize; +#endif + GSU.pfPlot = fx_apfPlotTable[GSU.vMode]; + GSU.pfRpix = fx_apfPlotTable[GSU.vMode + 5]; + + fx_ppfOpcodeTable[0x04c] = GSU.pfPlot; + fx_ppfOpcodeTable[0x14c] = GSU.pfRpix; + fx_ppfOpcodeTable[0x24c] = GSU.pfPlot; + fx_ppfOpcodeTable[0x34c] = GSU.pfRpix; + + fx_computeScreenPointers (); + + fx_backupCache(); +} + +void fx_computeScreenPointers () +{ + if (GSU.vMode != GSU.vPrevMode || + GSU.vPrevScreenHeight != GSU.vScreenHeight) + { + int i; + + /* Make a list of pointers to the start of each screen column */ + switch (GSU.vScreenHeight) + { + case 128: + switch (GSU.vMode) + { + case 0: + for (i = 0; i < 32; i++) + { + GSU.apvScreen[i] = GSU.pvScreenBase + (i << 4); + GSU.x[i] = i << 8; + } + break; + case 1: + for (i = 0; i < 32; i++) + { + GSU.apvScreen[i] = GSU.pvScreenBase + (i << 5); + GSU.x[i] = i << 9; + } + break; + case 2: + case 3: + for (i = 0; i < 32; i++) + { + GSU.apvScreen[i] = GSU.pvScreenBase + (i << 6); + GSU.x[i] = i << 10; + } + break; + } + break; + case 160: + switch (GSU.vMode) + { + case 0: + for (i = 0; i < 32; i++) + { + GSU.apvScreen[i] = GSU.pvScreenBase + (i << 4); + GSU.x[i] = (i << 8) + (i << 6); + } + break; + case 1: + for (i = 0; i < 32; i++) + { + GSU.apvScreen[i] = GSU.pvScreenBase + (i << 5); + GSU.x[i] = (i << 9) + (i << 7); + } + break; + case 2: + case 3: + for (i = 0; i < 32; i++) + { + GSU.apvScreen[i] = GSU.pvScreenBase + (i << 6); + GSU.x[i] = (i << 10) + (i << 8); + } + break; + } + break; + case 192: + switch (GSU.vMode) + { + case 0: + for (i = 0; i < 32; i++) + { + GSU.apvScreen[i] = GSU.pvScreenBase + (i << 4); + GSU.x[i] = (i << 8) + (i << 7); + } + break; + case 1: + for (i = 0; i < 32; i++) + { + GSU.apvScreen[i] = GSU.pvScreenBase + (i << 5); + GSU.x[i] = (i << 9) + (i << 8); + } + break; + case 2: + case 3: + for (i = 0; i < 32; i++) + { + GSU.apvScreen[i] = GSU.pvScreenBase + (i << 6); + GSU.x[i] = (i << 10) + (i << 9); + } + break; + } + break; + case 256: + switch (GSU.vMode) + { + case 0: + for (i = 0; i < 32; i++) + { + GSU.apvScreen[i] = GSU.pvScreenBase + + ((i & 0x10) << 9) + ((i & 0xf) << 8); + GSU.x[i] = ((i & 0x10) << 8) + ((i & 0xf) << 4); + } + break; + case 1: + for (i = 0; i < 32; i++) + { + GSU.apvScreen[i] = GSU.pvScreenBase + + ((i & 0x10) << 10) + ((i & 0xf) << 9); + GSU.x[i] = ((i & 0x10) << 9) + ((i & 0xf) << 5); + } + break; + case 2: + case 3: + for (i = 0; i < 32; i++) + { + GSU.apvScreen[i] = GSU.pvScreenBase + + ((i & 0x10) << 11) + ((i & 0xf) << 10); + GSU.x[i] = ((i & 0x10) << 10) + ((i & 0xf) << 6); + } + break; + } + break; + } + GSU.vPrevMode = GSU.vMode; + GSU.vPrevScreenHeight = GSU.vScreenHeight; + } +} + +static void fx_writeRegisterSpace() +{ + int i; + uint8 *p; + + p = GSU.pvRegisters; + for(i=0; i<16; i++) + { + *p++ = (uint8)GSU.avReg[i]; + *p++ = (uint8)(GSU.avReg[i] >> 8); + } + + /* Update status register */ + if( USEX16(GSU.vZero) == 0 ) SF(Z); + else CF(Z); + if( GSU.vSign & 0x8000 ) SF(S); + else CF(S); + if(GSU.vOverflow >= 0x8000 || GSU.vOverflow < -0x8000) SF(OV); + else CF(OV); + if(GSU.vCarry) SF(CY); + else CF(CY); + + p = GSU.pvRegisters; + p[GSU_SFR] = (uint8)GSU.vStatusReg; + p[GSU_SFR+1] = (uint8)(GSU.vStatusReg>>8); + p[GSU_PBR] = (uint8)GSU.vPrgBankReg; + p[GSU_ROMBR] = (uint8)GSU.vRomBankReg; + p[GSU_RAMBR] = (uint8)GSU.vRamBankReg; + p[GSU_CBR] = (uint8)GSU.vCacheBaseReg; + p[GSU_CBR+1] = (uint8)(GSU.vCacheBaseReg>>8); + + fx_restoreCache(); +} + +/* Reset the FxChip */ +void FxReset(struct FxInit_s *psFxInfo) +{ + int i; + static uint32 (**appfFunction[])(uint32) = { + &fx_apfFunctionTable[0], +#if 0 + &fx_a_apfFunctionTable[0], + &fx_r_apfFunctionTable[0], + &fx_ar_apfFunctionTable[0], +#endif + }; + static void (**appfPlot[])() = { + &fx_apfPlotTable[0], +#if 0 + &fx_a_apfPlotTable[0], + &fx_r_apfPlotTable[0], + &fx_ar_apfPlotTable[0], +#endif + }; + static void (**appfOpcode[])() = { + &fx_apfOpcodeTable[0], +#if 0 + &fx_a_apfOpcodeTable[0], + &fx_r_apfOpcodeTable[0], + &fx_ar_apfOpcodeTable[0], +#endif + }; + + /* Get function pointers for the current emulation mode */ + fx_ppfFunctionTable = appfFunction[psFxInfo->vFlags & 0x3]; + fx_ppfPlotTable = appfPlot[psFxInfo->vFlags & 0x3]; + fx_ppfOpcodeTable = appfOpcode[psFxInfo->vFlags & 0x3]; + + /* Clear all internal variables */ + memset((uint8*)&GSU,0,sizeof(struct FxRegs_s)); + + /* Set default registers */ + GSU.pvSreg = GSU.pvDreg = &R0; + + /* Set RAM and ROM pointers */ + GSU.pvRegisters = psFxInfo->pvRegisters; + GSU.nRamBanks = psFxInfo->nRamBanks; + GSU.pvRam = psFxInfo->pvRam; + GSU.nRomBanks = psFxInfo->nRomBanks; + GSU.pvRom = psFxInfo->pvRom; + GSU.vPrevScreenHeight = ~0; + GSU.vPrevMode = ~0; + + /* The GSU can't access more than 2mb (16mbits) */ + if(GSU.nRomBanks > 0x20) + GSU.nRomBanks = 0x20; + + /* Clear FxChip register space */ + memset(GSU.pvRegisters,0,0x300); + + /* Set FxChip version Number */ + GSU.pvRegisters[0x3b] = 0; + + /* Make ROM bank table */ + for(i=0; i<256; i++) + { + uint32 b = i & 0x7f; + if (b >= 0x40) + { + if (GSU.nRomBanks > 1) + b %= GSU.nRomBanks; + else + b &= 1; + + GSU.apvRomBank[i] = &GSU.pvRom[ b << 16 ]; + } + else + { + b %= GSU.nRomBanks * 2; + GSU.apvRomBank[i] = &GSU.pvRom[ (b << 16) + 0x200000]; + } + } + + /* Make RAM bank table */ + for(i=0; i<4; i++) + { + GSU.apvRamBank[i] = &GSU.pvRam[(i % GSU.nRamBanks) << 16]; + GSU.apvRomBank[0x70 + i] = GSU.apvRamBank[i]; + } + + /* Start with a nop in the pipe */ + GSU.vPipe = 0x01; + + /* Set pointer to GSU cache */ + GSU.pvCache = &GSU.pvRegisters[0x100]; + + fx_readRegisterSpace(); +} + +static uint8 fx_checkStartAddress() +{ + /* Check if we start inside the cache */ + if(GSU.bCacheActive && R15 >= GSU.vCacheBaseReg && R15 < (GSU.vCacheBaseReg+512)) + return TRUE; + + /* Check if we're in an unused area */ + if(GSU.vPrgBankReg < 0x40 && R15 < 0x8000) + return FALSE; + if(GSU.vPrgBankReg >= 0x60 && GSU.vPrgBankReg <= 0x6f) + return FALSE; + if(GSU.vPrgBankReg >= 0x74) + return FALSE; + + /* Check if we're in RAM and the RAN flag is not set */ + if(GSU.vPrgBankReg >= 0x70 && GSU.vPrgBankReg <= 0x73 && !(SCMR&(1<<3)) ) + return FALSE; + + /* If not, we're in ROM, so check if the RON flag is set */ + if(!(SCMR&(1<<4))) + return FALSE; + + return TRUE; +} + +/* Execute until the next stop instruction */ +int FxEmulate(uint32 nInstructions) +{ + uint32 vCount; + + /* Read registers and initialize GSU session */ + fx_readRegisterSpace(); + + /* Check if the start address is valid */ + if(!fx_checkStartAddress()) + { + CF(G); + fx_writeRegisterSpace(); +#if 0 + GSU.vIllegalAddress = (GSU.vPrgBankReg << 24) | R15; + return FX_ERROR_ILLEGAL_ADDRESS; +#else + return 0; +#endif + } + + /* Execute GSU session */ + CF(IRQ); + + if(GSU.bBreakPoint) + vCount = fx_ppfFunctionTable[FX_FUNCTION_RUN_TO_BREAKPOINT](nInstructions); + else + vCount = fx_ppfFunctionTable[FX_FUNCTION_RUN](nInstructions); + + /* Store GSU registers */ + fx_writeRegisterSpace(); + + /* Check for error code */ + if(GSU.vErrorCode) + return GSU.vErrorCode; + else + return vCount; +} + +/* Breakpoints */ +void FxBreakPointSet(uint32 vAddress) +{ + GSU.bBreakPoint = TRUE; + GSU.vBreakPoint = USEX16(vAddress); +} +void FxBreakPointClear() +{ + GSU.bBreakPoint = FALSE; +} + +/* Step by step execution */ +int FxStepOver(uint32 nInstructions) +{ + uint32 vCount; + fx_readRegisterSpace(); + + /* Check if the start address is valid */ + if(!fx_checkStartAddress()) + { + CF(G); +#if 0 + GSU.vIllegalAddress = (GSU.vPrgBankReg << 24) | R15; + return FX_ERROR_ILLEGAL_ADDRESS; +#else + return 0; +#endif + } + + if( PIPE >= 0xf0 ) + GSU.vStepPoint = USEX16(R15+3); + else if( (PIPE >= 0x05 && PIPE <= 0x0f) || (PIPE >= 0xa0 && PIPE <= 0xaf) ) + GSU.vStepPoint = USEX16(R15+2); + else + GSU.vStepPoint = USEX16(R15+1); + vCount = fx_ppfFunctionTable[FX_FUNCTION_STEP_OVER](nInstructions); + fx_writeRegisterSpace(); + if(GSU.vErrorCode) + return GSU.vErrorCode; + else + return vCount; +} + +/* Errors */ +int FxGetErrorCode() +{ + return GSU.vErrorCode; +} + +int FxGetIllegalAddress() +{ + return GSU.vIllegalAddress; +} + +/* Access to internal registers */ +uint32 FxGetColorRegister() +{ + return GSU.vColorReg & 0xff; +} + +uint32 FxGetPlotOptionRegister() +{ + return GSU.vPlotOptionReg & 0x1f; +} + +uint32 FxGetSourceRegisterIndex() +{ + return GSU.pvSreg - GSU.avReg; +} + +uint32 FxGetDestinationRegisterIndex() +{ + return GSU.pvDreg - GSU.avReg; +} + +uint8 FxPipe() +{ + return GSU.vPipe; +} diff --git a/src/snes4iphone_src/fxemu.h b/src/snes4iphone_src/fxemu.h new file mode 100755 index 0000000..37b361e --- /dev/null +++ b/src/snes4iphone_src/fxemu.h @@ -0,0 +1,122 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#ifndef _FXEMU_H_ +#define _FXEMU_H_ 1 + +/* Types used by structures and code */ +#ifndef snes9x_types_defined +#define snes9x_types_defined + +typedef unsigned char uint8; +typedef unsigned short uint16; +typedef unsigned int uint32; +typedef unsigned char bool8; +typedef signed char int8; +typedef short int16; +typedef int int32; +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +/* The FxInfo_s structure, the link between the FxEmulator and the Snes Emulator */ +struct FxInit_s +{ + uint32 vFlags; + uint8 * pvRegisters; /* 768 bytes located in the memory at address 0x3000 */ + uint32 nRamBanks; /* Number of 64kb-banks in GSU-RAM/BackupRAM (banks 0x70-0x73) */ + uint8 * pvRam; /* Pointer to GSU-RAM */ + uint32 nRomBanks; /* Number of 32kb-banks in Cart-ROM */ + uint8 * pvRom; /* Pointer to Cart-ROM */ +}; + +/* Reset the FxChip */ +extern void FxReset(struct FxInit_s *psFxInfo); + +/* Execute until the next stop instruction */ +extern int FxEmulate(uint32 nInstructions); + +/* Write access to the cache */ +extern void FxCacheWriteAccess(uint16 vAddress); +extern void FxFlushCache(); /* Callled when the G flag in SFR is set to zero */ + +/* Breakpoint */ +extern void FxBreakPointSet(uint32 vAddress); +extern void FxBreakPointClear(); + +/* Step by step execution */ +extern int FxStepOver(uint32 nInstructions); + +/* Errors */ +extern int FxGetErrorCode(); +extern int FxGetIllegalAddress(); + +/* Access to internal registers */ +extern uint32 FxGetColorRegister(); +extern uint32 FxGetPlotOptionRegister(); +extern uint32 FxGetSourceRegisterIndex(); +extern uint32 FxGetDestinationRegisterIndex(); + +/* Get string for opcode currently in the pipe */ +extern void FxPipeString(char * pvString); + +/* Get the byte currently in the pipe */ +extern uint8 FxPipe(); + +/* Option flags */ +#define FX_FLAG_ADDRESS_CHECKING 0x01 +#define FX_FLAG_ROM_BUFFER 0x02 + +/* Return codes from FxEmulate(), FxStepInto() or FxStepOver() */ +#define FX_BREAKPOINT -1 +#define FX_ERROR_ILLEGAL_ADDRESS -2 + +/* Return the number of bytes in an opcode */ +#define OPCODE_BYTES(op) ((((op)>=0x05&&(op)<=0xf)||((op)>=0xa0&&(op)<=0xaf))?2:(((op)>=0xf0)?3:1)) + +extern void fx_computeScreenPointers (); + +#endif diff --git a/src/snes4iphone_src/fxinst.cpp b/src/snes4iphone_src/fxinst.cpp new file mode 100755 index 0000000..54c300c --- /dev/null +++ b/src/snes4iphone_src/fxinst.cpp @@ -0,0 +1,1864 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#define FX_DO_ROMBUFFER + +#include "fxemu.h" +#include "fxinst.h" +#include +#include + +extern struct FxRegs_s GSU; +int gsu_bank [512] = {0}; + +/* Set this define if you wish the plot instruction to check for y-pos limits */ +/* (I don't think it's nessecary) */ +#define CHECK_LIMITS + +/* Codes used: + * + * rn = a GSU register (r0-r15) + * #n = 4 bit immediate value + * #pp = 8 bit immediate value + * (yy) = 8 bit word address (0x0000 - 0x01fe) + * #xx = 16 bit immediate value + * (xx) = 16 bit address (0x0000 - 0xffff) + * + */ + +/* 00 - stop - stop GSU execution (and maybe generate an IRQ) */ +static void fx_stop() +{ + CF(G); + GSU.vCounter = 0; + GSU.vInstCount = GSU.vCounter; + + /* Check if we need to generate an IRQ */ + if(!(GSU.pvRegisters[GSU_CFGR] & 0x80)) + SF(IRQ); + + GSU.vPlotOptionReg = 0; + GSU.vPipe = 1; + CLRFLAGS; + R15++; +} + +/* 01 - nop - no operation */ +static void fx_nop() { CLRFLAGS; R15++; } + +extern void fx_flushCache(); + +/* 02 - cache - reintialize GSU cache */ +static void fx_cache() +{ + uint32 c = R15 & 0xfff0; + if(GSU.vCacheBaseReg != c || !GSU.bCacheActive) + { + fx_flushCache(); + GSU.vCacheBaseReg = c; + GSU.bCacheActive = TRUE; +#if 0 + if(c < (0x10000-512)) + { + uint8 const* t = &ROM(c); + memcpy(GSU.pvCache,t,512); + } + else + { + uint8 const* t1; + uint8 const* t2; + uint32 i = 0x10000 - c; + t1 = &ROM(c); + t2 = &ROM(0); + memcpy(GSU.pvCache,t1,i); + memcpy(&GSU.pvCache[i],t2,512-i); + } +#endif + } + R15++; + CLRFLAGS; +} + +/* 03 - lsr - logic shift right */ +static void fx_lsr() +{ + uint32 v; + GSU.vCarry = SREG & 1; + v = USEX16(SREG) >> 1; + R15++; DREG = v; + GSU.vSign = v; + GSU.vZero = v; + TESTR14; + CLRFLAGS; +} + +/* 04 - rol - rotate left */ +static void fx_rol() +{ + uint32 v = (SREG << 1) + GSU.vCarry; + GSU.vCarry = (SREG >> 15) & 1; + R15++; DREG = v; + GSU.vSign = v; + GSU.vZero = v; + TESTR14; + CLRFLAGS; +} + +/* 05 - bra - branch always */ +static void fx_bra() { uint8 v = PIPE; R15++; FETCHPIPE; R15 += SEX8(v); } + +/* Branch on condition */ +#define BRA_COND(cond) uint8 v = PIPE; R15++; FETCHPIPE; if(cond) R15 += SEX8(v); else R15++; + +#define TEST_S (GSU.vSign & 0x8000) +#define TEST_Z (USEX16(GSU.vZero) == 0) +#define TEST_OV (GSU.vOverflow >= 0x8000 || GSU.vOverflow < -0x8000) +#define TEST_CY (GSU.vCarry & 1) + +/* 06 - blt - branch on less than */ +static void fx_blt() { BRA_COND( (TEST_S!=0) != (TEST_OV!=0) ); } + +/* 07 - bge - branch on greater or equals */ +static void fx_bge() { BRA_COND( (TEST_S!=0) == (TEST_OV!=0)); } + +/* 08 - bne - branch on not equal */ +static void fx_bne() { BRA_COND( !TEST_Z ); } + +/* 09 - beq - branch on equal */ +static void fx_beq() { BRA_COND( TEST_Z ); } + +/* 0a - bpl - branch on plus */ +static void fx_bpl() { BRA_COND( !TEST_S ); } + +/* 0b - bmi - branch on minus */ +static void fx_bmi() { BRA_COND( TEST_S ); } + +/* 0c - bcc - branch on carry clear */ +static void fx_bcc() { BRA_COND( !TEST_CY ); } + +/* 0d - bcs - branch on carry set */ +static void fx_bcs() { BRA_COND( TEST_CY ); } + +/* 0e - bvc - branch on overflow clear */ +static void fx_bvc() { BRA_COND( !TEST_OV ); } + +/* 0f - bvs - branch on overflow set */ +static void fx_bvs() { BRA_COND( TEST_OV ); } + +/* 10-1f - to rn - set register n as destination register */ +/* 10-1f(B) - move rn - move one register to another (if B flag is set) */ +#define FX_TO(reg) \ +if(TF(B)) { GSU.avReg[(reg)] = SREG; CLRFLAGS; } \ +else { GSU.pvDreg = &GSU.avReg[reg]; } R15++; +#define FX_TO_R14(reg) \ +if(TF(B)) { GSU.avReg[(reg)] = SREG; CLRFLAGS; READR14; } \ +else { GSU.pvDreg = &GSU.avReg[reg]; } R15++; +#define FX_TO_R15(reg) \ +if(TF(B)) { GSU.avReg[(reg)] = SREG; CLRFLAGS; } \ +else { GSU.pvDreg = &GSU.avReg[reg]; R15++; } +static void fx_to_r0() { FX_TO(0); } +static void fx_to_r1() { FX_TO(1); } +static void fx_to_r2() { FX_TO(2); } +static void fx_to_r3() { FX_TO(3); } +static void fx_to_r4() { FX_TO(4); } +static void fx_to_r5() { FX_TO(5); } +static void fx_to_r6() { FX_TO(6); } +static void fx_to_r7() { FX_TO(7); } +static void fx_to_r8() { FX_TO(8); } +static void fx_to_r9() { FX_TO(9); } +static void fx_to_r10() { FX_TO(10); } +static void fx_to_r11() { FX_TO(11); } +static void fx_to_r12() { FX_TO(12); } +static void fx_to_r13() { FX_TO(13); } +static void fx_to_r14() { FX_TO_R14(14); } +static void fx_to_r15() { FX_TO_R15(15); } + +/* 20-2f - to rn - set register n as source and destination register */ +#define FX_WITH(reg) SF(B); GSU.pvSreg = GSU.pvDreg = &GSU.avReg[reg]; R15++; +static void fx_with_r0() { FX_WITH(0); } +static void fx_with_r1() { FX_WITH(1); } +static void fx_with_r2() { FX_WITH(2); } +static void fx_with_r3() { FX_WITH(3); } +static void fx_with_r4() { FX_WITH(4); } +static void fx_with_r5() { FX_WITH(5); } +static void fx_with_r6() { FX_WITH(6); } +static void fx_with_r7() { FX_WITH(7); } +static void fx_with_r8() { FX_WITH(8); } +static void fx_with_r9() { FX_WITH(9); } +static void fx_with_r10() { FX_WITH(10); } +static void fx_with_r11() { FX_WITH(11); } +static void fx_with_r12() { FX_WITH(12); } +static void fx_with_r13() { FX_WITH(13); } +static void fx_with_r14() { FX_WITH(14); } +static void fx_with_r15() { FX_WITH(15); } + +/* 30-3b - stw (rn) - store word */ +#define FX_STW(reg) \ +GSU.vLastRamAdr = GSU.avReg[reg]; \ +RAM(GSU.avReg[reg]) = (uint8)SREG; \ +RAM(GSU.avReg[reg]^1) = (uint8)(SREG>>8); \ +CLRFLAGS; R15++ +static void fx_stw_r0() { FX_STW(0); } +static void fx_stw_r1() { FX_STW(1); } +static void fx_stw_r2() { FX_STW(2); } +static void fx_stw_r3() { FX_STW(3); } +static void fx_stw_r4() { FX_STW(4); } +static void fx_stw_r5() { FX_STW(5); } +static void fx_stw_r6() { FX_STW(6); } +static void fx_stw_r7() { FX_STW(7); } +static void fx_stw_r8() { FX_STW(8); } +static void fx_stw_r9() { FX_STW(9); } +static void fx_stw_r10() { FX_STW(10); } +static void fx_stw_r11() { FX_STW(11); } + +/* 30-3b(ALT1) - stb (rn) - store byte */ +#define FX_STB(reg) \ +GSU.vLastRamAdr = GSU.avReg[reg]; \ +RAM(GSU.avReg[reg]) = (uint8)SREG; \ +CLRFLAGS; R15++ +static void fx_stb_r0() { FX_STB(0); } +static void fx_stb_r1() { FX_STB(1); } +static void fx_stb_r2() { FX_STB(2); } +static void fx_stb_r3() { FX_STB(3); } +static void fx_stb_r4() { FX_STB(4); } +static void fx_stb_r5() { FX_STB(5); } +static void fx_stb_r6() { FX_STB(6); } +static void fx_stb_r7() { FX_STB(7); } +static void fx_stb_r8() { FX_STB(8); } +static void fx_stb_r9() { FX_STB(9); } +static void fx_stb_r10() { FX_STB(10); } +static void fx_stb_r11() { FX_STB(11); } + +/* 3c - loop - decrement loop counter, and branch on not zero */ +static void fx_loop() +{ + GSU.vSign = GSU.vZero = --R12; + if( (uint16) R12 != 0 ) + R15 = R13; + else + R15++; + + CLRFLAGS; +} + +/* 3d - alt1 - set alt1 mode */ +static void fx_alt1() { SF(ALT1); CF(B); R15++; } + +/* 3e - alt2 - set alt2 mode */ +static void fx_alt2() { SF(ALT2); CF(B); R15++; } + +/* 3f - alt3 - set alt3 mode */ +static void fx_alt3() { SF(ALT1); SF(ALT2); CF(B); R15++; } + +/* 40-4b - ldw (rn) - load word from RAM */ +#define FX_LDW(reg) uint32 v; \ +GSU.vLastRamAdr = GSU.avReg[reg]; \ +v = (uint32)RAM(GSU.avReg[reg]); \ +v |= ((uint32)RAM(GSU.avReg[reg]^1))<<8; \ +R15++; DREG = v; \ +TESTR14; \ +CLRFLAGS +static void fx_ldw_r0() { FX_LDW(0); } +static void fx_ldw_r1() { FX_LDW(1); } +static void fx_ldw_r2() { FX_LDW(2); } +static void fx_ldw_r3() { FX_LDW(3); } +static void fx_ldw_r4() { FX_LDW(4); } +static void fx_ldw_r5() { FX_LDW(5); } +static void fx_ldw_r6() { FX_LDW(6); } +static void fx_ldw_r7() { FX_LDW(7); } +static void fx_ldw_r8() { FX_LDW(8); } +static void fx_ldw_r9() { FX_LDW(9); } +static void fx_ldw_r10() { FX_LDW(10); } +static void fx_ldw_r11() { FX_LDW(11); } + +/* 40-4b(ALT1) - ldb (rn) - load byte */ +#define FX_LDB(reg) uint32 v; \ +GSU.vLastRamAdr = GSU.avReg[reg]; \ +v = (uint32)RAM(GSU.avReg[reg]); \ +R15++; DREG = v; \ +TESTR14; \ +CLRFLAGS +static void fx_ldb_r0() { FX_LDB(0); } +static void fx_ldb_r1() { FX_LDB(1); } +static void fx_ldb_r2() { FX_LDB(2); } +static void fx_ldb_r3() { FX_LDB(3); } +static void fx_ldb_r4() { FX_LDB(4); } +static void fx_ldb_r5() { FX_LDB(5); } +static void fx_ldb_r6() { FX_LDB(6); } +static void fx_ldb_r7() { FX_LDB(7); } +static void fx_ldb_r8() { FX_LDB(8); } +static void fx_ldb_r9() { FX_LDB(9); } +static void fx_ldb_r10() { FX_LDB(10); } +static void fx_ldb_r11() { FX_LDB(11); } + +/* 4c - plot - plot pixel with R1,R2 as x,y and the color register as the color */ +static void fx_plot_2bit() +{ + uint32 x = USEX8(R1); + uint32 y = USEX8(R2); + uint8 *a; + uint8 v,c; + + R15++; + CLRFLAGS; + R1++; + +#ifdef CHECK_LIMITS + if(y >= GSU.vScreenHeight) return; +#endif + if(GSU.vPlotOptionReg & 0x02) + c = (x^y)&1 ? (uint8)(GSU.vColorReg>>4) : (uint8)GSU.vColorReg; + else + c = (uint8)GSU.vColorReg; + + if( !(GSU.vPlotOptionReg & 0x01) && !(c & 0xf)) return; + a = GSU.apvScreen[y >> 3] + GSU.x[x >> 3] + ((y & 7) << 1); + v = 128 >> (x&7); + + if(c & 0x01) a[0] |= v; + else a[0] &= ~v; + if(c & 0x02) a[1] |= v; + else a[1] &= ~v; +} + +/* 2c(ALT1) - rpix - read color of the pixel with R1,R2 as x,y */ +static void fx_rpix_2bit() +{ + uint32 x = USEX8(R1); + uint32 y = USEX8(R2); + uint8 *a; + uint8 v; + + R15++; + CLRFLAGS; +#ifdef CHECK_LIMITS + if(y >= GSU.vScreenHeight) return; +#endif + + a = GSU.apvScreen[y >> 3] + GSU.x[x >> 3] + ((y & 7) << 1); + v = 128 >> (x&7); + + DREG = 0; + DREG |= ((uint32)((a[0] & v) != 0)) << 0; + DREG |= ((uint32)((a[1] & v) != 0)) << 1; + TESTR14; +} + +/* 4c - plot - plot pixel with R1,R2 as x,y and the color register as the color */ +static void fx_plot_4bit() +{ + uint32 x = USEX8(R1); + uint32 y = USEX8(R2); + uint8 *a; + uint8 v,c; + + R15++; + CLRFLAGS; + R1++; + +#ifdef CHECK_LIMITS + if(y >= GSU.vScreenHeight) return; +#endif + if(GSU.vPlotOptionReg & 0x02) + c = (x^y)&1 ? (uint8)(GSU.vColorReg>>4) : (uint8)GSU.vColorReg; + else + c = (uint8)GSU.vColorReg; + + if( !(GSU.vPlotOptionReg & 0x01) && !(c & 0xf)) return; + + a = GSU.apvScreen[y >> 3] + GSU.x[x >> 3] + ((y & 7) << 1); + v = 128 >> (x&7); + + if(c & 0x01) a[0x00] |= v; + else a[0x00] &= ~v; + if(c & 0x02) a[0x01] |= v; + else a[0x01] &= ~v; + if(c & 0x04) a[0x10] |= v; + else a[0x10] &= ~v; + if(c & 0x08) a[0x11] |= v; + else a[0x11] &= ~v; +} + +/* 4c(ALT1) - rpix - read color of the pixel with R1,R2 as x,y */ +static void fx_rpix_4bit() +{ + uint32 x = USEX8(R1); + uint32 y = USEX8(R2); + uint8 *a; + uint8 v; + + R15++; + CLRFLAGS; + +#ifdef CHECK_LIMITS + if(y >= GSU.vScreenHeight) return; +#endif + + a = GSU.apvScreen[y >> 3] + GSU.x[x >> 3] + ((y & 7) << 1); + v = 128 >> (x&7); + + DREG = 0; + DREG |= ((uint32)((a[0x00] & v) != 0)) << 0; + DREG |= ((uint32)((a[0x01] & v) != 0)) << 1; + DREG |= ((uint32)((a[0x10] & v) != 0)) << 2; + DREG |= ((uint32)((a[0x11] & v) != 0)) << 3; + TESTR14; +} + +/* 8c - plot - plot pixel with R1,R2 as x,y and the color register as the color */ +static void fx_plot_8bit() +{ + uint32 x = USEX8(R1); + uint32 y = USEX8(R2); + uint8 *a; + uint8 v,c; + + R15++; + CLRFLAGS; + R1++; + +#ifdef CHECK_LIMITS + if(y >= GSU.vScreenHeight) return; +#endif + c = (uint8)GSU.vColorReg; + if(GSU.vPlotOptionReg & 0x10) + if( !(GSU.vPlotOptionReg & 0x01) && !(c&0xf)) return; + else + if( !(GSU.vPlotOptionReg & 0x01) && !c) return; + + a = GSU.apvScreen[y >> 3] + GSU.x[x >> 3] + ((y & 7) << 1); + v = 128 >> (x&7); + + if(c & 0x01) a[0x00] |= v; + else a[0x00] &= ~v; + if(c & 0x02) a[0x01] |= v; + else a[0x01] &= ~v; + if(c & 0x04) a[0x10] |= v; + else a[0x10] &= ~v; + if(c & 0x08) a[0x11] |= v; + else a[0x11] &= ~v; + if(c & 0x10) a[0x20] |= v; + else a[0x20] &= ~v; + if(c & 0x20) a[0x21] |= v; + else a[0x21] &= ~v; + if(c & 0x40) a[0x30] |= v; + else a[0x30] &= ~v; + if(c & 0x80) a[0x31] |= v; + else a[0x31] &= ~v; +} + +/* 4c(ALT1) - rpix - read color of the pixel with R1,R2 as x,y */ +static void fx_rpix_8bit() +{ + uint32 x = USEX8(R1); + uint32 y = USEX8(R2); + uint8 *a; + uint8 v; + + R15++; + CLRFLAGS; + +#ifdef CHECK_LIMITS + if(y >= GSU.vScreenHeight) return; +#endif + a = GSU.apvScreen[y >> 3] + GSU.x[x >> 3] + ((y & 7) << 1); + v = 128 >> (x&7); + + DREG = 0; + DREG |= ((uint32)((a[0x00] & v) != 0)) << 0; + DREG |= ((uint32)((a[0x01] & v) != 0)) << 1; + DREG |= ((uint32)((a[0x10] & v) != 0)) << 2; + DREG |= ((uint32)((a[0x11] & v) != 0)) << 3; + DREG |= ((uint32)((a[0x20] & v) != 0)) << 4; + DREG |= ((uint32)((a[0x21] & v) != 0)) << 5; + DREG |= ((uint32)((a[0x30] & v) != 0)) << 6; + DREG |= ((uint32)((a[0x31] & v) != 0)) << 7; + TESTR14; +} + +/* 4o - plot - plot pixel with R1,R2 as x,y and the color register as the color */ +static void fx_plot_obj() +{ + printf ("ERROR fx_plot_obj called\n"); +} + +/* 4c(ALT1) - rpix - read color of the pixel with R1,R2 as x,y */ +static void fx_rpix_obj() +{ + printf ("ERROR fx_rpix_obj called\n"); +} + +/* 4d - swap - swap upper and lower byte of a register */ +static void fx_swap() +{ + uint8 c = (uint8)SREG; + uint8 d = (uint8)(SREG>>8); + uint32 v = (((uint32)c)<<8)|((uint32)d); + R15++; DREG = v; + GSU.vSign = v; + GSU.vZero = v; + TESTR14; + CLRFLAGS; +} + +/* 4e - color - copy source register to color register */ +static void fx_color() +{ + uint8 c = (uint8)SREG; + if(GSU.vPlotOptionReg & 0x04) + c = (c&0xf0) | (c>>4); + if(GSU.vPlotOptionReg & 0x08) + { + GSU.vColorReg &= 0xf0; + GSU.vColorReg |= c & 0x0f; + } + else + GSU.vColorReg = USEX8(c); + CLRFLAGS; + R15++; +} + +/* 4e(ALT1) - cmode - set plot option register */ +static void fx_cmode() +{ + GSU.vPlotOptionReg = SREG; + + if(GSU.vPlotOptionReg & 0x10) + { + /* OBJ Mode (for drawing into sprites) */ + GSU.vScreenHeight = 256; + } + else + GSU.vScreenHeight = GSU.vScreenRealHeight; + + fx_computeScreenPointers (); + CLRFLAGS; + R15++; +} + +/* 4f - not - perform exclusive exor with 1 on all bits */ +static void fx_not() +{ + uint32 v = ~SREG; + R15++; DREG = v; + GSU.vSign = v; + GSU.vZero = v; + TESTR14; + CLRFLAGS; +} + +/* 50-5f - add rn - add, register + register */ +#define FX_ADD(reg) \ +int32 s = SUSEX16(SREG) + SUSEX16(GSU.avReg[reg]); \ +GSU.vCarry = s >= 0x10000; \ +GSU.vOverflow = ~(SREG ^ GSU.avReg[reg]) & (GSU.avReg[reg] ^ s) & 0x8000; \ +GSU.vSign = s; \ +GSU.vZero = s; \ +R15++; DREG = s; \ +TESTR14; \ +CLRFLAGS +static void fx_add_r0() { FX_ADD(0); } +static void fx_add_r1() { FX_ADD(1); } +static void fx_add_r2() { FX_ADD(2); } +static void fx_add_r3() { FX_ADD(3); } +static void fx_add_r4() { FX_ADD(4); } +static void fx_add_r5() { FX_ADD(5); } +static void fx_add_r6() { FX_ADD(6); } +static void fx_add_r7() { FX_ADD(7); } +static void fx_add_r8() { FX_ADD(8); } +static void fx_add_r9() { FX_ADD(9); } +static void fx_add_r10() { FX_ADD(10); } +static void fx_add_r11() { FX_ADD(11); } +static void fx_add_r12() { FX_ADD(12); } +static void fx_add_r13() { FX_ADD(13); } +static void fx_add_r14() { FX_ADD(14); } +static void fx_add_r15() { FX_ADD(15); } + +/* 50-5f(ALT1) - adc rn - add with carry, register + register */ +#define FX_ADC(reg) \ +int32 s = SUSEX16(SREG) + SUSEX16(GSU.avReg[reg]) + SEX16(GSU.vCarry); \ +GSU.vCarry = s >= 0x10000; \ +GSU.vOverflow = ~(SREG ^ GSU.avReg[reg]) & (GSU.avReg[reg] ^ s) & 0x8000; \ +GSU.vSign = s; \ +GSU.vZero = s; \ +R15++; DREG = s; \ +TESTR14; \ +CLRFLAGS +static void fx_adc_r0() { FX_ADC(0); } +static void fx_adc_r1() { FX_ADC(1); } +static void fx_adc_r2() { FX_ADC(2); } +static void fx_adc_r3() { FX_ADC(3); } +static void fx_adc_r4() { FX_ADC(4); } +static void fx_adc_r5() { FX_ADC(5); } +static void fx_adc_r6() { FX_ADC(6); } +static void fx_adc_r7() { FX_ADC(7); } +static void fx_adc_r8() { FX_ADC(8); } +static void fx_adc_r9() { FX_ADC(9); } +static void fx_adc_r10() { FX_ADC(10); } +static void fx_adc_r11() { FX_ADC(11); } +static void fx_adc_r12() { FX_ADC(12); } +static void fx_adc_r13() { FX_ADC(13); } +static void fx_adc_r14() { FX_ADC(14); } +static void fx_adc_r15() { FX_ADC(15); } + +/* 50-5f(ALT2) - add #n - add, register + immediate */ +#define FX_ADD_I(imm) \ +int32 s = SUSEX16(SREG) + imm; \ +GSU.vCarry = s >= 0x10000; \ +GSU.vOverflow = ~(SREG ^ imm) & (imm ^ s) & 0x8000; \ +GSU.vSign = s; \ +GSU.vZero = s; \ +R15++; DREG = s; \ +TESTR14; \ +CLRFLAGS +static void fx_add_i0() { FX_ADD_I(0); } +static void fx_add_i1() { FX_ADD_I(1); } +static void fx_add_i2() { FX_ADD_I(2); } +static void fx_add_i3() { FX_ADD_I(3); } +static void fx_add_i4() { FX_ADD_I(4); } +static void fx_add_i5() { FX_ADD_I(5); } +static void fx_add_i6() { FX_ADD_I(6); } +static void fx_add_i7() { FX_ADD_I(7); } +static void fx_add_i8() { FX_ADD_I(8); } +static void fx_add_i9() { FX_ADD_I(9); } +static void fx_add_i10() { FX_ADD_I(10); } +static void fx_add_i11() { FX_ADD_I(11); } +static void fx_add_i12() { FX_ADD_I(12); } +static void fx_add_i13() { FX_ADD_I(13); } +static void fx_add_i14() { FX_ADD_I(14); } +static void fx_add_i15() { FX_ADD_I(15); } + +/* 50-5f(ALT3) - adc #n - add with carry, register + immediate */ +#define FX_ADC_I(imm) \ +int32 s = SUSEX16(SREG) + imm + SUSEX16(GSU.vCarry); \ +GSU.vCarry = s >= 0x10000; \ +GSU.vOverflow = ~(SREG ^ imm) & (imm ^ s) & 0x8000; \ +GSU.vSign = s; \ +GSU.vZero = s; \ +R15++; DREG = s; \ +TESTR14; \ +CLRFLAGS +static void fx_adc_i0() { FX_ADC_I(0); } +static void fx_adc_i1() { FX_ADC_I(1); } +static void fx_adc_i2() { FX_ADC_I(2); } +static void fx_adc_i3() { FX_ADC_I(3); } +static void fx_adc_i4() { FX_ADC_I(4); } +static void fx_adc_i5() { FX_ADC_I(5); } +static void fx_adc_i6() { FX_ADC_I(6); } +static void fx_adc_i7() { FX_ADC_I(7); } +static void fx_adc_i8() { FX_ADC_I(8); } +static void fx_adc_i9() { FX_ADC_I(9); } +static void fx_adc_i10() { FX_ADC_I(10); } +static void fx_adc_i11() { FX_ADC_I(11); } +static void fx_adc_i12() { FX_ADC_I(12); } +static void fx_adc_i13() { FX_ADC_I(13); } +static void fx_adc_i14() { FX_ADC_I(14); } +static void fx_adc_i15() { FX_ADC_I(15); } + +/* 60-6f - sub rn - subtract, register - register */ +#define FX_SUB(reg) \ +int32 s = SUSEX16(SREG) - SUSEX16(GSU.avReg[reg]); \ +GSU.vCarry = s >= 0; \ +GSU.vOverflow = (SREG ^ GSU.avReg[reg]) & (SREG ^ s) & 0x8000; \ +GSU.vSign = s; \ +GSU.vZero = s; \ +R15++; DREG = s; \ +TESTR14; \ +CLRFLAGS +static void fx_sub_r0() { FX_SUB(0); } +static void fx_sub_r1() { FX_SUB(1); } +static void fx_sub_r2() { FX_SUB(2); } +static void fx_sub_r3() { FX_SUB(3); } +static void fx_sub_r4() { FX_SUB(4); } +static void fx_sub_r5() { FX_SUB(5); } +static void fx_sub_r6() { FX_SUB(6); } +static void fx_sub_r7() { FX_SUB(7); } +static void fx_sub_r8() { FX_SUB(8); } +static void fx_sub_r9() { FX_SUB(9); } +static void fx_sub_r10() { FX_SUB(10); } +static void fx_sub_r11() { FX_SUB(11); } +static void fx_sub_r12() { FX_SUB(12); } +static void fx_sub_r13() { FX_SUB(13); } +static void fx_sub_r14() { FX_SUB(14); } +static void fx_sub_r15() { FX_SUB(15); } + +/* 60-6f(ALT1) - sbc rn - subtract with carry, register - register */ +#define FX_SBC(reg) \ +int32 s = SUSEX16(SREG) - SUSEX16(GSU.avReg[reg]) - (SUSEX16(GSU.vCarry^1)); \ +GSU.vCarry = s >= 0; \ +GSU.vOverflow = (SREG ^ GSU.avReg[reg]) & (SREG ^ s) & 0x8000; \ +GSU.vSign = s; \ +GSU.vZero = s; \ +R15++; DREG = s; \ +TESTR14; \ +CLRFLAGS +static void fx_sbc_r0() { FX_SBC(0); } +static void fx_sbc_r1() { FX_SBC(1); } +static void fx_sbc_r2() { FX_SBC(2); } +static void fx_sbc_r3() { FX_SBC(3); } +static void fx_sbc_r4() { FX_SBC(4); } +static void fx_sbc_r5() { FX_SBC(5); } +static void fx_sbc_r6() { FX_SBC(6); } +static void fx_sbc_r7() { FX_SBC(7); } +static void fx_sbc_r8() { FX_SBC(8); } +static void fx_sbc_r9() { FX_SBC(9); } +static void fx_sbc_r10() { FX_SBC(10); } +static void fx_sbc_r11() { FX_SBC(11); } +static void fx_sbc_r12() { FX_SBC(12); } +static void fx_sbc_r13() { FX_SBC(13); } +static void fx_sbc_r14() { FX_SBC(14); } +static void fx_sbc_r15() { FX_SBC(15); } + +/* 60-6f(ALT2) - sub #n - subtract, register - immediate */ +#define FX_SUB_I(imm) \ +int32 s = SUSEX16(SREG) - imm; \ +GSU.vCarry = s >= 0; \ +GSU.vOverflow = (SREG ^ imm) & (SREG ^ s) & 0x8000; \ +GSU.vSign = s; \ +GSU.vZero = s; \ +R15++; DREG = s; \ +TESTR14; \ +CLRFLAGS +static void fx_sub_i0() { FX_SUB_I(0); } +static void fx_sub_i1() { FX_SUB_I(1); } +static void fx_sub_i2() { FX_SUB_I(2); } +static void fx_sub_i3() { FX_SUB_I(3); } +static void fx_sub_i4() { FX_SUB_I(4); } +static void fx_sub_i5() { FX_SUB_I(5); } +static void fx_sub_i6() { FX_SUB_I(6); } +static void fx_sub_i7() { FX_SUB_I(7); } +static void fx_sub_i8() { FX_SUB_I(8); } +static void fx_sub_i9() { FX_SUB_I(9); } +static void fx_sub_i10() { FX_SUB_I(10); } +static void fx_sub_i11() { FX_SUB_I(11); } +static void fx_sub_i12() { FX_SUB_I(12); } +static void fx_sub_i13() { FX_SUB_I(13); } +static void fx_sub_i14() { FX_SUB_I(14); } +static void fx_sub_i15() { FX_SUB_I(15); } + +/* 60-6f(ALT3) - cmp rn - compare, register, register */ +#define FX_CMP(reg) \ +int32 s = SUSEX16(SREG) - SUSEX16(GSU.avReg[reg]); \ +GSU.vCarry = s >= 0; \ +GSU.vOverflow = (SREG ^ GSU.avReg[reg]) & (SREG ^ s) & 0x8000; \ +GSU.vSign = s; \ +GSU.vZero = s; \ +R15++; \ +CLRFLAGS; +static void fx_cmp_r0() { FX_CMP(0); } +static void fx_cmp_r1() { FX_CMP(1); } +static void fx_cmp_r2() { FX_CMP(2); } +static void fx_cmp_r3() { FX_CMP(3); } +static void fx_cmp_r4() { FX_CMP(4); } +static void fx_cmp_r5() { FX_CMP(5); } +static void fx_cmp_r6() { FX_CMP(6); } +static void fx_cmp_r7() { FX_CMP(7); } +static void fx_cmp_r8() { FX_CMP(8); } +static void fx_cmp_r9() { FX_CMP(9); } +static void fx_cmp_r10() { FX_CMP(10); } +static void fx_cmp_r11() { FX_CMP(11); } +static void fx_cmp_r12() { FX_CMP(12); } +static void fx_cmp_r13() { FX_CMP(13); } +static void fx_cmp_r14() { FX_CMP(14); } +static void fx_cmp_r15() { FX_CMP(15); } + +/* 70 - merge - R7 as upper byte, R8 as lower byte (used for texture-mapping) */ +static void fx_merge() +{ + uint32 v = (R7&0xff00) | ((R8&0xff00)>>8); + R15++; DREG = v; + GSU.vOverflow = (v & 0xc0c0) << 16; + GSU.vZero = !(v & 0xf0f0); + GSU.vSign = ((v | (v<<8)) & 0x8000); + GSU.vCarry = (v & 0xe0e0) != 0; + TESTR14; + CLRFLAGS; +} + +/* 71-7f - and rn - reister & register */ +#define FX_AND(reg) \ +uint32 v = SREG & GSU.avReg[reg]; \ +R15++; DREG = v; \ +GSU.vSign = v; \ +GSU.vZero = v; \ +TESTR14; \ +CLRFLAGS; +static void fx_and_r1() { FX_AND(1); } +static void fx_and_r2() { FX_AND(2); } +static void fx_and_r3() { FX_AND(3); } +static void fx_and_r4() { FX_AND(4); } +static void fx_and_r5() { FX_AND(5); } +static void fx_and_r6() { FX_AND(6); } +static void fx_and_r7() { FX_AND(7); } +static void fx_and_r8() { FX_AND(8); } +static void fx_and_r9() { FX_AND(9); } +static void fx_and_r10() { FX_AND(10); } +static void fx_and_r11() { FX_AND(11); } +static void fx_and_r12() { FX_AND(12); } +static void fx_and_r13() { FX_AND(13); } +static void fx_and_r14() { FX_AND(14); } +static void fx_and_r15() { FX_AND(15); } + +/* 71-7f(ALT1) - bic rn - reister & ~register */ +#define FX_BIC(reg) \ +uint32 v = SREG & ~GSU.avReg[reg]; \ +R15++; DREG = v; \ +GSU.vSign = v; \ +GSU.vZero = v; \ +TESTR14; \ +CLRFLAGS; +static void fx_bic_r1() { FX_AND(1); } +static void fx_bic_r2() { FX_AND(2); } +static void fx_bic_r3() { FX_AND(3); } +static void fx_bic_r4() { FX_AND(4); } +static void fx_bic_r5() { FX_AND(5); } +static void fx_bic_r6() { FX_AND(6); } +static void fx_bic_r7() { FX_AND(7); } +static void fx_bic_r8() { FX_AND(8); } +static void fx_bic_r9() { FX_AND(9); } +static void fx_bic_r10() { FX_AND(10); } +static void fx_bic_r11() { FX_AND(11); } +static void fx_bic_r12() { FX_AND(12); } +static void fx_bic_r13() { FX_AND(13); } +static void fx_bic_r14() { FX_AND(14); } +static void fx_bic_r15() { FX_AND(15); } + +/* 71-7f(ALT2) - and #n - reister & immediate */ +#define FX_AND_I(imm) \ +uint32 v = SREG & imm; \ +R15++; DREG = v; \ +GSU.vSign = v; \ +GSU.vZero = v; \ +TESTR14; \ +CLRFLAGS; +static void fx_and_i1() { FX_AND_I(1); } +static void fx_and_i2() { FX_AND_I(2); } +static void fx_and_i3() { FX_AND_I(3); } +static void fx_and_i4() { FX_AND_I(4); } +static void fx_and_i5() { FX_AND_I(5); } +static void fx_and_i6() { FX_AND_I(6); } +static void fx_and_i7() { FX_AND_I(7); } +static void fx_and_i8() { FX_AND_I(8); } +static void fx_and_i9() { FX_AND_I(9); } +static void fx_and_i10() { FX_AND_I(10); } +static void fx_and_i11() { FX_AND_I(11); } +static void fx_and_i12() { FX_AND_I(12); } +static void fx_and_i13() { FX_AND_I(13); } +static void fx_and_i14() { FX_AND_I(14); } +static void fx_and_i15() { FX_AND_I(15); } + +/* 71-7f(ALT3) - bic #n - reister & ~immediate */ +#define FX_BIC_I(imm) \ +uint32 v = SREG & ~imm; \ +R15++; DREG = v; \ +GSU.vSign = v; \ +GSU.vZero = v; \ +TESTR14; \ +CLRFLAGS; +static void fx_bic_i1() { FX_BIC_I(1); } +static void fx_bic_i2() { FX_BIC_I(2); } +static void fx_bic_i3() { FX_BIC_I(3); } +static void fx_bic_i4() { FX_BIC_I(4); } +static void fx_bic_i5() { FX_BIC_I(5); } +static void fx_bic_i6() { FX_BIC_I(6); } +static void fx_bic_i7() { FX_BIC_I(7); } +static void fx_bic_i8() { FX_BIC_I(8); } +static void fx_bic_i9() { FX_BIC_I(9); } +static void fx_bic_i10() { FX_BIC_I(10); } +static void fx_bic_i11() { FX_BIC_I(11); } +static void fx_bic_i12() { FX_BIC_I(12); } +static void fx_bic_i13() { FX_BIC_I(13); } +static void fx_bic_i14() { FX_BIC_I(14); } +static void fx_bic_i15() { FX_BIC_I(15); } + +/* 80-8f - mult rn - 8 bit to 16 bit signed multiply, register * register */ +#define FX_MULT(reg) \ +uint32 v = (uint32)(SEX8(SREG) * SEX8(GSU.avReg[reg])); \ +R15++; DREG = v; \ +GSU.vSign = v; \ +GSU.vZero = v; \ +TESTR14; \ +CLRFLAGS; +static void fx_mult_r0() { FX_MULT(0); } +static void fx_mult_r1() { FX_MULT(1); } +static void fx_mult_r2() { FX_MULT(2); } +static void fx_mult_r3() { FX_MULT(3); } +static void fx_mult_r4() { FX_MULT(4); } +static void fx_mult_r5() { FX_MULT(5); } +static void fx_mult_r6() { FX_MULT(6); } +static void fx_mult_r7() { FX_MULT(7); } +static void fx_mult_r8() { FX_MULT(8); } +static void fx_mult_r9() { FX_MULT(9); } +static void fx_mult_r10() { FX_MULT(10); } +static void fx_mult_r11() { FX_MULT(11); } +static void fx_mult_r12() { FX_MULT(12); } +static void fx_mult_r13() { FX_MULT(13); } +static void fx_mult_r14() { FX_MULT(14); } +static void fx_mult_r15() { FX_MULT(15); } + +/* 80-8f(ALT1) - umult rn - 8 bit to 16 bit unsigned multiply, register * register */ +#define FX_UMULT(reg) \ +uint32 v = USEX8(SREG) * USEX8(GSU.avReg[reg]); \ +R15++; DREG = v; \ +GSU.vSign = v; \ +GSU.vZero = v; \ +TESTR14; \ +CLRFLAGS; +static void fx_umult_r0() { FX_UMULT(0); } +static void fx_umult_r1() { FX_UMULT(1); } +static void fx_umult_r2() { FX_UMULT(2); } +static void fx_umult_r3() { FX_UMULT(3); } +static void fx_umult_r4() { FX_UMULT(4); } +static void fx_umult_r5() { FX_UMULT(5); } +static void fx_umult_r6() { FX_UMULT(6); } +static void fx_umult_r7() { FX_UMULT(7); } +static void fx_umult_r8() { FX_UMULT(8); } +static void fx_umult_r9() { FX_UMULT(9); } +static void fx_umult_r10() { FX_UMULT(10); } +static void fx_umult_r11() { FX_UMULT(11); } +static void fx_umult_r12() { FX_UMULT(12); } +static void fx_umult_r13() { FX_UMULT(13); } +static void fx_umult_r14() { FX_UMULT(14); } +static void fx_umult_r15() { FX_UMULT(15); } + +/* 80-8f(ALT2) - mult #n - 8 bit to 16 bit signed multiply, register * immediate */ +#define FX_MULT_I(imm) \ +uint32 v = (uint32) (SEX8(SREG) * ((int32)imm)); \ +R15++; DREG = v; \ +GSU.vSign = v; \ +GSU.vZero = v; \ +TESTR14; \ +CLRFLAGS; +static void fx_mult_i0() { FX_MULT_I(0); } +static void fx_mult_i1() { FX_MULT_I(1); } +static void fx_mult_i2() { FX_MULT_I(2); } +static void fx_mult_i3() { FX_MULT_I(3); } +static void fx_mult_i4() { FX_MULT_I(4); } +static void fx_mult_i5() { FX_MULT_I(5); } +static void fx_mult_i6() { FX_MULT_I(6); } +static void fx_mult_i7() { FX_MULT_I(7); } +static void fx_mult_i8() { FX_MULT_I(8); } +static void fx_mult_i9() { FX_MULT_I(9); } +static void fx_mult_i10() { FX_MULT_I(10); } +static void fx_mult_i11() { FX_MULT_I(11); } +static void fx_mult_i12() { FX_MULT_I(12); } +static void fx_mult_i13() { FX_MULT_I(13); } +static void fx_mult_i14() { FX_MULT_I(14); } +static void fx_mult_i15() { FX_MULT_I(15); } + +/* 80-8f(ALT3) - umult #n - 8 bit to 16 bit unsigned multiply, register * immediate */ +#define FX_UMULT_I(imm) \ +uint32 v = USEX8(SREG) * ((uint32)imm); \ +R15++; DREG = v; \ +GSU.vSign = v; \ +GSU.vZero = v; \ +TESTR14; \ +CLRFLAGS; +static void fx_umult_i0() { FX_UMULT_I(0); } +static void fx_umult_i1() { FX_UMULT_I(1); } +static void fx_umult_i2() { FX_UMULT_I(2); } +static void fx_umult_i3() { FX_UMULT_I(3); } +static void fx_umult_i4() { FX_UMULT_I(4); } +static void fx_umult_i5() { FX_UMULT_I(5); } +static void fx_umult_i6() { FX_UMULT_I(6); } +static void fx_umult_i7() { FX_UMULT_I(7); } +static void fx_umult_i8() { FX_UMULT_I(8); } +static void fx_umult_i9() { FX_UMULT_I(9); } +static void fx_umult_i10() { FX_UMULT_I(10); } +static void fx_umult_i11() { FX_UMULT_I(11); } +static void fx_umult_i12() { FX_UMULT_I(12); } +static void fx_umult_i13() { FX_UMULT_I(13); } +static void fx_umult_i14() { FX_UMULT_I(14); } +static void fx_umult_i15() { FX_UMULT_I(15); } + +/* 90 - sbk - store word to last accessed RAM address */ +static void fx_sbk() +{ + RAM(GSU.vLastRamAdr) = (uint8)SREG; + RAM(GSU.vLastRamAdr^1) = (uint8)(SREG>>8); + CLRFLAGS; + R15++; +} + +/* 91-94 - link #n - R11 = R15 + immediate */ +#define FX_LINK_I(lkn) R11 = R15 + lkn; CLRFLAGS; R15++ +static void fx_link_i1() { FX_LINK_I(1); } +static void fx_link_i2() { FX_LINK_I(2); } +static void fx_link_i3() { FX_LINK_I(3); } +static void fx_link_i4() { FX_LINK_I(4); } + +/* 95 - sex - sign extend 8 bit to 16 bit */ +static void fx_sex() +{ + uint32 v = (uint32)SEX8(SREG); + R15++; DREG = v; + GSU.vSign = v; + GSU.vZero = v; + TESTR14; + CLRFLAGS; +} + +/* 96 - asr - aritmetric shift right by one */ +static void fx_asr() +{ + uint32 v; + GSU.vCarry = SREG & 1; + v = (uint32)(SEX16(SREG)>>1); + R15++; DREG = v; + GSU.vSign = v; + GSU.vZero = v; + TESTR14; + CLRFLAGS; +} + +/* 96(ALT1) - div2 - aritmetric shift right by one */ +static void fx_div2() +{ + uint32 v; + int32 s = SEX16(SREG); + GSU.vCarry = s & 1; + if(s == -1) + v = 0; + else + v = (uint32)(s>>1); + R15++; DREG = v; + GSU.vSign = v; + GSU.vZero = v; + TESTR14; + CLRFLAGS; +} + +/* 97 - ror - rotate right by one */ +static void fx_ror() +{ + uint32 v = (USEX16(SREG)>>1) | (GSU.vCarry<<15); + GSU.vCarry = SREG & 1; + R15++; DREG = v; + GSU.vSign = v; + GSU.vZero = v; + TESTR14; + CLRFLAGS; +} + +/* 98-9d - jmp rn - jump to address of register */ +#define FX_JMP(reg) \ +R15 = GSU.avReg[reg]; \ +CLRFLAGS; +static void fx_jmp_r8() { FX_JMP(8); } +static void fx_jmp_r9() { FX_JMP(9); } +static void fx_jmp_r10() { FX_JMP(10); } +static void fx_jmp_r11() { FX_JMP(11); } +static void fx_jmp_r12() { FX_JMP(12); } +static void fx_jmp_r13() { FX_JMP(13); } + +/* 98-9d(ALT1) - ljmp rn - set program bank to source register and jump to address of register */ +#define FX_LJMP(reg) \ +GSU.vPrgBankReg = GSU.avReg[reg] & 0x7f; \ +GSU.pvPrgBank = GSU.apvRomBank[GSU.vPrgBankReg]; \ +R15 = SREG; \ +GSU.bCacheActive = FALSE; fx_cache(); R15--; +static void fx_ljmp_r8() { FX_LJMP(8); } +static void fx_ljmp_r9() { FX_LJMP(9); } +static void fx_ljmp_r10() { FX_LJMP(10); } +static void fx_ljmp_r11() { FX_LJMP(11); } +static void fx_ljmp_r12() { FX_LJMP(12); } +static void fx_ljmp_r13() { FX_LJMP(13); } + +/* 9e - lob - set upper byte to zero (keep low byte) */ +static void fx_lob() +{ + uint32 v = USEX8(SREG); + R15++; DREG = v; + GSU.vSign = v<<8; + GSU.vZero = v<<8; + TESTR14; + CLRFLAGS; +} + +/* 9f - fmult - 16 bit to 32 bit signed multiplication, upper 16 bits only */ +static void fx_fmult() +{ + uint32 v; + uint32 c = (uint32) (SEX16(SREG) * SEX16(R6)); + v = c >> 16; + R15++; DREG = v; + GSU.vSign = v; + GSU.vZero = v; + GSU.vCarry = (c >> 15) & 1; + TESTR14; + CLRFLAGS; +} + +/* 9f(ALT1) - lmult - 16 bit to 32 bit signed multiplication */ +static void fx_lmult() +{ + uint32 v; + uint32 c = (uint32) (SEX16(SREG) * SEX16(R6)); + R4 = c; + v = c >> 16; + R15++; DREG = v; + GSU.vSign = v; + GSU.vZero = v; + /* XXX R6 or R4? */ + GSU.vCarry = (R4 >> 15) & 1; /* should it be bit 15 of R4 instead? */ + TESTR14; + CLRFLAGS; +} + +/* a0-af - ibt rn,#pp - immediate byte transfer */ +#define FX_IBT(reg) \ +uint8 v = PIPE; R15++; \ +FETCHPIPE; R15++; \ +GSU.avReg[reg] = SEX8(v); \ +CLRFLAGS; +static void fx_ibt_r0() { FX_IBT(0); } +static void fx_ibt_r1() { FX_IBT(1); } +static void fx_ibt_r2() { FX_IBT(2); } +static void fx_ibt_r3() { FX_IBT(3); } +static void fx_ibt_r4() { FX_IBT(4); } +static void fx_ibt_r5() { FX_IBT(5); } +static void fx_ibt_r6() { FX_IBT(6); } +static void fx_ibt_r7() { FX_IBT(7); } +static void fx_ibt_r8() { FX_IBT(8); } +static void fx_ibt_r9() { FX_IBT(9); } +static void fx_ibt_r10() { FX_IBT(10); } +static void fx_ibt_r11() { FX_IBT(11); } +static void fx_ibt_r12() { FX_IBT(12); } +static void fx_ibt_r13() { FX_IBT(13); } +static void fx_ibt_r14() { FX_IBT(14); READR14; } +static void fx_ibt_r15() { FX_IBT(15); } + +/* a0-af(ALT1) - lms rn,(yy) - load word from RAM (short address) */ +#define FX_LMS(reg) \ +GSU.vLastRamAdr = ((uint32)PIPE) << 1; \ +R15++; FETCHPIPE; R15++; \ +GSU.avReg[reg] = (uint32)RAM(GSU.vLastRamAdr); \ +GSU.avReg[reg] |= ((uint32)RAM(GSU.vLastRamAdr+1))<<8; \ +CLRFLAGS; +static void fx_lms_r0() { FX_LMS(0); } +static void fx_lms_r1() { FX_LMS(1); } +static void fx_lms_r2() { FX_LMS(2); } +static void fx_lms_r3() { FX_LMS(3); } +static void fx_lms_r4() { FX_LMS(4); } +static void fx_lms_r5() { FX_LMS(5); } +static void fx_lms_r6() { FX_LMS(6); } +static void fx_lms_r7() { FX_LMS(7); } +static void fx_lms_r8() { FX_LMS(8); } +static void fx_lms_r9() { FX_LMS(9); } +static void fx_lms_r10() { FX_LMS(10); } +static void fx_lms_r11() { FX_LMS(11); } +static void fx_lms_r12() { FX_LMS(12); } +static void fx_lms_r13() { FX_LMS(13); } +static void fx_lms_r14() { FX_LMS(14); READR14; } +static void fx_lms_r15() { FX_LMS(15); } + +/* a0-af(ALT2) - sms (yy),rn - store word in RAM (short address) */ +/* If rn == r15, is the value of r15 before or after the extra byte is read? */ +#define FX_SMS(reg) \ +uint32 v = GSU.avReg[reg]; \ +GSU.vLastRamAdr = ((uint32)PIPE) << 1; \ +R15++; FETCHPIPE; \ +RAM(GSU.vLastRamAdr) = (uint8)v; \ +RAM(GSU.vLastRamAdr+1) = (uint8)(v>>8); \ +CLRFLAGS; R15++; +static void fx_sms_r0() { FX_SMS(0); } +static void fx_sms_r1() { FX_SMS(1); } +static void fx_sms_r2() { FX_SMS(2); } +static void fx_sms_r3() { FX_SMS(3); } +static void fx_sms_r4() { FX_SMS(4); } +static void fx_sms_r5() { FX_SMS(5); } +static void fx_sms_r6() { FX_SMS(6); } +static void fx_sms_r7() { FX_SMS(7); } +static void fx_sms_r8() { FX_SMS(8); } +static void fx_sms_r9() { FX_SMS(9); } +static void fx_sms_r10() { FX_SMS(10); } +static void fx_sms_r11() { FX_SMS(11); } +static void fx_sms_r12() { FX_SMS(12); } +static void fx_sms_r13() { FX_SMS(13); } +static void fx_sms_r14() { FX_SMS(14); } +static void fx_sms_r15() { FX_SMS(15); } + +/* b0-bf - from rn - set source register */ +/* b0-bf(B) - moves rn - move register to register, and set flags, (if B flag is set) */ +#define FX_FROM(reg) \ +if(TF(B)) { uint32 v = GSU.avReg[reg]; R15++; DREG = v; \ +GSU.vOverflow = (v&0x80) << 16; GSU.vSign = v; GSU.vZero = v; TESTR14; CLRFLAGS; } \ +else { GSU.pvSreg = &GSU.avReg[reg]; R15++; } +static void fx_from_r0() { FX_FROM(0); } +static void fx_from_r1() { FX_FROM(1); } +static void fx_from_r2() { FX_FROM(2); } +static void fx_from_r3() { FX_FROM(3); } +static void fx_from_r4() { FX_FROM(4); } +static void fx_from_r5() { FX_FROM(5); } +static void fx_from_r6() { FX_FROM(6); } +static void fx_from_r7() { FX_FROM(7); } +static void fx_from_r8() { FX_FROM(8); } +static void fx_from_r9() { FX_FROM(9); } +static void fx_from_r10() { FX_FROM(10); } +static void fx_from_r11() { FX_FROM(11); } +static void fx_from_r12() { FX_FROM(12); } +static void fx_from_r13() { FX_FROM(13); } +static void fx_from_r14() { FX_FROM(14); } +static void fx_from_r15() { FX_FROM(15); } + +/* c0 - hib - move high-byte to low-byte */ +static void fx_hib() +{ + uint32 v = USEX8(SREG>>8); + R15++; DREG = v; + GSU.vSign = v<<8; + GSU.vZero = v<<8; + TESTR14; + CLRFLAGS; +} + +/* c1-cf - or rn */ +#define FX_OR(reg) \ +uint32 v = SREG | GSU.avReg[reg]; R15++; DREG = v; \ +GSU.vSign = v; \ +GSU.vZero = v; \ +TESTR14; \ +CLRFLAGS; +static void fx_or_r1() { FX_OR(1); } +static void fx_or_r2() { FX_OR(2); } +static void fx_or_r3() { FX_OR(3); } +static void fx_or_r4() { FX_OR(4); } +static void fx_or_r5() { FX_OR(5); } +static void fx_or_r6() { FX_OR(6); } +static void fx_or_r7() { FX_OR(7); } +static void fx_or_r8() { FX_OR(8); } +static void fx_or_r9() { FX_OR(9); } +static void fx_or_r10() { FX_OR(10); } +static void fx_or_r11() { FX_OR(11); } +static void fx_or_r12() { FX_OR(12); } +static void fx_or_r13() { FX_OR(13); } +static void fx_or_r14() { FX_OR(14); } +static void fx_or_r15() { FX_OR(15); } + +/* c1-cf(ALT1) - xor rn */ +#define FX_XOR(reg) \ +uint32 v = SREG ^ GSU.avReg[reg]; R15++; DREG = v; \ +GSU.vSign = v; \ +GSU.vZero = v; \ +TESTR14; \ +CLRFLAGS; +static void fx_xor_r1() { FX_XOR(1); } +static void fx_xor_r2() { FX_XOR(2); } +static void fx_xor_r3() { FX_XOR(3); } +static void fx_xor_r4() { FX_XOR(4); } +static void fx_xor_r5() { FX_XOR(5); } +static void fx_xor_r6() { FX_XOR(6); } +static void fx_xor_r7() { FX_XOR(7); } +static void fx_xor_r8() { FX_XOR(8); } +static void fx_xor_r9() { FX_XOR(9); } +static void fx_xor_r10() { FX_XOR(10); } +static void fx_xor_r11() { FX_XOR(11); } +static void fx_xor_r12() { FX_XOR(12); } +static void fx_xor_r13() { FX_XOR(13); } +static void fx_xor_r14() { FX_XOR(14); } +static void fx_xor_r15() { FX_XOR(15); } + +/* c1-cf(ALT2) - or #n */ +#define FX_OR_I(imm) \ +uint32 v = SREG | imm; R15++; DREG = v; \ +GSU.vSign = v; \ +GSU.vZero = v; \ +TESTR14; \ +CLRFLAGS; +static void fx_or_i1() { FX_OR_I(1); } +static void fx_or_i2() { FX_OR_I(2); } +static void fx_or_i3() { FX_OR_I(3); } +static void fx_or_i4() { FX_OR_I(4); } +static void fx_or_i5() { FX_OR_I(5); } +static void fx_or_i6() { FX_OR_I(6); } +static void fx_or_i7() { FX_OR_I(7); } +static void fx_or_i8() { FX_OR_I(8); } +static void fx_or_i9() { FX_OR_I(9); } +static void fx_or_i10() { FX_OR_I(10); } +static void fx_or_i11() { FX_OR_I(11); } +static void fx_or_i12() { FX_OR_I(12); } +static void fx_or_i13() { FX_OR_I(13); } +static void fx_or_i14() { FX_OR_I(14); } +static void fx_or_i15() { FX_OR_I(15); } + +/* c1-cf(ALT3) - xor #n */ +#define FX_XOR_I(imm) \ +uint32 v = SREG ^ imm; R15++; DREG = v; \ +GSU.vSign = v; \ +GSU.vZero = v; \ +TESTR14; \ +CLRFLAGS; +static void fx_xor_i1() { FX_XOR_I(1); } +static void fx_xor_i2() { FX_XOR_I(2); } +static void fx_xor_i3() { FX_XOR_I(3); } +static void fx_xor_i4() { FX_XOR_I(4); } +static void fx_xor_i5() { FX_XOR_I(5); } +static void fx_xor_i6() { FX_XOR_I(6); } +static void fx_xor_i7() { FX_XOR_I(7); } +static void fx_xor_i8() { FX_XOR_I(8); } +static void fx_xor_i9() { FX_XOR_I(9); } +static void fx_xor_i10() { FX_XOR_I(10); } +static void fx_xor_i11() { FX_XOR_I(11); } +static void fx_xor_i12() { FX_XOR_I(12); } +static void fx_xor_i13() { FX_XOR_I(13); } +static void fx_xor_i14() { FX_XOR_I(14); } +static void fx_xor_i15() { FX_XOR_I(15); } + +/* d0-de - inc rn - increase by one */ +#define FX_INC(reg) \ +GSU.avReg[reg] += 1; \ +GSU.vSign = GSU.avReg[reg]; \ +GSU.vZero = GSU.avReg[reg]; \ +CLRFLAGS; R15++; +static void fx_inc_r0() { FX_INC(0); } +static void fx_inc_r1() { FX_INC(1); } +static void fx_inc_r2() { FX_INC(2); } +static void fx_inc_r3() { FX_INC(3); } +static void fx_inc_r4() { FX_INC(4); } +static void fx_inc_r5() { FX_INC(5); } +static void fx_inc_r6() { FX_INC(6); } +static void fx_inc_r7() { FX_INC(7); } +static void fx_inc_r8() { FX_INC(8); } +static void fx_inc_r9() { FX_INC(9); } +static void fx_inc_r10() { FX_INC(10); } +static void fx_inc_r11() { FX_INC(11); } +static void fx_inc_r12() { FX_INC(12); } +static void fx_inc_r13() { FX_INC(13); } +static void fx_inc_r14() { FX_INC(14); READR14; } + +/* df - getc - transfer ROM buffer to color register */ +static void fx_getc() +{ +#ifndef FX_DO_ROMBUFFER + uint8 c; + c = ROM(R14); +#else + uint8 c = GSU.vRomBuffer; +#endif + if(GSU.vPlotOptionReg & 0x04) + c = (c&0xf0) | (c>>4); + if(GSU.vPlotOptionReg & 0x08) + { + GSU.vColorReg &= 0xf0; + GSU.vColorReg |= c & 0x0f; + } + else + GSU.vColorReg = USEX8(c); + CLRFLAGS; + R15++; +} + +/* df(ALT2) - ramb - set current RAM bank */ +static void fx_ramb() +{ + GSU.vRamBankReg = SREG & (FX_RAM_BANKS-1); + GSU.pvRamBank = GSU.apvRamBank[GSU.vRamBankReg & 0x3]; + CLRFLAGS; + R15++; +} + +/* df(ALT3) - romb - set current ROM bank */ +static void fx_romb() +{ + GSU.vRomBankReg = USEX8(SREG) & 0x7f; + GSU.pvRomBank = GSU.apvRomBank[GSU.vRomBankReg]; + CLRFLAGS; + R15++; +} + +/* e0-ee - dec rn - decrement by one */ +#define FX_DEC(reg) \ +GSU.avReg[reg] -= 1; \ +GSU.vSign = GSU.avReg[reg]; \ +GSU.vZero = GSU.avReg[reg]; \ +CLRFLAGS; R15++; +static void fx_dec_r0() { FX_DEC(0); } +static void fx_dec_r1() { FX_DEC(1); } +static void fx_dec_r2() { FX_DEC(2); } +static void fx_dec_r3() { FX_DEC(3); } +static void fx_dec_r4() { FX_DEC(4); } +static void fx_dec_r5() { FX_DEC(5); } +static void fx_dec_r6() { FX_DEC(6); } +static void fx_dec_r7() { FX_DEC(7); } +static void fx_dec_r8() { FX_DEC(8); } +static void fx_dec_r9() { FX_DEC(9); } +static void fx_dec_r10() { FX_DEC(10); } +static void fx_dec_r11() { FX_DEC(11); } +static void fx_dec_r12() { FX_DEC(12); } +static void fx_dec_r13() { FX_DEC(13); } +static void fx_dec_r14() { FX_DEC(14); READR14; } + +/* ef - getb - get byte from ROM at address R14 */ +static void fx_getb() +{ + uint32 v; +#ifndef FX_DO_ROMBUFFER + v = (uint32)ROM(R14); +#else + v = (uint32)GSU.vRomBuffer; +#endif + R15++; DREG = v; + TESTR14; + CLRFLAGS; +} + +/* ef(ALT1) - getbh - get high-byte from ROM at address R14 */ +static void fx_getbh() +{ + uint32 v; +#ifndef FX_DO_ROMBUFFER + uint32 c; + c = (uint32)ROM(R14); +#else + uint32 c = USEX8(GSU.vRomBuffer); +#endif + v = USEX8(SREG) | (c<<8); + R15++; DREG = v; + TESTR14; + CLRFLAGS; +} + +/* ef(ALT2) - getbl - get low-byte from ROM at address R14 */ +static void fx_getbl() +{ + uint32 v; +#ifndef FX_DO_ROMBUFFER + uint32 c; + c = (uint32)ROM(R14); +#else + uint32 c = USEX8(GSU.vRomBuffer); +#endif + v = (SREG & 0xff00) | c; + R15++; DREG = v; + TESTR14; + CLRFLAGS; +} + +/* ef(ALT3) - getbs - get sign extended byte from ROM at address R14 */ +static void fx_getbs() +{ + uint32 v; +#ifndef FX_DO_ROMBUFFER + int8 c; + c = ROM(R14); + v = SEX8(c); +#else + v = SEX8(GSU.vRomBuffer); +#endif + R15++; DREG = v; + TESTR14; + CLRFLAGS; +} + +/* f0-ff - iwt rn,#xx - immediate word transfer to register */ +#define FX_IWT(reg) \ +uint32 v = PIPE; R15++; FETCHPIPE; R15++; \ +v |= USEX8(PIPE) << 8; FETCHPIPE; R15++; \ +GSU.avReg[reg] = v; \ +CLRFLAGS; +static void fx_iwt_r0() { FX_IWT(0); } +static void fx_iwt_r1() { FX_IWT(1); } +static void fx_iwt_r2() { FX_IWT(2); } +static void fx_iwt_r3() { FX_IWT(3); } +static void fx_iwt_r4() { FX_IWT(4); } +static void fx_iwt_r5() { FX_IWT(5); } +static void fx_iwt_r6() { FX_IWT(6); } +static void fx_iwt_r7() { FX_IWT(7); } +static void fx_iwt_r8() { FX_IWT(8); } +static void fx_iwt_r9() { FX_IWT(9); } +static void fx_iwt_r10() { FX_IWT(10); } +static void fx_iwt_r11() { FX_IWT(11); } +static void fx_iwt_r12() { FX_IWT(12); } +static void fx_iwt_r13() { FX_IWT(13); } +static void fx_iwt_r14() { FX_IWT(14); READR14; } +static void fx_iwt_r15() { FX_IWT(15); } + +/* f0-ff(ALT1) - lm rn,(xx) - load word from RAM */ +#define FX_LM(reg) \ +GSU.vLastRamAdr = PIPE; R15++; FETCHPIPE; R15++; \ +GSU.vLastRamAdr |= USEX8(PIPE) << 8; FETCHPIPE; R15++; \ +GSU.avReg[reg] = RAM(GSU.vLastRamAdr); \ +GSU.avReg[reg] |= USEX8(RAM(GSU.vLastRamAdr^1)) << 8; \ +CLRFLAGS; +static void fx_lm_r0() { FX_LM(0); } +static void fx_lm_r1() { FX_LM(1); } +static void fx_lm_r2() { FX_LM(2); } +static void fx_lm_r3() { FX_LM(3); } +static void fx_lm_r4() { FX_LM(4); } +static void fx_lm_r5() { FX_LM(5); } +static void fx_lm_r6() { FX_LM(6); } +static void fx_lm_r7() { FX_LM(7); } +static void fx_lm_r8() { FX_LM(8); } +static void fx_lm_r9() { FX_LM(9); } +static void fx_lm_r10() { FX_LM(10); } +static void fx_lm_r11() { FX_LM(11); } +static void fx_lm_r12() { FX_LM(12); } +static void fx_lm_r13() { FX_LM(13); } +static void fx_lm_r14() { FX_LM(14); READR14; } +static void fx_lm_r15() { FX_LM(15); } + +/* f0-ff(ALT2) - sm (xx),rn - store word in RAM */ +/* If rn == r15, is the value of r15 before or after the extra bytes are read? */ +#define FX_SM(reg) \ +uint32 v = GSU.avReg[reg]; \ +GSU.vLastRamAdr = PIPE; R15++; FETCHPIPE; R15++; \ +GSU.vLastRamAdr |= USEX8(PIPE) << 8; FETCHPIPE; \ +RAM(GSU.vLastRamAdr) = (uint8)v; \ +RAM(GSU.vLastRamAdr^1) = (uint8)(v>>8); \ +CLRFLAGS; R15++; +static void fx_sm_r0() { FX_SM(0); } +static void fx_sm_r1() { FX_SM(1); } +static void fx_sm_r2() { FX_SM(2); } +static void fx_sm_r3() { FX_SM(3); } +static void fx_sm_r4() { FX_SM(4); } +static void fx_sm_r5() { FX_SM(5); } +static void fx_sm_r6() { FX_SM(6); } +static void fx_sm_r7() { FX_SM(7); } +static void fx_sm_r8() { FX_SM(8); } +static void fx_sm_r9() { FX_SM(9); } +static void fx_sm_r10() { FX_SM(10); } +static void fx_sm_r11() { FX_SM(11); } +static void fx_sm_r12() { FX_SM(12); } +static void fx_sm_r13() { FX_SM(13); } +static void fx_sm_r14() { FX_SM(14); } +static void fx_sm_r15() { FX_SM(15); } + +/*** GSU executions functions ***/ + +static uint32 fx_run(uint32 nInstructions) +{ + GSU.vCounter = nInstructions; + READR14; + while(GSU.vCounter-- > 0) + FX_STEP; + /* +#ifndef FX_ADDRESS_CHECK + GSU.vPipeAdr = USEX16(R15-1) | (USEX8(GSU.vPrgBankReg)<<16); +#endif +*/ + return (nInstructions - GSU.vInstCount); +} + +static uint32 fx_run_to_breakpoint(uint32 nInstructions) +{ + uint32 vCounter = 0; + while(TF(G) && vCounter < nInstructions) + { + vCounter++; + FX_STEP; + if(USEX16(R15) == GSU.vBreakPoint) + { + GSU.vErrorCode = FX_BREAKPOINT; + break; + } + } + /* +#ifndef FX_ADDRESS_CHECK + GSU.vPipeAdr = USEX16(R15-1) | (USEX8(GSU.vPrgBankReg)<<16); +#endif +*/ + return vCounter; +} + +static uint32 fx_step_over(uint32 nInstructions) +{ + uint32 vCounter = 0; + while(TF(G) && vCounter < nInstructions) + { + vCounter++; + FX_STEP; + if(USEX16(R15) == GSU.vBreakPoint) + { + GSU.vErrorCode = FX_BREAKPOINT; + break; + } + if(USEX16(R15) == GSU.vStepPoint) + break; + } + /* +#ifndef FX_ADDRESS_CHECK + GSU.vPipeAdr = USEX16(R15-1) | (USEX8(GSU.vPrgBankReg)<<16); +#endif +*/ + return vCounter; +} + +#ifdef FX_FUNCTION_TABLE +uint32 (*FX_FUNCTION_TABLE[])(uint32) = +#else +uint32 (*fx_apfFunctionTable[])(uint32) = +#endif +{ + &fx_run, + &fx_run_to_breakpoint, + &fx_step_over, +}; + +/*** Special table for the different plot configurations ***/ + +#ifdef FX_PLOT_TABLE +void (*FX_PLOT_TABLE[])() = +#else +void (*fx_apfPlotTable[])() = +#endif +{ + &fx_plot_2bit, &fx_plot_4bit, &fx_plot_4bit, &fx_plot_8bit, &fx_plot_obj, + &fx_rpix_2bit, &fx_rpix_4bit, &fx_rpix_4bit, &fx_rpix_8bit, &fx_rpix_obj, +}; + +/*** Opcode table ***/ + +#ifdef FX_OPCODE_TABLE +void (*FX_OPCODE_TABLE[])() = +#else +void (*fx_apfOpcodeTable[])() = +#endif +{ + /* + * ALT0 Table + */ + /* 00 - 0f */ + &fx_stop, &fx_nop, &fx_cache, &fx_lsr, &fx_rol, &fx_bra, &fx_bge, &fx_blt, + &fx_bne, &fx_beq, &fx_bpl, &fx_bmi, &fx_bcc, &fx_bcs, &fx_bvc, &fx_bvs, + /* 10 - 1f */ + &fx_to_r0, &fx_to_r1, &fx_to_r2, &fx_to_r3, &fx_to_r4, &fx_to_r5, &fx_to_r6, &fx_to_r7, + &fx_to_r8, &fx_to_r9, &fx_to_r10, &fx_to_r11, &fx_to_r12, &fx_to_r13, &fx_to_r14, &fx_to_r15, + /* 20 - 2f */ + &fx_with_r0, &fx_with_r1, &fx_with_r2, &fx_with_r3, &fx_with_r4, &fx_with_r5, &fx_with_r6, &fx_with_r7, + &fx_with_r8, &fx_with_r9, &fx_with_r10, &fx_with_r11, &fx_with_r12, &fx_with_r13, &fx_with_r14, &fx_with_r15, + /* 30 - 3f */ + &fx_stw_r0, &fx_stw_r1, &fx_stw_r2, &fx_stw_r3, &fx_stw_r4, &fx_stw_r5, &fx_stw_r6, &fx_stw_r7, + &fx_stw_r8, &fx_stw_r9, &fx_stw_r10, &fx_stw_r11, &fx_loop, &fx_alt1, &fx_alt2, &fx_alt3, + /* 40 - 4f */ + &fx_ldw_r0, &fx_ldw_r1, &fx_ldw_r2, &fx_ldw_r3, &fx_ldw_r4, &fx_ldw_r5, &fx_ldw_r6, &fx_ldw_r7, + &fx_ldw_r8, &fx_ldw_r9, &fx_ldw_r10, &fx_ldw_r11, &fx_plot_2bit,&fx_swap, &fx_color, &fx_not, + /* 50 - 5f */ + &fx_add_r0, &fx_add_r1, &fx_add_r2, &fx_add_r3, &fx_add_r4, &fx_add_r5, &fx_add_r6, &fx_add_r7, + &fx_add_r8, &fx_add_r9, &fx_add_r10, &fx_add_r11, &fx_add_r12, &fx_add_r13, &fx_add_r14, &fx_add_r15, + /* 60 - 6f */ + &fx_sub_r0, &fx_sub_r1, &fx_sub_r2, &fx_sub_r3, &fx_sub_r4, &fx_sub_r5, &fx_sub_r6, &fx_sub_r7, + &fx_sub_r8, &fx_sub_r9, &fx_sub_r10, &fx_sub_r11, &fx_sub_r12, &fx_sub_r13, &fx_sub_r14, &fx_sub_r15, + /* 70 - 7f */ + &fx_merge, &fx_and_r1, &fx_and_r2, &fx_and_r3, &fx_and_r4, &fx_and_r5, &fx_and_r6, &fx_and_r7, + &fx_and_r8, &fx_and_r9, &fx_and_r10, &fx_and_r11, &fx_and_r12, &fx_and_r13, &fx_and_r14, &fx_and_r15, + /* 80 - 8f */ + &fx_mult_r0, &fx_mult_r1, &fx_mult_r2, &fx_mult_r3, &fx_mult_r4, &fx_mult_r5, &fx_mult_r6, &fx_mult_r7, + &fx_mult_r8, &fx_mult_r9, &fx_mult_r10, &fx_mult_r11, &fx_mult_r12, &fx_mult_r13, &fx_mult_r14, &fx_mult_r15, + /* 90 - 9f */ + &fx_sbk, &fx_link_i1, &fx_link_i2, &fx_link_i3, &fx_link_i4, &fx_sex, &fx_asr, &fx_ror, + &fx_jmp_r8, &fx_jmp_r9, &fx_jmp_r10, &fx_jmp_r11, &fx_jmp_r12, &fx_jmp_r13, &fx_lob, &fx_fmult, + /* a0 - af */ + &fx_ibt_r0, &fx_ibt_r1, &fx_ibt_r2, &fx_ibt_r3, &fx_ibt_r4, &fx_ibt_r5, &fx_ibt_r6, &fx_ibt_r7, + &fx_ibt_r8, &fx_ibt_r9, &fx_ibt_r10, &fx_ibt_r11, &fx_ibt_r12, &fx_ibt_r13, &fx_ibt_r14, &fx_ibt_r15, + /* b0 - bf */ + &fx_from_r0, &fx_from_r1, &fx_from_r2, &fx_from_r3, &fx_from_r4, &fx_from_r5, &fx_from_r6, &fx_from_r7, + &fx_from_r8, &fx_from_r9, &fx_from_r10, &fx_from_r11, &fx_from_r12, &fx_from_r13, &fx_from_r14, &fx_from_r15, + /* c0 - cf */ + &fx_hib, &fx_or_r1, &fx_or_r2, &fx_or_r3, &fx_or_r4, &fx_or_r5, &fx_or_r6, &fx_or_r7, + &fx_or_r8, &fx_or_r9, &fx_or_r10, &fx_or_r11, &fx_or_r12, &fx_or_r13, &fx_or_r14, &fx_or_r15, + /* d0 - df */ + &fx_inc_r0, &fx_inc_r1, &fx_inc_r2, &fx_inc_r3, &fx_inc_r4, &fx_inc_r5, &fx_inc_r6, &fx_inc_r7, + &fx_inc_r8, &fx_inc_r9, &fx_inc_r10, &fx_inc_r11, &fx_inc_r12, &fx_inc_r13, &fx_inc_r14, &fx_getc, + /* e0 - ef */ + &fx_dec_r0, &fx_dec_r1, &fx_dec_r2, &fx_dec_r3, &fx_dec_r4, &fx_dec_r5, &fx_dec_r6, &fx_dec_r7, + &fx_dec_r8, &fx_dec_r9, &fx_dec_r10, &fx_dec_r11, &fx_dec_r12, &fx_dec_r13, &fx_dec_r14, &fx_getb, + /* f0 - ff */ + &fx_iwt_r0, &fx_iwt_r1, &fx_iwt_r2, &fx_iwt_r3, &fx_iwt_r4, &fx_iwt_r5, &fx_iwt_r6, &fx_iwt_r7, + &fx_iwt_r8, &fx_iwt_r9, &fx_iwt_r10, &fx_iwt_r11, &fx_iwt_r12, &fx_iwt_r13, &fx_iwt_r14, &fx_iwt_r15, + + /* + * ALT1 Table + */ + + /* 00 - 0f */ + &fx_stop, &fx_nop, &fx_cache, &fx_lsr, &fx_rol, &fx_bra, &fx_bge, &fx_blt, + &fx_bne, &fx_beq, &fx_bpl, &fx_bmi, &fx_bcc, &fx_bcs, &fx_bvc, &fx_bvs, + /* 10 - 1f */ + &fx_to_r0, &fx_to_r1, &fx_to_r2, &fx_to_r3, &fx_to_r4, &fx_to_r5, &fx_to_r6, &fx_to_r7, + &fx_to_r8, &fx_to_r9, &fx_to_r10, &fx_to_r11, &fx_to_r12, &fx_to_r13, &fx_to_r14, &fx_to_r15, + /* 20 - 2f */ + &fx_with_r0, &fx_with_r1, &fx_with_r2, &fx_with_r3, &fx_with_r4, &fx_with_r5, &fx_with_r6, &fx_with_r7, + &fx_with_r8, &fx_with_r9, &fx_with_r10, &fx_with_r11, &fx_with_r12, &fx_with_r13, &fx_with_r14, &fx_with_r15, + /* 30 - 3f */ + &fx_stb_r0, &fx_stb_r1, &fx_stb_r2, &fx_stb_r3, &fx_stb_r4, &fx_stb_r5, &fx_stb_r6, &fx_stb_r7, + &fx_stb_r8, &fx_stb_r9, &fx_stb_r10, &fx_stb_r11, &fx_loop, &fx_alt1, &fx_alt2, &fx_alt3, + /* 40 - 4f */ + &fx_ldb_r0, &fx_ldb_r1, &fx_ldb_r2, &fx_ldb_r3, &fx_ldb_r4, &fx_ldb_r5, &fx_ldb_r6, &fx_ldb_r7, + &fx_ldb_r8, &fx_ldb_r9, &fx_ldb_r10, &fx_ldb_r11, &fx_rpix_2bit,&fx_swap, &fx_cmode, &fx_not, + /* 50 - 5f */ + &fx_adc_r0, &fx_adc_r1, &fx_adc_r2, &fx_adc_r3, &fx_adc_r4, &fx_adc_r5, &fx_adc_r6, &fx_adc_r7, + &fx_adc_r8, &fx_adc_r9, &fx_adc_r10, &fx_adc_r11, &fx_adc_r12, &fx_adc_r13, &fx_adc_r14, &fx_adc_r15, + /* 60 - 6f */ + &fx_sbc_r0, &fx_sbc_r1, &fx_sbc_r2, &fx_sbc_r3, &fx_sbc_r4, &fx_sbc_r5, &fx_sbc_r6, &fx_sbc_r7, + &fx_sbc_r8, &fx_sbc_r9, &fx_sbc_r10, &fx_sbc_r11, &fx_sbc_r12, &fx_sbc_r13, &fx_sbc_r14, &fx_sbc_r15, + /* 70 - 7f */ + &fx_merge, &fx_bic_r1, &fx_bic_r2, &fx_bic_r3, &fx_bic_r4, &fx_bic_r5, &fx_bic_r6, &fx_bic_r7, + &fx_bic_r8, &fx_bic_r9, &fx_bic_r10, &fx_bic_r11, &fx_bic_r12, &fx_bic_r13, &fx_bic_r14, &fx_bic_r15, + /* 80 - 8f */ + &fx_umult_r0,&fx_umult_r1,&fx_umult_r2, &fx_umult_r3, &fx_umult_r4, &fx_umult_r5, &fx_umult_r6, &fx_umult_r7, + &fx_umult_r8,&fx_umult_r9,&fx_umult_r10,&fx_umult_r11,&fx_umult_r12,&fx_umult_r13,&fx_umult_r14,&fx_umult_r15, + /* 90 - 9f */ + &fx_sbk, &fx_link_i1, &fx_link_i2, &fx_link_i3, &fx_link_i4, &fx_sex, &fx_div2, &fx_ror, + &fx_ljmp_r8, &fx_ljmp_r9, &fx_ljmp_r10, &fx_ljmp_r11, &fx_ljmp_r12, &fx_ljmp_r13, &fx_lob, &fx_lmult, + /* a0 - af */ + &fx_lms_r0, &fx_lms_r1, &fx_lms_r2, &fx_lms_r3, &fx_lms_r4, &fx_lms_r5, &fx_lms_r6, &fx_lms_r7, + &fx_lms_r8, &fx_lms_r9, &fx_lms_r10, &fx_lms_r11, &fx_lms_r12, &fx_lms_r13, &fx_lms_r14, &fx_lms_r15, + /* b0 - bf */ + &fx_from_r0, &fx_from_r1, &fx_from_r2, &fx_from_r3, &fx_from_r4, &fx_from_r5, &fx_from_r6, &fx_from_r7, + &fx_from_r8, &fx_from_r9, &fx_from_r10, &fx_from_r11, &fx_from_r12, &fx_from_r13, &fx_from_r14, &fx_from_r15, + /* c0 - cf */ + &fx_hib, &fx_xor_r1, &fx_xor_r2, &fx_xor_r3, &fx_xor_r4, &fx_xor_r5, &fx_xor_r6, &fx_xor_r7, + &fx_xor_r8, &fx_xor_r9, &fx_xor_r10, &fx_xor_r11, &fx_xor_r12, &fx_xor_r13, &fx_xor_r14, &fx_xor_r15, + /* d0 - df */ + &fx_inc_r0, &fx_inc_r1, &fx_inc_r2, &fx_inc_r3, &fx_inc_r4, &fx_inc_r5, &fx_inc_r6, &fx_inc_r7, + &fx_inc_r8, &fx_inc_r9, &fx_inc_r10, &fx_inc_r11, &fx_inc_r12, &fx_inc_r13, &fx_inc_r14, &fx_getc, + /* e0 - ef */ + &fx_dec_r0, &fx_dec_r1, &fx_dec_r2, &fx_dec_r3, &fx_dec_r4, &fx_dec_r5, &fx_dec_r6, &fx_dec_r7, + &fx_dec_r8, &fx_dec_r9, &fx_dec_r10, &fx_dec_r11, &fx_dec_r12, &fx_dec_r13, &fx_dec_r14, &fx_getbh, + /* f0 - ff */ + &fx_lm_r0, &fx_lm_r1, &fx_lm_r2, &fx_lm_r3, &fx_lm_r4, &fx_lm_r5, &fx_lm_r6, &fx_lm_r7, + &fx_lm_r8, &fx_lm_r9, &fx_lm_r10, &fx_lm_r11, &fx_lm_r12, &fx_lm_r13, &fx_lm_r14, &fx_lm_r15, + + /* + * ALT2 Table + */ + + /* 00 - 0f */ + &fx_stop, &fx_nop, &fx_cache, &fx_lsr, &fx_rol, &fx_bra, &fx_bge, &fx_blt, + &fx_bne, &fx_beq, &fx_bpl, &fx_bmi, &fx_bcc, &fx_bcs, &fx_bvc, &fx_bvs, + /* 10 - 1f */ + &fx_to_r0, &fx_to_r1, &fx_to_r2, &fx_to_r3, &fx_to_r4, &fx_to_r5, &fx_to_r6, &fx_to_r7, + &fx_to_r8, &fx_to_r9, &fx_to_r10, &fx_to_r11, &fx_to_r12, &fx_to_r13, &fx_to_r14, &fx_to_r15, + /* 20 - 2f */ + &fx_with_r0, &fx_with_r1, &fx_with_r2, &fx_with_r3, &fx_with_r4, &fx_with_r5, &fx_with_r6, &fx_with_r7, + &fx_with_r8, &fx_with_r9, &fx_with_r10, &fx_with_r11, &fx_with_r12, &fx_with_r13, &fx_with_r14, &fx_with_r15, + /* 30 - 3f */ + &fx_stw_r0, &fx_stw_r1, &fx_stw_r2, &fx_stw_r3, &fx_stw_r4, &fx_stw_r5, &fx_stw_r6, &fx_stw_r7, + &fx_stw_r8, &fx_stw_r9, &fx_stw_r10, &fx_stw_r11, &fx_loop, &fx_alt1, &fx_alt2, &fx_alt3, + /* 40 - 4f */ + &fx_ldw_r0, &fx_ldw_r1, &fx_ldw_r2, &fx_ldw_r3, &fx_ldw_r4, &fx_ldw_r5, &fx_ldw_r6, &fx_ldw_r7, + &fx_ldw_r8, &fx_ldw_r9, &fx_ldw_r10, &fx_ldw_r11, &fx_plot_2bit,&fx_swap, &fx_color, &fx_not, + /* 50 - 5f */ + &fx_add_i0, &fx_add_i1, &fx_add_i2, &fx_add_i3, &fx_add_i4, &fx_add_i5, &fx_add_i6, &fx_add_i7, + &fx_add_i8, &fx_add_i9, &fx_add_i10, &fx_add_i11, &fx_add_i12, &fx_add_i13, &fx_add_i14, &fx_add_i15, + /* 60 - 6f */ + &fx_sub_i0, &fx_sub_i1, &fx_sub_i2, &fx_sub_i3, &fx_sub_i4, &fx_sub_i5, &fx_sub_i6, &fx_sub_i7, + &fx_sub_i8, &fx_sub_i9, &fx_sub_i10, &fx_sub_i11, &fx_sub_i12, &fx_sub_i13, &fx_sub_i14, &fx_sub_i15, + /* 70 - 7f */ + &fx_merge, &fx_and_i1, &fx_and_i2, &fx_and_i3, &fx_and_i4, &fx_and_i5, &fx_and_i6, &fx_and_i7, + &fx_and_i8, &fx_and_i9, &fx_and_i10, &fx_and_i11, &fx_and_i12, &fx_and_i13, &fx_and_i14, &fx_and_i15, + /* 80 - 8f */ + &fx_mult_i0, &fx_mult_i1, &fx_mult_i2, &fx_mult_i3, &fx_mult_i4, &fx_mult_i5, &fx_mult_i6, &fx_mult_i7, + &fx_mult_i8, &fx_mult_i9, &fx_mult_i10, &fx_mult_i11, &fx_mult_i12, &fx_mult_i13, &fx_mult_i14, &fx_mult_i15, + /* 90 - 9f */ + &fx_sbk, &fx_link_i1, &fx_link_i2, &fx_link_i3, &fx_link_i4, &fx_sex, &fx_asr, &fx_ror, + &fx_jmp_r8, &fx_jmp_r9, &fx_jmp_r10, &fx_jmp_r11, &fx_jmp_r12, &fx_jmp_r13, &fx_lob, &fx_fmult, + /* a0 - af */ + &fx_sms_r0, &fx_sms_r1, &fx_sms_r2, &fx_sms_r3, &fx_sms_r4, &fx_sms_r5, &fx_sms_r6, &fx_sms_r7, + &fx_sms_r8, &fx_sms_r9, &fx_sms_r10, &fx_sms_r11, &fx_sms_r12, &fx_sms_r13, &fx_sms_r14, &fx_sms_r15, + /* b0 - bf */ + &fx_from_r0, &fx_from_r1, &fx_from_r2, &fx_from_r3, &fx_from_r4, &fx_from_r5, &fx_from_r6, &fx_from_r7, + &fx_from_r8, &fx_from_r9, &fx_from_r10, &fx_from_r11, &fx_from_r12, &fx_from_r13, &fx_from_r14, &fx_from_r15, + /* c0 - cf */ + &fx_hib, &fx_or_i1, &fx_or_i2, &fx_or_i3, &fx_or_i4, &fx_or_i5, &fx_or_i6, &fx_or_i7, + &fx_or_i8, &fx_or_i9, &fx_or_i10, &fx_or_i11, &fx_or_i12, &fx_or_i13, &fx_or_i14, &fx_or_i15, + /* d0 - df */ + &fx_inc_r0, &fx_inc_r1, &fx_inc_r2, &fx_inc_r3, &fx_inc_r4, &fx_inc_r5, &fx_inc_r6, &fx_inc_r7, + &fx_inc_r8, &fx_inc_r9, &fx_inc_r10, &fx_inc_r11, &fx_inc_r12, &fx_inc_r13, &fx_inc_r14, &fx_ramb, + /* e0 - ef */ + &fx_dec_r0, &fx_dec_r1, &fx_dec_r2, &fx_dec_r3, &fx_dec_r4, &fx_dec_r5, &fx_dec_r6, &fx_dec_r7, + &fx_dec_r8, &fx_dec_r9, &fx_dec_r10, &fx_dec_r11, &fx_dec_r12, &fx_dec_r13, &fx_dec_r14, &fx_getbl, + /* f0 - ff */ + &fx_sm_r0, &fx_sm_r1, &fx_sm_r2, &fx_sm_r3, &fx_sm_r4, &fx_sm_r5, &fx_sm_r6, &fx_sm_r7, + &fx_sm_r8, &fx_sm_r9, &fx_sm_r10, &fx_sm_r11, &fx_sm_r12, &fx_sm_r13, &fx_sm_r14, &fx_sm_r15, + + /* + * ALT3 Table + */ + + /* 00 - 0f */ + &fx_stop, &fx_nop, &fx_cache, &fx_lsr, &fx_rol, &fx_bra, &fx_bge, &fx_blt, + &fx_bne, &fx_beq, &fx_bpl, &fx_bmi, &fx_bcc, &fx_bcs, &fx_bvc, &fx_bvs, + /* 10 - 1f */ + &fx_to_r0, &fx_to_r1, &fx_to_r2, &fx_to_r3, &fx_to_r4, &fx_to_r5, &fx_to_r6, &fx_to_r7, + &fx_to_r8, &fx_to_r9, &fx_to_r10, &fx_to_r11, &fx_to_r12, &fx_to_r13, &fx_to_r14, &fx_to_r15, + /* 20 - 2f */ + &fx_with_r0, &fx_with_r1, &fx_with_r2, &fx_with_r3, &fx_with_r4, &fx_with_r5, &fx_with_r6, &fx_with_r7, + &fx_with_r8, &fx_with_r9, &fx_with_r10, &fx_with_r11, &fx_with_r12, &fx_with_r13, &fx_with_r14, &fx_with_r15, + /* 30 - 3f */ + &fx_stb_r0, &fx_stb_r1, &fx_stb_r2, &fx_stb_r3, &fx_stb_r4, &fx_stb_r5, &fx_stb_r6, &fx_stb_r7, + &fx_stb_r8, &fx_stb_r9, &fx_stb_r10, &fx_stb_r11, &fx_loop, &fx_alt1, &fx_alt2, &fx_alt3, + /* 40 - 4f */ + &fx_ldb_r0, &fx_ldb_r1, &fx_ldb_r2, &fx_ldb_r3, &fx_ldb_r4, &fx_ldb_r5, &fx_ldb_r6, &fx_ldb_r7, + &fx_ldb_r8, &fx_ldb_r9, &fx_ldb_r10, &fx_ldb_r11, &fx_rpix_2bit,&fx_swap, &fx_cmode, &fx_not, + /* 50 - 5f */ + &fx_adc_i0, &fx_adc_i1, &fx_adc_i2, &fx_adc_i3, &fx_adc_i4, &fx_adc_i5, &fx_adc_i6, &fx_adc_i7, + &fx_adc_i8, &fx_adc_i9, &fx_adc_i10, &fx_adc_i11, &fx_adc_i12, &fx_adc_i13, &fx_adc_i14, &fx_adc_i15, + /* 60 - 6f */ + &fx_cmp_r0, &fx_cmp_r1, &fx_cmp_r2, &fx_cmp_r3, &fx_cmp_r4, &fx_cmp_r5, &fx_cmp_r6, &fx_cmp_r7, + &fx_cmp_r8, &fx_cmp_r9, &fx_cmp_r10, &fx_cmp_r11, &fx_cmp_r12, &fx_cmp_r13, &fx_cmp_r14, &fx_cmp_r15, + /* 70 - 7f */ + &fx_merge, &fx_bic_i1, &fx_bic_i2, &fx_bic_i3, &fx_bic_i4, &fx_bic_i5, &fx_bic_i6, &fx_bic_i7, + &fx_bic_i8, &fx_bic_i9, &fx_bic_i10, &fx_bic_i11, &fx_bic_i12, &fx_bic_i13, &fx_bic_i14, &fx_bic_i15, + /* 80 - 8f */ + &fx_umult_i0,&fx_umult_i1,&fx_umult_i2, &fx_umult_i3, &fx_umult_i4, &fx_umult_i5, &fx_umult_i6, &fx_umult_i7, + &fx_umult_i8,&fx_umult_i9,&fx_umult_i10,&fx_umult_i11,&fx_umult_i12,&fx_umult_i13,&fx_umult_i14,&fx_umult_i15, + /* 90 - 9f */ + &fx_sbk, &fx_link_i1, &fx_link_i2, &fx_link_i3, &fx_link_i4, &fx_sex, &fx_div2, &fx_ror, + &fx_ljmp_r8, &fx_ljmp_r9, &fx_ljmp_r10, &fx_ljmp_r11, &fx_ljmp_r12, &fx_ljmp_r13, &fx_lob, &fx_lmult, + /* a0 - af */ + &fx_lms_r0, &fx_lms_r1, &fx_lms_r2, &fx_lms_r3, &fx_lms_r4, &fx_lms_r5, &fx_lms_r6, &fx_lms_r7, + &fx_lms_r8, &fx_lms_r9, &fx_lms_r10, &fx_lms_r11, &fx_lms_r12, &fx_lms_r13, &fx_lms_r14, &fx_lms_r15, + /* b0 - bf */ + &fx_from_r0, &fx_from_r1, &fx_from_r2, &fx_from_r3, &fx_from_r4, &fx_from_r5, &fx_from_r6, &fx_from_r7, + &fx_from_r8, &fx_from_r9, &fx_from_r10, &fx_from_r11, &fx_from_r12, &fx_from_r13, &fx_from_r14, &fx_from_r15, + /* c0 - cf */ + &fx_hib, &fx_xor_i1, &fx_xor_i2, &fx_xor_i3, &fx_xor_i4, &fx_xor_i5, &fx_xor_i6, &fx_xor_i7, + &fx_xor_i8, &fx_xor_i9, &fx_xor_i10, &fx_xor_i11, &fx_xor_i12, &fx_xor_i13, &fx_xor_i14, &fx_xor_i15, + /* d0 - df */ + &fx_inc_r0, &fx_inc_r1, &fx_inc_r2, &fx_inc_r3, &fx_inc_r4, &fx_inc_r5, &fx_inc_r6, &fx_inc_r7, + &fx_inc_r8, &fx_inc_r9, &fx_inc_r10, &fx_inc_r11, &fx_inc_r12, &fx_inc_r13, &fx_inc_r14, &fx_romb, + /* e0 - ef */ + &fx_dec_r0, &fx_dec_r1, &fx_dec_r2, &fx_dec_r3, &fx_dec_r4, &fx_dec_r5, &fx_dec_r6, &fx_dec_r7, + &fx_dec_r8, &fx_dec_r9, &fx_dec_r10, &fx_dec_r11, &fx_dec_r12, &fx_dec_r13, &fx_dec_r14, &fx_getbs, + /* f0 - ff */ + &fx_lm_r0, &fx_lm_r1, &fx_lm_r2, &fx_lm_r3, &fx_lm_r4, &fx_lm_r5, &fx_lm_r6, &fx_lm_r7, + &fx_lm_r8, &fx_lm_r9, &fx_lm_r10, &fx_lm_r11, &fx_lm_r12, &fx_lm_r13, &fx_lm_r14, &fx_lm_r15, +}; diff --git a/src/snes4iphone_src/fxinst.h b/src/snes4iphone_src/fxinst.h new file mode 100755 index 0000000..01d4163 --- /dev/null +++ b/src/snes4iphone_src/fxinst.h @@ -0,0 +1,417 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#ifndef _FXINST_H_ +#define _FXINST_H_ 1 + +/* + * FxChip(GSU) register space specification + * (Register address space 3000->32ff) + * + * The 16 generic 16 bit registers: + * (Some have a special function in special circumstances) + * 3000 - R0 default source/destination register + * 3002 - R1 pixel plot X position register + * 3004 - R2 pixel plot Y position register + * 3006 - R3 + * 3008 - R4 lower 16 bit result of lmult + * 300a - R5 + * 300c - R6 multiplier for fmult and lmult + * 300e - R7 fixed point texel X position for merge + * 3010 - R8 fixed point texel Y position for merge + * 3012 - R9 + * 3014 - R10 + * 3016 - R11 return address set by link + * 3018 - R12 loop counter + * 301a - R13 loop point address + * 301c - R14 rom address for getb, getbh, getbl, getbs + * 301e - R15 program counter + * + * 3020-302f - unused + * + * Other internal registers + * 3030 - SFR status flag register (16bit) + * 3032 - unused + * 3033 - BRAMR Backup RAM register (8bit) + * 3034 - PBR program bank register (8bit) + * 3035 - unused + * 3036 - ROMBR rom bank register (8bit) + * 3037 - CFGR control flags register (8bit) + * 3038 - SCBR screen base register (8bit) + * 3039 - CLSR clock speed register (8bit) + * 303a - SCMR screen mode register (8bit) + * 303b - VCR version code register (8bit) (read only) + * 303c - RAMBR ram bank register (8bit) + * 303d - unused + * 303e - CBR cache base register (16bit) + * + * 3040-30ff - unused + * + * 3100-32ff - CACHERAM 512 bytes of GSU cache memory + * + * SFR status flag register bits: + * 0 - + * 1 Z Zero flag + * 2 CY Carry flag + * 3 S Sign flag + * 4 OV Overflow flag + * 5 G Go flag (set to 1 when the GSU is running) + * 6 R Set to 1 when reading ROM using R14 address + * 7 - + * 8 ALT1 Mode set-up flag for the next instruction + * 9 ALT2 Mode set-up flag for the next instruction + * 10 IL Immediate lower 8-bit flag + * 11 IH Immediate higher 8-bit flag + * 12 B Set to 1 when the WITH instruction is executed + * 13 - + * 14 - + * 15 IRQ Set to 1 when GSU caused an interrupt + * Set to 0 when read by 658c16 + * + * BRAMR = 0, BackupRAM is disabled + * BRAMR = 1, BackupRAM is enabled + * + * CFGR control flags register bits: + * 0 - + * 1 - + * 2 - + * 3 - + * 4 - + * 5 MS0 Multiplier speed, 0=standard, 1=high speed + * 6 - + * 7 IRQ Set to 1 when GSU interrupt request is masked + * + * CLSR clock speed register bits: + * 0 CLSR clock speed, 0 = 10.7Mhz, 1 = 21.4Mhz + * + * SCMR screen mode register bits: + * 0 MD0 color depth mode bit 0 + * 1 MD1 color depth mode bit 1 + * 2 HT0 screen height bit 1 + * 3 RAN RAM access control + * 4 RON ROM access control + * 5 HT1 screen height bit 2 + * 6 - + * 7 - + * + * RON = 0 SNES CPU has ROM access + * RON = 1 GSU has ROM access + * + * RAN = 0 SNES has game pak RAM access + * RAN = 1 GSU has game pak RAM access + * + * HT1 HT0 Screen height mode + * 0 0 128 pixels high + * 0 1 160 pixels high + * 1 0 192 pixels high + * 1 1 OBJ mode + * + * MD1 MD0 Color depth mode + * 0 0 4 color mode + * 0 1 16 color mode + * 1 0 not used + * 1 1 256 color mode + * + * CBR cache base register bits: + * 15-4 Specify base address for data to cache from ROM or RAM + * 3-0 Are 0 when address is read + * + * Write access to the program counter (301e) from + * the SNES-CPU will start the GSU, and it will not + * stop until it reaches a stop instruction. + * + */ + +/* Number of banks in GSU RAM */ +#define FX_RAM_BANKS 4 + +/* Emulate proper R14 ROM access (slower, but safer) */ +/* #define FX_DO_ROMBUFFER */ + +/* Address checking (definately slow) */ +/* #define FX_ADDRESS_CHECK */ + +struct FxRegs_s +{ + /* FxChip registers */ + uint32 avReg[16]; /* 16 Generic registers */ + uint32 vColorReg; /* Internal color register */ + uint32 vPlotOptionReg; /* Plot option register */ + uint32 vStatusReg; /* Status register */ + uint32 vPrgBankReg; /* Program bank index register */ + uint32 vRomBankReg; /* Rom bank index register */ + uint32 vRamBankReg; /* Ram bank index register */ + uint32 vCacheBaseReg; /* Cache base address register */ + uint32 vCacheFlags; /* Saying what parts of the cache was written to */ + uint32 vLastRamAdr; /* Last RAM address accessed */ + uint32 * pvDreg; /* Pointer to current destination register */ + uint32 * pvSreg; /* Pointer to current source register */ + uint8 vRomBuffer; /* Current byte read by R14 */ + uint8 vPipe; /* Instructionset pipe */ + uint32 vPipeAdr; /* The address of where the pipe was read from */ + + /* status register optimization stuff */ + uint32 vSign; /* v & 0x8000 */ + uint32 vZero; /* v == 0 */ + uint32 vCarry; /* a value of 1 or 0 */ + int32 vOverflow; /* (v >= 0x8000 || v < -0x8000) */ + + /* Other emulator variables */ + + int32 vErrorCode; + uint32 vIllegalAddress; + + uint8 bBreakPoint; + uint32 vBreakPoint; + uint32 vStepPoint; + + uint8 * pvRegisters; /* 768 bytes located in the memory at address 0x3000 */ + uint32 nRamBanks; /* Number of 64kb-banks in FxRam (Don't confuse it with SNES-Ram!!!) */ + uint8 * pvRam; /* Pointer to FxRam */ + uint32 nRomBanks; /* Number of 32kb-banks in Cart-ROM */ + uint8 * pvRom; /* Pointer to Cart-ROM */ + + uint32 vMode; /* Color depth/mode */ + uint32 vPrevMode; /* Previous depth */ + uint8 * pvScreenBase; + uint8 * apvScreen[32]; /* Pointer to each of the 32 screen colums */ + int x[32]; + uint32 vScreenHeight; /* 128, 160, 192 or 256 (could be overriden by cmode) */ + uint32 vScreenRealHeight; /* 128, 160, 192 or 256 */ + uint32 vPrevScreenHeight; + uint32 vScreenSize; + void (*pfPlot)(); + void (*pfRpix)(); + + uint8 * pvRamBank; /* Pointer to current RAM-bank */ + uint8 * pvRomBank; /* Pointer to current ROM-bank */ + uint8 * pvPrgBank; /* Pointer to current program ROM-bank */ + + uint8 * apvRamBank[FX_RAM_BANKS];/* Ram bank table (max 256kb) */ + uint8 * apvRomBank[256]; /* Rom bank table */ + + uint8 bCacheActive; + uint8 * pvCache; /* Pointer to the GSU cache */ + uint8 avCacheBackup[512]; /* Backup of ROM when the cache has replaced it */ + uint32 vCounter; + uint32 vInstCount; +}; + +/* GSU registers */ +#define GSU_R0 0x000 +#define GSU_R1 0x002 +#define GSU_R2 0x004 +#define GSU_R3 0x006 +#define GSU_R4 0x008 +#define GSU_R5 0x00a +#define GSU_R6 0x00c +#define GSU_R7 0x00e +#define GSU_R8 0x010 +#define GSU_R9 0x012 +#define GSU_R10 0x014 +#define GSU_R11 0x016 +#define GSU_R12 0x018 +#define GSU_R13 0x01a +#define GSU_R14 0x01c +#define GSU_R15 0x01e +#define GSU_SFR 0x030 +#define GSU_BRAMR 0x033 +#define GSU_PBR 0x034 +#define GSU_ROMBR 0x036 +#define GSU_CFGR 0x037 +#define GSU_SCBR 0x038 +#define GSU_CLSR 0x039 +#define GSU_SCMR 0x03a +#define GSU_VCR 0x03b +#define GSU_RAMBR 0x03c +#define GSU_CBR 0x03e +#define GSU_CACHERAM 0x100 + +/* SFR flags */ +#define FLG_Z (1<<1) +#define FLG_CY (1<<2) +#define FLG_S (1<<3) +#define FLG_OV (1<<4) +#define FLG_G (1<<5) +#define FLG_R (1<<6) +#define FLG_ALT1 (1<<8) +#define FLG_ALT2 (1<<9) +#define FLG_IL (1<<10) +#define FLG_IH (1<<11) +#define FLG_B (1<<12) +#define FLG_IRQ (1<<15) + +/* Test flag */ +#define TF(a) (GSU.vStatusReg & FLG_##a ) +#define CF(a) (GSU.vStatusReg &= ~FLG_##a ) +#define SF(a) (GSU.vStatusReg |= FLG_##a ) + +/* Test and set flag if condition, clear if not */ +#define TS(a,b) GSU.vStatusReg = ( (GSU.vStatusReg & (~FLG_##a)) | ( (!!(##b)) * FLG_##a ) ) + +/* Testing ALT1 & ALT2 bits */ +#define ALT0 (!TF(ALT1)&&!TF(ALT2)) +#define ALT1 (TF(ALT1)&&!TF(ALT2)) +#define ALT2 (!TF(ALT1)&&TF(ALT2)) +#define ALT3 (TF(ALT1)&&TF(ALT2)) + +/* Sign extend from 8/16 bit to 32 bit */ +#define SEX16(a) ((int32)((int16)(a))) +#define SEX8(a) ((int32)((int8)(a))) + +/* Unsign extend from 8/16 bit to 32 bit */ +#define USEX16(a) ((uint32)((uint16)(a))) +#define USEX8(a) ((uint32)((uint8)(a))) + +#define SUSEX16(a) ((int32)((uint16)(a))) + +/* Set/Clr Sign and Zero flag */ +#define TSZ(num) TS(S, (num & 0x8000)); TS(Z, (!USEX16(num)) ) + +/* Clear flags */ +#define CLRFLAGS GSU.vStatusReg &= ~(FLG_ALT1|FLG_ALT2|FLG_B); GSU.pvDreg = GSU.pvSreg = &R0; + +/* Read current RAM-Bank */ +#define RAM(adr) GSU.pvRamBank[USEX16(adr)] + +/* Read current ROM-Bank */ +#define ROM(idx) (GSU.pvRomBank[USEX16(idx)]) + +/* Access the current value in the pipe */ +#define PIPE GSU.vPipe + +/* Access data in the current program bank */ +#define PRGBANK(idx) GSU.pvPrgBank[USEX16(idx)] + +/* Update pipe from ROM */ +#if 0 +#define FETCHPIPE { PIPE = PRGBANK(R15); GSU.vPipeAdr = (GSU.vPrgBankReg<<16) + R15; } +#else +#define FETCHPIPE { PIPE = PRGBANK(R15); } +#endif + +/* ABS */ +#define ABS(x) ((x)<0?-(x):(x)) + +/* Access source register */ +#define SREG (*GSU.pvSreg) + +/* Access destination register */ +#define DREG (*GSU.pvDreg) + +#ifndef FX_DO_ROMBUFFER + +/* Don't read R14 */ +#define READR14 + +/* Don't test and/or read R14 */ +#define TESTR14 + +#else + +/* Read R14 */ +#define READR14 GSU.vRomBuffer = ROM(R14) + +/* Test and/or read R14 */ +#define TESTR14 if(GSU.pvDreg == &R14) READR14 + +#endif + +/* Access to registers */ +#define R0 GSU.avReg[0] +#define R1 GSU.avReg[1] +#define R2 GSU.avReg[2] +#define R3 GSU.avReg[3] +#define R4 GSU.avReg[4] +#define R5 GSU.avReg[5] +#define R6 GSU.avReg[6] +#define R7 GSU.avReg[7] +#define R8 GSU.avReg[8] +#define R9 GSU.avReg[9] +#define R10 GSU.avReg[10] +#define R11 GSU.avReg[11] +#define R12 GSU.avReg[12] +#define R13 GSU.avReg[13] +#define R14 GSU.avReg[14] +#define R15 GSU.avReg[15] +#define SFR GSU.vStatusReg +#define PBR GSU.vPrgBankReg +#define ROMBR GSU.vRomBankReg +#define RAMBR GSU.vRamBankReg +#define CBR GSU.vCacheBaseReg +#define SCBR USEX8(GSU.pvRegisters[GSU_SCBR]) +#define SCMR USEX8(GSU.pvRegisters[GSU_SCMR]) +#define COLR GSU.vColorReg +#define POR GSU.vPlotOptionReg +#define BRAMR USEX8(GSU.pvRegisters[GSU_BRAMR]) +#define VCR USEX8(GSU.pvRegisters[GSU_VCR]) +#define CFGR USEX8(GSU.pvRegisters[GSU_CFGR]) +#define CLSR USEX8(GSU.pvRegisters[GSU_CLSR]) + +/* Execute instruction from the pipe, and fetch next byte to the pipe */ +#define FX_STEP { uint32 vOpcode = (uint32)PIPE; FETCHPIPE; \ +(*fx_ppfOpcodeTable[ (GSU.vStatusReg & 0x300) | vOpcode ])(); } \ + +#define FX_FUNCTION_RUN 0 +#define FX_FUNCTION_RUN_TO_BREAKPOINT 1 +#define FX_FUNCTION_STEP_OVER 2 + +extern uint32 (**fx_ppfFunctionTable)(uint32); +extern void (**fx_ppfPlotTable)(); +extern void (**fx_ppfOpcodeTable)(); + +extern uint32 (*fx_apfFunctionTable[])(uint32); +extern void (*fx_apfOpcodeTable[])(); +extern void (*fx_apfPlotTable[])(); +extern uint32 (*fx_a_apfFunctionTable[])(uint32); +extern void (*fx_a_apfOpcodeTable[])(); +extern void (*fx_a_apfPlotTable[])(); +extern uint32 (*fx_r_apfFunctionTable[])(uint32); +extern void (*fx_r_apfOpcodeTable[])(); +extern void (*fx_r_apfPlotTable[])(); +extern uint32 (*fx_ar_apfFunctionTable[])(uint32); +extern void (*fx_ar_apfOpcodeTable[])(); +extern void (*fx_ar_apfPlotTable[])(); + +/* Set this define if branches are relative to the instruction in the delay slot */ +/* (I think they are) */ +#define BRANCH_DELAY_RELATIVE + +#endif diff --git a/src/snes4iphone_src/gammatab.h b/src/snes4iphone_src/gammatab.h new file mode 100755 index 0000000..11f6f4c --- /dev/null +++ b/src/snes4iphone_src/gammatab.h @@ -0,0 +1,22 @@ +unsigned char gammatab[10][32]={ + {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F}, + {0x00,0x01,0x02,0x03,0x04,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x10, + 0x11,0x12,0x13,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F}, + {0x00,0x01,0x03,0x04,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11, + 0x12,0x13,0x14,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F}, + {0x00,0x02,0x04,0x06,0x07,0x08,0x09,0x0A,0x0C,0x0D,0x0E,0x0F,0x0F,0x10,0x11,0x12, + 0x13,0x14,0x15,0x16,0x16,0x17,0x18,0x19,0x19,0x1A,0x1B,0x1C,0x1C,0x1D,0x1E,0x1F}, + {0x00,0x03,0x05,0x07,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,0x13,0x14, + 0x14,0x15,0x16,0x17,0x17,0x18,0x19,0x19,0x1A,0x1B,0x1B,0x1C,0x1D,0x1D,0x1E,0x1F}, + {0x00,0x05,0x07,0x09,0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,0x13,0x14,0x14,0x15, + 0x16,0x16,0x17,0x18,0x18,0x19,0x1A,0x1A,0x1B,0x1B,0x1C,0x1C,0x1D,0x1D,0x1E,0x1F}, + {0x00,0x07,0x0A,0x0C,0x0D,0x0E,0x10,0x11,0x12,0x12,0x13,0x14,0x15,0x15,0x16,0x17, + 0x17,0x18,0x18,0x19,0x1A,0x1A,0x1B,0x1B,0x1B,0x1C,0x1C,0x1D,0x1D,0x1E,0x1E,0x1F}, + {0x00,0x0B,0x0D,0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x16,0x17,0x17,0x18,0x18, + 0x19,0x19,0x1A,0x1A,0x1B,0x1B,0x1B,0x1C,0x1C,0x1D,0x1D,0x1D,0x1E,0x1E,0x1E,0x1F}, + {0x00,0x0F,0x11,0x13,0x14,0x15,0x16,0x17,0x17,0x18,0x18,0x19,0x19,0x1A,0x1A,0x1A, + 0x1B,0x1B,0x1B,0x1C,0x1C,0x1C,0x1C,0x1D,0x1D,0x1D,0x1D,0x1E,0x1E,0x1E,0x1E,0x1F}, + {0x00,0x15,0x17,0x18,0x19,0x19,0x1A,0x1A,0x1B,0x1B,0x1B,0x1B,0x1C,0x1C,0x1C,0x1C, + 0x1D,0x1D,0x1D,0x1D,0x1D,0x1D,0x1D,0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,0x1F} +}; diff --git a/src/snes4iphone_src/getset.h b/src/snes4iphone_src/getset.h new file mode 100755 index 0000000..eb10b8f --- /dev/null +++ b/src/snes4iphone_src/getset.h @@ -0,0 +1,695 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#ifndef _GETSET_H_ +#define _GETSET_H_ + +#include "ppu.h" +#include "dsp1.h" +#include "cpuexec.h" +#include "sa1.h" + +#define __memcheck__ +//#define __show_io__ +extern int oppause; +extern uint16 mem_check; + +INLINE uint8 S9xGetByte (uint32 Address) +{ +#ifdef __show_io__ + char str[64]; + sprintf(str,"rd @ %04X",Address); + S9xMessage(0,0,str); + gp32_pause(); +#endif +#ifdef __memcheck__ + mem_check+=(Address>>16)+Address; +#endif +#if defined(VAR_CYCLES) || defined(CPU_SHUTDOWN) + int block; + uint8 *GetAddress = Memory.Map [block = (Address >> MEMMAP_SHIFT) & MEMMAP_MASK]; +#else + uint8 *GetAddress = Memory.Map [(Address >> MEMMAP_SHIFT) & MEMMAP_MASK]; +#endif + if (GetAddress >= (uint8 *) CMemory::MAP_LAST) + { +#ifdef VAR_CYCLES + CPU.Cycles += Memory.MemorySpeed [block]; +#endif +#ifdef CPU_SHUTDOWN + if (Memory.BlockIsRAM [block]) + CPU.WaitAddress = CPU.PCAtOpcodeStart; +#endif + return (*(GetAddress + (Address & 0xffff))); + } + + switch ((int) GetAddress) + { + case CMemory::MAP_PPU: +#ifdef VAR_CYCLES + if (!CPU.InDMA) + CPU.Cycles += ONE_CYCLE; +#endif + return (S9xGetPPU (Address & 0xffff)); + case CMemory::MAP_CPU: +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + return (S9xGetCPU (Address & 0xffff)); + case CMemory::MAP_DSP: +#ifdef VAR_CYCLES + CPU.Cycles += SLOW_ONE_CYCLE; +#endif + return (S9xGetDSP (Address & 0xffff)); + case CMemory::MAP_SA1RAM: + case CMemory::MAP_LOROM_SRAM: +#ifdef VAR_CYCLES + CPU.Cycles += SLOW_ONE_CYCLE; +#endif + return (*(Memory.SRAM + ((Address & CPU.Memory_SRAMMask)))); + + case CMemory::MAP_HIROM_SRAM: +#ifdef VAR_CYCLES + CPU.Cycles += SLOW_ONE_CYCLE; +#endif + return (*(Memory.SRAM + (((Address & 0x7fff) - 0x6000 + + ((Address & 0xf0000) >> 3)) & CPU.Memory_SRAMMask))); + + case CMemory::MAP_DEBUG: +#ifdef DEBUGGER + printf ("R(B) %06x\n", Address); +#endif + + case CMemory::MAP_BWRAM: +#ifdef VAR_CYCLES + CPU.Cycles += SLOW_ONE_CYCLE; +#endif + return (*(Memory.BWRAM + ((Address & 0x7fff) - 0x6000))); +//#ifndef __GP32__ + case CMemory::MAP_C4: + return (S9xGetC4 (Address & 0xffff)); +//#endif + default: + case CMemory::MAP_NONE: +#ifdef VAR_CYCLES + CPU.Cycles += SLOW_ONE_CYCLE; +#endif +#ifdef DEBUGGER + printf ("R(B) %06x\n", Address); +#endif + return ((Address >> 8) & 0xff); + } +} + +INLINE uint16 S9xGetWord (uint32 Address) +{ +#ifdef __show_io__ + char str[64]; + sprintf(str,"rd @ %04X",Address); + S9xMessage(0,0,str); + gp32_pause(); +#endif +#ifdef __memcheck__ + mem_check+=(Address>>16)+Address; +#endif + if ((Address & 0x1fff) == 0x1fff) + { + return (S9xGetByte (Address) | (S9xGetByte (Address + 1) << 8)); + } +#if defined(VAR_CYCLES) || defined(CPU_SHUTDOWN) + int block; + uint8 *GetAddress = Memory.Map [block = (Address >> MEMMAP_SHIFT) & MEMMAP_MASK]; +#else + uint8 *GetAddress = Memory.Map [(Address >> MEMMAP_SHIFT) & MEMMAP_MASK]; +#endif + if (GetAddress >= (uint8 *) CMemory::MAP_LAST) + { +#ifdef VAR_CYCLES + CPU.Cycles += Memory.MemorySpeed [block] << 1; +#endif +#ifdef CPU_SHUTDOWN + if (Memory.BlockIsRAM [block]) + CPU.WaitAddress = CPU.PCAtOpcodeStart; +#endif +#ifdef FAST_LSB_WORD_ACCESS + return (*(uint16 *) (GetAddress + (Address & 0xffff))); +#else + return (*(GetAddress + (Address & 0xffff)) | + (*(GetAddress + (Address & 0xffff) + 1) << 8)); +#endif + } + + switch ((int) GetAddress) + { + case CMemory::MAP_PPU: +#ifdef VAR_CYCLES + if (!CPU.InDMA) + CPU.Cycles += TWO_CYCLES; +#endif + return (S9xGetPPU (Address & 0xffff) | + (S9xGetPPU ((Address + 1) & 0xffff) << 8)); + case CMemory::MAP_CPU: +#ifdef VAR_CYCLES + CPU.Cycles += TWO_CYCLES; +#endif + return (S9xGetCPU (Address & 0xffff) | + (S9xGetCPU ((Address + 1) & 0xffff) << 8)); + case CMemory::MAP_DSP: +#ifdef VAR_CYCLES + CPU.Cycles += SLOW_ONE_CYCLE * 2; +#endif + return (S9xGetDSP (Address & 0xffff) | + (S9xGetDSP ((Address + 1) & 0xffff) << 8)); + case CMemory::MAP_SA1RAM: + case CMemory::MAP_LOROM_SRAM: +#ifdef VAR_CYCLES + CPU.Cycles += SLOW_ONE_CYCLE * 2; +#endif + return (*(Memory.SRAM + (Address & CPU.Memory_SRAMMask)) | + (*(Memory.SRAM + ((Address + 1) & CPU.Memory_SRAMMask)) << 8)); + + case CMemory::MAP_HIROM_SRAM: +#ifdef VAR_CYCLES + CPU.Cycles += SLOW_ONE_CYCLE * 2; +#endif + return (*(Memory.SRAM + + (((Address & 0x7fff) - 0x6000 + + ((Address & 0xf0000) >> 3)) & CPU.Memory_SRAMMask)) | + (*(Memory.SRAM + + ((((Address + 1) & 0x7fff) - 0x6000 + + (((Address + 1) & 0xf0000) >> 3)) & CPU.Memory_SRAMMask)) << 8)); + + case CMemory::MAP_BWRAM: +#ifdef VAR_CYCLES + CPU.Cycles += SLOW_ONE_CYCLE * 2; +#endif + return (*(Memory.BWRAM + ((Address & 0x7fff) - 0x6000)) | + (*(Memory.BWRAM + (((Address + 1) & 0x7fff) - 0x6000)) << 8)); + + case CMemory::MAP_DEBUG: +#ifdef DEBUGGER + printf ("R(W) %06x\n", Address); +#endif + +//#ifndef __GP32__ + case CMemory::MAP_C4: + return (S9xGetC4 (Address & 0xffff) | + (S9xGetC4 ((Address + 1) & 0xffff) << 8)); +//#endif + default: + case CMemory::MAP_NONE: +#ifdef VAR_CYCLES + CPU.Cycles += SLOW_ONE_CYCLE * 2; +#endif +#ifdef DEBUGGER + printf ("R(W) %06x\n", Address); +#endif + return (((Address >> 8) | (Address & 0xff00)) & 0xffff); + } +} + +INLINE void S9xSetByte (uint8 Byte, uint32 Address) +{ +#ifdef __show_io__ + char str[64]; + sprintf(str,"wr @ %04X %02X",Address,Byte); + S9xMessage(0,0,str); + gp32_pause(); +#endif +#ifdef __memcheck__ + mem_check+=Byte; +#endif + +#if defined(CPU_SHUTDOWN) + CPU.WaitAddress = NULL; +#endif +#if defined(VAR_CYCLES) + int block; + uint8 *SetAddress = Memory.WriteMap [block = ((Address >> MEMMAP_SHIFT) & MEMMAP_MASK)]; +#else + uint8 *SetAddress = Memory.WriteMap [(Address >> MEMMAP_SHIFT) & MEMMAP_MASK]; +#endif + + if (SetAddress >= (uint8 *) CMemory::MAP_LAST) + { +#ifdef VAR_CYCLES + CPU.Cycles += Memory.MemorySpeed [block]; +#endif +#ifdef CPU_SHUTDOWN + SetAddress += Address & 0xffff; +#ifdef USE_SA1 + if (SetAddress == SA1.WaitByteAddress1 || + SetAddress == SA1.WaitByteAddress2) + { + SA1.Executing = SA1.S9xOpcodes != NULL; + SA1.WaitCounter = 0; + } +#endif + *SetAddress = Byte; +#else + *(SetAddress + (Address & 0xffff)) = Byte; +#endif + return; + } + + switch ((int) SetAddress) + { + case CMemory::MAP_PPU: +#ifdef VAR_CYCLES + if (!CPU.InDMA) + CPU.Cycles += ONE_CYCLE; +#endif + S9xSetPPU (Byte, Address & 0xffff); + return; + + case CMemory::MAP_CPU: +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + S9xSetCPU (Byte, Address & 0xffff); + return; + + case CMemory::MAP_DSP: +#ifdef VAR_CYCLES + CPU.Cycles += SLOW_ONE_CYCLE; +#endif + S9xSetDSP (Byte, Address & 0xffff); + return; + + case CMemory::MAP_LOROM_SRAM: +#ifdef VAR_CYCLES + CPU.Cycles += SLOW_ONE_CYCLE; +#endif + if (CPU.Memory_SRAMMask) + { + *(Memory.SRAM + (Address & CPU.Memory_SRAMMask)) = Byte; + CPU.SRAMModified = TRUE; + } + return; + + case CMemory::MAP_HIROM_SRAM: +#ifdef VAR_CYCLES + CPU.Cycles += SLOW_ONE_CYCLE; +#endif + if (CPU.Memory_SRAMMask) + { + *(Memory.SRAM + (((Address & 0x7fff) - 0x6000 + + ((Address & 0xf0000) >> 3)) & CPU.Memory_SRAMMask)) = Byte; + CPU.SRAMModified = TRUE; + } + return; + + case CMemory::MAP_BWRAM: +#ifdef VAR_CYCLES + CPU.Cycles += SLOW_ONE_CYCLE; +#endif + *(Memory.BWRAM + ((Address & 0x7fff) - 0x6000)) = Byte; + CPU.SRAMModified = TRUE; + return; + + case CMemory::MAP_DEBUG: +#ifdef DEBUGGER + printf ("W(B) %06x\n", Address); +#endif + + case CMemory::MAP_SA1RAM: +#ifdef VAR_CYCLES + CPU.Cycles += SLOW_ONE_CYCLE; +#endif + *(Memory.SRAM + (Address & 0xffff)) = Byte; + SA1.Executing = !SA1.Waiting; + break; +//#ifndef __GP32__ + case CMemory::MAP_C4: + S9xSetC4 (Byte, Address & 0xffff); + return; +//#endif + default: + case CMemory::MAP_NONE: +#ifdef VAR_CYCLES + CPU.Cycles += SLOW_ONE_CYCLE; +#endif +#ifdef DEBUGGER + printf ("W(B) %06x\n", Address); +#endif + return; + } +} + +INLINE void S9xSetWord (uint16 Word, uint32 Address) +{ +#ifdef __show_io__ + char str[64]; + sprintf(str,"wr @ %04X %04X",Address,Word); + S9xMessage(0,0,str); + gp32_pause(); +#endif +#ifdef __memcheck__ + mem_check+=Word; +#endif +#if defined(CPU_SHUTDOWN) + CPU.WaitAddress = NULL; +#endif +#if defined (VAR_CYCLES) + int block; + uint8 *SetAddress = Memory.WriteMap [block = ((Address >> MEMMAP_SHIFT) & MEMMAP_MASK)]; +#else + uint8 *SetAddress = Memory.WriteMap [(Address >> MEMMAP_SHIFT) & MEMMAP_MASK]; +#endif + + if (SetAddress >= (uint8 *) CMemory::MAP_LAST) + { +#ifdef VAR_CYCLES + CPU.Cycles += Memory.MemorySpeed [block] << 1; +#endif +#if defined(CPU_SHUTDOWN) && defined(USE_SA1) + uint8 *SetAddressSA1 = (uint8 *)(Address & 0xffff); + if (SetAddressSA1 == SA1.WaitByteAddress1 || + SetAddressSA1 == SA1.WaitByteAddress2) + { + SA1.Executing = SA1.S9xOpcodes != NULL; + SA1.WaitCounter = 0; + } +#endif +#ifdef FAST_LSB_WORD_ACCESS + *(uint16 *) (SetAddress + (Address & 0xffff)) = Word; +#else + *(SetAddress + (Address & 0xffff)) = (uint8) Word; + *(SetAddress + ((Address + 1) & 0xffff)) = Word >> 8; +#endif + return; + } + + switch ((int) SetAddress) + { + case CMemory::MAP_PPU: +#ifdef VAR_CYCLES + if (!CPU.InDMA) + CPU.Cycles += TWO_CYCLES; +#endif + S9xSetPPU ((uint8) Word, Address & 0xffff); + S9xSetPPU (Word >> 8, (Address & 0xffff) + 1); + return; + + case CMemory::MAP_CPU: +#ifdef VAR_CYCLES + CPU.Cycles += TWO_CYCLES; +#endif + S9xSetCPU ((uint8) Word, (Address & 0xffff)); + S9xSetCPU (Word >> 8, (Address & 0xffff) + 1); + return; + + case CMemory::MAP_DSP: +#ifdef VAR_CYCLES + CPU.Cycles += SLOW_ONE_CYCLE * 2; +#endif + S9xSetDSP ((uint8) Word, (Address & 0xffff)); + S9xSetDSP (Word >> 8, (Address & 0xffff) + 1); + return; + + case CMemory::MAP_LOROM_SRAM: +#ifdef VAR_CYCLES + CPU.Cycles += SLOW_ONE_CYCLE * 2; +#endif + if (CPU.Memory_SRAMMask) + { + *(Memory.SRAM + (Address & CPU.Memory_SRAMMask)) = (uint8) Word; + *(Memory.SRAM + ((Address + 1) & CPU.Memory_SRAMMask)) = Word >> 8; + CPU.SRAMModified = TRUE; + } + return; + + case CMemory::MAP_HIROM_SRAM: +#ifdef VAR_CYCLES + CPU.Cycles += SLOW_ONE_CYCLE * 2; +#endif + if (CPU.Memory_SRAMMask) + { + *(Memory.SRAM + + (((Address & 0x7fff) - 0x6000 + + ((Address & 0xf0000) >> MEMMAP_SHIFT) & CPU.Memory_SRAMMask))) = (uint8) Word; + *(Memory.SRAM + + ((((Address + 1) & 0x7fff) - 0x6000 + + (((Address + 1) & 0xf0000) >> MEMMAP_SHIFT) & CPU.Memory_SRAMMask))) = (uint8) (Word >> 8); + CPU.SRAMModified = TRUE; + } + return; + + case CMemory::MAP_BWRAM: +#ifdef VAR_CYCLES + CPU.Cycles += SLOW_ONE_CYCLE * 2; +#endif + *(Memory.BWRAM + ((Address & 0x7fff) - 0x6000)) = (uint8) Word; + *(Memory.BWRAM + (((Address + 1) & 0x7fff) - 0x6000)) = (uint8) (Word >> 8); + CPU.SRAMModified = TRUE; + return; + + case CMemory::MAP_DEBUG: +#ifdef DEBUGGER + printf ("W(W) %06x\n", Address); +#endif + + case CMemory::MAP_SA1RAM: +#ifdef VAR_CYCLES + CPU.Cycles += SLOW_ONE_CYCLE; +#endif + *(Memory.SRAM + (Address & 0xffff)) = (uint8) Word; + *(Memory.SRAM + ((Address + 1) & 0xffff)) = (uint8) (Word >> 8); + SA1.Executing = !SA1.Waiting; + break; +//#ifndef __GP32__ + case CMemory::MAP_C4: + S9xSetC4 (Word & 0xff, Address & 0xffff); + S9xSetC4 ((uint8) (Word >> 8), (Address + 1) & 0xffff); + return; +//#endif + default: + case CMemory::MAP_NONE: +#ifdef VAR_CYCLES + CPU.Cycles += SLOW_ONE_CYCLE * 2; +#endif +#ifdef DEBUGGER + printf ("W(W) %06x\n", Address); +#endif + return; + } +} + +INLINE uint8 *GetBasePointer (uint32 Address) +{ + uint8 *GetAddress = Memory.Map [(Address >> MEMMAP_SHIFT) & MEMMAP_MASK]; + if (GetAddress >= (uint8 *) CMemory::MAP_LAST) + return (GetAddress); + + switch ((int) GetAddress) + { + case CMemory::MAP_PPU: + return (Memory.FillRAM - 0x2000); + case CMemory::MAP_CPU: + return (Memory.FillRAM - 0x4000); + case CMemory::MAP_DSP: + return (Memory.FillRAM - 0x6000); + case CMemory::MAP_SA1RAM: + case CMemory::MAP_LOROM_SRAM: + return (Memory.SRAM); + case CMemory::MAP_BWRAM: + return (Memory.BWRAM - 0x6000); + case CMemory::MAP_HIROM_SRAM: + return (Memory.SRAM - 0x6000); +//#ifndef __GP32__ + case CMemory::MAP_C4: + return (Memory.C4RAM - 0x6000); +//#endif + case CMemory::MAP_DEBUG: +#ifdef DEBUGGER + printf ("GBP %06x\n", Address); +#endif + + default: + case CMemory::MAP_NONE: +#ifdef DEBUGGER + printf ("GBP %06x\n", Address); +#endif + return (0); + } +} + +INLINE uint8 *S9xGetMemPointer (uint32 Address) +{ + uint8 *GetAddress = Memory.Map [(Address >> MEMMAP_SHIFT) & MEMMAP_MASK]; + if (GetAddress >= (uint8 *) CMemory::MAP_LAST) + return (GetAddress + (Address & 0xffff)); + + switch ((int) GetAddress) + { + case CMemory::MAP_PPU: + return (Memory.FillRAM - 0x2000 + (Address & 0xffff)); + case CMemory::MAP_CPU: + return (Memory.FillRAM - 0x4000 + (Address & 0xffff)); + case CMemory::MAP_DSP: + return (Memory.FillRAM - 0x6000 + (Address & 0xffff)); + case CMemory::MAP_SA1RAM: + case CMemory::MAP_LOROM_SRAM: + return (Memory.SRAM + (Address & 0xffff)); + case CMemory::MAP_BWRAM: + return (Memory.BWRAM - 0x6000 + (Address & 0xffff)); + case CMemory::MAP_HIROM_SRAM: + return (Memory.SRAM - 0x6000 + (Address & 0xffff)); +//#ifndef __GP32__ + case CMemory::MAP_C4: + return (Memory.C4RAM - 0x6000 + (Address & 0xffff)); +//#endif + case CMemory::MAP_DEBUG: +#ifdef DEBUGGER + printf ("GMP %06x\n", Address); +#endif + default: + case CMemory::MAP_NONE: +#ifdef DEBUGGER + printf ("GMP %06x\n", Address); +#endif + return (0); + } +} + +INLINE void S9xSetPCBase (uint32 Address) +{ +#ifdef VAR_CYCLES + int block; + uint8 *GetAddress = Memory.Map [block = (Address >> MEMMAP_SHIFT) & MEMMAP_MASK]; +#else + uint8 *GetAddress = Memory.Map [(Address >> MEMMAP_SHIFT) & MEMMAP_MASK]; +#endif + if (GetAddress >= (uint8 *) CMemory::MAP_LAST) + { +#ifdef VAR_CYCLES + CPU.MemSpeed = Memory.MemorySpeed [block]; + CPU.MemSpeedx2 = CPU.MemSpeed << 1; +#endif + CPU.PCBase = GetAddress; + CPU.PC = GetAddress + (Address & 0xffff); + return; + } + + switch ((int) GetAddress) + { + case CMemory::MAP_PPU: +#ifdef VAR_CYCLES + CPU.MemSpeed = ONE_CYCLE; + CPU.MemSpeedx2 = TWO_CYCLES; +#endif + CPU.PCBase = Memory.FillRAM - 0x2000; + CPU.PC = CPU.PCBase + (Address & 0xffff); + return; + + case CMemory::MAP_CPU: +#ifdef VAR_CYCLES + CPU.MemSpeed = ONE_CYCLE; + CPU.MemSpeedx2 = TWO_CYCLES; +#endif + CPU.PCBase = Memory.FillRAM - 0x4000; + CPU.PC = CPU.PCBase + (Address & 0xffff); + return; + + case CMemory::MAP_DSP: +#ifdef VAR_CYCLES + CPU.MemSpeed = SLOW_ONE_CYCLE; + CPU.MemSpeedx2 = SLOW_ONE_CYCLE * 2; +#endif + CPU.PCBase = Memory.FillRAM - 0x6000; + CPU.PC = CPU.PCBase + (Address & 0xffff); + return; + + case CMemory::MAP_SA1RAM: + case CMemory::MAP_LOROM_SRAM: +#ifdef VAR_CYCLES + CPU.MemSpeed = SLOW_ONE_CYCLE; + CPU.MemSpeedx2 = SLOW_ONE_CYCLE * 2; +#endif + CPU.PCBase = Memory.SRAM; + CPU.PC = CPU.PCBase + (Address & 0xffff); + return; + + case CMemory::MAP_BWRAM: +#ifdef VAR_CYCLES + CPU.MemSpeed = SLOW_ONE_CYCLE; + CPU.MemSpeedx2 = SLOW_ONE_CYCLE * 2; +#endif + CPU.PCBase = Memory.BWRAM - 0x6000; + CPU.PC = CPU.PCBase + (Address & 0xffff); + return; + case CMemory::MAP_HIROM_SRAM: +#ifdef VAR_CYCLES + CPU.MemSpeed = SLOW_ONE_CYCLE; + CPU.MemSpeedx2 = SLOW_ONE_CYCLE * 2; +#endif + CPU.PCBase = Memory.SRAM - 0x6000; + CPU.PC = CPU.PCBase + (Address & 0xffff); + return; +//#ifndef __GP32__ + case CMemory::MAP_C4: +#ifdef VAR_CYCLES + CPU.MemSpeed = SLOW_ONE_CYCLE; + CPU.MemSpeedx2 = SLOW_ONE_CYCLE * 2; +#endif + CPU.PCBase = Memory.C4RAM - 0x6000; + CPU.PC = CPU.PCBase + (Address & 0xffff); + return; +//#endif + case CMemory::MAP_DEBUG: +#ifdef DEBUGGER + printf ("SBP %06x\n", Address); +#endif + + default: + case CMemory::MAP_NONE: +#ifdef VAR_CYCLES + CPU.MemSpeed = SLOW_ONE_CYCLE; + CPU.MemSpeedx2 = SLOW_ONE_CYCLE * 2; +#endif +#ifdef DEBUGGER + printf ("SBP %06x\n", Address); +#endif + CPU.PCBase = Memory.SRAM; + CPU.PC = Memory.SRAM + (Address & 0xffff); + return; + } +} +#endif diff --git a/src/snes4iphone_src/gfx.cpp b/src/snes4iphone_src/gfx.cpp new file mode 100755 index 0000000..b909251 --- /dev/null +++ b/src/snes4iphone_src/gfx.cpp @@ -0,0 +1,4061 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#include "snes9x.h" + +#include "memmap.h" +#include "ppu.h" +#include "cpuexec.h" +#include "display.h" +#include "gfx.h" +#include "apu.h" +#include "cheats.h" +#include +//#include "asmmemfuncs.h" + +#define M7 19 +#define M8 19 + +void ComputeClipWindows (); +static void S9xDisplayFrameRate (); +static void S9xDisplayString (const char *string); + +extern uint8 BitShifts[8][4]; +extern uint8 TileShifts[8][4]; +extern uint8 PaletteShifts[8][4]; +extern uint8 PaletteMasks[8][4]; +extern uint8 Depths[8][4]; +extern uint8 BGSizes [2]; + +extern NormalTileRenderer DrawTilePtr; +extern ClippedTileRenderer DrawClippedTilePtr; +extern NormalTileRenderer DrawHiResTilePtr; +extern ClippedTileRenderer DrawHiResClippedTilePtr; +extern LargePixelRenderer DrawLargePixelPtr; + +extern struct SBG BG; + +extern struct SLineData LineData[240]; +extern struct SLineMatrixData LineMatrixData [240]; + +extern uint8 Mode7Depths [2]; + +#define ON_MAIN(N) \ +(GFX.r212c & (1 << (N)) && \ + !(PPU.BG_Forced & (1 << (N)))) + +#define SUB_OR_ADD(N) \ +(GFX.r2131 & (1 << (N))) + +#define ON_SUB(N) \ +((GFX.r2130 & 0x30) != 0x30 && \ + (GFX.r2130 & 2) && \ + (GFX.r212d & (1 << N)) && \ + !(PPU.BG_Forced & (1 << (N)))) + +#define ANYTHING_ON_SUB \ +((GFX.r2130 & 0x30) != 0x30 && \ + (GFX.r2130 & 2) && \ + (GFX.r212d & 0x1f)) + +#define ADD_OR_SUB_ON_ANYTHING \ +(GFX.r2131 & 0x3f) + +#define BLACK BUILD_PIXEL(0,0,0) + +void DrawTile (uint32 Tile, uint32 Offset, uint32 StartLine, + uint32 LineCount, struct SGFX * gfx); +void DrawClippedTile (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount, struct SGFX * gfx); +void DrawTilex2 (uint32 Tile, uint32 Offset, uint32 StartLine, + uint32 LineCount, struct SGFX * gfx); +void DrawClippedTilex2 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount, struct SGFX * gfx); +void DrawTilex2x2 (uint32 Tile, uint32 Offset, uint32 StartLine, + uint32 LineCount, struct SGFX * gfx); +void DrawClippedTilex2x2 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount, struct SGFX * gfx); +void DrawLargePixel (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Pixels, + uint32 StartLine, uint32 LineCount, struct SGFX * gfx); + +void DrawTile16 (uint32 Tile, uint32 Offset, uint32 StartLine, + uint32 LineCount, struct SGFX * gfx); +void DrawClippedTile16 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount, struct SGFX * gfx); +void DrawTile16x2 (uint32 Tile, uint32 Offset, uint32 StartLine, + uint32 LineCount, struct SGFX * gfx); +void DrawClippedTile16x2 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount, struct SGFX * gfx); +void DrawTile16x2x2 (uint32 Tile, uint32 Offset, uint32 StartLine, + uint32 LineCount, struct SGFX * gfx); +void DrawClippedTile16x2x2 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount, struct SGFX * gfx); +void DrawLargePixel16 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Pixels, + uint32 StartLine, uint32 LineCount, struct SGFX * gfx); + +void DrawTile16Add (uint32 Tile, uint32 Offset, uint32 StartLine, + uint32 LineCount, struct SGFX * gfx); + +void DrawClippedTile16Add (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount, struct SGFX * gfx); + +void DrawTile16Add1_2 (uint32 Tile, uint32 Offset, uint32 StartLine, + uint32 LineCount, struct SGFX * gfx); + +void DrawClippedTile16Add1_2 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount, struct SGFX * gfx); + +void DrawTile16FixedAdd1_2 (uint32 Tile, uint32 Offset, uint32 StartLine, + uint32 LineCount, struct SGFX * gfx); + +void DrawClippedTile16FixedAdd1_2 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount, struct SGFX * gfx); + +void DrawTile16Sub (uint32 Tile, uint32 Offset, uint32 StartLine, + uint32 LineCount, struct SGFX * gfx); + +void DrawClippedTile16Sub (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount, struct SGFX * gfx); + +void DrawTile16Sub1_2 (uint32 Tile, uint32 Offset, uint32 StartLine, + uint32 LineCount, struct SGFX * gfx); + +void DrawClippedTile16Sub1_2 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount, struct SGFX * gfx); + +void DrawTile16FixedSub1_2 (uint32 Tile, uint32 Offset, uint32 StartLine, + uint32 LineCount, struct SGFX * gfx); + +void DrawClippedTile16FixedSub1_2 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount, struct SGFX * gfx); + +void DrawLargePixel16Add (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Pixels, + uint32 StartLine, uint32 LineCount, struct SGFX * gfx); + +void DrawLargePixel16Add1_2 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Pixels, + uint32 StartLine, uint32 LineCount, struct SGFX * gfx); + +void DrawLargePixel16Sub (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Pixels, + uint32 StartLine, uint32 LineCount, struct SGFX * gfx); + +void DrawLargePixel16Sub1_2 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Pixels, + uint32 StartLine, uint32 LineCount, struct SGFX * gfx); + +void DrawHiResClippedTile16 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount, struct SGFX * gfx); + +void DrawHiResTile16 (uint32 Tile, uint32 Offset, + uint32 StartLine, uint32 LineCount, struct SGFX * gfx); + +bool8_32 S9xGraphicsInit () +{ + register uint32 PixelOdd = 1; + register uint32 PixelEven = 2; + +#ifdef GFX_MULTI_FORMAT + if (GFX.BuildPixel == NULL) + S9xSetRenderPixelFormat (RGB565); +#endif + + for (uint8 bitshift = 0; bitshift < 4; bitshift++) + { + for (register char i = 0; i < 16; i++) + { + register uint32 h = 0; + register uint32 l = 0; + +#if defined(LSB_FIRST) + if (i & 8) + h |= PixelOdd; + if (i & 4) + h |= PixelOdd << 8; + if (i & 2) + h |= PixelOdd << 16; + if (i & 1) + h |= PixelOdd << 24; + if (i & 8) + l |= PixelOdd; + if (i & 4) + l |= PixelOdd << 8; + if (i & 2) + l |= PixelOdd << 16; + if (i & 1) + l |= PixelOdd << 24; +#else + if (i & 8) + h |= (PixelOdd << 24); + if (i & 4) + h |= (PixelOdd << 16); + if (i & 2) + h |= (PixelOdd << 8); + if (i & 1) + h |= PixelOdd; + if (i & 8) + l |= (PixelOdd << 24); + if (i & 4) + l |= (PixelOdd << 16); + if (i & 2) + l |= (PixelOdd << 8); + if (i & 1) + l |= PixelOdd; +#endif + + odd_high[bitshift][i] = h; + odd_low[bitshift][i] = l; + h = l = 0; + +#if defined(LSB_FIRST) + if (i & 8) + h |= PixelEven; + if (i & 4) + h |= PixelEven << 8; + if (i & 2) + h |= PixelEven << 16; + if (i & 1) + h |= PixelEven << 24; + if (i & 8) + l |= PixelEven; + if (i & 4) + l |= PixelEven << 8; + if (i & 2) + l |= PixelEven << 16; + if (i & 1) + l |= PixelEven << 24; +#else + if (i & 8) + h |= (PixelEven << 24); + if (i & 4) + h |= (PixelEven << 16); + if (i & 2) + h |= (PixelEven << 8); + if (i & 1) + h |= PixelEven; + if (i & 8) + l |= (PixelEven << 24); + if (i & 4) + l |= (PixelEven << 16); + if (i & 2) + l |= (PixelEven << 8); + if (i & 1) + l |= PixelEven; +#endif + + even_high[bitshift][i] = h; + even_low[bitshift][i] = l; + } + PixelEven <<= 2; + PixelOdd <<= 2; + } + + GFX.RealPitch = GFX.Pitch2 = GFX.Pitch; + GFX.ZPitch = GFX.Pitch; + if (Settings.SixteenBit) + GFX.ZPitch >>= 1; + GFX.Delta = (GFX.SubScreen - GFX.Screen) >> 1; + GFX.DepthDelta = GFX.SubZBuffer - GFX.ZBuffer; + //GFX.InfoStringTimeout = 0; + //GFX.InfoString = NULL; + + PPU.BG_Forced = 0; + IPPU.OBJChanged = TRUE; + if (Settings.Transparency) + Settings.SixteenBit = TRUE; + + IPPU.DirectColourMapsNeedRebuild = TRUE; + GFX.PixSize = 1; + if (Settings.SixteenBit) + { + DrawTilePtr = DrawTile16; + DrawClippedTilePtr = DrawClippedTile16; + DrawLargePixelPtr = DrawLargePixel16; + DrawHiResTilePtr= DrawHiResTile16; + DrawHiResClippedTilePtr = DrawHiResClippedTile16; + GFX.PPL = GFX.Pitch >> 1; + GFX.PPLx2 = GFX.Pitch; + } + else + { + DrawTilePtr = DrawTile; + DrawClippedTilePtr = DrawClippedTile; + DrawLargePixelPtr = DrawLargePixel; + DrawHiResTilePtr = DrawTile; + DrawHiResClippedTilePtr = DrawClippedTile; + GFX.PPL = GFX.Pitch; + GFX.PPLx2 = GFX.Pitch * 2; + } + S9xFixColourBrightness (); + + if (Settings.SixteenBit) + { + if (!(GFX.X2 = (uint16 *) malloc (sizeof (uint16) * 0x10000))) + return (FALSE); + + if (!(GFX.ZERO_OR_X2 = (uint16 *) malloc (sizeof (uint16) * 0x10000)) || + !(GFX.ZERO = (uint16 *) malloc (sizeof (uint16) * 0x10000))) + { + if (GFX.ZERO_OR_X2) + { + free ((char *) GFX.ZERO_OR_X2); + GFX.ZERO_OR_X2 = NULL; + } + if (GFX.X2) + { + free ((char *) GFX.X2); + GFX.X2 = NULL; + } + return (FALSE); + } + uint32 r, g, b; + + // Build a lookup table that multiplies a packed RGB value by 2 with + // saturation. + for (r = 0; r <= MAX_RED; r++) + { + uint32 r2 = r << 1; + if (r2 > MAX_RED) + r2 = MAX_RED; + for (g = 0; g <= MAX_GREEN; g++) + { + uint32 g2 = g << 1; + if (g2 > MAX_GREEN) + g2 = MAX_GREEN; + for (b = 0; b <= MAX_BLUE; b++) + { + uint32 b2 = b << 1; + if (b2 > MAX_BLUE) + b2 = MAX_BLUE; + GFX.X2 [BUILD_PIXEL2 (r, g, b)] = BUILD_PIXEL2 (r2, g2, b2); + GFX.X2 [BUILD_PIXEL2 (r, g, b) & ~ALPHA_BITS_MASK] = BUILD_PIXEL2 (r2, g2, b2); + } + } + } + ZeroMemory (GFX.ZERO, 0x10000 * sizeof (uint16)); + ZeroMemory (GFX.ZERO_OR_X2, 0x10000 * sizeof (uint16)); + // Build a lookup table that if the top bit of the color value is zero + // then the value is zero, otherwise multiply the value by 2. Used by + // the color subtraction code. + +#if defined(OLD_COLOUR_BLENDING) + for (r = 0; r <= MAX_RED; r++) + { + uint32 r2 = r; + if ((r2 & 0x10) == 0) + r2 = 0; + else + r2 = (r2 << 1) & MAX_RED; + + for (g = 0; g <= MAX_GREEN; g++) + { + uint32 g2 = g; + if ((g2 & GREEN_HI_BIT) == 0) + g2 = 0; + else + g2 = (g2 << 1) & MAX_GREEN; + + for (b = 0; b <= MAX_BLUE; b++) + { + uint32 b2 = b; + if ((b2 & 0x10) == 0) + b2 = 0; + else + b2 = (b2 << 1) & MAX_BLUE; + + GFX.ZERO_OR_X2 [BUILD_PIXEL2 (r, g, b)] = BUILD_PIXEL2 (r2, g2, b2); + GFX.ZERO_OR_X2 [BUILD_PIXEL2 (r, g, b) & ~ALPHA_BITS_MASK] = BUILD_PIXEL2 (r2, g2, b2); + } + } + } +#else + for (r = 0; r <= MAX_RED; r++) + { + uint32 r2 = r; + if ((r2 & 0x10) == 0) + r2 = 0; + else + r2 = (r2 << 1) & MAX_RED; + + if (r2 == 0) + r2 = 1; + for (g = 0; g <= MAX_GREEN; g++) + { + uint32 g2 = g; + if ((g2 & GREEN_HI_BIT) == 0) + g2 = 0; + else + g2 = (g2 << 1) & MAX_GREEN; + + if (g2 == 0) + g2 = 1; + for (b = 0; b <= MAX_BLUE; b++) + { + uint32 b2 = b; + if ((b2 & 0x10) == 0) + b2 = 0; + else + b2 = (b2 << 1) & MAX_BLUE; + + if (b2 == 0) + b2 = 1; + GFX.ZERO_OR_X2 [BUILD_PIXEL2 (r, g, b)] = BUILD_PIXEL2 (r2, g2, b2); + GFX.ZERO_OR_X2 [BUILD_PIXEL2 (r, g, b) & ~ALPHA_BITS_MASK] = BUILD_PIXEL2 (r2, g2, b2); + } + } + } +#endif + + // Build a lookup table that if the top bit of the color value is zero + // then the value is zero, otherwise its just the value. + for (r = 0; r <= MAX_RED; r++) + { + uint32 r2 = r; + if ((r2 & 0x10) == 0) + r2 = 0; + else + r2 &= ~0x10; + + for (g = 0; g <= MAX_GREEN; g++) + { + uint32 g2 = g; + if ((g2 & GREEN_HI_BIT) == 0) + g2 = 0; + else + g2 &= ~GREEN_HI_BIT; + for (b = 0; b <= MAX_BLUE; b++) + { + uint32 b2 = b; + if ((b2 & 0x10) == 0) + b2 = 0; + else + b2 &= ~0x10; + + GFX.ZERO [BUILD_PIXEL2 (r, g, b)] = BUILD_PIXEL2 (r2, g2, b2); + GFX.ZERO [BUILD_PIXEL2 (r, g, b) & ~ALPHA_BITS_MASK] = BUILD_PIXEL2 (r2, g2, b2); + } + } + } + } + else + { + GFX.X2 = NULL; + GFX.ZERO_OR_X2 = NULL; + GFX.ZERO = NULL; + } + + return (TRUE); +} + +void S9xGraphicsDeinit (void) +{ + // Free any memory allocated in S9xGraphicsInit + if (GFX.X2) + { + free ((char *) GFX.X2); + GFX.X2 = NULL; + } + if (GFX.ZERO_OR_X2) + { + free ((char *) GFX.ZERO_OR_X2); + GFX.ZERO_OR_X2 = NULL; + } + if (GFX.ZERO) + { + free ((char *) GFX.ZERO); + GFX.ZERO = NULL; + } +} + +void S9xBuildDirectColourMaps () +{ + for (uint32 p = 0; p < 8; p++) + { + for (uint32 c = 0; c < 256; c++) + { +// XXX: Brightness + DirectColourMaps [p][c] = BUILD_PIXEL (((c & 7) << 2) | ((p & 1) << 1), + ((c & 0x38) >> 1) | (p & 2), + ((c & 0xc0) >> 3) | (p & 4)); + } + } + IPPU.DirectColourMapsNeedRebuild = FALSE; +} + +void S9xStartScreenRefresh () +{ + if (GFX.InfoStringTimeout > 0 && --GFX.InfoStringTimeout == 0) + GFX.InfoString = NULL; + + if (IPPU.RenderThisFrame) + { +#ifndef _SNESPPC + if (!S9xInitUpdate ()) + { + IPPU.RenderThisFrame = FALSE; + return; + } +#endif + IPPU.RenderedFramesCount++; + IPPU.PreviousLine = IPPU.CurrentLine = 0; + IPPU.MaxBrightness = PPU.Brightness; + IPPU.LatchedBlanking = PPU.ForcedBlanking; + IPPU.LatchedInterlace = (Memory.FillRAM[0x2133] & 1); + IPPU.RenderedScreenWidth = 256; + IPPU.RenderedScreenHeight = PPU.ScreenHeight; + IPPU.DoubleWidthPixels = FALSE; + GFX.Pitch2 = GFX.Pitch = GFX.RealPitch; + GFX.PPL = GFX.PPLx2 >> 1; + GFX.ZPitch = GFX.RealPitch; + if (Settings.SixteenBit) + GFX.ZPitch >>= 1; + PPU.RecomputeClipWindows = TRUE; + GFX.DepthDelta = GFX.SubZBuffer - GFX.ZBuffer; + GFX.Delta = (GFX.SubScreen - GFX.Screen) >> 1; + } + if (++IPPU.FrameCount % Memory.ROMFramesPerSecond == 0) + { + IPPU.DisplayedRenderedFrameCount = IPPU.RenderedFramesCount; + IPPU.RenderedFramesCount = 0; + IPPU.FrameCount = 0; + } +} + +void RenderLine (uint8 C) +{ + if (IPPU.RenderThisFrame) + { + + LineData[C].BG[0].VOffset = PPU.BG[0].VOffset + 1; + LineData[C].BG[0].HOffset = PPU.BG[0].HOffset; + LineData[C].BG[1].VOffset = PPU.BG[1].VOffset + 1; + LineData[C].BG[1].HOffset = PPU.BG[1].HOffset; + + if (PPU.BGMode == 7) + { + struct SLineMatrixData *p = &LineMatrixData [C]; + p->MatrixA = PPU.MatrixA; + p->MatrixB = PPU.MatrixB; + p->MatrixC = PPU.MatrixC; + p->MatrixD = PPU.MatrixD; + p->CentreX = PPU.CentreX; + p->CentreY = PPU.CentreY; + } + else + { +#ifndef RC_OPTIMIZED + if (Settings.StarfoxHack && PPU.BG[2].VOffset == 0 && + PPU.BG[2].HOffset == 0xe000) + { + LineData[C].BG[2].VOffset = 0xe1; + LineData[C].BG[2].HOffset = 0; + } + else +#endif + + { + LineData[C].BG[2].VOffset = PPU.BG[2].VOffset + 1; + LineData[C].BG[2].HOffset = PPU.BG[2].HOffset; + LineData[C].BG[3].VOffset = PPU.BG[3].VOffset + 1; + LineData[C].BG[3].HOffset = PPU.BG[3].HOffset; + } + + } + IPPU.CurrentLine = C + 1; + } +} + + +void S9xEndScreenRefresh() +{ + IPPU.HDMAStarted = FALSE; + +//RC + if (IPPU.RenderThisFrame) + { + FLUSH_REDRAW (); + if (IPPU.ColorsChanged) + { + uint32 saved = PPU.CGDATA[0]; + if (!Settings.SixteenBit) + { + // Hack for Super Mario World - to get its sky blue + // (It uses Fixed colour addition on the backdrop colour) + if (!(Memory.FillRAM [0x2131] & 0x80) && + (Memory.FillRAM[0x2131] & 0x20) && + (PPU.FixedColourRed || PPU.FixedColourGreen || + PPU.FixedColourBlue)) + { + PPU.CGDATA[0] = PPU.FixedColourRed | + (PPU.FixedColourGreen << 5) | + (PPU.FixedColourBlue << 10); + } + } + IPPU.ColorsChanged = FALSE; + + S9xSetPalette (); + + PPU.CGDATA[0] = saved; + } + GFX.Pitch = GFX.Pitch2 = GFX.RealPitch; + GFX.PPL = GFX.PPLx2 >> 1; + + if (Settings.DisplayFrameRate) + S9xDisplayFrameRate (); + if (GFX.InfoString) + S9xDisplayString (GFX.InfoString); + + S9xDeinitUpdate (IPPU.RenderedScreenWidth, IPPU.RenderedScreenHeight, + Settings.SixteenBit); + } +#ifndef RC_OPTIMIZED + S9xApplyCheats (); +#endif + + +#ifdef DEBUGGER + if (CPU.Flags & FRAME_ADVANCE_FLAG) + { + if (ICPU.FrameAdvanceCount) + { + ICPU.FrameAdvanceCount--; + IPPU.RenderThisFrame = TRUE; + IPPU.FrameSkip = 0; + } + else + { + CPU.Flags &= ~FRAME_ADVANCE_FLAG; + CPU.Flags |= DEBUG_MODE_FLAG; + } + } +#endif + + if (CPU.SRAMModified) + { + if (!CPU.AutoSaveTimer) + { + if (!(CPU.AutoSaveTimer = Settings.AutoSaveDelay * Memory.ROMFramesPerSecond)) + CPU.SRAMModified = FALSE; + } + else + { + if (!--CPU.AutoSaveTimer) + { + S9xAutoSaveSRAM (); + CPU.SRAMModified = FALSE; + } + } + } +} + +void S9xSetInfoString (const char *string) +{ + GFX.InfoString = string; + GFX.InfoStringTimeout = 120; +} + +INLINE void SelectTileRenderer (bool8_32 normal) +{ + if (normal) + { + DrawTilePtr = DrawTile16; + DrawClippedTilePtr = DrawClippedTile16; + DrawLargePixelPtr = DrawLargePixel16; + } + else + { + if (GFX.r2131 & 0x80) + { + if (GFX.r2131 & 0x40) + { + if (GFX.r2130 & 2) + { + DrawTilePtr = DrawTile16Sub1_2; + DrawClippedTilePtr = DrawClippedTile16Sub1_2; + } + else + { + // Fixed colour substraction + DrawTilePtr = DrawTile16FixedSub1_2; + DrawClippedTilePtr = DrawClippedTile16FixedSub1_2; + } + DrawLargePixelPtr = DrawLargePixel16Sub1_2; + } + else + { + DrawTilePtr = DrawTile16Sub; + DrawClippedTilePtr = DrawClippedTile16Sub; + DrawLargePixelPtr = DrawLargePixel16Sub; + } + } + else + { + if (GFX.r2131 & 0x40) + { + if (GFX.r2130 & 2) + { + DrawTilePtr = DrawTile16Add1_2; + DrawClippedTilePtr = DrawClippedTile16Add1_2; + } + else + { + // Fixed colour addition + DrawTilePtr = DrawTile16FixedAdd1_2; + DrawClippedTilePtr = DrawClippedTile16FixedAdd1_2; + } + DrawLargePixelPtr = DrawLargePixel16Add1_2; + } + else + { + DrawTilePtr = DrawTile16Add; + DrawClippedTilePtr = DrawClippedTile16Add; + DrawLargePixelPtr = DrawLargePixel16Add; + } + } + } +} + +void S9xSetupOBJ () +{ + int SmallSize; + int LargeSize; + + switch (PPU.OBJSizeSelect) + { + case 0: + SmallSize = 8; + LargeSize = 16; + break; + case 1: + SmallSize = 8; + LargeSize = 32; + break; + case 2: + SmallSize = 8; + LargeSize = 64; + break; + case 3: + SmallSize = 16; + LargeSize = 32; + break; + case 4: + SmallSize = 16; + LargeSize = 64; + break; + case 5: + default: + SmallSize = 32; + LargeSize = 64; + break; + } + + int C = 0; + + int FirstSprite = PPU.FirstSprite & 0x7f; + int S = FirstSprite; + do + { + int Size; + if (PPU.OBJ [S].Size) + Size = LargeSize; + else + Size = SmallSize; + + long VPos = PPU.OBJ [S].VPos; + + if (VPos >= PPU.ScreenHeight) + VPos -= 256; + if (PPU.OBJ [S].HPos < 256 && PPU.OBJ [S].HPos > -Size && + VPos < PPU.ScreenHeight && VPos > -Size) + { + GFX.OBJList [C++] = S; + GFX.Sizes[S] = Size; + GFX.VPositions[S] = VPos; + } + S = (S + 1) & 0x7f; + } while (S != FirstSprite); + + // Terminate the list + GFX.OBJList [C] = -1; + IPPU.OBJChanged = FALSE; +} + +void DrawOBJS (bool8_32 OnMain = FALSE, uint8 D = 0) +{ + uint32 O; + uint32 BaseTile, Tile; + + CHECK_SOUND(); + + BG.BitShift = 4; + BG.TileShift = 5; + BG.TileAddress = PPU.OBJNameBase; + BG.StartPalette = 128; + BG.PaletteShift = 4; + BG.PaletteMask = 7; + BG.Buffer = IPPU.TileCache [TILE_4BIT]; + BG.Buffered = IPPU.TileCached [TILE_4BIT]; + BG.NameSelect = PPU.OBJNameSelect; + BG.DirectColourMode = FALSE; + + GFX.PixSize = 1; + + GFX.Z1 = D + 2; + + int I = 0; + for (int S = GFX.OBJList [I++]; S >= 0; S = GFX.OBJList [I++]) + { + int VPos = GFX.VPositions [S]; + int Size = GFX.Sizes[S]; + int TileInc = 1; + int Offset; + + if (VPos + Size <= (int) GFX.StartY || VPos > (int) GFX.EndY) + continue; + + if (OnMain && SUB_OR_ADD(4)) + { + SelectTileRenderer (!GFX.Pseudo && PPU.OBJ [S].Palette < 4); + } + + BaseTile = PPU.OBJ[S].Name | (PPU.OBJ[S].Palette << 10); + + if (PPU.OBJ[S].HFlip) + { + BaseTile += ((Size >> 3) - 1) | H_FLIP; + TileInc = -1; + } + if (PPU.OBJ[S].VFlip) + BaseTile |= V_FLIP; + + int clipcount = GFX.pCurrentClip->Count [4]; + if (!clipcount) + clipcount = 1; + + GFX.Z2 = (PPU.OBJ[S].Priority + 1) * 4 + D; + + for (int clip = 0; clip < clipcount; clip++) + { + int Left; + int Right; + if (!GFX.pCurrentClip->Count [4]) + { + Left = 0; + Right = 256; + } + else + { + Left = GFX.pCurrentClip->Left [clip][4]; + Right = GFX.pCurrentClip->Right [clip][4]; + } + + if (Right <= Left || PPU.OBJ[S].HPos + Size <= Left || + PPU.OBJ[S].HPos >= Right) + continue; + + for (int Y = 0; Y < Size; Y += 8) + { + if (VPos + Y + 7 >= (int) GFX.StartY && VPos + Y <= (int) GFX.EndY) + { + int StartLine; + int TileLine; + int LineCount; + int Last; + + if ((StartLine = VPos + Y) < (int) GFX.StartY) + { + StartLine = GFX.StartY - StartLine; + LineCount = 8 - StartLine; + } + else + { + StartLine = 0; + LineCount = 8; + } + if ((Last = VPos + Y + 7 - GFX.EndY) > 0) + if ((LineCount -= Last) <= 0) + break; + + TileLine = StartLine << 3; + O = (VPos + Y + StartLine) * GFX.PPL; + if (!PPU.OBJ[S].VFlip) + Tile = BaseTile + (Y << 1); + else + Tile = BaseTile + ((Size - Y - 8) << 1); + + int Middle = Size >> 3; + if (PPU.OBJ[S].HPos < Left) + { + Tile += ((Left - PPU.OBJ[S].HPos) >> 3) * TileInc; + Middle -= (Left - PPU.OBJ[S].HPos) >> 3; + O += Left * GFX.PixSize; + if ((Offset = (Left - PPU.OBJ[S].HPos) & 7)) + { + O -= Offset * GFX.PixSize; + int W = 8 - Offset; + int Width = Right - Left; + if (W > Width) + W = Width; + (*DrawClippedTilePtr) (Tile, O, Offset, W, + TileLine, LineCount, &GFX); + + if (W >= Width) + continue; + Tile += TileInc; + Middle--; + O += 8 * GFX.PixSize; + } + } + else + O += PPU.OBJ[S].HPos * GFX.PixSize; + + if (PPU.OBJ[S].HPos + Size >= Right) + { + Middle -= ((PPU.OBJ[S].HPos + Size + 7) - + Right) >> 3; + Offset = (Right - (PPU.OBJ[S].HPos + Size)) & 7; + } + else + Offset = 0; + + for (int X = 0; X < Middle; X++, O += 8 * GFX.PixSize, + Tile += TileInc) + { + (*DrawTilePtr) (Tile, O, TileLine, LineCount, &GFX); + } + if (Offset) + { + (*DrawClippedTilePtr) (Tile, O, 0, Offset, + TileLine, LineCount, &GFX); + } + } + } + } + } +} + +void DrawBackgroundMosaic (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2) +{ + CHECK_SOUND(); + + uint32 Tile; + uint16 *SC0; + uint16 *SC1; + uint16 *SC2; + uint16 *SC3; + uint8 depths [2] = {Z1, Z2}; + + if (BGMode == 0) + BG.StartPalette = bg << 5; + else + BG.StartPalette = 0; + + SC0 = (uint16 *) &Memory.VRAM[PPU.BG[bg].SCBase << 1]; + + if (PPU.BG[bg].SCSize & 1) + SC1 = SC0 + 1024; + else + SC1 = SC0; + + if (PPU.BG[bg].SCSize & 2) + SC2 = SC1 + 1024; + else + SC2 = SC0; + + if (PPU.BG[bg].SCSize & 1) + SC3 = SC2 + 1024; + else + SC3 = SC2; + + uint32 Lines; + uint32 OffsetMask; + uint32 OffsetShift; + + if (BG.TileSize == 16) + { + OffsetMask = 0x3ff; + OffsetShift = 4; + } + else + { + OffsetMask = 0x1ff; + OffsetShift = 3; + } + + for (uint32 Y = GFX.StartY; Y <= GFX.EndY; Y += Lines) + { + uint32 VOffset = LineData [Y].BG[bg].VOffset; + uint32 HOffset = LineData [Y].BG[bg].HOffset; + uint32 MosaicOffset = Y % PPU.Mosaic; + + for (Lines = 1; Lines < PPU.Mosaic - MosaicOffset; Lines++) + if ((VOffset != LineData [Y + Lines].BG[bg].VOffset) || + (HOffset != LineData [Y + Lines].BG[bg].HOffset)) + break; + + uint32 MosaicLine = VOffset + Y - MosaicOffset; + + if (Y + Lines > GFX.EndY) + Lines = GFX.EndY + 1 - Y; + uint32 VirtAlign = (MosaicLine & 7) << 3; + + uint16 *b1; + uint16 *b2; + + uint32 ScreenLine = MosaicLine >> OffsetShift; + uint32 Rem16 = MosaicLine & 15; + + if (ScreenLine & 0x20) + b1 = SC2, b2 = SC3; + else + b1 = SC0, b2 = SC1; + + b1 += (ScreenLine & 0x1f) << 5; + b2 += (ScreenLine & 0x1f) << 5; + uint16 *t; + uint32 Left = 0; + uint32 Right = 256; + + uint32 ClipCount = GFX.pCurrentClip->Count [bg]; + uint32 HPos = HOffset; + uint32 PixWidth = PPU.Mosaic; + + if (!ClipCount) + ClipCount = 1; + + for (uint32 clip = 0; clip < ClipCount; clip++) + { + if (GFX.pCurrentClip->Count [bg]) + { + Left = GFX.pCurrentClip->Left [clip][bg]; + Right = GFX.pCurrentClip->Right [clip][bg]; + uint32 r = Left % PPU.Mosaic; + HPos = HOffset + Left; + PixWidth = PPU.Mosaic - r; + } + uint32 s = Y * GFX.PPL + Left * GFX.PixSize; + for (uint32 x = Left; x < Right; x += PixWidth, + s += PixWidth * GFX.PixSize, + HPos += PixWidth, PixWidth = PPU.Mosaic) + { + uint32 Quot = (HPos & OffsetMask) >> 3; + + if (x + PixWidth >= Right) + PixWidth = Right - x; + + if (BG.TileSize == 8) + { + if (Quot > 31) + t = b2 + (Quot & 0x1f); + else + t = b1 + Quot; + } + else + { + if (Quot > 63) + t = b2 + ((Quot >> 1) & 0x1f); + else + t = b1 + (Quot >> 1); + } + + Tile = READ_2BYTES (t); + GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13]; + + // Draw tile... + if (BG.TileSize != 8) + { + if (Tile & H_FLIP) + { + // Horizontal flip, but what about vertical flip ? + if (Tile & V_FLIP) + { + // Both horzontal & vertical flip + if (Rem16 < 8) + { + (*DrawLargePixelPtr) (Tile + 17 - (Quot & 1), s, + HPos & 7, PixWidth, + VirtAlign, Lines, &GFX); + } + else + { + (*DrawLargePixelPtr) (Tile + 1 - (Quot & 1), s, + HPos & 7, PixWidth, + VirtAlign, Lines, &GFX); + } + } + else + { + // Horizontal flip only + if (Rem16 > 7) + { + (*DrawLargePixelPtr) (Tile + 17 - (Quot & 1), s, + HPos & 7, PixWidth, + VirtAlign, Lines, &GFX); + } + else + { + (*DrawLargePixelPtr) (Tile + 1 - (Quot & 1), s, + HPos & 7, PixWidth, + VirtAlign, Lines, &GFX); + } + } + } + else + { + // No horizontal flip, but is there a vertical flip ? + if (Tile & V_FLIP) + { + // Vertical flip only + if (Rem16 < 8) + { + (*DrawLargePixelPtr) (Tile + 16 + (Quot & 1), s, + HPos & 7, PixWidth, + VirtAlign, Lines, &GFX); + } + else + { + (*DrawLargePixelPtr) (Tile + (Quot & 1), s, + HPos & 7, PixWidth, + VirtAlign, Lines, &GFX); + } + } + else + { + // Normal unflipped + if (Rem16 > 7) + { + (*DrawLargePixelPtr) (Tile + 16 + (Quot & 1), s, + HPos & 7, PixWidth, + VirtAlign, Lines, &GFX); + } + else + { + (*DrawLargePixelPtr) (Tile + (Quot & 1), s, + HPos & 7, PixWidth, + VirtAlign, Lines, &GFX); + } + } + } + } + else + (*DrawLargePixelPtr) (Tile, s, HPos & 7, PixWidth, + VirtAlign, Lines, &GFX); + } + } + } +} + +void DrawBackgroundOffset (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2) +{ + CHECK_SOUND(); + + uint32 Tile; + uint16 *SC0; + uint16 *SC1; + uint16 *SC2; + uint16 *SC3; + uint16 *BPS0; + uint16 *BPS1; + uint16 *BPS2; + uint16 *BPS3; + uint32 Width; + int VOffsetOffset = BGMode == 4 ? 0 : 32; + uint8 depths [2] = {Z1, Z2}; + + BG.StartPalette = 0; + + BPS0 = (uint16 *) &Memory.VRAM[PPU.BG[2].SCBase << 1]; + + if (PPU.BG[2].SCSize & 1) + BPS1 = BPS0 + 1024; + else + BPS1 = BPS0; + + if (PPU.BG[2].SCSize & 2) + BPS2 = BPS1 + 1024; + else + BPS2 = BPS0; + + if (PPU.BG[2].SCSize & 1) + BPS3 = BPS2 + 1024; + else + BPS3 = BPS2; + + SC0 = (uint16 *) &Memory.VRAM[PPU.BG[bg].SCBase << 1]; + + if (PPU.BG[bg].SCSize & 1) + SC1 = SC0 + 1024; + else + SC1 = SC0; + + if (PPU.BG[bg].SCSize & 2) + SC2 = SC1 + 1024; + else + SC2 = SC0; + if (PPU.BG[bg].SCSize & 1) + SC3 = SC2 + 1024; + else + SC3 = SC2; + + static const int Lines = 1; + int OffsetMask; + int OffsetShift; + int OffsetEnableMask = 1 << (bg + 13); + + if (BG.TileSize == 16) + { + OffsetMask = 0x3ff; + OffsetShift = 4; + } + else + { + OffsetMask = 0x1ff; + OffsetShift = 3; + } + + for (uint32 Y = GFX.StartY; Y <= GFX.EndY; Y++) + { + uint32 VOff = LineData [Y].BG[2].VOffset; + uint32 HOff = LineData [Y].BG[2].HOffset; + int VirtAlign; + int ScreenLine = VOff >> 3; + int t1; + int t2; + uint16 *s0; + uint16 *s1; + uint16 *s2; + + if (ScreenLine & 0x20) + s1 = BPS2, s2 = BPS3; + else + s1 = BPS0, s2 = BPS1; + + s1 += (ScreenLine & 0x1f) << 5; + s2 += (ScreenLine & 0x1f) << 5; + + int clipcount = GFX.pCurrentClip->Count [bg]; + if (!clipcount) + clipcount = 1; + + for (int clip = 0; clip < clipcount; clip++) + { + uint32 Left; + uint32 Right; + + if (!GFX.pCurrentClip->Count [bg]) + { + Left = 0; + Right = 256; + } + else + { + Left = GFX.pCurrentClip->Left [clip][bg]; + Right = GFX.pCurrentClip->Right [clip][bg]; + + if (Right <= Left) + continue; + } + + uint32 VOffset; + uint32 HOffset; + uint32 LineHOffset=LineData [Y].BG[bg].HOffset; + uint32 Offset; + uint32 HPos; + uint32 Quot; + uint32 Count; + uint16 *t; + uint32 Quot2; + uint32 VCellOffset; + uint32 HCellOffset; + uint16 *b1; + uint16 *b2; + uint32 TotalCount = 0; + uint32 MaxCount = 8; + + uint32 s = Left * GFX.PixSize + Y * GFX.PPL; + bool8_32 left_hand_edge = (Left == 0); + Width = Right - Left; + + if (Left & 7) + MaxCount = 8 - (Left & 7); + + while (Left < Right) + { + if (left_hand_edge) + { + // The SNES offset-per-tile background mode has a + // hardware limitation that the offsets cannot be set + // for the tile at the left-hand edge of the screen. + VOffset = LineData [Y].BG[bg].VOffset; + HOffset = LineHOffset; + left_hand_edge = FALSE; + } + else + { + // All subsequent offset tile data is shifted left by one, + // hence the - 1 below. + Quot2 = ((HOff + Left - 1) & OffsetMask) >> 3; + + if (Quot2 > 31) + s0 = s2 + (Quot2 & 0x1f); + else + s0 = s1 + Quot2; + + HCellOffset = READ_2BYTES (s0); + + if (BGMode == 4) + { + VOffset = LineData [Y].BG[bg].VOffset; + HOffset=LineHOffset; + if ((HCellOffset & OffsetEnableMask)) + { + if (HCellOffset & 0x8000) + VOffset = HCellOffset + 1; + else + HOffset = HCellOffset; + } + } + else + { + VCellOffset = READ_2BYTES (s0 + VOffsetOffset); + if ((VCellOffset & OffsetEnableMask)) + VOffset = VCellOffset + 1; + else + VOffset = LineData [Y].BG[bg].VOffset; + + if ((HCellOffset & OffsetEnableMask)) + HOffset = (HCellOffset & ~7)|(LineHOffset&7); + else + HOffset=LineHOffset; + } + } + VirtAlign = ((Y + VOffset) & 7) << 3; + ScreenLine = (VOffset + Y) >> OffsetShift; + + if (((VOffset + Y) & 15) > 7) + { + t1 = 16; + t2 = 0; + } + else + { + t1 = 0; + t2 = 16; + } + + if (ScreenLine & 0x20) + b1 = SC2, b2 = SC3; + else + b1 = SC0, b2 = SC1; + + b1 += (ScreenLine & 0x1f) << 5; + b2 += (ScreenLine & 0x1f) << 5; + + HPos = (HOffset + Left) & OffsetMask; + + Quot = HPos >> 3; + + if (BG.TileSize == 8) + { + if (Quot > 31) + t = b2 + (Quot & 0x1f); + else + t = b1 + Quot; + } + else + { + if (Quot > 63) + t = b2 + ((Quot >> 1) & 0x1f); + else + t = b1 + (Quot >> 1); + } + + if (MaxCount + TotalCount > Width) + MaxCount = Width - TotalCount; + + Offset = HPos & 7; + + Count = 8 - Offset; + if (Count > MaxCount) + Count = MaxCount; + + s -= Offset * GFX.PixSize; + Tile = READ_2BYTES(t); + GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13]; + + if (BG.TileSize == 8) + (*DrawClippedTilePtr) (Tile, s, Offset, Count, VirtAlign, Lines, &GFX); + else + { + if (!(Tile & (V_FLIP | H_FLIP))) + { + // Normal, unflipped + (*DrawClippedTilePtr) (Tile + t1 + (Quot & 1), + s, Offset, Count, VirtAlign, Lines, &GFX); + } + else + if (Tile & H_FLIP) + { + if (Tile & V_FLIP) + { + // H & V flip + (*DrawClippedTilePtr) (Tile + t2 + 1 - (Quot & 1), + s, Offset, Count, VirtAlign, Lines, &GFX); + } + else + { + // H flip only + (*DrawClippedTilePtr) (Tile + t1 + 1 - (Quot & 1), + s, Offset, Count, VirtAlign, Lines, &GFX); + } + } + else + { + // V flip only + (*DrawClippedTilePtr) (Tile + t2 + (Quot & 1), + s, Offset, Count, VirtAlign, Lines, &GFX); + } + } + + Left += Count; + TotalCount += Count; + s += (Offset + Count) * GFX.PixSize; + MaxCount = 8; + } + } + } +} + +void DrawBackgroundMode5 (uint32 /* BGMODE */, uint32 bg, uint8 Z1, uint8 Z2) +{ + CHECK_SOUND(); + + GFX.Pitch = GFX.RealPitch; + GFX.PPL = GFX.PPLx2 >> 1; + GFX.PixSize = 1; + uint8 depths [2] = {Z1, Z2}; + + uint32 Tile; + uint16 *SC0; + uint16 *SC1; + uint16 *SC2; + uint16 *SC3; + uint32 Width; + + BG.StartPalette = 0; + + SC0 = (uint16 *) &Memory.VRAM[PPU.BG[bg].SCBase << 1]; + + if ((PPU.BG[bg].SCSize & 1)) + SC1 = SC0 + 1024; + else + SC1 = SC0; + + if ((PPU.BG[bg].SCSize & 2)) + SC2 = SC1 + 1024; + else + SC2 = SC0; + + if ((PPU.BG[bg].SCSize & 1)) + SC3 = SC2 + 1024; + else + SC3 = SC2; + + int Lines; + int VOffsetMask; + int VOffsetShift; + + if (BG.TileSize == 16) + { + VOffsetMask = 0x3ff; + VOffsetShift = 4; + } + else + { + VOffsetMask = 0x1ff; + VOffsetShift = 3; + } + int endy = GFX.EndY; + + for (int Y = GFX.StartY; Y <= endy; Y += Lines) + { + int y = Y; + uint32 VOffset = LineData [y].BG[bg].VOffset; + uint32 HOffset = LineData [y].BG[bg].HOffset; + int VirtAlign = (Y + VOffset) & 7; + + for (Lines = 1; Lines < 8 - VirtAlign; Lines++) + if ((VOffset != LineData [y + Lines].BG[bg].VOffset) || + (HOffset != LineData [y + Lines].BG[bg].HOffset)) + break; + + HOffset <<= 1; + if (Y + Lines > endy) + Lines = endy + 1 - Y; + + int ScreenLine = (VOffset + Y) >> VOffsetShift; + int t1; + int t2; + if (((VOffset + Y) & 15) > 7) + { + t1 = 16; + t2 = 0; + } + else + { + t1 = 0; + t2 = 16; + } + uint16 *b1; + uint16 *b2; + + if (ScreenLine & 0x20) + b1 = SC2, b2 = SC3; + else + b1 = SC0, b2 = SC1; + + b1 += (ScreenLine & 0x1f) << 5; + b2 += (ScreenLine & 0x1f) << 5; + + int clipcount = GFX.pCurrentClip->Count [bg]; + if (!clipcount) + clipcount = 1; + for (int clip = 0; clip < clipcount; clip++) + { + int Left; + int Right; + + if (!GFX.pCurrentClip->Count [bg]) + { + Left = 0; + Right = 512; + } + else + { + Left = GFX.pCurrentClip->Left [clip][bg] * 2; + Right = GFX.pCurrentClip->Right [clip][bg] * 2; + + if (Right <= Left) + continue; + } + + uint32 s = (Left>>1) * GFX.PixSize + Y * GFX.PPL; + uint32 HPos = (HOffset + Left * GFX.PixSize) & 0x3ff; + + uint32 Quot = HPos >> 3; + uint32 Count = 0; + + uint16 *t; + if (Quot > 63) + t = b2 + ((Quot >> 1) & 0x1f); + else + t = b1 + (Quot >> 1); + + Width = Right - Left; + // Left hand edge clipped tile + if (HPos & 7) + { + int Offset = (HPos & 7); + Count = 8 - Offset; + if (Count > Width) + Count = Width; + s -= (Offset>>1); + Tile = READ_2BYTES (t); + GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13]; + + if (BG.TileSize == 8) + { + if (!(Tile & H_FLIP)) + { + // Normal, unflipped + (*DrawHiResClippedTilePtr) (Tile + (Quot & 1), + s, Offset, Count, VirtAlign, Lines, &GFX); + } + else + { + // H flip + (*DrawHiResClippedTilePtr) (Tile + 1 - (Quot & 1), + s, Offset, Count, VirtAlign, Lines, &GFX); + } + } + else + { + if (!(Tile & (V_FLIP | H_FLIP))) + { + // Normal, unflipped + (*DrawHiResClippedTilePtr) (Tile + t1 + (Quot & 1), + s, Offset, Count, VirtAlign, Lines, &GFX); + } + else + if (Tile & H_FLIP) + { + if (Tile & V_FLIP) + { + // H & V flip + (*DrawHiResClippedTilePtr) (Tile + t2 + 1 - (Quot & 1), + s, Offset, Count, VirtAlign, Lines, &GFX); + } + else + { + // H flip only + (*DrawHiResClippedTilePtr) (Tile + t1 + 1 - (Quot & 1), + s, Offset, Count, VirtAlign, Lines, &GFX); + } + } + else + { + // V flip only + (*DrawHiResClippedTilePtr) (Tile + t2 + (Quot & 1), + s, Offset, Count, VirtAlign, Lines, &GFX); + } + } + + t += Quot & 1; + if (Quot == 63) + t = b2; + else if (Quot == 127) + t = b1; + Quot++; + s += 4; + } + + // Middle, unclipped tiles + Count = Width - Count; + int Middle = Count >> 3; + Count &= 7; + for (int C = Middle; C > 0; s += 4, Quot++, C--) + { + Tile = READ_2BYTES(t); + GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13]; + if (BG.TileSize == 8) + { + if (!(Tile & H_FLIP)) + { + // Normal, unflipped + (*DrawHiResTilePtr) (Tile + (Quot & 1), + s, VirtAlign, Lines, &GFX); + } + else + { + // H flip + (*DrawHiResTilePtr) (Tile + 1 - (Quot & 1), + s, VirtAlign, Lines, &GFX); + } + } + else + { + if (!(Tile & (V_FLIP | H_FLIP))) + { + // Normal, unflipped + (*DrawHiResTilePtr) (Tile + t1 + (Quot & 1), + s, VirtAlign, Lines, &GFX); + } + else + if (Tile & H_FLIP) + { + if (Tile & V_FLIP) + { + // H & V flip + (*DrawHiResTilePtr) (Tile + t2 + 1 - (Quot & 1), + s, VirtAlign, Lines, &GFX); + } + else + { + // H flip only + (*DrawHiResTilePtr) (Tile + t1 + 1 - (Quot & 1), + s, VirtAlign, Lines, &GFX); + } + } + else + { + // V flip only + (*DrawHiResTilePtr) (Tile + t2 + (Quot & 1), + s, VirtAlign, Lines, &GFX); + } + } + + t += Quot & 1; + if (Quot == 63) + t = b2; + else + if (Quot == 127) + t = b1; + } + + // Right-hand edge clipped tiles + if (Count) + { + Tile = READ_2BYTES(t); + GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13]; + if (BG.TileSize == 8) + { + if (!(Tile & H_FLIP)) + { + // Normal, unflipped + (*DrawHiResClippedTilePtr) (Tile + (Quot & 1), + s, 0, Count, VirtAlign, Lines, &GFX); + } + else + { + // H flip + (*DrawHiResClippedTilePtr) (Tile + 1 - (Quot & 1), + s, 0, Count, VirtAlign, Lines, &GFX); + } + } + else + { + if (!(Tile & (V_FLIP | H_FLIP))) + { + // Normal, unflipped + (*DrawHiResClippedTilePtr) (Tile + t1 + (Quot & 1), + s, 0, Count, VirtAlign, Lines, &GFX); + } + else + if (Tile & H_FLIP) + { + if (Tile & V_FLIP) + { + // H & V flip + (*DrawHiResClippedTilePtr) (Tile + t2 + 1 - (Quot & 1), + s, 0, Count, VirtAlign, Lines, &GFX); + } + else + { + // H flip only + (*DrawHiResClippedTilePtr) (Tile + t1 + 1 - (Quot & 1), + s, 0, Count, VirtAlign, Lines, &GFX); + } + } + else + { + // V flip only + (*DrawHiResClippedTilePtr) (Tile + t2 + (Quot & 1), + s, 0, Count, VirtAlign, Lines, &GFX); + } + } + } + } + } +} + +void DrawBackground (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2) +{ + GFX.PixSize = 1; + + BG.TileSize = BGSizes [PPU.BG[bg].BGSize]; + BG.BitShift = BitShifts[BGMode][bg]; + BG.TileShift = TileShifts[BGMode][bg]; + BG.TileAddress = PPU.BG[bg].NameBase << 1; + BG.NameSelect = 0; + BG.Buffer = IPPU.TileCache [Depths [BGMode][bg]]; + BG.Buffered = IPPU.TileCached [Depths [BGMode][bg]]; + BG.PaletteShift = PaletteShifts[BGMode][bg]; + BG.PaletteMask = PaletteMasks[BGMode][bg]; + BG.DirectColourMode = (BGMode == 3 || BGMode == 4) && bg == 0 && + (GFX.r2130 & 1); + + if (PPU.BGMosaic [bg] && PPU.Mosaic > 1) + { + DrawBackgroundMosaic (BGMode, bg, Z1, Z2); + return; + + } + switch (BGMode) + { + case 2: + if (Settings.WrestlemaniaArcade) + break; + case 4: // Used by Puzzle Bobble + DrawBackgroundOffset (BGMode, bg, Z1, Z2); + return; + + case 5: + case 6: // XXX: is also offset per tile. + DrawBackgroundMode5 (BGMode, bg, Z1, Z2); + return; + } + + + + + + CHECK_SOUND(); + + uint32 Tile; + uint16 *SC0; + uint16 *SC1; + uint16 *SC2; + uint16 *SC3; + uint32 Width; + uint8 depths [2] = {Z1, Z2}; + + if (BGMode == 0) + BG.StartPalette = bg << 5; + else + BG.StartPalette = 0; + + SC0 = (uint16 *) &Memory.VRAM[PPU.BG[bg].SCBase << 1]; + + if (PPU.BG[bg].SCSize & 1) + SC1 = SC0 + 1024; + else + SC1 = SC0; + + if (PPU.BG[bg].SCSize & 2) + SC2 = SC1 + 1024; + else + SC2 = SC0; + + if (PPU.BG[bg].SCSize & 1) + SC3 = SC2 + 1024; + else + SC3 = SC2; + + int Lines; + int OffsetMask; + int OffsetShift; + + if (BG.TileSize == 16) + { + OffsetMask = 0x3ff; + OffsetShift = 4; + } + else + { + OffsetMask = 0x1ff; + OffsetShift = 3; + } + + for (uint32 Y = GFX.StartY; Y <= GFX.EndY; Y += Lines) + { + uint32 VOffset = LineData [Y].BG[bg].VOffset; + uint32 HOffset = LineData [Y].BG[bg].HOffset; + int VirtAlign = (Y + VOffset) & 7; + + for (Lines = 1; Lines < 8 - VirtAlign; Lines++) + if ((VOffset != LineData [Y + Lines].BG[bg].VOffset) || + (HOffset != LineData [Y + Lines].BG[bg].HOffset)) + break; + + if (Y + Lines > GFX.EndY) + Lines = GFX.EndY + 1 - Y; + + VirtAlign <<= 3; + + uint32 ScreenLine = (VOffset + Y) >> OffsetShift; + uint32 t1; + uint32 t2; + if (((VOffset + Y) & 15) > 7) + { + t1 = 16; + t2 = 0; + } + else + { + t1 = 0; + t2 = 16; + } + uint16 *b1; + uint16 *b2; + + if (ScreenLine & 0x20) + b1 = SC2, b2 = SC3; + else + b1 = SC0, b2 = SC1; + + b1 += (ScreenLine & 0x1f) << 5; + b2 += (ScreenLine & 0x1f) << 5; + + int clipcount = GFX.pCurrentClip->Count [bg]; + if (!clipcount) + clipcount = 1; + for (int clip = 0; clip < clipcount; clip++) + { + uint32 Left; + uint32 Right; + + if (!GFX.pCurrentClip->Count [bg]) + { + Left = 0; + Right = 256; + } + else + { + Left = GFX.pCurrentClip->Left [clip][bg]; + Right = GFX.pCurrentClip->Right [clip][bg]; + + if (Right <= Left) + continue; + } + + uint32 s = Left * GFX.PixSize + Y * GFX.PPL; + uint32 HPos = (HOffset + Left) & OffsetMask; + + uint32 Quot = HPos >> 3; + uint32 Count = 0; + + uint16 *t; + if (BG.TileSize == 8) + { + if (Quot > 31) + t = b2 + (Quot & 0x1f); + else + t = b1 + Quot; + } + else + { + if (Quot > 63) + t = b2 + ((Quot >> 1) & 0x1f); + else + t = b1 + (Quot >> 1); + } + + Width = Right - Left; + // Left hand edge clipped tile + if (HPos & 7) + { + uint32 Offset = (HPos & 7); + Count = 8 - Offset; + if (Count > Width) + Count = Width; + s -= Offset * GFX.PixSize; + Tile = READ_2BYTES(t); + GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13]; + + if (BG.TileSize == 8) + { + (*DrawClippedTilePtr) (Tile, s, Offset, Count, VirtAlign, + Lines, &GFX); + } + else + { + if (!(Tile & (V_FLIP | H_FLIP))) + { + // Normal, unflipped + (*DrawClippedTilePtr) (Tile + t1 + (Quot & 1), + s, Offset, Count, VirtAlign, Lines, &GFX); + } + else + if (Tile & H_FLIP) + { + if (Tile & V_FLIP) + { + // H & V flip + (*DrawClippedTilePtr) (Tile + t2 + 1 - (Quot & 1), + s, Offset, Count, VirtAlign, Lines, &GFX); + } + else + { + // H flip only + (*DrawClippedTilePtr) (Tile + t1 + 1 - (Quot & 1), + s, Offset, Count, VirtAlign, Lines, &GFX); + } + } + else + { + // V flip only + (*DrawClippedTilePtr) (Tile + t2 + (Quot & 1), s, + Offset, Count, VirtAlign, Lines, &GFX); + } + } + + if (BG.TileSize == 8) + { + t++; + if (Quot == 31) + t = b2; + else if (Quot == 63) + t = b1; + } + else + { + t += Quot & 1; + if (Quot == 63) + t = b2; + else if (Quot == 127) + t = b1; + } + Quot++; + s += 8 * GFX.PixSize; + } + + // Middle, unclipped tiles + Count = Width - Count; + int Middle = Count >> 3; + Count &= 7; + for (int C = Middle; C > 0; s += 8 * GFX.PixSize, Quot++, C--) + { + Tile = READ_2BYTES(t); + GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13]; + + if (BG.TileSize != 8) + { + if (Tile & H_FLIP) + { + // Horizontal flip, but what about vertical flip ? + if (Tile & V_FLIP) + { + // Both horzontal & vertical flip + (*DrawTilePtr) (Tile + t2 + 1 - (Quot & 1), s, + VirtAlign, Lines, &GFX); + } + else + { + // Horizontal flip only + (*DrawTilePtr) (Tile + t1 + 1 - (Quot & 1), s, + VirtAlign, Lines, &GFX); + } + } + else + { + // No horizontal flip, but is there a vertical flip ? + if (Tile & V_FLIP) + { + // Vertical flip only + (*DrawTilePtr) (Tile + t2 + (Quot & 1), s, + VirtAlign, Lines, &GFX); + } + else + { + // Normal unflipped + (*DrawTilePtr) (Tile + t1 + (Quot & 1), s, + VirtAlign, Lines, &GFX); + } + } + } + else + { + (*DrawTilePtr) (Tile, s, VirtAlign, Lines, &GFX); + } + + if (BG.TileSize == 8) + { + t++; + if (Quot == 31) + t = b2; + else + if (Quot == 63) + t = b1; + } + else + { + t += Quot & 1; + if (Quot == 63) + t = b2; + else + if (Quot == 127) + t = b1; + } + } + // Right-hand edge clipped tiles + if (Count) + { + Tile = READ_2BYTES(t); + GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13]; + + if (BG.TileSize == 8) + (*DrawClippedTilePtr) (Tile, s, 0, Count, VirtAlign, + Lines, &GFX); + else + { + if (!(Tile & (V_FLIP | H_FLIP))) + { + // Normal, unflipped + (*DrawClippedTilePtr) (Tile + t1 + (Quot & 1), s, 0, + Count, VirtAlign, Lines, &GFX); + } + else + if (Tile & H_FLIP) + { + if (Tile & V_FLIP) + { + // H & V flip + (*DrawClippedTilePtr) (Tile + t2 + 1 - (Quot & 1), + s, 0, Count, VirtAlign, + Lines, &GFX); + } + else + { + // H flip only + (*DrawClippedTilePtr) (Tile + t1 + 1 - (Quot & 1), + s, 0, Count, VirtAlign, + Lines, &GFX); + } + } + else + { + // V flip only + (*DrawClippedTilePtr) (Tile + t2 + (Quot & 1), + s, 0, Count, VirtAlign, + Lines, &GFX); + } + } + } + } + } +} + +#define RENDER_BACKGROUND_MODE7(TYPE,FUNC) \ + CHECK_SOUND(); \ +\ + uint8 *VRAM1 = Memory.VRAM + 1; \ + if (GFX.r2130 & 1) \ + { \ + if (IPPU.DirectColourMapsNeedRebuild) \ + S9xBuildDirectColourMaps (); \ + GFX.ScreenColors = DirectColourMaps [0]; \ + } \ + else \ + GFX.ScreenColors = IPPU.ScreenColors; \ +\ + int aa, cc; \ + int dir; \ + int startx, endx; \ + uint32 Left = 0; \ + uint32 Right = 256; \ + uint32 ClipCount = GFX.pCurrentClip->Count [bg]; \ +\ + if (!ClipCount) \ + ClipCount = 1; \ +\ + Screen += GFX.StartY * GFX.Pitch; \ + uint8 *Depth = GFX.DB + GFX.StartY * GFX.PPL; \ + struct SLineMatrixData *l = &LineMatrixData [GFX.StartY]; \ +\ + for (uint32 Line = GFX.StartY; Line <= GFX.EndY; Line++, Screen += GFX.Pitch, Depth += GFX.PPL, l++) \ + { \ + int yy; \ +\ + int32 HOffset = ((int32) LineData [Line].BG[0].HOffset << M7) >> M7; \ + int32 VOffset = ((int32) LineData [Line].BG[0].VOffset << M7) >> M7; \ +\ + int32 CentreX = ((int32) l->CentreX << M7) >> M7; \ + int32 CentreY = ((int32) l->CentreY << M7) >> M7; \ +\ + if (PPU.Mode7VFlip) \ + yy = 261 - (int) Line; \ + else \ + yy = Line; \ +\ + if (PPU.Mode7Repeat == 0) \ + yy += (VOffset - CentreY) % 1023; \ + else \ + yy += VOffset - CentreY; \ + int BB = l->MatrixB * yy + (CentreX << 8); \ + int DD = l->MatrixD * yy + (CentreY << 8); \ +\ + for (uint32 clip = 0; clip < ClipCount; clip++) \ + { \ + if (GFX.pCurrentClip->Count [bg]) \ + { \ + Left = GFX.pCurrentClip->Left [clip][bg]; \ + Right = GFX.pCurrentClip->Right [clip][bg]; \ + if (Right <= Left) \ + continue; \ + } \ + TYPE *p = (TYPE *) Screen + Left; \ + uint8 *d = Depth + Left; \ +\ + if (PPU.Mode7HFlip) \ + { \ + startx = Right - 1; \ + endx = Left - 1; \ + dir = -1; \ + aa = -l->MatrixA; \ + cc = -l->MatrixC; \ + } \ + else \ + { \ + startx = Left; \ + endx = Right; \ + dir = 1; \ + aa = l->MatrixA; \ + cc = l->MatrixC; \ + } \ + int xx; \ + if (PPU.Mode7Repeat == 0) \ + xx = startx + (HOffset - CentreX) % 1023; \ + else \ + xx = startx + HOffset - CentreX; \ + int AA = l->MatrixA * xx; \ + int CC = l->MatrixC * xx; \ +\ + if (!PPU.Mode7Repeat) \ + { \ + for (int x = startx; x != endx; x += dir, AA += aa, CC += cc, p++, d++) \ + { \ + int X = ((AA + BB) >> 8) & 0x3ff; \ + int Y = ((CC + DD) >> 8) & 0x3ff; \ + uint8 *TileData = VRAM1 + (Memory.VRAM[((Y & ~7) << 5) + ((X >> 2) & ~1)] << 7); \ + uint32 b = *(TileData + ((Y & 7) << 4) + ((X & 7) << 1)); \ + GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \ + if (GFX.Z1 > *d && b) \ + { \ + *p = (FUNC); \ + *d = GFX.Z1; \ + } \ + } \ + } \ + else \ + { \ + for (int x = startx; x != endx; x += dir, AA += aa, CC += cc, p++, d++) \ + { \ + int X = ((AA + BB) >> 8); \ + int Y = ((CC + DD) >> 8); \ +\ + if (Settings.Dezaemon && PPU.Mode7Repeat == 2) \ + { \ + X &= 0x7ff; \ + Y &= 0x7ff; \ + } \ +\ + if (((X | Y) & ~0x3ff) == 0) \ + { \ + uint8 *TileData = VRAM1 + (Memory.VRAM[((Y & ~7) << 5) + ((X >> 2) & ~1)] << 7); \ + uint32 b = *(TileData + ((Y & 7) << 4) + ((X & 7) << 1)); \ + GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \ + if (GFX.Z1 > *d && b) \ + { \ + *p = (FUNC); \ + *d = GFX.Z1; \ + } \ + } \ + else \ + { \ + if (PPU.Mode7Repeat == 3) \ + { \ + X = (x + HOffset) & 7; \ + Y = (yy + CentreY) & 7; \ + uint32 b = *(VRAM1 + ((Y & 7) << 4) + ((X & 7) << 1)); \ + GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \ + if (GFX.Z1 > *d && b) \ + { \ + *p = (FUNC); \ + *d = GFX.Z1; \ + } \ + } \ + } \ + } \ + } \ + } \ + } + +void DrawBGMode7Background (uint8 *Screen, int bg) +{ + RENDER_BACKGROUND_MODE7 (uint8, (uint8) (b & GFX.Mode7Mask)) +} + +void DrawBGMode7Background16 (uint8 *Screen, int bg) +{ + RENDER_BACKGROUND_MODE7 (uint16, GFX.ScreenColors [b & GFX.Mode7Mask]); +} + +void DrawBGMode7Background16Add (uint8 *Screen, int bg) +{ + RENDER_BACKGROUND_MODE7 (uint16, *(d + GFX.DepthDelta) ? + (*(d + GFX.DepthDelta) != 1 ? + COLOR_ADD (GFX.ScreenColors [b & GFX.Mode7Mask], + p [GFX.Delta]) : + COLOR_ADD (GFX.ScreenColors [b & GFX.Mode7Mask], + GFX.FixedColour)) : + GFX.ScreenColors [b & GFX.Mode7Mask]); +} + +void DrawBGMode7Background16Add1_2 (uint8 *Screen, int bg) +{ + RENDER_BACKGROUND_MODE7 (uint16, *(d + GFX.DepthDelta) ? + (*(d + GFX.DepthDelta) != 1 ? + COLOR_ADD1_2 (GFX.ScreenColors [b & GFX.Mode7Mask], + p [GFX.Delta]) : + COLOR_ADD (GFX.ScreenColors [b & GFX.Mode7Mask], + GFX.FixedColour)) : + GFX.ScreenColors [b & GFX.Mode7Mask]); +} + +void DrawBGMode7Background16Sub (uint8 *Screen, int bg) +{ + RENDER_BACKGROUND_MODE7 (uint16, *(d + GFX.DepthDelta) ? + (*(d + GFX.DepthDelta) != 1 ? + COLOR_SUB (GFX.ScreenColors [b & GFX.Mode7Mask], + p [GFX.Delta]) : + COLOR_SUB (GFX.ScreenColors [b & GFX.Mode7Mask], + GFX.FixedColour)) : + GFX.ScreenColors [b & GFX.Mode7Mask]); +} + +void DrawBGMode7Background16Sub1_2 (uint8 *Screen, int bg) +{ + RENDER_BACKGROUND_MODE7 (uint16, *(d + GFX.DepthDelta) ? + (*(d + GFX.DepthDelta) != 1 ? + COLOR_SUB1_2 (GFX.ScreenColors [b & GFX.Mode7Mask], + p [GFX.Delta]) : + COLOR_SUB (GFX.ScreenColors [b & GFX.Mode7Mask], + GFX.FixedColour)) : + GFX.ScreenColors [b & GFX.Mode7Mask]); +} + +#define RENDER_BACKGROUND_MODE7_i(TYPE,FUNC,COLORFUNC) \ + CHECK_SOUND(); \ +\ + uint8 *VRAM1 = Memory.VRAM + 1; \ + if (GFX.r2130 & 1) \ + { \ + if (IPPU.DirectColourMapsNeedRebuild) \ + S9xBuildDirectColourMaps (); \ + GFX.ScreenColors = DirectColourMaps [0]; \ + } \ + else \ + GFX.ScreenColors = IPPU.ScreenColors; \ + \ + int aa, cc; \ + int dir; \ + int startx, endx; \ + uint32 Left = 0; \ + uint32 Right = 256; \ + uint32 ClipCount = GFX.pCurrentClip->Count [bg]; \ + \ + if (!ClipCount) \ + ClipCount = 1; \ + \ + Screen += GFX.StartY * GFX.Pitch; \ + uint8 *Depth = GFX.DB + GFX.StartY * GFX.PPL; \ + struct SLineMatrixData *l = &LineMatrixData [GFX.StartY]; \ + bool8_32 allowSimpleCase = FALSE; \ + if (!l->MatrixB && !l->MatrixC && (l->MatrixA == 0x0100) && (l->MatrixD == 0x0100) \ + && !LineMatrixData[GFX.EndY].MatrixB && !LineMatrixData[GFX.EndY].MatrixC \ + && (LineMatrixData[GFX.EndY].MatrixA == 0x0100) && (LineMatrixData[GFX.EndY].MatrixD == 0x0100) \ + ) \ + allowSimpleCase = TRUE; \ + \ + for (uint32 Line = GFX.StartY; Line <= GFX.EndY; Line++, Screen += GFX.Pitch, Depth += GFX.PPL, l++) \ + { \ + int yy; \ + \ + int HOffset = ((int) LineData [Line].BG[0].HOffset << M7) >> M7; \ + int VOffset = ((int) LineData [Line].BG[0].VOffset << M7) >> M7; \ + \ + int CentreX = ((int) l->CentreX << M7) >> M7; \ + int CentreY = ((int) l->CentreY << M7) >> M7; \ + \ + if (PPU.Mode7VFlip) \ + yy = 261 - (int) Line; \ + else \ + yy = Line; \ + \ + if (PPU.Mode7Repeat == 0) \ + yy += (VOffset - CentreY) % 1023; \ + else \ + yy += VOffset - CentreY; \ + bool8_32 simpleCase = FALSE; \ + int BB; \ + int DD; \ + /* Make a special case for the identity matrix, since it's a common case and */ \ + /* can be done much more quickly without special effects */ \ + if (allowSimpleCase && !l->MatrixB && !l->MatrixC && (l->MatrixA == 0x0100) && (l->MatrixD == 0x0100)) \ + { \ + BB = CentreX << 8; \ + DD = (yy + CentreY) << 8; \ + simpleCase = TRUE; \ + } \ + else \ + { \ + BB = l->MatrixB * yy + (CentreX << 8); \ + DD = l->MatrixD * yy + (CentreY << 8); \ + } \ + \ + for (uint32 clip = 0; clip < ClipCount; clip++) \ + { \ + if (GFX.pCurrentClip->Count [bg]) \ + { \ + Left = GFX.pCurrentClip->Left [clip][bg]; \ + Right = GFX.pCurrentClip->Right [clip][bg]; \ + if (Right <= Left) \ + continue; \ + } \ + TYPE *p = (TYPE *) Screen + Left; \ + uint8 *d = Depth + Left; \ + \ + if (PPU.Mode7HFlip) \ + { \ + startx = Right - 1; \ + endx = Left - 1; \ + dir = -1; \ + aa = -l->MatrixA; \ + cc = -l->MatrixC; \ + } \ + else \ + { \ + startx = Left; \ + endx = Right; \ + dir = 1; \ + aa = l->MatrixA; \ + cc = l->MatrixC; \ + } \ + int xx; \ + if (PPU.Mode7Repeat == 0) \ + xx = startx + (HOffset - CentreX) % 1023; \ + else \ + xx = startx + HOffset - CentreX; \ + int AA, CC = 0; \ + if (simpleCase) \ + { \ + AA = xx << 8; \ + } \ + else \ + { \ + AA = l->MatrixA * xx; \ + CC = l->MatrixC * xx; \ + } \ + if (simpleCase) \ + { \ + if (!PPU.Mode7Repeat) \ + { \ + int x = startx; \ + do \ + { \ + int X = ((AA + BB) >> 8) & 0x3ff; \ + int Y = (DD >> 8) & 0x3ff; \ + uint8 *TileData = VRAM1 + (Memory.VRAM[((Y & ~7) << 5) + ((X >> 2) & ~1)] << 7); \ + uint32 b = *(TileData + ((Y & 7) << 4) + ((X & 7) << 1)); \ + GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \ + if (GFX.Z1 > *d && b) \ + { \ + TYPE theColor = COLORFUNC; \ + *p = (FUNC) | ALPHA_BITS_MASK; \ + *d = GFX.Z1; \ + } \ + AA += aa, p++, d++; \ + x += dir; \ + } while (x != endx); \ + } \ + else \ + { \ + int x = startx; \ + do { \ + int X = (AA + BB) >> 8; \ + int Y = DD >> 8; \ +\ + if(Settings.Dezaemon && PPU.Mode7Repeat == 2) \ + { \ + X &= 0x7ff; \ + Y &= 0x7ff; \ + } \ +\ + if (((X | Y) & ~0x3ff) == 0) \ + { \ + uint8 *TileData = VRAM1 + (Memory.VRAM[((Y & ~7) << 5) + ((X >> 2) & ~1)] << 7); \ + uint32 b = *(TileData + ((Y & 7) << 4) + ((X & 7) << 1)); \ + GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \ + if (GFX.Z1 > *d && b) \ + { \ + TYPE theColor = COLORFUNC; \ + *p = (FUNC) | ALPHA_BITS_MASK; \ + *d = GFX.Z1; \ + } \ + } \ + else if (PPU.Mode7Repeat == 3) \ + { \ + X = (x + HOffset) & 7; \ + Y = (yy + CentreY) & 7; \ + uint8 *TileData = VRAM1 + (Memory.VRAM[((Y & ~7) << 5) + ((X >> 2) & ~1)] << 7); \ + uint32 b = *(TileData + ((Y & 7) << 4) + ((X & 7) << 1)); \ + GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \ + if (GFX.Z1 > *d && b) \ + { \ + TYPE theColor = COLORFUNC; \ + *p = (FUNC) | ALPHA_BITS_MASK; \ + *d = GFX.Z1; \ + } \ + } \ + AA += aa; p++; d++; \ + x += dir; \ + } while (x != endx); \ + } \ + } \ + else if (!PPU.Mode7Repeat) \ + { \ + /* The bilinear interpolator: get the colors at the four points surrounding */ \ + /* the location of one point in the _sampled_ image, and weight them according */ \ + /* to their (city block) distance. It's very smooth, but blurry with "close up" */ \ + /* points. */ \ + \ + /* 460 (slightly less than 2 source pixels per displayed pixel) is an educated */ \ + /* guess for where bilinear filtering will become a poor method for averaging. */ \ + /* (When reducing the image, the weighting used by a bilinear filter becomes */ \ + /* arbitrary, and a simple mean is a better way to represent the source image.) */ \ + /* You can think of this as a kind of mipmapping. */ \ + if ((aa < 460 && aa > -460) && (cc < 460 && cc > -460)) \ + {\ + for (int x = startx; x != endx; x += dir, AA += aa, CC += cc, p++, d++) \ + { \ + uint32 xPos = AA + BB; \ + uint32 xPix = xPos >> 8; \ + uint32 yPos = CC + DD; \ + uint32 yPix = yPos >> 8; \ + uint32 X = xPix & 0x3ff; \ + uint32 Y = yPix & 0x3ff; \ + uint8 *TileData = VRAM1 + (Memory.VRAM[((Y & ~7) << 5) + ((X >> 2) & ~1)] << 7); \ + uint32 b = *(TileData + ((Y & 7) << 4) + ((X & 7) << 1)); \ + GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \ + if (GFX.Z1 > *d && b) \ + { \ + /* X10 and Y01 are the X and Y coordinates of the next source point over. */ \ + uint32 X10 = (xPix + dir) & 0x3ff; \ + uint32 Y01 = (yPix + dir) & 0x3ff; \ + uint8 *TileData10 = VRAM1 + (Memory.VRAM[((Y & ~7) << 5) + ((X10 >> 2) & ~1)] << 7); \ + uint8 *TileData11 = VRAM1 + (Memory.VRAM[((Y01 & ~7) << 5) + ((X10 >> 2) & ~1)] << 7); \ + uint8 *TileData01 = VRAM1 + (Memory.VRAM[((Y01 & ~7) << 5) + ((X >> 2) & ~1)] << 7); \ + uint32 p1 = COLORFUNC; \ + p1 = (p1 & FIRST_THIRD_COLOR_MASK) | ((p1 & SECOND_COLOR_MASK) << 16); \ + b = *(TileData10 + ((Y & 7) << 4) + ((X10 & 7) << 1)); \ + uint32 p2 = COLORFUNC; \ + p2 = (p2 & FIRST_THIRD_COLOR_MASK) | ((p2 & SECOND_COLOR_MASK) << 16); \ + b = *(TileData11 + ((Y01 & 7) << 4) + ((X10 & 7) << 1)); \ + uint32 p4 = COLORFUNC; \ + p4 = (p4 & FIRST_THIRD_COLOR_MASK) | ((p4 & SECOND_COLOR_MASK) << 16); \ + b = *(TileData01 + ((Y01 & 7) << 4) + ((X & 7) << 1)); \ + uint32 p3 = COLORFUNC; \ + p3 = (p3 & FIRST_THIRD_COLOR_MASK) | ((p3 & SECOND_COLOR_MASK) << 16); \ + /* Xdel, Ydel: position (in 1/32nds) between the points */ \ + uint32 Xdel = (xPos >> 3) & 0x1F; \ + uint32 Ydel = (yPos >> 3) & 0x1F; \ + uint32 XY = (Xdel*Ydel) >> 5; \ + uint32 area1 = 0x20 + XY - Xdel - Ydel; \ + uint32 area2 = Xdel - XY; \ + uint32 area3 = Ydel - XY; \ + uint32 area4 = XY; \ + uint32 tempColor = ((area1 * p1) + \ + (area2 * p2) + \ + (area3 * p3) + \ + (area4 * p4)) >> 5; \ + TYPE theColor = (tempColor & FIRST_THIRD_COLOR_MASK) | ((tempColor >> 16) & SECOND_COLOR_MASK); \ + *p = (FUNC) | ALPHA_BITS_MASK; \ + *d = GFX.Z1; \ + } \ + } \ + } \ + else \ + /* The oversampling method: get the colors at four corners of a square */ \ + /* in the _displayed_ image, and average them. It's sharp and clean, but */ \ + /* gives the usual huge pixels when the source image gets "close." */ \ + { \ + /* Find the dimensions of the square in the source image whose corners will be examined. */ \ + uint32 aaDelX = aa >> 1; \ + uint32 ccDelX = cc >> 1; \ + uint32 bbDelY = l->MatrixB >> 1; \ + uint32 ddDelY = l->MatrixD >> 1; \ + /* Offset the location within the source image so that the four sampled points */ \ + /* center around where the single point would otherwise have been drawn. */ \ + BB -= (bbDelY >> 1); \ + DD -= (ddDelY >> 1); \ + AA -= (aaDelX >> 1); \ + CC -= (ccDelX >> 1); \ + uint32 BB10 = BB + aaDelX; \ + uint32 BB01 = BB + bbDelY; \ + uint32 BB11 = BB + aaDelX + bbDelY; \ + uint32 DD10 = DD + ccDelX; \ + uint32 DD01 = DD + ddDelY; \ + uint32 DD11 = DD + ccDelX + ddDelY; \ + for (int x = startx; x != endx; x += dir, AA += aa, CC += cc, p++, d++) \ + { \ + uint32 X = ((AA + BB) >> 8) & 0x3ff; \ + uint32 Y = ((CC + DD) >> 8) & 0x3ff; \ + uint8 *TileData = VRAM1 + (Memory.VRAM[((Y & ~7) << 5) + ((X >> 2) & ~1)] << 7); \ + uint32 b = *(TileData + ((Y & 7) << 4) + ((X & 7) << 1)); \ + GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \ + if (GFX.Z1 > *d && b) \ + { \ + /* X, Y, X10, Y10, etc. are the coordinates of the four pixels within the */ \ + /* source image that we're going to examine. */ \ + uint32 X10 = ((AA + BB10) >> 8) & 0x3ff; \ + uint32 Y10 = ((CC + DD10) >> 8) & 0x3ff; \ + uint32 X01 = ((AA + BB01) >> 8) & 0x3ff; \ + uint32 Y01 = ((CC + DD01) >> 8) & 0x3ff; \ + uint32 X11 = ((AA + BB11) >> 8) & 0x3ff; \ + uint32 Y11 = ((CC + DD11) >> 8) & 0x3ff; \ + uint8 *TileData10 = VRAM1 + (Memory.VRAM[((Y10 & ~7) << 5) + ((X10 >> 2) & ~1)] << 7); \ + uint8 *TileData01 = VRAM1 + (Memory.VRAM[((Y01 & ~7) << 5) + ((X01 >> 2) & ~1)] << 7); \ + uint8 *TileData11 = VRAM1 + (Memory.VRAM[((Y11 & ~7) << 5) + ((X11 >> 2) & ~1)] << 7); \ + TYPE p1 = COLORFUNC; \ + b = *(TileData10 + ((Y10 & 7) << 4) + ((X10 & 7) << 1)); \ + TYPE p2 = COLORFUNC; \ + b = *(TileData01 + ((Y01 & 7) << 4) + ((X01 & 7) << 1)); \ + TYPE p3 = COLORFUNC; \ + b = *(TileData11 + ((Y11 & 7) << 4) + ((X11 & 7) << 1)); \ + TYPE p4 = COLORFUNC; \ + TYPE theColor = Q_INTERPOLATE(p1, p2, p3, p4); \ + *p = (FUNC) | ALPHA_BITS_MASK; \ + *d = GFX.Z1; \ + } \ + } \ + } \ + } \ + else \ + { \ + for (int x = startx; x != endx; x += dir, AA += aa, CC += cc, p++, d++) \ + { \ + uint32 xPos = AA + BB; \ + uint32 xPix = xPos >> 8; \ + uint32 yPos = CC + DD; \ + uint32 yPix = yPos >> 8; \ + uint32 X = xPix; \ + uint32 Y = yPix; \ + \ +\ + if(Settings.Dezaemon && PPU.Mode7Repeat == 2) \ + { \ + X &= 0x7ff; \ + Y &= 0x7ff; \ + } \ +\ + if (((X | Y) & ~0x3ff) == 0) \ + { \ + uint8 *TileData = VRAM1 + (Memory.VRAM[((Y & ~7) << 5) + ((X >> 2) & ~1)] << 7); \ + uint32 b = *(TileData + ((Y & 7) << 4) + ((X & 7) << 1)); \ + GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \ + if (GFX.Z1 > *d && b) \ + { \ + /* X10 and Y01 are the X and Y coordinates of the next source point over. */ \ + uint32 X10 = (xPix + dir) & 0x3ff; \ + uint32 Y01 = (yPix + dir) & 0x3ff; \ + uint8 *TileData10 = VRAM1 + (Memory.VRAM[((Y & ~7) << 5) + ((X10 >> 2) & ~1)] << 7); \ + uint8 *TileData11 = VRAM1 + (Memory.VRAM[((Y01 & ~7) << 5) + ((X10 >> 2) & ~1)] << 7); \ + uint8 *TileData01 = VRAM1 + (Memory.VRAM[((Y01 & ~7) << 5) + ((X >> 2) & ~1)] << 7); \ + uint32 p1 = COLORFUNC; \ + p1 = (p1 & FIRST_THIRD_COLOR_MASK) | ((p1 & SECOND_COLOR_MASK) << 16); \ + b = *(TileData10 + ((Y & 7) << 4) + ((X10 & 7) << 1)); \ + uint32 p2 = COLORFUNC; \ + p2 = (p2 & FIRST_THIRD_COLOR_MASK) | ((p2 & SECOND_COLOR_MASK) << 16); \ + b = *(TileData11 + ((Y01 & 7) << 4) + ((X10 & 7) << 1)); \ + uint32 p4 = COLORFUNC; \ + p4 = (p4 & FIRST_THIRD_COLOR_MASK) | ((p4 & SECOND_COLOR_MASK) << 16); \ + b = *(TileData01 + ((Y01 & 7) << 4) + ((X & 7) << 1)); \ + uint32 p3 = COLORFUNC; \ + p3 = (p3 & FIRST_THIRD_COLOR_MASK) | ((p3 & SECOND_COLOR_MASK) << 16); \ + /* Xdel, Ydel: position (in 1/32nds) between the points */ \ + uint32 Xdel = (xPos >> 3) & 0x1F; \ + uint32 Ydel = (yPos >> 3) & 0x1F; \ + uint32 XY = (Xdel*Ydel) >> 5; \ + uint32 area1 = 0x20 + XY - Xdel - Ydel; \ + uint32 area2 = Xdel - XY; \ + uint32 area3 = Ydel - XY; \ + uint32 area4 = XY; \ + uint32 tempColor = ((area1 * p1) + \ + (area2 * p2) + \ + (area3 * p3) + \ + (area4 * p4)) >> 5; \ + TYPE theColor = (tempColor & FIRST_THIRD_COLOR_MASK) | ((tempColor >> 16) & SECOND_COLOR_MASK); \ + *p = (FUNC) | ALPHA_BITS_MASK; \ + *d = GFX.Z1; \ + } \ + } \ + else \ + { \ + if (PPU.Mode7Repeat == 3) \ + { \ + X = (x + HOffset) & 7; \ + Y = (yy + CentreY) & 7; \ + uint32 b = *(VRAM1 + ((Y & 7) << 4) + ((X & 7) << 1)); \ + GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \ + if (GFX.Z1 > *d && b) \ + { \ + TYPE theColor = COLORFUNC; \ + *p = (FUNC) | ALPHA_BITS_MASK; \ + *d = GFX.Z1; \ + } \ + } \ + } \ + } \ + } \ + } \ + } + +STATIC uint32 Q_INTERPOLATE(uint32 A, uint32 B, uint32 C, uint32 D) +{ + register uint32 x = ((A >> 2) & HIGH_BITS_SHIFTED_TWO_MASK) + + ((B >> 2) & HIGH_BITS_SHIFTED_TWO_MASK) + + ((C >> 2) & HIGH_BITS_SHIFTED_TWO_MASK) + + ((D >> 2) & HIGH_BITS_SHIFTED_TWO_MASK); + register uint32 y = (A & TWO_LOW_BITS_MASK) + + (B & TWO_LOW_BITS_MASK) + + (C & TWO_LOW_BITS_MASK) + + (D & TWO_LOW_BITS_MASK); + y = (y>>2) & TWO_LOW_BITS_MASK; + return x+y; +} + +void DrawBGMode7Background16_i (uint8 *Screen, int bg) +{ + RENDER_BACKGROUND_MODE7_i (uint16, theColor, (GFX.ScreenColors[b & GFX.Mode7Mask])); +} + +void DrawBGMode7Background16Add_i (uint8 *Screen, int bg) +{ + RENDER_BACKGROUND_MODE7_i (uint16, *(d + GFX.DepthDelta) ? + (*(d + GFX.DepthDelta) != 1 ? + (COLOR_ADD (theColor, + p [GFX.Delta])) : + (COLOR_ADD (theColor, + GFX.FixedColour))) : + theColor, (GFX.ScreenColors[b & GFX.Mode7Mask])); +} + +void DrawBGMode7Background16Add1_2_i (uint8 *Screen, int bg) +{ + RENDER_BACKGROUND_MODE7_i (uint16, *(d + GFX.DepthDelta) ? + (*(d + GFX.DepthDelta) != 1 ? + COLOR_ADD1_2 (theColor, + p [GFX.Delta]) : + COLOR_ADD (theColor, + GFX.FixedColour)) : + theColor, (GFX.ScreenColors[b & GFX.Mode7Mask])); +} + +void DrawBGMode7Background16Sub_i (uint8 *Screen, int bg) +{ + RENDER_BACKGROUND_MODE7_i (uint16, *(d + GFX.DepthDelta) ? + (*(d + GFX.DepthDelta) != 1 ? + COLOR_SUB (theColor, + p [GFX.Delta]) : + COLOR_SUB (theColor, + GFX.FixedColour)) : + theColor, (GFX.ScreenColors[b & GFX.Mode7Mask])); +} + +void DrawBGMode7Background16Sub1_2_i (uint8 *Screen, int bg) +{ + RENDER_BACKGROUND_MODE7_i (uint16, *(d + GFX.DepthDelta) ? + (*(d + GFX.DepthDelta) != 1 ? + COLOR_SUB1_2 (theColor, + p [GFX.Delta]) : + COLOR_SUB (theColor, + GFX.FixedColour)) : + theColor, (GFX.ScreenColors[b & GFX.Mode7Mask])); +} + +#define _BUILD_SETUP(F) \ +GFX.BuildPixel = BuildPixel##F; \ +GFX.BuildPixel2 = BuildPixel2##F; \ +GFX.DecomposePixel = DecomposePixel##F; \ +RED_LOW_BIT_MASK = RED_LOW_BIT_MASK_##F; \ +GREEN_LOW_BIT_MASK = GREEN_LOW_BIT_MASK_##F; \ +BLUE_LOW_BIT_MASK = BLUE_LOW_BIT_MASK_##F; \ +RED_HI_BIT_MASK = RED_HI_BIT_MASK_##F; \ +GREEN_HI_BIT_MASK = GREEN_HI_BIT_MASK_##F; \ +BLUE_HI_BIT_MASK = BLUE_HI_BIT_MASK_##F; \ +MAX_RED = MAX_RED_##F; \ +MAX_GREEN = MAX_GREEN_##F; \ +MAX_BLUE = MAX_BLUE_##F; \ +GREEN_HI_BIT = ((MAX_GREEN_##F + 1) >> 1); \ +SPARE_RGB_BIT_MASK = SPARE_RGB_BIT_MASK_##F; \ +RGB_LOW_BITS_MASK = (RED_LOW_BIT_MASK_##F | \ + GREEN_LOW_BIT_MASK_##F | \ + BLUE_LOW_BIT_MASK_##F); \ +RGB_HI_BITS_MASK = (RED_HI_BIT_MASK_##F | \ + GREEN_HI_BIT_MASK_##F | \ + BLUE_HI_BIT_MASK_##F); \ +RGB_HI_BITS_MASKx2 = ((RED_HI_BIT_MASK_##F | \ + GREEN_HI_BIT_MASK_##F | \ + BLUE_HI_BIT_MASK_##F) << 1); \ +RGB_REMOVE_LOW_BITS_MASK = ~RGB_LOW_BITS_MASK; \ +FIRST_COLOR_MASK = FIRST_COLOR_MASK_##F; \ +SECOND_COLOR_MASK = SECOND_COLOR_MASK_##F; \ +THIRD_COLOR_MASK = THIRD_COLOR_MASK_##F; \ +ALPHA_BITS_MASK = ALPHA_BITS_MASK_##F; \ +FIRST_THIRD_COLOR_MASK = FIRST_COLOR_MASK | THIRD_COLOR_MASK; \ +TWO_LOW_BITS_MASK = RGB_LOW_BITS_MASK | (RGB_LOW_BITS_MASK << 1); \ +HIGH_BITS_SHIFTED_TWO_MASK = (( (FIRST_COLOR_MASK | SECOND_COLOR_MASK | THIRD_COLOR_MASK) & \ + ~TWO_LOW_BITS_MASK ) >> 2); + +void RenderScreen (uint8 *Screen, bool8_32 sub, bool8_32 force_no_add, uint8 D) +{ + bool8_32 BG0; + bool8_32 BG1; + bool8_32 BG2; + bool8_32 BG3; + bool8_32 OB; + + GFX.S = Screen; + + if (!sub) + { + GFX.pCurrentClip = &IPPU.Clip [0]; + BG0 = ON_MAIN (0); + BG1 = ON_MAIN (1); + BG2 = ON_MAIN (2); + BG3 = ON_MAIN (3); + OB = ON_MAIN (4); + } + else + { + GFX.pCurrentClip = &IPPU.Clip [1]; + BG0 = ON_SUB (0); + BG1 = ON_SUB (1); + BG2 = ON_SUB (2); + BG3 = ON_SUB (3); + OB = ON_SUB (4); + } + + sub |= force_no_add; + + if (PPU.BGMode <= 1) + { + if (OB) + { + SelectTileRenderer (sub || !SUB_OR_ADD(4)); + DrawOBJS (!sub, D); + } + if (BG0) + { + SelectTileRenderer (sub || !SUB_OR_ADD(0)); + DrawBackground (PPU.BGMode, 0, D + 10, D + 14); + } + if (BG1) + { + SelectTileRenderer (sub || !SUB_OR_ADD(1)); + DrawBackground (PPU.BGMode, 1, D + 9, D + 13); + } + if (BG2) + { + SelectTileRenderer (sub || !SUB_OR_ADD(2)); + DrawBackground (PPU.BGMode, 2, D + 3, + (Memory.FillRAM [0x2105] & 8) == 0 ? D + 6 : D + 17); + } + if (BG3 && PPU.BGMode == 0) + { + SelectTileRenderer (sub || !SUB_OR_ADD(3)); + DrawBackground (PPU.BGMode, 3, D + 2, D + 5); + } + } + else if (PPU.BGMode != 7) + { + if (OB) + { + SelectTileRenderer (sub || !SUB_OR_ADD(4)); + DrawOBJS (!sub, D); + } + if (BG0) + { + SelectTileRenderer (sub || !SUB_OR_ADD(0)); + DrawBackground (PPU.BGMode, 0, D + 5, D + 13); + } + if (PPU.BGMode != 6 && BG1) + { + SelectTileRenderer (sub || !SUB_OR_ADD(1)); + DrawBackground (PPU.BGMode, 1, D + 2, D + 9); + } + } + else + { + if (OB) + { + SelectTileRenderer (sub || !SUB_OR_ADD(4)); + DrawOBJS (!sub, D); + } + if (BG0 || ((Memory.FillRAM [0x2133] & 0x40) && BG1)) + { + int bg; + + if (Memory.FillRAM [0x2133] & 0x40) + { + GFX.Mode7Mask = 0x7f; + GFX.Mode7PriorityMask = 0x80; + Mode7Depths [0] = 5 + D; + Mode7Depths [1] = 9 + D; + bg = 1; + } + else + { + GFX.Mode7Mask = 0xff; + GFX.Mode7PriorityMask = 0; + Mode7Depths [0] = 5 + D; + Mode7Depths [1] = 5 + D; + bg = 0; + } + if (sub || !SUB_OR_ADD(0)) + { + if (!Settings.Mode7Interpolate) + DrawBGMode7Background16 (Screen, bg); + else + DrawBGMode7Background16_i (Screen, bg); + } + else + { + if (GFX.r2131 & 0x80) + { + if (GFX.r2131 & 0x40) + { + if (!Settings.Mode7Interpolate) + DrawBGMode7Background16Sub1_2 (Screen, bg); + else + DrawBGMode7Background16Sub1_2_i (Screen, bg); + } + else + { + if (!Settings.Mode7Interpolate) + DrawBGMode7Background16Sub (Screen, bg); + else + DrawBGMode7Background16Sub_i (Screen, bg); + } + } + else + { + if (GFX.r2131 & 0x40) + { + if (!Settings.Mode7Interpolate) + DrawBGMode7Background16Add1_2 (Screen, bg); + else + DrawBGMode7Background16Add1_2_i (Screen, bg); + } + else + { + if (!Settings.Mode7Interpolate) + DrawBGMode7Background16Add (Screen, bg); + else + DrawBGMode7Background16Add_i (Screen, bg); + } + } + } + } + } +} + +#include "font.h" + +void DisplayChar (uint8 *Screen, uint8 c) +{ + int line = (((c & 0x7f) - 32) >> 4) * font_height; + int offset = (((c & 0x7f) - 32) & 15) * font_width; +#ifndef _SNESPPC + if (Settings.SixteenBit) +#endif + { + int h, w; + uint16 *s = (uint16 *) Screen; + for (h = 0; h < font_height; h++, line++, + s += GFX.PPL - font_width) + { + for (w = 0; w < font_width; w++, s++) + { + uint8 p = font [line][offset + w]; + + if (p == '#') + *s = 0xffff; + else + if (p == '.') + *s = BLACK; + } + } + } +#ifndef _SNESPPC + else + { + int h, w; + uint8 *s = Screen; + for (h = 0; h < font_height; h++, line++, + s += GFX.PPL - font_width) + { + for (w = 0; w < font_width; w++, s++) + { + uint8 p = font [line][offset + w]; + + if (p == '#') + *s = 255; + else + if (p == '.') + *s = BLACK; + } + } + } +#endif +} + +static void S9xDisplayFrameRate () +{ + uint8 *Screen = GFX.Screen + 2 + + (IPPU.RenderedScreenHeight - font_height - 1) * GFX.Pitch2; + char string [10]; + int len = 5; + + sprintf (string, "%02d/%02d", IPPU.DisplayedRenderedFrameCount, + (int) Memory.ROMFramesPerSecond); + + int i; +#ifdef _SNESPPC + Screen += (font_width - 1) * sizeof(uint16); +#endif + for (i = 0; i < len; i++) + { + DisplayChar (Screen, string [i]); + Screen += Settings.SixteenBit ? (font_width - 1) * sizeof (uint16) : + (font_width - 1); + } +} + +static void S9xDisplayString (const char *string) +{ + uint8 *Screen = GFX.Screen + 2 + + (IPPU.RenderedScreenHeight - font_height * 5) * GFX.Pitch2; + int len = strlen (string); + int max_chars = IPPU.RenderedScreenWidth / (font_width - 1); + int char_count = 0; + int i; + + for (i = 0; i < len; i++, char_count++) + { + if (char_count >= max_chars || string [i] < 32) + { + Screen -= Settings.SixteenBit ? + (font_width - 1) * sizeof (uint16) * max_chars : + (font_width - 1) * max_chars; + Screen += font_height * GFX.Pitch; + if (Screen >= GFX.Screen + GFX.Pitch * IPPU.RenderedScreenHeight) + break; + char_count -= max_chars; + } + if (string [i] < 32) + continue; + DisplayChar (Screen, string [i]); + Screen += Settings.SixteenBit ? (font_width - 1) * sizeof (uint16) : + (font_width - 1); + } +} + +void S9xUpdateScreen () // ~30-50ms! (called from FLUSH_REDRAW()) +{ + int32 x2 = 1; + + GFX.S = GFX.Screen; + + unsigned char *memoryfillram = Memory.FillRAM; + + // get local copies of vid registers to be used later + GFX.r2131 = memoryfillram [0x2131]; // ADDITION/SUBTRACTION & SUBTRACTION DESIGNATION FOR EACH SCREEN + GFX.r212c = memoryfillram [0x212c]; // MAIN SCREEN, DESIGNATION - used to enable BGS + GFX.r212d = memoryfillram [0x212d]; // SUB SCREEN DESIGNATION - used to enable sub BGS + GFX.r2130 = memoryfillram [0x2130]; // INITIAL SETTINGS FOR FIXED COLOR ADDITION OR SCREEN ADDITION + + // If external sync is off and + // main screens have not been configured the same as the sub screen and + // color addition and subtraction has been diabled then + // Pseudo is 1 + // anything else it is 0 + GFX.Pseudo = (memoryfillram [0x2133] & 8) != 0 && // Use EXTERNAL SYNCHRONIZATION? + (GFX.r212c & 15) != (GFX.r212d & 15) && // Are the main screens different from the sub screens? + (GFX.r2131 & 0x3f) == 0; // Is colour data addition/subtraction disabled on all BGS? + + // If sprite data has been changed then go through and + // refresh the sprites. + if (IPPU.OBJChanged) + { + S9xSetupOBJ (); + } + + if (PPU.RecomputeClipWindows) + { + ComputeClipWindows (); + PPU.RecomputeClipWindows = FALSE; + } + + GFX.StartY = IPPU.PreviousLine; + if ((GFX.EndY = IPPU.CurrentLine - 1) >= PPU.ScreenHeight) + GFX.EndY = PPU.ScreenHeight - 1; + + uint32 starty = GFX.StartY; + uint32 endy = GFX.EndY; + +#ifndef RC_OPTIMIZED + if (Settings.SupportHiRes && + (PPU.BGMode == 5 || PPU.BGMode == 6 || IPPU.LatchedInterlace)) + { + if (PPU.BGMode == 5 || PPU.BGMode == 6) + { + IPPU.RenderedScreenWidth = 512; + x2 = 2; + } + if (IPPU.LatchedInterlace) + { + starty = GFX.StartY * 2; + endy = GFX.EndY * 2 + 1; + } + if (!IPPU.DoubleWidthPixels) + { + // The game has switched from lo-res to hi-res mode part way down + // the screen. Scale any existing lo-res pixels on screen +#ifndef _SNESPPC + if (Settings.SixteenBit) +#endif + { +#if defined (USE_GLIDE) || defined (USE_OPENGL) + if ( +#ifdef USE_GLIDE + (Settings.GlideEnable && GFX.Pitch == 512) || +#endif +#ifdef USE_OPENGL + (Settings.OpenGLEnable && GFX.Pitch == 512) || +#endif + 0) + { + // Have to back out of the speed up hack where the low res. + // SNES image was rendered into a 256x239 sized buffer, + // ignoring the true, larger size of the buffer. + + for (register int32 y = (int32) GFX.StartY - 1; y >= 0; y--) + { + register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch) + 255; + register uint16 *q = (uint16 *) (GFX.Screen + y * GFX.RealPitch) + 510; + for (register int x = 255; x >= 0; x--, p--, q -= 2) + *q = *(q + 1) = *p; + } + GFX.Pitch = GFX.Pitch2 = GFX.RealPitch; + GFX.PPL = GFX.Pitch >> 1; + GFX.PPLx2 = GFX.Pitch; + GFX.ZPitch = GFX.PPL; + } + else +#endif + for (register uint32 y = 0; y < GFX.StartY; y++) + { + register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch) + 255; + register uint16 *q = (uint16 *) (GFX.Screen + y * GFX.Pitch) + 510; + for (register int x = 255; x >= 0; x--, p--, q -= 2) + *q = *(q + 1) = *p; + } + } +#ifndef _SNESPPC + else + { + for (register uint32 y = 0; y < GFX.StartY; y++) + { + register uint8 *p = GFX.Screen + y * GFX.Pitch + 255; + register uint8 *q = GFX.Screen + y * GFX.Pitch + 510; + for (register int x = 255; x >= 0; x--, p--, q -= 2) + *q = *(q + 1) = *p; + } + } +#endif + IPPU.DoubleWidthPixels = TRUE; + } + } +#endif //RC_OPTIMIZED (DONT DO ABOVE) + + uint32 black = BLACK | (BLACK << 16); + + // Are we worrying about transparencies? + if (Settings.Transparency && Settings.SixteenBit) + { + if (GFX.Pseudo) + { + GFX.r2131 = 0x5f; //0101 1111 - enable addition/subtraction on all BGS and sprites and "1/2 OF COLOR DATA" DESIGNATION + GFX.r212d = (Memory.FillRAM [0x212c] ^ // any BGS which are set as main and as sub then switch off the sub + Memory.FillRAM [0x212d]) & 15; + GFX.r212c &= ~GFX.r212d; // make sure the main BG reg is the reverse of the sub BG reg + GFX.r2130 |= 2; // enable ADDITION/SUBTRACTION FOR SUB SCREEN + } + + // Check to see if any transparency effects are currently in use + if (!PPU.ForcedBlanking && ADD_OR_SUB_ON_ANYTHING && + (GFX.r2130 & 0x30) != 0x30 && + !((GFX.r2130 & 0x30) == 0x10 && IPPU.Clip[1].Count[5] == 0)) + { + // transparency effects in use, so lets get busy! + struct ClipData *pClip; + uint32 fixedColour; + GFX.FixedColour = BUILD_PIXEL (IPPU.XB [PPU.FixedColourRed], + IPPU.XB [PPU.FixedColourGreen], + IPPU.XB [PPU.FixedColourBlue]); + fixedColour = (GFX.FixedColour<<16|GFX.FixedColour); + // Clear the z-buffer, marking areas 'covered' by the fixed + // colour as depth 1. + pClip = &IPPU.Clip [1]; + + // Clear the z-buffer + + if (pClip->Count [5]) + { + + // Colour window enabled. + +#ifdef RC_OPTIMIZED + for (uint32 y = starty; y <= endy; y++) + { + + ZeroMemory (GFX.SubZBuffer + y * GFX.ZPitch, + IPPU.RenderedScreenWidth); + ZeroMemory (GFX.ZBuffer + y * GFX.ZPitch, + IPPU.RenderedScreenWidth); + + if (IPPU.Clip [0].Count [5]) + { + memset ((GFX.SubScreen + y * GFX.Pitch2), black, IPPU.RenderedScreenWidth); + } + for (uint32 c = 0; c < pClip->Count [5]; c++) + { + if (pClip->Right [c][5] > pClip->Left [c][5]) + { + memset (GFX.SubZBuffer + y * GFX.ZPitch + pClip->Left [c][5] * x2, + 1, (pClip->Right [c][5] - pClip->Left [c][5]) * x2); + if (IPPU.Clip [0].Count [5]) + { + // Blast, have to clear the sub-screen to the fixed-colour + // because there is a colour window in effect clipping + // the main screen that will allow the sub-screen + // 'underneath' to show through. + memset ((GFX.SubScreen + y * GFX.Pitch2) + pClip->Left [c][5] * x2, + GFX.FixedColour, + pClip->Right[c][5]*x2 - pClip->Left [c][5] * x2); + } + } + } + } + +#else // NOT RC_OPTIMIZED + // loop around all of the lines being updated + for (uint32 y = starty; y <= endy; y++) + { + // Clear the subZbuffer + memset32 ((uint32_t*)(GFX.SubZBuffer + y * GFX.ZPitch),0, + IPPU.RenderedScreenWidth>>2); + // Clear the Zbuffer + memset32 ((uint32_t*)(GFX.ZBuffer + y * GFX.ZPitch),0, + IPPU.RenderedScreenWidth>>2); + + // if there is clipping then clear subscreen to a black color + if (IPPU.Clip [0].Count [5]) + { + memset32 ((uint32_t*)(GFX.SubScreen + y * GFX.Pitch2), black, IPPU.RenderedScreenWidth>>1); + } + + // loop through all window clippings + for (uint32 c = 0; c < pClip->Count [5]; c++) + { + if (pClip->Right [c][5] > pClip->Left [c][5]) + { + memset (GFX.SubZBuffer + y * GFX.ZPitch + pClip->Left [c][5] * x2, + 1, (pClip->Right [c][5] - pClip->Left [c][5]) * x2); + if (IPPU.Clip [0].Count [5]) + { + // Blast, have to clear the sub-screen to the fixed-colour + // because there is a colour window in effect clipping + // the main screen that will allow the sub-screen + // 'underneath' to show through. + + register uint16 *p = (uint16 *) (GFX.SubScreen + y * GFX.Pitch2); + register uint16 *q = p + pClip->Right [c][5] * x2; + p += pClip->Left [c][5] * x2; + + while (p < q) + *p++ = (uint16) GFX.FixedColour; + } + } + } + } +#endif +//#undef RC_OPTIMIZED + + } + else + { + // No windows are clipping the main screen + // this simplifies the screen clearing process +#ifdef RC_OPTIMIZED + + if (GFX.ZPitch == (uint32)IPPU.RenderedScreenWidth) + { + + memset (GFX.ZBuffer + starty * GFX.ZPitch, 0, GFX.ZPitch * (endy - starty - 1)); + memset (GFX.SubZBuffer + starty * GFX.ZPitch, 1, GFX.ZPitch * (endy - starty - 1)); + } + else + { + for (uint32 y = starty; y <= endy; y++) + { + ZeroMemory (GFX.ZBuffer + y * GFX.ZPitch, + IPPU.RenderedScreenWidth); + memset (GFX.SubZBuffer + y * GFX.ZPitch, 1, + IPPU.RenderedScreenWidth); + } + } + + if (IPPU.Clip [0].Count [5]) + { + // Blast, have to clear the sub-screen to the fixed-colour + // because there is a colour window in effect clipping + // the main screen that will allow the sub-screen + // 'underneath' to show through. + if (GFX.Pitch2 == (uint32)IPPU.RenderedScreenWidth) + { + memset ((GFX.SubScreen + starty * GFX.Pitch2), + GFX.FixedColour | (GFX.FixedColour << 16), + GFX.Pitch2 * (endy - starty - 1)); + } + else + { + for (uint32 y = starty; y <= endy; y++) + { + memset ((GFX.SubScreen + y * GFX.Pitch2), + GFX.FixedColour | (GFX.FixedColour << 16), + IPPU.RenderedScreenWidth); + } + } + } + +#else // NOT RC_OPTIMIZED + // loop through all of the lines to be updated + for (uint32 y = starty; y <= endy; y++) + { + // Clear the Zbuffer + memset32 ((uint32_t*)(GFX.ZBuffer + y * GFX.ZPitch),0, + IPPU.RenderedScreenWidth>>2); + // clear the sub Zbuffer to 1 + memset32 ((uint32_t*)(GFX.SubZBuffer + y * GFX.ZPitch), 0x01010101, + IPPU.RenderedScreenWidth>>2); + if (IPPU.Clip [0].Count [5]) + { + // Blast, have to clear the sub-screen to the fixed-colour + // because there is a colour window in effect clipping + // the main screen that will allow the sub-screen + // 'underneath' to show through. + + + memset32 ((uint32_t*)(GFX.SubScreen + y * GFX.Pitch2), fixedColour, + IPPU.RenderedScreenWidth>>1); + } + } +#endif + + } + + if (ANYTHING_ON_SUB) + { + GFX.DB = GFX.SubZBuffer; + RenderScreen (GFX.SubScreen, TRUE, TRUE, SUB_SCREEN_DEPTH); + } + + if (IPPU.Clip [0].Count [5]) + { + for (uint32 y = starty; y <= endy; y++) + { + register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2); + register uint8 *d = GFX.SubZBuffer + y * GFX.ZPitch ; + register uint8 *e = d + SNES_WIDTH; + + while (d < e) + { + if (*d > 1) + *p = *(p + GFX.Delta); + else + *p = BLACK; + d++; + p++; + } + } + } + + GFX.DB = GFX.ZBuffer; + RenderScreen (GFX.Screen, FALSE, FALSE, MAIN_SCREEN_DEPTH); + if (SUB_OR_ADD(5)) + { + uint32 back = IPPU.ScreenColors [0]; + uint32 Left = 0; + uint32 Right = 256; + uint32 Count; + + pClip = &IPPU.Clip [0]; + + for (uint32 y = starty; y <= endy; y++) + { + if (!(Count = pClip->Count [5])) + { + Left = 0; + Right = 256 * x2; + Count = 1; + } + + for (uint32 b = 0; b < Count; b++) + { + if (pClip->Count [5]) + { + Left = pClip->Left [b][5] * x2; + Right = pClip->Right [b][5] * x2; + if (Right <= Left) + continue; + } + + if (GFX.r2131 & 0x80) + { + if (GFX.r2131 & 0x40) + { + // Subtract, halving the result. + register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + Left; + register uint8 *d = GFX.ZBuffer + y * GFX.ZPitch; + register uint8 *s = GFX.SubZBuffer + y * GFX.ZPitch + Left; + register uint8 *e = d + Right; + uint16 back_fixed = COLOR_SUB (back, GFX.FixedColour); + + d += Left; + while (d < e) + { + if (*d == 0) + { + if (*s) + { + if (*s != 1) + *p = COLOR_SUB1_2 (back, *(p + GFX.Delta)); + else + *p = back_fixed; + } + else + *p = (uint16) back; + } + d++; + p++; + s++; + } + } + else + { + // Subtract + register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + Left; + register uint8 *s = GFX.SubZBuffer + y * GFX.ZPitch + Left; + register uint8 *d = GFX.ZBuffer + y * GFX.ZPitch; + register uint8 *e = d + Right; + uint16 back_fixed = COLOR_SUB (back, GFX.FixedColour); + + d += Left; + while (d < e) + { + if (*d == 0) + { + if (*s) + { + if (*s != 1) + *p = COLOR_SUB (back, *(p + GFX.Delta)); + else + *p = back_fixed; + } + else + *p = (uint16) back; + } + d++; + p++; + s++; + } + } + } + else + if (GFX.r2131 & 0x40) + { + register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + Left; + register uint8 *d = GFX.ZBuffer + y * GFX.ZPitch; + register uint8 *s = GFX.SubZBuffer + y * GFX.ZPitch + Left; + register uint8 *e = d + Right; + uint16 back_fixed = COLOR_ADD (back, GFX.FixedColour); + d += Left; + while (d < e) + { + if (*d == 0) + { + if (*s) + { + if (*s != 1) + *p = COLOR_ADD1_2 (back, *(p + GFX.Delta)); + else + *p = back_fixed; + } + else + *p = (uint16) back; + } + d++; + p++; + s++; + } + } + else + if (back != 0) + { + register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + Left; + register uint8 *d = GFX.ZBuffer + y * GFX.ZPitch; + register uint8 *s = GFX.SubZBuffer + y * GFX.ZPitch + Left; + register uint8 *e = d + Right; + uint16 back_fixed = COLOR_ADD (back, GFX.FixedColour); + d += Left; + while (d < e) + { + if (*d == 0) + { + if (*s) + { + if (*s != 1) + *p = COLOR_ADD (back, *(p + GFX.Delta)); + else + *p = back_fixed; + } + else + *p = (uint16) back; + } + d++; + p++; + s++; + } + } + else + { + if (!pClip->Count [5]) + { + // The backdrop has not been cleared yet - so + // copy the sub-screen to the main screen + // or fill it with the back-drop colour if the + // sub-screen is clear. + register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + Left; + register uint8 *d = GFX.ZBuffer + y * GFX.ZPitch; + register uint8 *s = GFX.SubZBuffer + y * GFX.ZPitch + Left; + register uint8 *e = d + Right; + d += Left; + while (d < e) + { + if (*d == 0) + { + if (*s) + { + if (*s != 1) + *p = *(p + GFX.Delta); + else + *p = GFX.FixedColour; + } + else + *p = (uint16) back; + } + d++; + p++; + s++; + } + } + } + } + } + + } + else + { + // Subscreen not being added to back + uint32 back = IPPU.ScreenColors [0] | (IPPU.ScreenColors [0] << 16); + pClip = &IPPU.Clip [0]; + + if (pClip->Count [5]) + { + for (uint32 y = starty; y <= endy; y++) + { + for (uint32 b = 0; b < pClip->Count [5]; b++) + { + uint32 Left = pClip->Left [b][5] * x2; + uint32 Right = pClip->Right [b][5] * x2; + register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + Left; + register uint8 *d = GFX.ZBuffer + y * GFX.ZPitch; + register uint8 *e = d + Right; + d += Left; + + while (d < e) + { + if (*d++ == 0) + *p = (int16) back; + p++; + } + } + } + } + else + { + for (uint32 y = starty; y <= endy; y++) + { + register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2); + register uint8 *d = GFX.ZBuffer + y * GFX.ZPitch; + register uint8 *e = d + 256 * x2; + + while (d < e) + { + if (*d == 0) +#ifdef RC_OPTIMIZED + *p++ = back; + d++; +#else + *p = (int16) back; + d++; + p++; +#endif + } + } + } + } + } + else + { + // 16bit and transparency but currently no transparency effects in + // operation. + + // get the back colour of the current screen + uint32 back = IPPU.ScreenColors [0] | + (IPPU.ScreenColors [0] << 16); + + // if forceblanking in use then use black instead of the back color + if (PPU.ForcedBlanking) + back = black; + + // not sure what Clip is used for yet + // could be a check to see if there is any clipping present? + if (IPPU.Clip [0].Count[5]) + { + +#ifdef RC_OPTIMIZED + if (GFX.Pitch2 == (uint32)IPPU.RenderedScreenWidth) + { + memset (GFX.Screen + starty * GFX.Pitch2, black, + GFX.Pitch2 * (endy - starty - 1)); + } + else + { + for (uint32 y = starty; y <= endy; y++) + { + memset (GFX.Screen + y * GFX.Pitch2, black, + GFX.Pitch2); + } + } + for (uint32 y = starty; y <= endy; y++) + { + for (uint32 c = 0; c < IPPU.Clip [0].Count [5]; c++) + { + if (IPPU.Clip [0].Right [c][5] > IPPU.Clip [0].Left [c][5]) + { + + memset ((GFX.Screen + y * GFX.Pitch2) + IPPU.Clip [0].Left [c][5] * x2, + back, + IPPU.Clip [0].Right [c][5] * x2 - IPPU.Clip [0].Left [c][5] * x2); + } + } + } +#else + // loop through all of the lines that are going to be updated as part of this screen update + for (uint32 y = starty; y <= endy; y++) + { + memset32 ((uint32_t*)(GFX.Screen + y * GFX.Pitch2), black, + IPPU.RenderedScreenWidth>>1); + + if (black!=back) + { + for (uint32 c = 0; c < IPPU.Clip [0].Count [5]; c++) + { + if (IPPU.Clip [0].Right [c][5] > IPPU.Clip [0].Left [c][5]) + { + register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2); // get pointer to current line in screen buffer + register uint16 *q = p + IPPU.Clip [0].Right [c][5] * x2; // get pointer to end of line + p += IPPU.Clip [0].Left [c][5] * x2; + + while (p < q) + *p++ = (uint16) back; // fill all pixels in clipped section with the back colour + } + } + } + } +#endif + } + else + { +#ifdef RC_OPTIMIZED + if (GFX.Pitch2 == (uint32)IPPU.RenderedScreenWidth) + { + memset (GFX.Screen + starty * GFX.Pitch2, back, + GFX.Pitch2 * (endy - starty - 1)); + } + else + { + for (uint32 y = starty; y <= endy; y++) + { + memset (GFX.Screen + y * GFX.Pitch2, back, + GFX.Pitch2); + } + } +#else + // there is no clipping to worry about so just fill with the back colour + for (uint32 y = starty; y <= endy; y++) + { + memset32 ((uint32_t*)(GFX.Screen + y * GFX.Pitch2), back, + IPPU.RenderedScreenWidth>>1); + } +#endif + } + + // If Forced blanking is not in effect + if (!PPU.ForcedBlanking) + { +#ifdef RC_OPTIMIZED + if (GFX.ZPitch == (uint32)IPPU.RenderedScreenWidth) + { + memset (GFX.ZBuffer + starty * GFX.ZPitch, 0, + GFX.ZPitch * (endy - starty - 1)); + } + else + { + for (uint32 y = starty; y <= endy; y++) + { + memset (GFX.ZBuffer + y * GFX.ZPitch, 0, + GFX.ZPitch); + } + } +#else + // Clear the Zbuffer for each of the lines which are going to be updated + for (uint32 y = starty; y <= endy; y++) + { + memset32 ((uint32_t*)(GFX.ZBuffer + y * GFX.ZPitch), 0, + IPPU.RenderedScreenWidth>>2); + } +#endif + GFX.DB = GFX.ZBuffer; // save pointer to Zbuffer in GFX object + RenderScreen (GFX.Screen, FALSE, TRUE, SUB_SCREEN_DEPTH); + } + } + } + else // Transparencys are disabled, ahh lovely ... nice and easy. + { +#ifndef _SNESPPC + if (Settings.SixteenBit) +#endif + { + // get back colour to be used in clearing the screen + register uint32 back; + if (!(Memory.FillRAM [0x2131] & 0x80) &&(Memory.FillRAM[0x2131] & 0x20) && + (PPU.FixedColourRed || PPU.FixedColourGreen || PPU.FixedColourBlue)) + { + back = (IPPU.XB[PPU.FixedColourRed]<<11) | + (IPPU.XB[PPU.FixedColourGreen] << 6) | + (IPPU.XB[PPU.FixedColourBlue] << 1) | 1; + back = (back << 16) | back; + } + else + { + back = IPPU.ScreenColors [0] | (IPPU.ScreenColors [0] << 16); + } + + // if Forcedblanking in use then back colour becomes black + if (PPU.ForcedBlanking) + back = black; + else + { + SelectTileRenderer (TRUE); //selects the tile renderers to be used + // TRUE means to use the default + // FALSE means use best renderer based on current + // graphics register settings + } + + // now clear all graphics lines which are being updated using the back colour + for (register uint32 y = starty; y <= endy; y++) + { + memset32 ((uint32_t*)(GFX.Screen + y * GFX.Pitch2), back, + IPPU.RenderedScreenWidth>>1); + } + } +#ifndef _SNESPPC + else // Settings.SixteenBit == false + { + // because we are in 8 bit we can just use 0 to clear the screen + // this means we can use the Zero Memory function + + // Loop through all lines being updated and clear the pixels to 0 + for (uint32 y = starty; y <= endy; y++) + { + ZeroMemory (GFX.Screen + y * GFX.Pitch2, + IPPU.RenderedScreenWidth); + } + } +#endif + if (!PPU.ForcedBlanking) + { + // Loop through all lines being updated and clear the + // zbuffer for each of the lines + for (uint32 y = starty; y <= endy; y++) + { + memset32 ((uint32_t*)(GFX.ZBuffer + y * GFX.ZPitch), 0, + IPPU.RenderedScreenWidth>>2); + } + GFX.DB = GFX.ZBuffer; // save pointer to Zbuffer in GFX object + GFX.pCurrentClip = &IPPU.Clip [0]; + +// Define an inline function to handle clipping +#define FIXCLIP(n) \ +if (GFX.r212c & (1 << (n))) \ + GFX.pCurrentClip = &IPPU.Clip [0]; \ +else \ + GFX.pCurrentClip = &IPPU.Clip [1] + +// Define an inline function to handle which BGs are being displayed +#define DISPLAY(n) \ +(!(PPU.BG_Forced & n) && \ +(GFX.r212c & n) || \ +((GFX.r212d & n) && subadd)) + + uint8 subadd = GFX.r2131 & 0x3f; + + // go through all BGS are check if they need to be displayed + bool8_32 BG0 = DISPLAY(1); + bool8_32 BG1 = DISPLAY(2); + bool8_32 BG2 = DISPLAY(4); + bool8_32 BG3 = DISPLAY(8); + bool8_32 OB = DISPLAY(16); + + if (PPU.BGMode <= 1) + { + // screen modes 0 and 1 + if (OB) + { + FIXCLIP(4); + DrawOBJS (); + } + if (BG0) + { + FIXCLIP(0); + DrawBackground (PPU.BGMode, 0, 10, 14); + } + if (BG1) + { + FIXCLIP(1); + DrawBackground (PPU.BGMode, 1, 9, 13); + } + if (BG2) + { + FIXCLIP(2); + DrawBackground (PPU.BGMode, 2, 3, + (Memory.FillRAM [0x2105] & 8) == 0 ? 6 : 17); + } + if (BG3 && PPU.BGMode == 0) + { + FIXCLIP(3); + DrawBackground (PPU.BGMode, 3, 2, 5); + } + } + else if (PPU.BGMode != 7) + { + // screen modes 2 and up but not mode 7 + if (OB) + { + FIXCLIP(4); + DrawOBJS (); + } + if (BG0) + { + FIXCLIP(0); + DrawBackground (PPU.BGMode, 0, 5, 13); + } + if (BG1 && PPU.BGMode != 6) + { + FIXCLIP(1); + DrawBackground (PPU.BGMode, 1, 2, 9); + } + } + else + { + // screen mode 7 + if (OB) + { + FIXCLIP(4); + DrawOBJS (); + } + if (BG0 || ((Memory.FillRAM [0x2133] & 0x40) && BG1)) + { + int bg; + FIXCLIP(0); + if (Memory.FillRAM [0x2133] & 0x40) + { + GFX.Mode7Mask = 0x7f; + GFX.Mode7PriorityMask = 0x80; + Mode7Depths [0] = 5; + Mode7Depths [1] = 9; + bg = 1; + } + else + { + GFX.Mode7Mask = 0xff; + GFX.Mode7PriorityMask = 0; + Mode7Depths [0] = 5; + Mode7Depths [1] = 5; + bg = 0; + } + +#ifndef _SNESPPC + if (!Settings.SixteenBit) + DrawBGMode7Background (GFX.Screen, bg); + else +#endif + { + if (!Settings.Mode7Interpolate) + { + DrawBGMode7Background16 (GFX.Screen, bg); + } + else + { + DrawBGMode7Background16_i (GFX.Screen, bg); + } + } + } + } + } + } +#ifndef RC_OPTIMIZE // no hi res + if (Settings.SupportHiRes && PPU.BGMode != 5 && PPU.BGMode != 6) + { + if (IPPU.DoubleWidthPixels) + { + // Mixure of background modes used on screen - scale width + // of all non-mode 5 and 6 pixels. +#ifndef _SNESPPC + if (Settings.SixteenBit) +#endif + { + for (register uint32 y = GFX.StartY; y <= GFX.EndY; y++) + { + register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch) + 255; + register uint16 *q = (uint16 *) (GFX.Screen + y * GFX.Pitch) + 510; + for (register int x = 255; x >= 0; x--, p--, q -= 2) + *q = *(q + 1) = *p; + } + } +#ifndef _SNESPPC + else + { + for (register uint32 y = GFX.StartY; y <= GFX.EndY; y++) + { + register uint8 *p = GFX.Screen + y * GFX.Pitch + 255; + register uint8 *q = GFX.Screen + y * GFX.Pitch + 510; + for (register int x = 255; x >= 0; x--, p--, q -= 2) + *q = *(q + 1) = *p; + } + } +#endif + } + + if (IPPU.LatchedInterlace) + { + // Interlace is enabled - double the height of all non-mode 5 and 6 + // pixels. + for (uint32 y = GFX.StartY; y <= GFX.EndY; y++) + { + memcpy32 ((uint32_t*)(GFX.Screen + (y * 2 + 1) * GFX.Pitch2), + (uint32_t*)(GFX.Screen + y * 2 * GFX.Pitch2), + GFX.Pitch2>>2); + } + } + } +#endif + IPPU.PreviousLine = IPPU.CurrentLine; +} + +#ifdef GFX_MULTI_FORMAT + +#define _BUILD_PIXEL(F) \ +uint32 BuildPixel##F(uint32 R, uint32 G, uint32 B) \ +{ \ + return (BUILD_PIXEL_##F(R,G,B)); \ +}\ +uint32 BuildPixel2##F(uint32 R, uint32 G, uint32 B) \ +{ \ + return (BUILD_PIXEL2_##F(R,G,B)); \ +} \ +void DecomposePixel##F(uint32 pixel, uint32 &R, uint32 &G, uint32 &B) \ +{ \ + DECOMPOSE_PIXEL_##F(pixel,R,G,B); \ +} + +_BUILD_PIXEL(RGB565) +_BUILD_PIXEL(RGB555) +_BUILD_PIXEL(BGR565) +_BUILD_PIXEL(BGR555) +_BUILD_PIXEL(GBR565) +_BUILD_PIXEL(GBR555) +_BUILD_PIXEL(RGB5551) + +bool8_32 S9xSetRenderPixelFormat (int format) +{ + extern uint32 current_graphic_format; + + current_graphic_format = format; + + switch (format) + { + case RGB565: + _BUILD_SETUP(RGB565) + return (TRUE); + case RGB555: + _BUILD_SETUP(RGB555) + return (TRUE); + case BGR565: + _BUILD_SETUP(BGR565) + return (TRUE); + case BGR555: + _BUILD_SETUP(BGR555) + return (TRUE); + case GBR565: + _BUILD_SETUP(GBR565) + return (TRUE); + case GBR555: + _BUILD_SETUP(GBR555) + return (TRUE); + case RGB5551: + _BUILD_SETUP(RGB5551) + return (TRUE); + default: + break; + } + return (FALSE); +} +#endif diff --git a/src/snes4iphone_src/gfx.h b/src/snes4iphone_src/gfx.h new file mode 100755 index 0000000..b72dbac --- /dev/null +++ b/src/snes4iphone_src/gfx.h @@ -0,0 +1,239 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#ifndef _GFX_H_ +#define _GFX_H_ + +#include "port.h" + +struct SGFX{ + // Initialize these variables + uint8 *Screen; + uint8 *SubScreen; + uint8 *ZBuffer; + uint8 *SubZBuffer; + uint32 Pitch; + + // Setup in call to S9xGraphicsInit() + int Delta; + uint16 *X2; + uint16 *ZERO_OR_X2; + uint16 *ZERO; + uint32 RealPitch; // True pitch of Screen buffer. + uint32 Pitch2; // Same as RealPitch except while using speed up hack for Glide. + uint32 ZPitch; // Pitch of ZBuffer + uint32 PPL; // Number of pixels on each of Screen buffer + uint32 PPLx2; + uint32 PixSize; + uint8 *S; + uint8 *DB; + uint16 *ScreenColors; + uint32 DepthDelta; + uint8 Z1; + uint8 Z2; + uint32 FixedColour; + const char *InfoString; + uint32 InfoStringTimeout; + uint32 StartY; + uint32 EndY; + struct ClipData *pCurrentClip; + uint32 Mode7Mask; + uint32 Mode7PriorityMask; + int OBJList [129]; + uint32 Sizes [129]; + int VPositions [129]; + + uint8 r212c; + uint8 r212d; + uint8 r2130; + uint8 r2131; + bool8_32 Pseudo; + +#ifdef GFX_MULTI_FORMAT + uint32 PixelFormat; + uint32 (*BuildPixel) (uint32 R, uint32 G, uint32 B); + uint32 (*BuildPixel2) (uint32 R, uint32 G, uint32 B); + void (*DecomposePixel) (uint32 Pixel, uint32 &R, uint32 &G, uint32 &B); +#endif +}; + +struct SLineData { + struct { + uint16 VOffset; + uint16 HOffset; + } BG [4]; +}; + +#define H_FLIP 0x4000 +#define V_FLIP 0x8000 +#define BLANK_TILE 2 + +struct SBG +{ + uint32 TileSize; + uint32 BitShift; + uint32 TileShift; + uint32 TileAddress; + uint32 NameSelect; + uint32 SCBase; + + uint32 StartPalette; + uint32 PaletteShift; + uint32 PaletteMask; + + uint8 *Buffer; + uint8 *Buffered; + bool8_32 DirectColourMode; +}; + +struct SLineMatrixData +{ + short MatrixA; + short MatrixB; + short MatrixC; + short MatrixD; + short CentreX; + short CentreY; +}; + +extern uint32 odd_high [4][16]; +extern uint32 odd_low [4][16]; +extern uint32 even_high [4][16]; +extern uint32 even_low [4][16]; +extern SBG BG; +extern uint16 DirectColourMaps [8][256]; + +//extern uint8 add32_32 [32][32]; +//extern uint8 add32_32_half [32][32]; +//extern uint8 sub32_32 [32][32]; +//extern uint8 sub32_32_half [32][32]; +extern uint8 mul_brightness [16][32]; + +// Could use BSWAP instruction on Intel port... +#define SWAP_DWORD(dw) dw = ((dw & 0xff) << 24) | ((dw & 0xff00) << 8) | \ + ((dw & 0xff0000) >> 8) | ((dw & 0xff000000) >> 24) + +#ifdef FAST_LSB_WORD_ACCESS +#define READ_2BYTES(s) (*(uint16 *) (s)) +#define WRITE_2BYTES(s, d) *(uint16 *) (s) = (d) +#else +#ifdef LSB_FIRST +#define READ_2BYTES(s) (*(uint8 *) (s) | (*((uint8 *) (s) + 1) << 8)) +#define WRITE_2BYTES(s, d) *(uint8 *) (s) = (d), \ + *((uint8 *) (s) + 1) = (d) >> 8 +#else // else MSB_FISRT +#define READ_2BYTES(s) (*(uint8 *) (s) | (*((uint8 *) (s) + 1) << 8)) +#define WRITE_2BYTES(s, d) *(uint8 *) (s) = (d), \ + *((uint8 *) (s) + 1) = (d) >> 8 +#endif // LSB_FIRST +#endif // i386 + +#define SUB_SCREEN_DEPTH 0 +#define MAIN_SCREEN_DEPTH 32 + +#if defined(OLD_COLOUR_BLENDING) +#define COLOR_ADD(C1, C2) \ +GFX.X2 [((((C1) & RGB_REMOVE_LOW_BITS_MASK) + \ + ((C2) & RGB_REMOVE_LOW_BITS_MASK)) >> 1) + \ + ((C1) & (C2) & RGB_LOW_BITS_MASK)] +#else +#define COLOR_ADD(C1, C2) \ +(GFX.X2 [((((C1) & RGB_REMOVE_LOW_BITS_MASK) + \ + ((C2) & RGB_REMOVE_LOW_BITS_MASK)) >> 1) + \ + ((C1) & (C2) & RGB_LOW_BITS_MASK)] | \ + (((C1) ^ (C2)) & RGB_LOW_BITS_MASK)) +#endif + +#define COLOR_ADD1_2(C1, C2) \ +(((((C1) & RGB_REMOVE_LOW_BITS_MASK) + \ + ((C2) & RGB_REMOVE_LOW_BITS_MASK)) >> 1) + \ + ((C1) & (C2) & RGB_LOW_BITS_MASK) | ALPHA_BITS_MASK) + +#if defined(OLD_COLOUR_BLENDING) +#define COLOR_SUB(C1, C2) \ +GFX.ZERO_OR_X2 [(((C1) | RGB_HI_BITS_MASKx2) - \ + ((C2) & RGB_REMOVE_LOW_BITS_MASK)) >> 1] +#else +#define COLOR_SUB(C1, C2) \ +(GFX.ZERO_OR_X2 [(((C1) | RGB_HI_BITS_MASKx2) - \ + ((C2) & RGB_REMOVE_LOW_BITS_MASK)) >> 1] + \ +((C1) & RGB_LOW_BITS_MASK) - ((C2) & RGB_LOW_BITS_MASK)) +#endif + +#define COLOR_SUB1_2(C1, C2) \ +GFX.ZERO [(((C1) | RGB_HI_BITS_MASKx2) - \ + ((C2) & RGB_REMOVE_LOW_BITS_MASK)) >> 1] + +typedef void (*NormalTileRenderer) (uint32 Tile, uint32 Offset, + uint32 StartLine, uint32 LineCount, struct SGFX * gfx); +typedef void (*ClippedTileRenderer) (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount, struct SGFX * gfx); +typedef void (*LargePixelRenderer) (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Pixels, + uint32 StartLine, uint32 LineCount, struct SGFX * gfx); + +START_EXTERN_C +void S9xStartScreenRefresh (); +void S9xDrawScanLine (uint8 Line); +void S9xEndScreenRefresh (); +void S9xSetupOBJ (struct SOBJ *); +void S9xUpdateScreen (); +void RenderLine (uint8 line); +void S9xBuildDirectColourMaps (); + +// External port interface which must be implemented or initialised for each +// port. +extern struct SGFX GFX; + +bool8_32 S9xGraphicsInit (); +void S9xGraphicsDeinit(); +bool8_32 S9xInitUpdate (void); +bool8_32 S9xDeinitUpdate (int Width, int Height, bool8_32 sixteen_bit); +void S9xSetPalette (); +void S9xSyncSpeed (); + +#ifdef GFX_MULTI_FORMAT +bool8_32 S9xSetRenderPixelFormat (int format); +#endif + +END_EXTERN_C + +#endif diff --git a/src/snes4iphone_src/gfx_org.cpp b/src/snes4iphone_src/gfx_org.cpp new file mode 100755 index 0000000..35d048b --- /dev/null +++ b/src/snes4iphone_src/gfx_org.cpp @@ -0,0 +1,3857 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#include "snes9x.h" + +#include "memmap.h" +#include "ppu.h" +#include "cpuexec.h" +#include "display.h" +#include "gfx.h" +#include "apu.h" +#include "cheats.h" + +#define M7 19 +#define M8 19 + +extern uint32 gp32_gammavalue; + +void ComputeClipWindows (); + +extern void S9xSetupOBJ(void); + +extern uint8 BitShifts[8][4]; +extern uint8 TileShifts[8][4]; +extern uint8 PaletteShifts[8][4]; +extern uint8 PaletteMasks[8][4]; +extern uint8 Depths[8][4]; +extern uint8 BGSizes [2]; + +extern NormalTileRenderer DrawTilePtr; +extern ClippedTileRenderer DrawClippedTilePtr; +extern NormalTileRenderer DrawHiResTilePtr; +extern ClippedTileRenderer DrawHiResClippedTilePtr; +extern LargePixelRenderer DrawLargePixelPtr; + +extern struct SBG BG; + +extern struct SLineData LineData[240]; +extern struct SLineMatrixData LineMatrixData [240]; + +extern uint8 Mode7Depths [2]; +extern unsigned char gammatab[10][32]; +#define ON_MAIN(N) \ +(GFX.r212c & (1 << (N)) && \ + !(PPU.BG_Forced & (1 << (N)))) + +#define SUB_OR_ADD(N) \ +(GFX.r2131 & (1 << (N))) + +#define ON_SUB(N) \ +((GFX.r2130 & 0x30) != 0x30 && \ + (GFX.r2130 & 2) && \ + (GFX.r212d & (1 << N)) && \ + !(PPU.BG_Forced & (1 << (N)))) + +#define ANYTHING_ON_SUB \ +((GFX.r2130 & 0x30) != 0x30 && \ + (GFX.r2130 & 2) && \ + (GFX.r212d & 0x1f)) + +#define ADD_OR_SUB_ON_ANYTHING \ +(GFX.r2131 & 0x3f) + +#define BLACK BUILD_PIXEL(0,0,0) + +void orgDrawTileHi16 (uint32 Tile, uint32 Offset, uint32 StartLine, + uint32 LineCount); +void orgDrawClippedTileHi16 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount); + +void orgDrawTile16 (uint32 Tile, uint32 Offset, uint32 StartLine, + uint32 LineCount); +void orgDrawClippedTile16 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount); +void orgDrawTile16x2 (uint32 Tile, uint32 Offset, uint32 StartLine, + uint32 LineCount); +void orgDrawClippedTile16x2 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount); +void orgDrawTile16x2x2 (uint32 Tile, uint32 Offset, uint32 StartLine, + uint32 LineCount); +void orgDrawClippedTile16x2x2 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount); +void orgDrawLargePixel16 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Pixels, + uint32 StartLine, uint32 LineCount); + +void orgDrawTile16Add (uint32 Tile, uint32 Offset, uint32 StartLine, + uint32 LineCount); + +void orgDrawClippedTile16Add (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount); + +void orgDrawTile16Add1_2 (uint32 Tile, uint32 Offset, uint32 StartLine, + uint32 LineCount); + +void orgDrawClippedTile16Add1_2 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount); + +void orgDrawTile16FixedAdd1_2 (uint32 Tile, uint32 Offset, uint32 StartLine, + uint32 LineCount); + +void orgDrawClippedTile16FixedAdd1_2 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount); + +void orgDrawTile16Sub (uint32 Tile, uint32 Offset, uint32 StartLine, + uint32 LineCount); + +void orgDrawClippedTile16Sub (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount); + +void orgDrawTile16Sub1_2 (uint32 Tile, uint32 Offset, uint32 StartLine, + uint32 LineCount); + +void orgDrawClippedTile16Sub1_2 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount); + +void orgDrawTile16FixedSub1_2 (uint32 Tile, uint32 Offset, uint32 StartLine, + uint32 LineCount); + +void orgDrawClippedTile16FixedSub1_2 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount); + +void orgDrawLargePixel16Add (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Pixels, + uint32 StartLine, uint32 LineCount); + +void orgDrawLargePixel16Add1_2 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Pixels, + uint32 StartLine, uint32 LineCount); + +void orgDrawLargePixel16Sub (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Pixels, + uint32 StartLine, uint32 LineCount); + +void orgDrawLargePixel16Sub1_2 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Pixels, + uint32 StartLine, uint32 LineCount); + + +bool8 S9xGraphicsInit () +{ + register uint32 PixelOdd = 1; + register uint32 PixelEven = 2; + +#ifdef GFX_MULTI_FORMAT + if (GFX.BuildPixel == NULL) + S9xSetRenderPixelFormat (RGB565); +#endif + + for (uint8 bitshift = 0; bitshift < 4; bitshift++) + { + for (register char i = 0; i < 16; i++) + { + register uint32 h = 0; + register uint32 l = 0; + +#if defined(LSB_FIRST) + if (i & 8) + h |= PixelOdd; + if (i & 4) + h |= PixelOdd << 8; + if (i & 2) + h |= PixelOdd << 16; + if (i & 1) + h |= PixelOdd << 24; + if (i & 8) + l |= PixelOdd; + if (i & 4) + l |= PixelOdd << 8; + if (i & 2) + l |= PixelOdd << 16; + if (i & 1) + l |= PixelOdd << 24; +#else + if (i & 8) + h |= (PixelOdd << 24); + if (i & 4) + h |= (PixelOdd << 16); + if (i & 2) + h |= (PixelOdd << 8); + if (i & 1) + h |= PixelOdd; + if (i & 8) + l |= (PixelOdd << 24); + if (i & 4) + l |= (PixelOdd << 16); + if (i & 2) + l |= (PixelOdd << 8); + if (i & 1) + l |= PixelOdd; +#endif + + odd_high[bitshift][i] = h; + odd_low[bitshift][i] = l; + h = l = 0; + +#if defined(LSB_FIRST) + if (i & 8) + h |= PixelEven; + if (i & 4) + h |= PixelEven << 8; + if (i & 2) + h |= PixelEven << 16; + if (i & 1) + h |= PixelEven << 24; + if (i & 8) + l |= PixelEven; + if (i & 4) + l |= PixelEven << 8; + if (i & 2) + l |= PixelEven << 16; + if (i & 1) + l |= PixelEven << 24; +#else + if (i & 8) + h |= (PixelEven << 24); + if (i & 4) + h |= (PixelEven << 16); + if (i & 2) + h |= (PixelEven << 8); + if (i & 1) + h |= PixelEven; + if (i & 8) + l |= (PixelEven << 24); + if (i & 4) + l |= (PixelEven << 16); + if (i & 2) + l |= (PixelEven << 8); + if (i & 1) + l |= PixelEven; +#endif + + even_high[bitshift][i] = h; + even_low[bitshift][i] = l; + } + PixelEven <<= 2; + PixelOdd <<= 2; + } + + GFX.RealPitch = GFX.Pitch2 = GFX.Pitch; + GFX.ZPitch = GFX.Pitch; + if (Settings.SixteenBit) + GFX.ZPitch >>= 1; + GFX.Delta = (GFX.SubScreen - GFX.Screen) >> 1; + GFX.DepthDelta = GFX.SubZBuffer - GFX.ZBuffer; + //GFX.InfoStringTimeout = 0; + //GFX.InfoString = NULL; + + PPU.BG_Forced = 0; + IPPU.OBJChanged = TRUE; + if (Settings.Transparency) + Settings.SixteenBit = TRUE; + + IPPU.DirectColourMapsNeedRebuild = TRUE; + GFX.PixSize = 1; + if (Settings.SixteenBit) + { + GFX.PPL = GFX.Pitch >> 1; + GFX.PPLx2 = GFX.Pitch; + } + else + { + GFX.PPL = GFX.Pitch; + GFX.PPLx2 = GFX.Pitch * 2; + } + S9xFixColourBrightness (); + +#ifdef _TRANSP_SUPPORT_ + if (!(GFX.X2 = (uint16 *) malloc (sizeof (uint16) * 0x10000))) + return (FALSE); + + if ((!(GFX.ZERO_OR_X2 = (uint16 *) malloc (sizeof (uint16) * 0x10000))) + ||!(GFX.ZERO = (uint16 *) malloc (sizeof (uint16) * 0x10000))) + { + if (GFX.ZERO_OR_X2) + { + free ((char *) GFX.ZERO_OR_X2); + GFX.ZERO_OR_X2 = NULL; + } + if (GFX.X2) + { + free ((char *) GFX.X2); + GFX.X2 = NULL; + } + return (FALSE); + } + uint32 r, g, b; + + // Build a lookup table that multiplies a packed RGB value by 2 with + // saturation. + for (r = 0; r <= MAX_RED; r++) + { + uint32 r2 = r << 1; + if (r2 > MAX_RED) + r2 = MAX_RED; + for (g = 0; g <= MAX_GREEN; g++) + { + uint32 g2 = g << 1; + if (g2 > MAX_GREEN) + g2 = MAX_GREEN; + for (b = 0; b <= MAX_BLUE; b++) + { + uint32 b2 = b << 1; + if (b2 > MAX_BLUE) + b2 = MAX_BLUE; + GFX.X2 [BUILD_PIXEL2 (r, g, b)] = BUILD_PIXEL2 (r2, g2, b2); + GFX.X2 [BUILD_PIXEL2 (r, g, b) & ~ALPHA_BITS_MASK] = BUILD_PIXEL2 (r2, g2, b2); + } + } + } + ZeroMemory (GFX.ZERO, 0x10000 * sizeof (uint16)); + ZeroMemory (GFX.ZERO_OR_X2, 0x10000 * sizeof (uint16)); + // Build a lookup table that if the top bit of the color value is zero + // then the value is zero, otherwise multiply the value by 2. Used by + // the color subtraction code. + +#if defined(OLD_COLOUR_BLENDING) + for (r = 0; r <= MAX_RED; r++) + { + uint32 r2 = r; + if ((r2 & 0x10) == 0) + r2 = 0; + else + r2 = (r2 << 1) & MAX_RED; + + for (g = 0; g <= MAX_GREEN; g++) + { + uint32 g2 = g; + if ((g2 & GREEN_HI_BIT) == 0) + g2 = 0; + else + g2 = (g2 << 1) & MAX_GREEN; + + for (b = 0; b <= MAX_BLUE; b++) + { + uint32 b2 = b; + if ((b2 & 0x10) == 0) + b2 = 0; + else + b2 = (b2 << 1) & MAX_BLUE; + + GFX.ZERO_OR_X2 [BUILD_PIXEL2 (r, g, b)] = BUILD_PIXEL2 (r2, g2, b2); + GFX.ZERO_OR_X2 [BUILD_PIXEL2 (r, g, b) & ~ALPHA_BITS_MASK] = BUILD_PIXEL2 (r2, g2, b2); + } + } + } +#else + for (r = 0; r <= MAX_RED; r++) + { + uint32 r2 = r; + if ((r2 & 0x10) == 0) + r2 = 0; + else + r2 = (r2 << 1) & MAX_RED; + + if (r2 == 0) + r2 = 1; + for (g = 0; g <= MAX_GREEN; g++) + { + uint32 g2 = g; + if ((g2 & GREEN_HI_BIT) == 0) + g2 = 0; + else + g2 = (g2 << 1) & MAX_GREEN; + + if (g2 == 0) + g2 = 1; + for (b = 0; b <= MAX_BLUE; b++) + { + uint32 b2 = b; + if ((b2 & 0x10) == 0) + b2 = 0; + else + b2 = (b2 << 1) & MAX_BLUE; + + if (b2 == 0) + b2 = 1; + GFX.ZERO_OR_X2 [BUILD_PIXEL2 (r, g, b)] = BUILD_PIXEL2 (r2, g2, b2); + GFX.ZERO_OR_X2 [BUILD_PIXEL2 (r, g, b) & ~ALPHA_BITS_MASK] = BUILD_PIXEL2 (r2, g2, b2); + } + } + } +#endif + + // Build a lookup table that if the top bit of the color value is zero + // then the value is zero, otherwise its just the value. + for (r = 0; r <= MAX_RED; r++) + { + uint32 r2 = r; + if ((r2 & 0x10) == 0) + r2 = 0; + else + r2 &= ~0x10; + + for (g = 0; g <= MAX_GREEN; g++) + { + uint32 g2 = g; + if ((g2 & GREEN_HI_BIT) == 0) + g2 = 0; + else + g2 &= ~GREEN_HI_BIT; + for (b = 0; b <= MAX_BLUE; b++) + { + uint32 b2 = b; + if ((b2 & 0x10) == 0) + b2 = 0; + else + b2 &= ~0x10; + + GFX.ZERO [BUILD_PIXEL2 (r, g, b)] = BUILD_PIXEL2 (r2, g2, b2); + GFX.ZERO [BUILD_PIXEL2 (r, g, b) & ~ALPHA_BITS_MASK] = BUILD_PIXEL2 (r2, g2, b2); + } + } + } +// GFX.ZERO = NULL; +#else + { + GFX.X2 = NULL; + GFX.ZERO_OR_X2 = NULL; + GFX.ZERO = NULL; + } +#endif + return (TRUE); +} + +void S9xGraphicsDeinit (void) +{ + // Free any memory allocated in S9xGraphicsInit + if (GFX.X2) + { + free (GFX.X2); + GFX.X2 = NULL; + } + if (GFX.ZERO_OR_X2) + { + free (GFX.ZERO_OR_X2); + GFX.ZERO_OR_X2 = NULL; + } + if (GFX.ZERO) + { + free (GFX.ZERO); + GFX.ZERO = NULL; + } +} + + +void S9xBuildDirectColourMaps () +{ + uint8 *cgamma=(uint8*)gammatab[gp32_gammavalue]; + for (uint32 p = 0; p < 8; p++) + { + for (uint32 c = 0; c < 256; c++) + { +// XXX: Brightness + DirectColourMaps [p][c] = BUILD_PIXEL (cgamma[((c & 7) << 2) | ((p & 1) << 1)], + cgamma[((c & 0x38) >> 1) | (p & 2)], + cgamma[((c & 0xc0) >> 3) | (p & 4)]); + } + } + IPPU.DirectColourMapsNeedRebuild = FALSE; +} + +void S9xStartScreenRefresh () +{ + if (GFX.InfoStringTimeout > 0 && --GFX.InfoStringTimeout == 0) + GFX.InfoString = NULL; + + if (IPPU.RenderThisFrame) + { + if (!S9xInitUpdate ()) + { + IPPU.RenderThisFrame = FALSE; + return; + } + IPPU.RenderedFramesCount++; + IPPU.PreviousLine = IPPU.CurrentLine = 0; + IPPU.MaxBrightness = PPU.Brightness; + IPPU.LatchedBlanking = PPU.ForcedBlanking; + IPPU.LatchedInterlace = (Memory.FillRAM[0x2133] & 1); +// IPPU.Interlace = (Memory.FillRAM[0x2133] & 1); + if (Settings.SupportHiRes && (PPU.BGMode == 5 || PPU.BGMode == 6 || + IPPU.LatchedInterlace/*IPPU.Interlace*/)) + { + if (PPU.BGMode == 5 || PPU.BGMode == 6) + { + IPPU.RenderedScreenWidth = 512; + IPPU.DoubleWidthPixels = TRUE; + } + if (/*IPPU.Interlace*/IPPU.LatchedInterlace) + { + IPPU.RenderedScreenHeight = PPU.ScreenHeight << 1; + GFX.Pitch2 = GFX.RealPitch; + GFX.Pitch = GFX.RealPitch * 2; + if (Settings.SixteenBit) + GFX.PPL = GFX.PPLx2 = GFX.RealPitch; + else + GFX.PPL = GFX.PPLx2 = GFX.RealPitch << 1; + } + else + { + IPPU.RenderedScreenHeight = PPU.ScreenHeight; + GFX.Pitch2 = GFX.Pitch = GFX.RealPitch; + if (Settings.SixteenBit) + GFX.PPL = GFX.Pitch >> 1; + else + GFX.PPL = GFX.Pitch; + GFX.PPLx2 = GFX.PPL << 1; + } +#if defined(USE_GLIDE) || defined(USE_OPENGL) + GFX.ZPitch = GFX.RealPitch; + if (Settings.SixteenBit) + GFX.ZPitch >>= 1; +#endif + } + else + { + IPPU.RenderedScreenWidth = 256; + IPPU.RenderedScreenHeight = PPU.ScreenHeight; + IPPU.DoubleWidthPixels = FALSE; + { + GFX.Pitch2 = GFX.Pitch = GFX.RealPitch; + GFX.PPL = GFX.PPLx2 >> 1; + GFX.ZPitch = GFX.RealPitch; + if (Settings.SixteenBit) + GFX.ZPitch >>= 1; + } + } + PPU.RecomputeClipWindows = TRUE; + GFX.DepthDelta = GFX.SubZBuffer - GFX.ZBuffer; + GFX.Delta = (GFX.SubScreen - GFX.Screen) >> 1; + } + if (++IPPU.FrameCount % Memory.ROMFramesPerSecond == 0) + { + IPPU.DisplayedRenderedFrameCount = IPPU.RenderedFramesCount; + IPPU.RenderedFramesCount = 0; + IPPU.FrameCount = 0; + } + +} + +void RenderLine (uint8 C) +{ + if (IPPU.RenderThisFrame) + { + LineData[C].BG[0].VOffset = PPU.BG[0].VOffset + 1; + LineData[C].BG[0].HOffset = PPU.BG[0].HOffset; + LineData[C].BG[1].VOffset = PPU.BG[1].VOffset + 1; + LineData[C].BG[1].HOffset = PPU.BG[1].HOffset; + + if (PPU.BGMode == 7) + { + struct SLineMatrixData *p = &LineMatrixData [C]; + p->MatrixA = PPU.MatrixA; + p->MatrixB = PPU.MatrixB; + p->MatrixC = PPU.MatrixC; + p->MatrixD = PPU.MatrixD; + p->CentreX = PPU.CentreX; + p->CentreY = PPU.CentreY; + } + else + { + if (Settings.StarfoxHack && PPU.BG[2].VOffset == 0 && + PPU.BG[2].HOffset == 0xe000) + { + LineData[C].BG[2].VOffset = 0xe1; + LineData[C].BG[2].HOffset = 0; + } + else + { + LineData[C].BG[2].VOffset = PPU.BG[2].VOffset + 1; + LineData[C].BG[2].HOffset = PPU.BG[2].HOffset; + LineData[C].BG[3].VOffset = PPU.BG[3].VOffset + 1; + LineData[C].BG[3].HOffset = PPU.BG[3].HOffset; + } + } + IPPU.CurrentLine = C + 1; + } +} + +void S9xEndScreenRefresh () +{ + IPPU.HDMAStarted = FALSE; + if (IPPU.RenderThisFrame) + { + FLUSH_REDRAW (); + if (IPPU.ColorsChanged) + { + uint32 saved = PPU.CGDATA[0]; + if (!Settings.SixteenBit) + { + // Hack for Super Mario World - to get its sky blue + // (It uses Fixed colour addition on the backdrop colour) + if (!(Memory.FillRAM [0x2131] & 0x80) && + (Memory.FillRAM[0x2131] & 0x20) && + (PPU.FixedColourRed || PPU.FixedColourGreen || + PPU.FixedColourBlue)) + { + PPU.CGDATA[0] = PPU.FixedColourRed | + (PPU.FixedColourGreen << 5) | + (PPU.FixedColourBlue << 10); + } + } + IPPU.ColorsChanged = FALSE; + S9xSetPalette (); + PPU.CGDATA[0] = saved; + } + GFX.Pitch = GFX.Pitch2 = GFX.RealPitch; + GFX.PPL = GFX.PPLx2 >> 1; + + +/* if (Settings.DisplayFrameRate) + S9xDisplayFrameRate (); + if (GFX.InfoString) + S9xDisplayString (GFX.InfoString);*/ + + S9xDeinitUpdate (IPPU.RenderedScreenWidth, IPPU.RenderedScreenHeight, + Settings.SixteenBit); + } +// S9xApplyCheats (); +#ifdef DEBUGGER + if (CPU.Flags & FRAME_ADVANCE_FLAG) + { + if (ICPU.FrameAdvanceCount) + { + ICPU.FrameAdvanceCount--; + IPPU.RenderThisFrame = TRUE; + IPPU.FrameSkip = 0; + } + else + { + CPU.Flags &= ~FRAME_ADVANCE_FLAG; + CPU.Flags |= DEBUG_MODE_FLAG; + } + } +#endif + if (CPU.SRAMModified) + { + if (!CPU.AutoSaveTimer) + { + if (!(CPU.AutoSaveTimer = Settings.AutoSaveDelay * Memory.ROMFramesPerSecond)) + CPU.SRAMModified = FALSE; + } + else + { + if (!--CPU.AutoSaveTimer) + { + S9xAutoSaveSRAM (); + CPU.SRAMModified = FALSE; + } + } + } +} + +void S9xSetInfoString (const char *string) +{ + GFX.InfoString = string; + GFX.InfoStringTimeout = 120; +} + + + + +void S9xSetupOBJ () +{ + int SmallSize; + int LargeSize; + + switch (PPU.OBJSizeSelect) + { + case 0: + SmallSize = 8; + LargeSize = 16; + break; + case 1: + SmallSize = 8; + LargeSize = 32; + break; + case 2: + SmallSize = 8; + LargeSize = 64; + break; + case 3: + SmallSize = 16; + LargeSize = 32; + break; + case 4: + SmallSize = 16; + LargeSize = 64; + break; + case 5: + default: + SmallSize = 32; + LargeSize = 64; + break; + } + + int C = 0; + + int FirstSprite = PPU.FirstSprite & 0x7f; + int S = FirstSprite; + do + { + int Size; + if (PPU.OBJ [S].Size) + Size = LargeSize; + else + Size = SmallSize; + + long VPos = PPU.OBJ [S].VPos; + + if (VPos >= PPU.ScreenHeight) + VPos -= 256; + if (PPU.OBJ [S].HPos < 256 && PPU.OBJ [S].HPos > -Size && + VPos < PPU.ScreenHeight && VPos > -Size) + { + GFX.OBJList [C++] = S; + GFX.Sizes[S] = Size; + GFX.VPositions[S] = VPos; + } + S = (S + 1) & 0x7f; + } while (S != FirstSprite); + + // Terminate the list + GFX.OBJList [C] = -1; + IPPU.OBJChanged = FALSE; +} + + + + +inline void orgSelectTileRenderer (bool8 normal) +{ + DrawHiResTilePtr= orgDrawTileHi16; + DrawHiResClippedTilePtr = orgDrawClippedTileHi16; + + + if (normal) + { + DrawTilePtr = orgDrawTile16; + DrawClippedTilePtr = orgDrawClippedTile16; + DrawLargePixelPtr = orgDrawLargePixel16; + } + else + { + if (GFX.r2131 & 0x80) + { + if (GFX.r2131 & 0x40) + { + if (GFX.r2130 & 2) + { + DrawTilePtr = orgDrawTile16Sub1_2; + DrawClippedTilePtr = orgDrawClippedTile16Sub1_2; + } + else + { + // Fixed colour substraction + DrawTilePtr = orgDrawTile16FixedSub1_2; + DrawClippedTilePtr = orgDrawClippedTile16FixedSub1_2; + } + DrawLargePixelPtr = orgDrawLargePixel16Sub1_2; + } + else + { + DrawTilePtr = orgDrawTile16Sub; + DrawClippedTilePtr = orgDrawClippedTile16Sub; + DrawLargePixelPtr = orgDrawLargePixel16Sub; + } + } + else + { + if (GFX.r2131 & 0x40) + { + if (GFX.r2130 & 2) + { + DrawTilePtr = orgDrawTile16Add1_2; + DrawClippedTilePtr = orgDrawClippedTile16Add1_2; + } + else + { + // Fixed colour addition + DrawTilePtr = orgDrawTile16FixedAdd1_2; + DrawClippedTilePtr = orgDrawClippedTile16FixedAdd1_2; + } + DrawLargePixelPtr = orgDrawLargePixel16Add1_2; + } + else + { + DrawTilePtr = orgDrawTile16Add; + DrawClippedTilePtr = orgDrawClippedTile16Add; + DrawLargePixelPtr = orgDrawLargePixel16Add; + } + } + } +} + +void orgDrawOBJS (bool8 OnMain = FALSE, uint8 D = 0) +{ + uint32 O; + uint32 BaseTile, Tile; + + CHECK_SOUND(); + + BG.BitShift = 4; + BG.TileShift = 5; + BG.TileAddress = PPU.OBJNameBase; + BG.StartPalette = 128; + BG.PaletteShift = 4; + BG.PaletteMask = 7; + BG.Buffer = IPPU.TileCache [TILE_4BIT]; + BG.Buffered = IPPU.TileCached [TILE_4BIT]; + BG.NameSelect = PPU.OBJNameSelect; + BG.DirectColourMode = FALSE; + + GFX.PixSize = 1; + + + + DrawTilePtr = orgDrawTile16; + DrawClippedTilePtr = orgDrawClippedTile16; + + GFX.Z1 = D + 2; + + int I = 0; + for (int S = GFX.OBJList [I++]; S >= 0; S = GFX.OBJList [I++]) + { + int VPos = GFX.VPositions [S]; + int Size = GFX.Sizes[S]; + int TileInc = 1; + int Offset; + + if (VPos + Size <= (int) GFX.StartY || VPos > (int) GFX.EndY) + continue; + + if (OnMain && SUB_OR_ADD(4)) + { + orgSelectTileRenderer (!GFX.Pseudo && PPU.OBJ [S].Palette < 4); + } + + BaseTile = PPU.OBJ[S].Name | (PPU.OBJ[S].Palette << 10); + + if (PPU.OBJ[S].HFlip) + { + BaseTile += ((Size >> 3) - 1) | H_FLIP; + TileInc = -1; + } + if (PPU.OBJ[S].VFlip) + BaseTile |= V_FLIP; + + int clipcount = GFX.pCurrentClip->Count [4]; + if (!clipcount) + clipcount = 1; + + GFX.Z2 = (PPU.OBJ[S].Priority + 1) * 4 + D; + + for (int clip = 0; clip < clipcount; clip++) + { + int Left; + int Right; + if (!GFX.pCurrentClip->Count [4]) + { + Left = 0; + Right = 256; + } + else + { + Left = GFX.pCurrentClip->Left [clip][4]; + Right = GFX.pCurrentClip->Right [clip][4]; + } + + if (Right <= Left || PPU.OBJ[S].HPos + Size <= Left || + PPU.OBJ[S].HPos >= Right) + continue; + + for (int Y = 0; Y < Size; Y += 8) + { + if (VPos + Y + 7 >= (int) GFX.StartY && VPos + Y <= (int) GFX.EndY) + { + int StartLine; + int TileLine; + int LineCount; + int Last; + + if ((StartLine = VPos + Y) < (int) GFX.StartY) + { + StartLine = GFX.StartY - StartLine; + LineCount = 8 - StartLine; + } + else + { + StartLine = 0; + LineCount = 8; + } + if ((Last = VPos + Y + 7 - GFX.EndY) > 0) + if ((LineCount -= Last) <= 0) + break; + + TileLine = StartLine << 3; + O = (VPos + Y + StartLine) * GFX.PPL; + if (!PPU.OBJ[S].VFlip) + Tile = BaseTile + (Y << 1); + else + Tile = BaseTile + ((Size - Y - 8) << 1); + + int Middle = Size >> 3; + if (PPU.OBJ[S].HPos < Left) + { + Tile += ((Left - PPU.OBJ[S].HPos) >> 3) * TileInc; + Middle -= (Left - PPU.OBJ[S].HPos) >> 3; + O += Left * GFX.PixSize; + if ((Offset = (Left - PPU.OBJ[S].HPos) & 7)) + { + O -= Offset * GFX.PixSize; + int W = 8 - Offset; + int Width = Right - Left; + if (W > Width) + W = Width; + (*DrawClippedTilePtr) (Tile, O, Offset, W, + TileLine, LineCount); + + if (W >= Width) + continue; + Tile += TileInc; + Middle--; + O += 8 * GFX.PixSize; + } + } + else + O += PPU.OBJ[S].HPos * GFX.PixSize; + + if (PPU.OBJ[S].HPos + Size >= Right) + { + Middle -= ((PPU.OBJ[S].HPos + Size + 7) - + Right) >> 3; + Offset = (Right - (PPU.OBJ[S].HPos + Size)) & 7; + } + else + Offset = 0; + + for (int X = 0; X < Middle; X++, O += 8 * GFX.PixSize, + Tile += TileInc) + { + (*DrawTilePtr) (Tile, O, TileLine, LineCount); + } + if (Offset) + { + (*DrawClippedTilePtr) (Tile, O, 0, Offset, + TileLine, LineCount); + } + } + } + } + } +} + +void orgDrawBackgroundMosaic (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2) +{ + CHECK_SOUND(); + + uint32 Tile; + uint16 *SC0; + uint16 *SC1; + uint16 *SC2; + uint16 *SC3; + uint8 depths [2] = {Z1, Z2}; + + if (BGMode == 0) + BG.StartPalette = bg << 5; + else + BG.StartPalette = 0; + + SC0 = (uint16 *) &Memory.VRAM[PPU.BG[bg].SCBase << 1]; + + if (PPU.BG[bg].SCSize & 1) + SC1 = SC0 + 1024; + else + SC1 = SC0; + + if((SC1-(unsigned short*)Memory.VRAM)>0x10000) + SC1-=0x10000; + + + if (PPU.BG[bg].SCSize & 2) + SC2 = SC1 + 1024; + else + SC2 = SC0; + + if((SC2-(unsigned short*)Memory.VRAM)>0x10000) + SC2-=0x10000; + + + if (PPU.BG[bg].SCSize & 1) + SC3 = SC2 + 1024; + else + SC3 = SC2; + + if((SC3-(unsigned short*)Memory.VRAM)>0x10000) + SC3-=0x10000; + + uint32 Lines; + uint32 OffsetMask; + uint32 OffsetShift; + + if (BG.TileSize == 16) + { + OffsetMask = 0x3ff; + OffsetShift = 4; + } + else + { + OffsetMask = 0x1ff; + OffsetShift = 3; + } + + for (uint32 Y = GFX.StartY; Y <= GFX.EndY; Y += Lines) + { + uint32 VOffset = LineData [Y].BG[bg].VOffset; + uint32 HOffset = LineData [Y].BG[bg].HOffset; + uint32 MosaicOffset = Y % PPU.Mosaic; + + for (Lines = 1; Lines < PPU.Mosaic - MosaicOffset; Lines++) + if ((VOffset != LineData [Y + Lines].BG[bg].VOffset) || + (HOffset != LineData [Y + Lines].BG[bg].HOffset)) + break; + + uint32 MosaicLine = VOffset + Y - MosaicOffset; + + if (Y + Lines > GFX.EndY) + Lines = GFX.EndY + 1 - Y; + uint32 VirtAlign = (MosaicLine & 7) << 3; + + uint16 *b1; + uint16 *b2; + + uint32 ScreenLine = MosaicLine >> OffsetShift; + uint32 Rem16 = MosaicLine & 15; + + if (ScreenLine & 0x20) + b1 = SC2, b2 = SC3; + else + b1 = SC0, b2 = SC1; + + b1 += (ScreenLine & 0x1f) << 5; + b2 += (ScreenLine & 0x1f) << 5; + uint16 *t; + uint32 Left = 0; + uint32 Right = 256; + + uint32 ClipCount = GFX.pCurrentClip->Count [bg]; + uint32 HPos = HOffset; + uint32 PixWidth = PPU.Mosaic; + + if (!ClipCount) + ClipCount = 1; + + for (uint32 clip = 0; clip < ClipCount; clip++) + { + if (GFX.pCurrentClip->Count [bg]) + { + Left = GFX.pCurrentClip->Left [clip][bg]; + Right = GFX.pCurrentClip->Right [clip][bg]; + uint32 r = Left % PPU.Mosaic; + HPos = HOffset + Left; + PixWidth = PPU.Mosaic - r; + } + uint32 s = Y * GFX.PPL + Left * GFX.PixSize; + for (uint32 x = Left; x < Right; x += PixWidth, + s += PixWidth * GFX.PixSize, + HPos += PixWidth, PixWidth = PPU.Mosaic) + { + uint32 Quot = (HPos & OffsetMask) >> 3; + + if (x + PixWidth >= Right) + PixWidth = Right - x; + + if (BG.TileSize == 8) + { + if (Quot > 31) + t = b2 + (Quot & 0x1f); + else + t = b1 + Quot; + } + else + { + if (Quot > 63) + t = b2 + ((Quot >> 1) & 0x1f); + else + t = b1 + (Quot >> 1); + } + + Tile = READ_2BYTES (t); + GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13]; + + // orgDraw tile... + if (BG.TileSize != 8) + { + if (Tile & H_FLIP) + { + // Horizontal flip, but what about vertical flip ? + if (Tile & V_FLIP) + { + // Both horzontal & vertical flip + if (Rem16 < 8) + { + (*DrawLargePixelPtr) (Tile + 17 - (Quot & 1), s, + HPos & 7, PixWidth, + VirtAlign, Lines); + } + else + { + (*DrawLargePixelPtr) (Tile + 1 - (Quot & 1), s, + HPos & 7, PixWidth, + VirtAlign, Lines); + } + } + else + { + // Horizontal flip only + if (Rem16 > 7) + { + (*DrawLargePixelPtr) (Tile + 17 - (Quot & 1), s, + HPos & 7, PixWidth, + VirtAlign, Lines); + } + else + { + (*DrawLargePixelPtr) (Tile + 1 - (Quot & 1), s, + HPos & 7, PixWidth, + VirtAlign, Lines); + } + } + } + else + { + // No horizontal flip, but is there a vertical flip ? + if (Tile & V_FLIP) + { + // Vertical flip only + if (Rem16 < 8) + { + (*DrawLargePixelPtr) (Tile + 16 + (Quot & 1), s, + HPos & 7, PixWidth, + VirtAlign, Lines); + } + else + { + (*DrawLargePixelPtr) (Tile + (Quot & 1), s, + HPos & 7, PixWidth, + VirtAlign, Lines); + } + } + else + { + // Normal unflipped + if (Rem16 > 7) + { + (*DrawLargePixelPtr) (Tile + 16 + (Quot & 1), s, + HPos & 7, PixWidth, + VirtAlign, Lines); + } + else + { + (*DrawLargePixelPtr) (Tile + (Quot & 1), s, + HPos & 7, PixWidth, + VirtAlign, Lines); + } + } + } + } + else + (*DrawLargePixelPtr) (Tile, s, HPos & 7, PixWidth, + VirtAlign, Lines); + } + } + } +} + +void orgDrawBackgroundOffset (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2) +{ + CHECK_SOUND(); + + uint32 Tile; + uint16 *SC0; + uint16 *SC1; + uint16 *SC2; + uint16 *SC3; + uint16 *BPS0; + uint16 *BPS1; + uint16 *BPS2; + uint16 *BPS3; + uint32 Width; + int VOffsetOffset = BGMode == 4 ? 0 : 32; + uint8 depths [2] = {Z1, Z2}; + + BG.StartPalette = 0; + + BPS0 = (uint16 *) &Memory.VRAM[PPU.BG[2].SCBase << 1]; + + if (PPU.BG[2].SCSize & 1) + BPS1 = BPS0 + 1024; + else + BPS1 = BPS0; + + if (PPU.BG[2].SCSize & 2) + BPS2 = BPS1 + 1024; + else + BPS2 = BPS0; + + if (PPU.BG[2].SCSize & 1) + BPS3 = BPS2 + 1024; + else + BPS3 = BPS2; + + SC0 = (uint16 *) &Memory.VRAM[PPU.BG[bg].SCBase << 1]; + + if (PPU.BG[bg].SCSize & 1) + SC1 = SC0 + 1024; + else + SC1 = SC0; + + if((SC1-(unsigned short*)Memory.VRAM)>0x10000) + SC1-=0x10000; + + + if (PPU.BG[bg].SCSize & 2) + SC2 = SC1 + 1024; + else + SC2 = SC0; + + if((SC2-(unsigned short*)Memory.VRAM)>0x10000) + SC2-=0x10000; + + + if (PPU.BG[bg].SCSize & 1) + SC3 = SC2 + 1024; + else + SC3 = SC2; + + if((SC3-(unsigned short*)Memory.VRAM)>0x10000) + SC3-=0x10000; + + + static const int Lines = 1; + int OffsetMask; + int OffsetShift; + int OffsetEnableMask = 1 << (bg + 13); + + if (BG.TileSize == 16) + { + OffsetMask = 0x3ff; + OffsetShift = 4; + } + else + { + OffsetMask = 0x1ff; + OffsetShift = 3; + } + + for (uint32 Y = GFX.StartY; Y <= GFX.EndY; Y++) + { + uint32 VOff = LineData [Y].BG[2].VOffset - 1; +// uint32 VOff = LineData [Y].BG[2].VOffset; + uint32 HOff = LineData [Y].BG[2].HOffset; + + int VirtAlign; + int ScreenLine = VOff >> 3; + int t1; + int t2; + uint16 *s0; + uint16 *s1; + uint16 *s2; + + if (ScreenLine & 0x20) + s1 = BPS2, s2 = BPS3; + else + s1 = BPS0, s2 = BPS1; + + s1 += (ScreenLine & 0x1f) << 5; + s2 += (ScreenLine & 0x1f) << 5; + + if(BGMode != 4) + { + if((ScreenLine & 0x1f) == 0x1f) + { + if(ScreenLine & 0x20) + VOffsetOffset = BPS0 - BPS2 - 0x1f*32; + else + VOffsetOffset = BPS2 - BPS0 - 0x1f*32; + } + else + { + VOffsetOffset = 32; + } + } + + int clipcount = GFX.pCurrentClip->Count [bg]; + if (!clipcount) + clipcount = 1; + + for (int clip = 0; clip < clipcount; clip++) + { + uint32 Left; + uint32 Right; + + if (!GFX.pCurrentClip->Count [bg]) + { + Left = 0; + Right = 256; + } + else + { + Left = GFX.pCurrentClip->Left [clip][bg]; + Right = GFX.pCurrentClip->Right [clip][bg]; + + if (Right <= Left) + continue; + } + + uint32 VOffset; + uint32 HOffset; + //added: + uint32 LineHOffset=LineData [Y].BG[bg].HOffset; + + uint32 Offset; + uint32 HPos; + uint32 Quot; + uint32 Count; + uint16 *t; + uint32 Quot2; + uint32 VCellOffset; + uint32 HCellOffset; + uint16 *b1; + uint16 *b2; + uint32 TotalCount = 0; + uint32 MaxCount = 8; + + uint32 s = Left * GFX.PixSize + Y * GFX.PPL; + bool8 left_hand_edge = (Left == 0); + Width = Right - Left; + + if (Left & 7) + MaxCount = 8 - (Left & 7); + + while (Left < Right) + { + if (left_hand_edge) + { + // The SNES offset-per-tile background mode has a + // hardware limitation that the offsets cannot be set + // for the tile at the left-hand edge of the screen. + VOffset = LineData [Y].BG[bg].VOffset; + + //MKendora; use temp var to reduce memory accesses + //HOffset = LineData [Y].BG[bg].HOffset; + + HOffset = LineHOffset; + //End MK + + left_hand_edge = FALSE; + } + else + + { + // All subsequent offset tile data is shifted left by one, + // hence the - 1 below. + + Quot2 = ((HOff + Left - 1) & OffsetMask) >> 3; + + if (Quot2 > 31) + s0 = s2 + (Quot2 & 0x1f); + else + s0 = s1 + Quot2; + + HCellOffset = READ_2BYTES (s0); + + if (BGMode == 4) + { + VOffset = LineData [Y].BG[bg].VOffset; + + //MKendora another mem access hack + //HOffset = LineData [Y].BG[bg].HOffset; + HOffset=LineHOffset; + //end MK + + if ((HCellOffset & OffsetEnableMask)) + { + if (HCellOffset & 0x8000) + VOffset = HCellOffset + 1; + else + HOffset = HCellOffset; + } + } + else + { + VCellOffset = READ_2BYTES (s0 + VOffsetOffset); + if ((VCellOffset & OffsetEnableMask)) + VOffset = VCellOffset + 1; + else + VOffset = LineData [Y].BG[bg].VOffset; + + //MKendora Strike Gunner fix + if ((HCellOffset & OffsetEnableMask)) + { + //HOffset= HCellOffset; + + HOffset = (HCellOffset & ~7)|(LineHOffset&7); + //HOffset |= LineData [Y].BG[bg].HOffset&7; + } + else + HOffset=LineHOffset; + //HOffset = LineData [Y].BG[bg].HOffset - + //Settings.StrikeGunnerOffsetHack; + //HOffset &= (~7); + //end MK + } + } + VirtAlign = ((Y + VOffset) & 7) << 3; + ScreenLine = (VOffset + Y) >> OffsetShift; + + if (((VOffset + Y) & 15) > 7) + { + t1 = 16; + t2 = 0; + } + else + { + t1 = 0; + t2 = 16; + } + + if (ScreenLine & 0x20) + b1 = SC2, b2 = SC3; + else + b1 = SC0, b2 = SC1; + + b1 += (ScreenLine & 0x1f) << 5; + b2 += (ScreenLine & 0x1f) << 5; + + HPos = (HOffset + Left) & OffsetMask; + + Quot = HPos >> 3; + + if (BG.TileSize == 8) + { + if (Quot > 31) + t = b2 + (Quot & 0x1f); + else + t = b1 + Quot; + } + else + { + if (Quot > 63) + t = b2 + ((Quot >> 1) & 0x1f); + else + t = b1 + (Quot >> 1); + } + + if (MaxCount + TotalCount > Width) + MaxCount = Width - TotalCount; + + Offset = HPos & 7; + + //Count =1; + Count = 8 - Offset; + if (Count > MaxCount) + Count = MaxCount; + + s -= Offset * GFX.PixSize; + Tile = READ_2BYTES(t); + GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13]; + + if (BG.TileSize == 8) + (*DrawClippedTilePtr) (Tile, s, Offset, Count, VirtAlign, Lines); + else + { + if (!(Tile & (V_FLIP | H_FLIP))) + { + // Normal, unflipped + (*DrawClippedTilePtr) (Tile + t1 + (Quot & 1), + s, Offset, Count, VirtAlign, Lines); + } + else + if (Tile & H_FLIP) + { + if (Tile & V_FLIP) + { + // H & V flip + (*DrawClippedTilePtr) (Tile + t2 + 1 - (Quot & 1), + s, Offset, Count, VirtAlign, Lines); + } + else + { + // H flip only + (*DrawClippedTilePtr) (Tile + t1 + 1 - (Quot & 1), + s, Offset, Count, VirtAlign, Lines); + } + } + else + { + // V flip only + (*DrawClippedTilePtr) (Tile + t2 + (Quot & 1), + s, Offset, Count, VirtAlign, Lines); + } + } + + Left += Count; + TotalCount += Count; + s += (Offset + Count) * GFX.PixSize; + MaxCount = 8; + } + } + } +} + +void orgDrawBackgroundMode5 (uint32 /* BGMODE */, uint32 bg, uint8 Z1, uint8 Z2) +{ + CHECK_SOUND(); + + GFX.Pitch = GFX.RealPitch; + GFX.PPL = GFX.PPLx2 >> 1; + GFX.PixSize = 1; + uint8 depths [2] = {Z1, Z2}; + + uint32 Tile; + uint16 *SC0; + uint16 *SC1; + uint16 *SC2; + uint16 *SC3; + uint32 Width; + + BG.StartPalette = 0; + + SC0 = (uint16 *) &Memory.VRAM[PPU.BG[bg].SCBase << 1]; + + if ((PPU.BG[bg].SCSize & 1)) + SC1 = SC0 + 1024; + else + SC1 = SC0; + + if((SC1-(unsigned short*)Memory.VRAM)>0x10000) + SC1=(uint16*)&Memory.VRAM[(((uint8*)SC1)-Memory.VRAM)%0x10000]; + + if ((PPU.BG[bg].SCSize & 2)) + SC2 = SC1 + 1024; + else + SC2 = SC0; + + if((SC2-(unsigned short*)Memory.VRAM)>0x10000) + SC2=(uint16*)&Memory.VRAM[(((uint8*)SC2)-Memory.VRAM)%0x10000]; + + + if ((PPU.BG[bg].SCSize & 1)) + SC3 = SC2 + 1024; + else + SC3 = SC2; + + if((SC3-(unsigned short*)Memory.VRAM)>0x10000) + SC3=(uint16*)&Memory.VRAM[(((uint8*)SC3)-Memory.VRAM)%0x10000]; + + + int Lines; + int VOffsetMask; + int VOffsetShift; + + if (BG.TileSize == 16) + { + VOffsetMask = 0x3ff; + VOffsetShift = 4; + } + else + { + VOffsetMask = 0x1ff; + VOffsetShift = 3; + } + int endy = GFX.EndY; + + for (int Y = GFX.StartY; Y <= endy; Y += Lines) + { + int y = Y; + uint32 VOffset = LineData [y].BG[bg].VOffset; + uint32 HOffset = LineData [y].BG[bg].HOffset; + int VirtAlign = (Y + VOffset) & 7; + + for (Lines = 1; Lines < 8 - VirtAlign; Lines++) + if ((VOffset != LineData [y + Lines].BG[bg].VOffset) || + (HOffset != LineData [y + Lines].BG[bg].HOffset)) + break; + + HOffset <<= 1; + if (Y + Lines > endy) + Lines = endy + 1 - Y; +// VirtAlign <<= 3; + + int ScreenLine = (VOffset + Y) >> VOffsetShift; + int t1; + int t2; + if (((VOffset + Y) & 15) > 7) + { + t1 = 16; + t2 = 0; + } + else + { + t1 = 0; + t2 = 16; + } + uint16 *b1; + uint16 *b2; + + if (ScreenLine & 0x20) + b1 = SC2, b2 = SC3; + else + b1 = SC0, b2 = SC1; + + b1 += (ScreenLine & 0x1f) << 5; + b2 += (ScreenLine & 0x1f) << 5; + + int clipcount = GFX.pCurrentClip->Count [bg]; + if (!clipcount) + clipcount = 1; + for (int clip = 0; clip < clipcount; clip++) + { + int Left; + int Right; + + if (!GFX.pCurrentClip->Count [bg]) + { + Left = 0; + Right = 512; + } + else + { + Left = GFX.pCurrentClip->Left [clip][bg]* 2; + Right = GFX.pCurrentClip->Right [clip][bg] * 2; + + if (Right <= Left) + continue; + } + + uint32 s = (Left>>1) /** GFX.PixSize*/ + Y * 256;//GFX.PPL; + uint32 HPos = (HOffset + Left /** GFX.PixSize*/) & 0x3ff; + + uint32 Quot = HPos >> 3; + uint32 Count = 0; + + uint16 *t; + if (Quot > 63) + t = b2 + ((Quot >> 1) & 0x1f); + else + t = b1 + (Quot >> 1); + + Width = Right - Left; + // Left hand edge clipped tile + if (HPos & 7) + { + int Offset = (HPos & 7); + Count = 8 - Offset; + if (Count > Width) + Count = Width; + s -= Offset>>1; + Tile = READ_2BYTES (t); + GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13]; + + if (BG.TileSize == 8) + { + if (!(Tile & H_FLIP)) + { + // Normal, unflipped + (*DrawHiResClippedTilePtr) (Tile + (Quot & 1), + s, Offset, Count, VirtAlign, Lines); + } + else + { + // H flip + (*DrawHiResClippedTilePtr) (Tile + 1 - (Quot & 1), + s, Offset, Count, VirtAlign, Lines); + } + } + else + { + if (!(Tile & (V_FLIP | H_FLIP))) + { + // Normal, unflipped + (*DrawHiResClippedTilePtr) (Tile + t1 + (Quot & 1), + s, Offset, Count, VirtAlign, Lines); + } + else + if (Tile & H_FLIP) + { + if (Tile & V_FLIP) + { + // H & V flip + (*DrawHiResClippedTilePtr) (Tile + t2 + 1 - (Quot & 1), + s, Offset, Count, VirtAlign, Lines); + } + else + { + // H flip only + (*DrawHiResClippedTilePtr) (Tile + t1 + 1 - (Quot & 1), + s, Offset, Count, VirtAlign, Lines); + } + } + else + { + // V flip only + (*DrawHiResClippedTilePtr) (Tile + t2 + (Quot & 1), + s, Offset, Count, VirtAlign, Lines); + } + } + + t += Quot & 1; + if (Quot == 63) + t = b2; + else if (Quot == 127) + t = b1; + Quot++; + s += /*8*/4; + } + + // Middle, unclipped tiles + Count = Width - Count; + int Middle = Count >> 3; + Count &= 7; + for (int C = Middle; C > 0; s += /*8*/4, Quot++, C--) + { + Tile = READ_2BYTES(t); + GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13]; + if (BG.TileSize == 8) + { + if (!(Tile & H_FLIP)) + { + // Normal, unflipped + (*DrawHiResTilePtr) (Tile + (Quot & 1), + s, VirtAlign, Lines); + } + else + { + // H flip + (*DrawHiResTilePtr) (Tile + 1 - (Quot & 1), + s, VirtAlign, Lines); + } + } + else + { + if (!(Tile & (V_FLIP | H_FLIP))) + { + // Normal, unflipped + (*DrawHiResTilePtr) (Tile + t1 + (Quot & 1), + s, VirtAlign, Lines); + } + else + if (Tile & H_FLIP) + { + if (Tile & V_FLIP) + { + // H & V flip + (*DrawHiResTilePtr) (Tile + t2 + 1 - (Quot & 1), + s, VirtAlign, Lines); + } + else + { + // H flip only + (*DrawHiResTilePtr) (Tile + t1 + 1 - (Quot & 1), + s, VirtAlign, Lines); + } + } + else + { + // V flip only + (*DrawHiResTilePtr) (Tile + t2 + (Quot & 1), + s, VirtAlign, Lines); + } + } + + t += Quot & 1; + if (Quot == 63) + t = b2; + else + if (Quot == 127) + t = b1; + } + + // Right-hand edge clipped tiles + if (Count) + { + Tile = READ_2BYTES(t); + GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13]; + if (BG.TileSize == 8) + { + if (!(Tile & H_FLIP)) + { + // Normal, unflipped + (*DrawHiResClippedTilePtr) (Tile + (Quot & 1), + s, 0, Count, VirtAlign, Lines); + } + else + { + // H flip + (*DrawHiResClippedTilePtr) (Tile + 1 - (Quot & 1), + s, 0, Count, VirtAlign, Lines); + } + } + else + { + if (!(Tile & (V_FLIP | H_FLIP))) + { + // Normal, unflipped + (*DrawHiResClippedTilePtr) (Tile + t1 + (Quot & 1), + s, 0, Count, VirtAlign, Lines); + } + else + if (Tile & H_FLIP) + { + if (Tile & V_FLIP) + { + // H & V flip + (*DrawHiResClippedTilePtr) (Tile + t2 + 1 - (Quot & 1), + s, 0, Count, VirtAlign, Lines); + } + else + { + // H flip only + (*DrawHiResClippedTilePtr) (Tile + t1 + 1 - (Quot & 1), + s, 0, Count, VirtAlign, Lines); + } + } + else + { + // V flip only + (*DrawHiResClippedTilePtr) (Tile + t2 + (Quot & 1), + s, 0, Count, VirtAlign, Lines); + } + } + } + } + } + GFX.Pitch = GFX.RealPitch; + GFX.PPL = GFX.PPLx2 >> 1; +} + +void orgDrawBackground (uint32 BGMode, uint32 bg, uint8 Z1, uint8 Z2) +{ + GFX.PixSize = 1; + + BG.TileSize = BGSizes [PPU.BG[bg].BGSize]; + BG.BitShift = BitShifts[BGMode][bg]; + BG.TileShift = TileShifts[BGMode][bg]; + BG.TileAddress = PPU.BG[bg].NameBase << 1; + BG.NameSelect = 0; + BG.Buffer = IPPU.TileCache [Depths [BGMode][bg]]; + BG.Buffered = IPPU.TileCached [Depths [BGMode][bg]]; + BG.PaletteShift = PaletteShifts[BGMode][bg]; + BG.PaletteMask = PaletteMasks[BGMode][bg]; + BG.DirectColourMode = (BGMode == 3 || BGMode == 4) && bg == 0 && + (GFX.r2130 & 1); + + if (PPU.BGMosaic [bg] && PPU.Mosaic > 1) + { + orgDrawBackgroundMosaic (BGMode, bg, Z1, Z2); + return; + + } + switch (BGMode) + { + case 2: + if (Settings.WrestlemaniaArcade) + break; + case 4: // Used by Puzzle Bobble + orgDrawBackgroundOffset (BGMode, bg, Z1, Z2); + return; + + case 5: + case 6: // XXX: is also offset per tile. +// if (Settings.SupportHiRes) + { + orgDrawBackgroundMode5 (BGMode, bg, Z1, Z2); + return; + } + break; + } + CHECK_SOUND(); + + uint32 Tile; + uint16 *SC0; + uint16 *SC1; + uint16 *SC2; + uint16 *SC3; + uint32 Width; + uint8 depths [2] = {Z1, Z2}; + + if (BGMode == 0) + BG.StartPalette = bg << 5; + else + BG.StartPalette = 0; + + SC0 = (uint16 *) &Memory.VRAM[PPU.BG[bg].SCBase << 1]; + + if (PPU.BG[bg].SCSize & 1) + SC1 = SC0 + 1024; + else + SC1 = SC0; + + if(SC1>=(unsigned short*)(Memory.VRAM+0x10000)) + SC1=(uint16*)&Memory.VRAM[((uint8*)SC1-&Memory.VRAM[0])%0x10000]; + + if (PPU.BG[bg].SCSize & 2) + SC2 = SC1 + 1024; + else + SC2 = SC0; + + if((SC2-(unsigned short*)Memory.VRAM)>0x10000) + SC2-=0x10000; + + + if (PPU.BG[bg].SCSize & 1) + SC3 = SC2 + 1024; + else + SC3 = SC2; + + if((SC3-(unsigned short*)Memory.VRAM)>0x10000) + SC3-=0x10000; + + + int Lines; + int OffsetMask; + int OffsetShift; + + if (BG.TileSize == 16) + { + OffsetMask = 0x3ff; + OffsetShift = 4; + } + else + { + OffsetMask = 0x1ff; + OffsetShift = 3; + } + + for (uint32 Y = GFX.StartY; Y <= GFX.EndY; Y += Lines) + { + uint32 VOffset = LineData [Y].BG[bg].VOffset; + uint32 HOffset = LineData [Y].BG[bg].HOffset; + int VirtAlign = (Y + VOffset) & 7; + + for (Lines = 1; Lines < 8 - VirtAlign; Lines++) + if ((VOffset != LineData [Y + Lines].BG[bg].VOffset) || + (HOffset != LineData [Y + Lines].BG[bg].HOffset)) + break; + + if (Y + Lines > GFX.EndY) + Lines = GFX.EndY + 1 - Y; + + VirtAlign <<= 3; + + uint32 ScreenLine = (VOffset + Y) >> OffsetShift; + uint32 t1; + uint32 t2; + if (((VOffset + Y) & 15) > 7) + { + t1 = 16; + t2 = 0; + } + else + { + t1 = 0; + t2 = 16; + } + uint16 *b1; + uint16 *b2; + + if (ScreenLine & 0x20) + b1 = SC2, b2 = SC3; + else + b1 = SC0, b2 = SC1; + + b1 += (ScreenLine & 0x1f) << 5; + b2 += (ScreenLine & 0x1f) << 5; + + int clipcount = GFX.pCurrentClip->Count [bg]; + if (!clipcount) + clipcount = 1; + for (int clip = 0; clip < clipcount; clip++) + { + uint32 Left; + uint32 Right; + + if (!GFX.pCurrentClip->Count [bg]) + { + Left = 0; + Right = 256; + } + else + { + Left = GFX.pCurrentClip->Left [clip][bg]; + Right = GFX.pCurrentClip->Right [clip][bg]; + + if (Right <= Left) + continue; + } + + uint32 s = Left * GFX.PixSize + Y * GFX.PPL; + uint32 HPos = (HOffset + Left) & OffsetMask; + + uint32 Quot = HPos >> 3; + uint32 Count = 0; + + uint16 *t; + if (BG.TileSize == 8) + { + if (Quot > 31) + t = b2 + (Quot & 0x1f); + else + t = b1 + Quot; + } + else + { + if (Quot > 63) + t = b2 + ((Quot >> 1) & 0x1f); + else + t = b1 + (Quot >> 1); + } + + Width = Right - Left; + // Left hand edge clipped tile + if (HPos & 7) + { + uint32 Offset = (HPos & 7); + Count = 8 - Offset; + if (Count > Width) + Count = Width; + s -= Offset * GFX.PixSize; + Tile = READ_2BYTES(t); + GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13]; + + if (BG.TileSize == 8) + { + (*DrawClippedTilePtr) (Tile, s, Offset, Count, VirtAlign, + Lines); + } + else + { + if (!(Tile & (V_FLIP | H_FLIP))) + { + // Normal, unflipped + (*DrawClippedTilePtr) (Tile + t1 + (Quot & 1), + s, Offset, Count, VirtAlign, Lines); + } + else + if (Tile & H_FLIP) + { + if (Tile & V_FLIP) + { + // H & V flip + (*DrawClippedTilePtr) (Tile + t2 + 1 - (Quot & 1), + s, Offset, Count, VirtAlign, Lines); + } + else + { + // H flip only + (*DrawClippedTilePtr) (Tile + t1 + 1 - (Quot & 1), + s, Offset, Count, VirtAlign, Lines); + } + } + else + { + // V flip only + (*DrawClippedTilePtr) (Tile + t2 + (Quot & 1), s, + Offset, Count, VirtAlign, Lines); + } + } + + if (BG.TileSize == 8) + { + t++; + if (Quot == 31) + t = b2; + else if (Quot == 63) + t = b1; + } + else + { + t += Quot & 1; + if (Quot == 63) + t = b2; + else if (Quot == 127) + t = b1; + } + Quot++; + s += 8 * GFX.PixSize; + } + + // Middle, unclipped tiles + Count = Width - Count; + int Middle = Count >> 3; + Count &= 7; + for (int C = Middle; C > 0; s += 8 * GFX.PixSize, Quot++, C--) + { + Tile = READ_2BYTES(t); + GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13]; + + if (BG.TileSize != 8) + { + if (Tile & H_FLIP) + { + // Horizontal flip, but what about vertical flip ? + if (Tile & V_FLIP) + { + // Both horzontal & vertical flip + (*DrawTilePtr) (Tile + t2 + 1 - (Quot & 1), s, + VirtAlign, Lines); + } + else + { + // Horizontal flip only + (*DrawTilePtr) (Tile + t1 + 1 - (Quot & 1), s, + VirtAlign, Lines); + } + } + else + { + // No horizontal flip, but is there a vertical flip ? + if (Tile & V_FLIP) + { + // Vertical flip only + (*DrawTilePtr) (Tile + t2 + (Quot & 1), s, + VirtAlign, Lines); + } + else + { + // Normal unflipped + (*DrawTilePtr) (Tile + t1 + (Quot & 1), s, + VirtAlign, Lines); + } + } + } + else + { + (*DrawTilePtr) (Tile, s, VirtAlign, Lines); + } + + if (BG.TileSize == 8) + { + t++; + if (Quot == 31) + t = b2; + else + if (Quot == 63) + t = b1; + } + else + { + t += Quot & 1; + if (Quot == 63) + t = b2; + else + if (Quot == 127) + t = b1; + } + } + // Right-hand edge clipped tiles + if (Count) + { + Tile = READ_2BYTES(t); + GFX.Z1 = GFX.Z2 = depths [(Tile & 0x2000) >> 13]; + + if (BG.TileSize == 8) + (*DrawClippedTilePtr) (Tile, s, 0, Count, VirtAlign, + Lines); + else + { + if (!(Tile & (V_FLIP | H_FLIP))) + { + // Normal, unflipped + (*DrawClippedTilePtr) (Tile + t1 + (Quot & 1), s, 0, + Count, VirtAlign, Lines); + } + else + if (Tile & H_FLIP) + { + if (Tile & V_FLIP) + { + // H & V flip + (*DrawClippedTilePtr) (Tile + t2 + 1 - (Quot & 1), + s, 0, Count, VirtAlign, + Lines); + } + else + { + // H flip only + (*DrawClippedTilePtr) (Tile + t1 + 1 - (Quot & 1), + s, 0, Count, VirtAlign, + Lines); + } + } + else + { + // V flip only + (*DrawClippedTilePtr) (Tile + t2 + (Quot & 1), + s, 0, Count, VirtAlign, + Lines); + } + } + } + } + } +} + +#define RENDER_BACKGROUND_MODE7(TYPE,FUNC) \ + CHECK_SOUND(); \ +\ + uint8 *VRAM1 = Memory.VRAM + 1; \ + if (GFX.r2130 & 1) \ + { \ + if (IPPU.DirectColourMapsNeedRebuild) \ + S9xBuildDirectColourMaps (); \ + GFX.ScreenColors = DirectColourMaps [0]; \ + } \ + else \ + GFX.ScreenColors = IPPU.ScreenColors; \ +\ + int aa, cc; \ + int dir; \ + int startx, endx; \ + uint32 Left = 0; \ + uint32 Right = 256; \ + uint32 ClipCount = GFX.pCurrentClip->Count [bg]; \ +\ + if (!ClipCount) \ + ClipCount = 1; \ +\ + Screen += GFX.StartY * GFX.Pitch; \ + uint8 *Depth = GFX.DB + GFX.StartY * GFX.PPL; \ + struct SLineMatrixData *l = &LineMatrixData [GFX.StartY]; \ +\ + for (uint32 Line = GFX.StartY; Line <= GFX.EndY; Line++, Screen += GFX.Pitch, Depth += GFX.PPL, l++) \ + { \ + int yy; \ +\ + int32 HOffset = ((int32) LineData [Line].BG[0].HOffset << M7) >> M7; \ + int32 VOffset = ((int32) LineData [Line].BG[0].VOffset << M7) >> M7; \ +\ + int32 CentreX = ((int32) l->CentreX << M7) >> M7; \ + int32 CentreY = ((int32) l->CentreY << M7) >> M7; \ +\ + if (PPU.Mode7VFlip) \ + yy = 261 - (int) Line; \ + else \ + yy = Line; \ +\ + if (PPU.Mode7Repeat == 0) \ + yy += (VOffset - CentreY) % 1023; \ + else \ + yy += VOffset - CentreY; \ + int BB = l->MatrixB * yy + (CentreX << 8); \ + int DD = l->MatrixD * yy + (CentreY << 8); \ +\ + for (uint32 clip = 0; clip < ClipCount; clip++) \ + { \ + if (GFX.pCurrentClip->Count [bg]) \ + { \ + Left = GFX.pCurrentClip->Left [clip][bg]; \ + Right = GFX.pCurrentClip->Right [clip][bg]; \ + if (Right <= Left) \ + continue; \ + } \ + TYPE *p = (TYPE *) Screen + Left; \ + uint8 *d = Depth + Left; \ +\ + if (PPU.Mode7HFlip) \ + { \ + startx = Right - 1; \ + endx = Left - 1; \ + dir = -1; \ + aa = -l->MatrixA; \ + cc = -l->MatrixC; \ + } \ + else \ + { \ + startx = Left; \ + endx = Right; \ + dir = 1; \ + aa = l->MatrixA; \ + cc = l->MatrixC; \ + } \ + int xx; \ + if (PPU.Mode7Repeat == 0) \ + xx = startx + (HOffset - CentreX) % 1023; \ + else \ + xx = startx + HOffset - CentreX; \ + int AA = l->MatrixA * xx; \ + int CC = l->MatrixC * xx; \ +\ + if (!PPU.Mode7Repeat) \ + { \ + for (int x = startx; x != endx; x += dir, AA += aa, CC += cc, p++, d++) \ + { \ + int X = ((AA + BB) >> 8) & 0x3ff; \ + int Y = ((CC + DD) >> 8) & 0x3ff; \ + uint8 *TileData = VRAM1 + (Memory.VRAM[((Y & ~7) << 5) + ((X >> 2) & ~1)] << 7); \ + uint32 b = *(TileData + ((Y & 7) << 4) + ((X & 7) << 1)); \ + GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \ + if (GFX.Z1 > *d && (b & GFX.Mode7Mask) ) \ + { \ + *p = (FUNC); \ + *d = GFX.Z1; \ + } \ + } \ + } \ + else \ + { \ + for (int x = startx; x != endx; x += dir, AA += aa, CC += cc, p++, d++) \ + { \ + int X = ((AA + BB) >> 8); \ + int Y = ((CC + DD) >> 8); \ +\ + if (Settings.Dezaemon && PPU.Mode7Repeat == 2) \ + { \ + X &= 0x7ff; \ + Y &= 0x7ff; \ + } \ +\ + if (((X | Y) & ~0x3ff) == 0) \ + { \ + uint8 *TileData = VRAM1 + (Memory.VRAM[((Y & ~7) << 5) + ((X >> 2) & ~1)] << 7); \ + uint32 b = *(TileData + ((Y & 7) << 4) + ((X & 7) << 1)); \ + GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \ + if (GFX.Z1 > *d && (b & GFX.Mode7Mask) ) \ + { \ + *p = (FUNC); \ + *d = GFX.Z1; \ + } \ + } \ + else \ + { \ + if (PPU.Mode7Repeat == 3) \ + { \ + X = (x + HOffset) & 7; \ + Y = (yy + CentreY) & 7; \ + uint32 b = *(VRAM1 + ((Y & 7) << 4) + ((X & 7) << 1)); \ + GFX.Z1 = Mode7Depths [(b & GFX.Mode7PriorityMask) >> 7]; \ + if (GFX.Z1 > *d && (b & GFX.Mode7Mask) ) \ + { \ + *p = (FUNC); \ + *d = GFX.Z1; \ + } \ + } \ + } \ + } \ + } \ + } \ + } + + +void orgDrawBGMode7Background16 (uint8 *Screen, int bg) +{ + RENDER_BACKGROUND_MODE7 (uint16, GFX.ScreenColors [b & GFX.Mode7Mask]); +} + +void orgDrawBGMode7Background16Add (uint8 *Screen, int bg) +{ + RENDER_BACKGROUND_MODE7 (uint16, *(d + GFX.DepthDelta) ? + (*(d + GFX.DepthDelta) != 1 ? + COLOR_ADD (GFX.ScreenColors [b & GFX.Mode7Mask], + p [GFX.Delta]) : + COLOR_ADD (GFX.ScreenColors [b & GFX.Mode7Mask], + GFX.FixedColour)) : + GFX.ScreenColors [b & GFX.Mode7Mask]); +} + +void orgDrawBGMode7Background16Add1_2 (uint8 *Screen, int bg) +{ + RENDER_BACKGROUND_MODE7 (uint16, *(d + GFX.DepthDelta) ? + (*(d + GFX.DepthDelta) != 1 ? + COLOR_ADD1_2 (GFX.ScreenColors [b & GFX.Mode7Mask], + p [GFX.Delta]) : + COLOR_ADD (GFX.ScreenColors [b & GFX.Mode7Mask], + GFX.FixedColour)) : + GFX.ScreenColors [b & GFX.Mode7Mask]); +} + +void orgDrawBGMode7Background16Sub (uint8 *Screen, int bg) +{ + RENDER_BACKGROUND_MODE7 (uint16, *(d + GFX.DepthDelta) ? + (*(d + GFX.DepthDelta) != 1 ? + COLOR_SUB (GFX.ScreenColors [b & GFX.Mode7Mask], + p [GFX.Delta]) : + COLOR_SUB (GFX.ScreenColors [b & GFX.Mode7Mask], + GFX.FixedColour)) : + GFX.ScreenColors [b & GFX.Mode7Mask]); +} + +void orgDrawBGMode7Background16Sub1_2 (uint8 *Screen, int bg) +{ + RENDER_BACKGROUND_MODE7 (uint16, *(d + GFX.DepthDelta) ? + (*(d + GFX.DepthDelta) != 1 ? + COLOR_SUB1_2 (GFX.ScreenColors [b & GFX.Mode7Mask], + p [GFX.Delta]) : + COLOR_SUB (GFX.ScreenColors [b & GFX.Mode7Mask], + GFX.FixedColour)) : + GFX.ScreenColors [b & GFX.Mode7Mask]); +} + + +#define _BUILD_SETUP(F) \ +GFX.BuildPixel = BuildPixel##F; \ +GFX.BuildPixel2 = BuildPixel2##F; \ +GFX.DecomposePixel = DecomposePixel##F; \ +RED_LOW_BIT_MASK = RED_LOW_BIT_MASK_##F; \ +GREEN_LOW_BIT_MASK = GREEN_LOW_BIT_MASK_##F; \ +BLUE_LOW_BIT_MASK = BLUE_LOW_BIT_MASK_##F; \ +RED_HI_BIT_MASK = RED_HI_BIT_MASK_##F; \ +GREEN_HI_BIT_MASK = GREEN_HI_BIT_MASK_##F; \ +BLUE_HI_BIT_MASK = BLUE_HI_BIT_MASK_##F; \ +MAX_RED = MAX_RED_##F; \ +MAX_GREEN = MAX_GREEN_##F; \ +MAX_BLUE = MAX_BLUE_##F; \ +GREEN_HI_BIT = ((MAX_GREEN_##F + 1) >> 1); \ +SPARE_RGB_BIT_MASK = SPARE_RGB_BIT_MASK_##F; \ +RGB_LOW_BITS_MASK = (RED_LOW_BIT_MASK_##F | \ + GREEN_LOW_BIT_MASK_##F | \ + BLUE_LOW_BIT_MASK_##F); \ +RGB_HI_BITS_MASK = (RED_HI_BIT_MASK_##F | \ + GREEN_HI_BIT_MASK_##F | \ + BLUE_HI_BIT_MASK_##F); \ +RGB_HI_BITS_MASKx2 = ((RED_HI_BIT_MASK_##F | \ + GREEN_HI_BIT_MASK_##F | \ + BLUE_HI_BIT_MASK_##F) << 1); \ +RGB_REMOVE_LOW_BITS_MASK = ~RGB_LOW_BITS_MASK; \ +FIRST_COLOR_MASK = FIRST_COLOR_MASK_##F; \ +SECOND_COLOR_MASK = SECOND_COLOR_MASK_##F; \ +THIRD_COLOR_MASK = THIRD_COLOR_MASK_##F; \ +ALPHA_BITS_MASK = ALPHA_BITS_MASK_##F; \ +FIRST_THIRD_COLOR_MASK = FIRST_COLOR_MASK | THIRD_COLOR_MASK; \ +TWO_LOW_BITS_MASK = RGB_LOW_BITS_MASK | (RGB_LOW_BITS_MASK << 1); \ +HIGH_BITS_SHIFTED_TWO_MASK = (( (FIRST_COLOR_MASK | SECOND_COLOR_MASK | THIRD_COLOR_MASK) & \ + ~TWO_LOW_BITS_MASK ) >> 2); + +void RenderScreen (uint8 *Screen, bool8 sub, bool8 force_no_add, uint8 D) +{ + bool8 BG0; + bool8 BG1; + bool8 BG2; + bool8 BG3; + bool8 OB; + + GFX.S = Screen; + + if (!sub) + { + GFX.pCurrentClip = &IPPU.Clip [0]; + BG0 = ON_MAIN (0); + BG1 = ON_MAIN (1); + BG2 = ON_MAIN (2); + BG3 = ON_MAIN (3); + OB = ON_MAIN (4); + } + else + { + GFX.pCurrentClip = &IPPU.Clip [1]; + BG0 = ON_SUB (0); + BG1 = ON_SUB (1); + BG2 = ON_SUB (2); + BG3 = ON_SUB (3); + OB = ON_SUB (4); + } + + sub |= force_no_add; + + if (PPU.BGMode <= 1) + { + if (OB) + { + orgSelectTileRenderer (sub || !SUB_OR_ADD(4)); + orgDrawOBJS (!sub, D); + } + if (BG0) + { + orgSelectTileRenderer (sub || !SUB_OR_ADD(0)); + orgDrawBackground (PPU.BGMode, 0, D + 10, D + 14); + } + if (BG1) + { + orgSelectTileRenderer (sub || !SUB_OR_ADD(1)); + orgDrawBackground (PPU.BGMode, 1, D + 9, D + 13); + } + if (BG2) + { + orgSelectTileRenderer (sub || !SUB_OR_ADD(2)); + orgDrawBackground (PPU.BGMode, 2, D + 3, + (Memory.FillRAM [0x2105] & 8) == 0 ? D + 6 : D + 17); + } + if (BG3 && PPU.BGMode == 0) + { + orgSelectTileRenderer (sub || !SUB_OR_ADD(3)); + orgDrawBackground (PPU.BGMode, 3, D + 2, D + 5); + } + } + else if (PPU.BGMode != 7) + { + if (OB) + { + orgSelectTileRenderer (sub || !SUB_OR_ADD(4)); + orgDrawOBJS (!sub, D); + } + if (BG0) + { + orgSelectTileRenderer (sub || !SUB_OR_ADD(0)); + orgDrawBackground (PPU.BGMode, 0, D + 5, D + 13); + } + if (PPU.BGMode != 6 && BG1) + { + orgSelectTileRenderer (sub || !SUB_OR_ADD(1)); + orgDrawBackground (PPU.BGMode, 1, D + 2, D + 9); + } + } + else + { + if (OB) + { + orgSelectTileRenderer (sub || !SUB_OR_ADD(4)); + orgDrawOBJS (!sub, D); + } + if (BG0 || ((Memory.FillRAM [0x2133] & 0x40) && BG1)) + { + int bg; + + if (Memory.FillRAM [0x2133] & 0x40) + { + GFX.Mode7Mask = 0x7f; + GFX.Mode7PriorityMask = 0x80; + Mode7Depths [0] = 5 + D; + Mode7Depths [1] = 9 + D; + bg = 1; + } + else + { + GFX.Mode7Mask = 0xff; + GFX.Mode7PriorityMask = 0; + Mode7Depths [0] = 5 + D; + Mode7Depths [1] = 5 + D; + bg = 0; + } + if (sub || !SUB_OR_ADD(0)) + { + + orgDrawBGMode7Background16 (Screen, bg); + } + else + { + if (GFX.r2131 & 0x80) + { + if (GFX.r2131 & 0x40) + { + orgDrawBGMode7Background16Sub1_2 (Screen, bg); + } + else + { + orgDrawBGMode7Background16Sub (Screen, bg); + } + } + else + { + if (GFX.r2131 & 0x40) + { + orgDrawBGMode7Background16Add1_2 (Screen, bg); + } + else + { + + orgDrawBGMode7Background16Add (Screen, bg); + } + } + } + } + } +} + + +void orgS9xUpdateScreen () +{ + int32 x2 = 1; + + GFX.S = GFX.Screen; + GFX.r2131 = Memory.FillRAM [0x2131]; + GFX.r212c = Memory.FillRAM [0x212c]; + GFX.r212d = Memory.FillRAM [0x212d]; + GFX.r2130 = Memory.FillRAM [0x2130]; + GFX.Pseudo = (Memory.FillRAM [0x2133] & 8) != 0 && + (GFX.r212c & 15) != (GFX.r212d & 15) && + (GFX.r2131 & 0x3f) == 0; + + if (IPPU.OBJChanged) + S9xSetupOBJ (); + + if (PPU.RecomputeClipWindows) + { + ComputeClipWindows (); + PPU.RecomputeClipWindows = FALSE; + } + + GFX.StartY = IPPU.PreviousLine; + if ((GFX.EndY = IPPU.CurrentLine - 1) >= PPU.ScreenHeight) + GFX.EndY = PPU.ScreenHeight - 1; + + uint32 starty = GFX.StartY; + uint32 endy = GFX.EndY; + + uint32 black = BLACK | (BLACK << 16); + + + + if (GFX.Pseudo) + { + GFX.r2131 = 0x5f; + GFX.r212d = (Memory.FillRAM [0x212c] ^ + Memory.FillRAM [0x212d]) & 15; + GFX.r212c &= ~GFX.r212d; + GFX.r2130 |= 2; + } + + if (!PPU.ForcedBlanking && ADD_OR_SUB_ON_ANYTHING && + (GFX.r2130 & 0x30) != 0x30 && + !((GFX.r2130 & 0x30) == 0x10 && IPPU.Clip[1].Count[5] == 0)) + { + struct ClipData *pClip; + + GFX.FixedColour = BUILD_PIXEL (IPPU.XB [PPU.FixedColourRed], + IPPU.XB [PPU.FixedColourGreen], + IPPU.XB [PPU.FixedColourBlue]); + + // Clear the z-buffer, marking areas 'covered' by the fixed + // colour as depth 1. + pClip = &IPPU.Clip [1]; + + // Clear the z-buffer + if (pClip->Count [5]) + { + // Colour window enabled. + for (uint32 y = starty; y <= endy; y++) + { + ZeroMemory (GFX.SubZBuffer + y * GFX.ZPitch, + IPPU.RenderedScreenWidth); + ZeroMemory (GFX.ZBuffer + y * GFX.ZPitch, + IPPU.RenderedScreenWidth); + if (IPPU.Clip [0].Count [5]) + { + uint32 *p = (uint32 *) (GFX.SubScreen + y * GFX.Pitch2); + uint32 *q = (uint32 *) ((uint16 *) p + IPPU.RenderedScreenWidth); + while (p < q) + *p++ = black; + } + for (uint32 c = 0; c < pClip->Count [5]; c++) + { + if (pClip->Right [c][5] > pClip->Left [c][5]) + { + memset (GFX.SubZBuffer + y * GFX.ZPitch + pClip->Left [c][5] * x2, + 1, (pClip->Right [c][5] - pClip->Left [c][5]) * x2); + if (IPPU.Clip [0].Count [5]) + { + // Blast, have to clear the sub-screen to the fixed-colour + // because there is a colour window in effect clipping + // the main screen that will allow the sub-screen + // 'underneath' to show through. + + uint16 *p = (uint16 *) (GFX.SubScreen + y * GFX.Pitch2); + uint16 *q = p + pClip->Right [c][5] * x2; + p += pClip->Left [c][5] * x2; + + while (p < q) + *p++ = (uint16) GFX.FixedColour; + } + } + } + } + } + else + { + for (uint32 y = starty; y <= endy; y++) + { + ZeroMemory (GFX.ZBuffer + y * GFX.ZPitch, + IPPU.RenderedScreenWidth); + memset (GFX.SubZBuffer + y * GFX.ZPitch, 1, + IPPU.RenderedScreenWidth); + + if (IPPU.Clip [0].Count [5]) + { + // Blast, have to clear the sub-screen to the fixed-colour + // because there is a colour window in effect clipping + // the main screen that will allow the sub-screen + // 'underneath' to show through. + + uint32 b = GFX.FixedColour | (GFX.FixedColour << 16); + uint32 *p = (uint32 *) (GFX.SubScreen + y * GFX.Pitch2); + uint32 *q = (uint32 *) ((uint16 *) p + IPPU.RenderedScreenWidth); + + while (p < q) + *p++ = b; + } + } + } + if (ANYTHING_ON_SUB) + { + GFX.DB = GFX.SubZBuffer; + RenderScreen (GFX.SubScreen, TRUE, TRUE, SUB_SCREEN_DEPTH); + } + + if (IPPU.Clip [0].Count [5]) + { + + for (uint32 y = starty; y <= endy; y++) + { + register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2); + register uint8 *d = GFX.SubZBuffer + y * GFX.ZPitch; + register uint8 *e = d + IPPU.RenderedScreenWidth; + + while (d < e) + { + if (*d > 1) + *p = *(p + GFX.Delta); + else + *p = BLACK; + d++; + p++; + } + } + } + + GFX.DB = GFX.ZBuffer; + RenderScreen (GFX.Screen, FALSE, FALSE, MAIN_SCREEN_DEPTH); + + if (SUB_OR_ADD(5)) + { + uint32 back = IPPU.ScreenColors [0]; + uint32 Left = 0; + uint32 Right = 256; + uint32 Count; + + pClip = &IPPU.Clip [0]; + for (uint32 y = starty; y <= endy; y++) + { + if (!(Count = pClip->Count [5])) + { + Left = 0; + Right = 256 * x2; + Count = 1; + } + + for (uint32 b = 0; b < Count; b++) + { + if (pClip->Count [5]) + { + Left = pClip->Left [b][5] * x2; + Right = pClip->Right [b][5] * x2; + if (Right <= Left) + continue; + } + + if (GFX.r2131 & 0x80) + { + if (GFX.r2131 & 0x40) + { + // Subtract, halving the result. + register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + Left; + register uint8 *d = GFX.ZBuffer + y * GFX.ZPitch; + register uint8 *s = GFX.SubZBuffer + y * GFX.ZPitch + Left; + register uint8 *e = d + Right; + uint16 back_fixed = COLOR_SUB (back, GFX.FixedColour); + + d += Left; + while (d < e) + { + if (*d == 0) + { + if (*s) + { + if (*s != 1) + *p = COLOR_SUB1_2 (back, *(p + GFX.Delta)); + else + *p = back_fixed; + } + else + *p = (uint16) back; + } + d++; + p++; + s++; + } + } + else + { + // Subtract + register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + Left; + register uint8 *s = GFX.SubZBuffer + y * GFX.ZPitch + Left; + register uint8 *d = GFX.ZBuffer + y * GFX.ZPitch; + register uint8 *e = d + Right; + uint16 back_fixed = COLOR_SUB (back, GFX.FixedColour); + + d += Left; + while (d < e) + { + if (*d == 0) + { + if (*s) + { + if (*s != 1) + *p = COLOR_SUB (back, *(p + GFX.Delta)); + else + *p = back_fixed; + } + else + *p = (uint16) back; + } + d++; + p++; + s++; + } + } + } + else + if (GFX.r2131 & 0x40) + { + register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + Left; + register uint8 *d = GFX.ZBuffer + y * GFX.ZPitch; + register uint8 *s = GFX.SubZBuffer + y * GFX.ZPitch + Left; + register uint8 *e = d + Right; + uint16 back_fixed = COLOR_ADD (back, GFX.FixedColour); + d += Left; + while (d < e) + { + if (*d == 0) + { + if (*s) + { + if (*s != 1) + *p = COLOR_ADD1_2 (back, *(p + GFX.Delta)); + else + *p = back_fixed; + } + else + *p = (uint16) back; + } + d++; + p++; + s++; + } + } + else + if (back != 0) + { + register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + Left; + register uint8 *d = GFX.ZBuffer + y * GFX.ZPitch; + register uint8 *s = GFX.SubZBuffer + y * GFX.ZPitch + Left; + register uint8 *e = d + Right; + uint16 back_fixed = COLOR_ADD (back, GFX.FixedColour); + d += Left; + while (d < e) + { + if (*d == 0) + { + if (*s) + { + if (*s != 1) + *p = COLOR_ADD (back, *(p + GFX.Delta)); + else + *p = back_fixed; + } + else + *p = (uint16) back; + } + d++; + p++; + s++; + } + } + else + { + if (!pClip->Count [5]) + { + // The backdrop has not been cleared yet - so + // copy the sub-screen to the main screen + // or fill it with the back-drop colour if the + // sub-screen is clear. + register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + Left; + register uint8 *d = GFX.ZBuffer + y * GFX.ZPitch; + register uint8 *s = GFX.SubZBuffer + y * GFX.ZPitch + Left; + register uint8 *e = d + Right; + d += Left; + while (d < e) + { + if (*d == 0) + { + if (*s) + { + if (*s != 1) + *p = *(p + GFX.Delta); + else + *p = GFX.FixedColour; + } + else + *p = (uint16) back; + } + d++; + p++; + s++; + } + } + } + } + } + } + else + { + // Subscreen not being added to back + uint32 back = IPPU.ScreenColors [0] | (IPPU.ScreenColors [0] << 16); + pClip = &IPPU.Clip [0]; + + if (pClip->Count [5]) + { + for (uint32 y = starty; y <= endy; y++) + { + for (uint32 b = 0; b < pClip->Count [5]; b++) + { + uint32 Left = pClip->Left [b][5] * x2; + uint32 Right = pClip->Right [b][5] * x2; + uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + Left; + uint8 *d = GFX.ZBuffer + y * GFX.ZPitch; + uint8 *e = d + Right; + d += Left; + + while (d < e) + { + if (*d == 0) + *p = (int16) back; + d++; + p++; + } + } + } + } + else + { + for (uint32 y = starty; y <= endy; y++) + { + uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2); + uint8 *d = GFX.ZBuffer + y * GFX.ZPitch; + uint8 *e = d + 256 * x2; + + while (d < e) + { + if (*d == 0) + *p = (int16) back; + d++; + p++; + } + } + } + } + } + else + { + // 16bit and transparency but currently no transparency effects in + // operation. + + uint32 back = IPPU.ScreenColors [0] | + (IPPU.ScreenColors [0] << 16); + + if (PPU.ForcedBlanking) + back = black; + + if (IPPU.Clip [0].Count[5]) + { + for (uint32 y = starty; y <= endy; y++) + { + uint32 *p = (uint32 *) (GFX.Screen + y * GFX.Pitch2); + uint32 *q = (uint32 *) ((uint16 *) p + IPPU.RenderedScreenWidth); + + while (p < q) + *p++ = black; + + for (uint32 c = 0; c < IPPU.Clip [0].Count [5]; c++) + { + if (IPPU.Clip [0].Right [c][5] > IPPU.Clip [0].Left [c][5]) + { + uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2); + uint16 *q = p + IPPU.Clip [0].Right [c][5] * x2; + p += IPPU.Clip [0].Left [c][5] * x2; + + while (p < q) + *p++ = (uint16) back; + } + } + } + } + else + { + for (uint32 y = starty; y <= endy; y++) + { + uint32 *p = (uint32 *) (GFX.Screen + y * GFX.Pitch2); + uint32 *q = (uint32 *) ((uint16 *) p + IPPU.RenderedScreenWidth); + while (p < q) + *p++ = back; + } + } + if (!PPU.ForcedBlanking) + { + for (uint32 y = starty; y <= endy; y++) + { + ZeroMemory (GFX.ZBuffer + y * GFX.ZPitch, + IPPU.RenderedScreenWidth); + } + GFX.DB = GFX.ZBuffer; + RenderScreen (GFX.Screen, FALSE, TRUE, SUB_SCREEN_DEPTH); + } + } + + + IPPU.PreviousLine = IPPU.CurrentLine; +} + +#ifdef GFX_MULTI_FORMAT + +#define _BUILD_PIXEL(F) \ +uint32 BuildPixel##F(uint32 R, uint32 G, uint32 B) \ +{ \ + return (BUILD_PIXEL_##F(R,G,B)); \ +}\ +uint32 BuildPixel2##F(uint32 R, uint32 G, uint32 B) \ +{ \ + return (BUILD_PIXEL2_##F(R,G,B)); \ +} \ +void DecomposePixel##F(uint32 pixel, uint32 &R, uint32 &G, uint32 &B) \ +{ \ + DECOMPOSE_PIXEL_##F(pixel,R,G,B); \ +} + +_BUILD_PIXEL(RGB565) +_BUILD_PIXEL(RGB555) +_BUILD_PIXEL(BGR565) +_BUILD_PIXEL(BGR555) +_BUILD_PIXEL(GBR565) +_BUILD_PIXEL(GBR555) +_BUILD_PIXEL(RGB5551) + +bool8 S9xSetRenderPixelFormat (int format) +{ + extern uint32 current_graphic_format; + + current_graphic_format = format; + + switch (format) + { + case RGB565: + _BUILD_SETUP(RGB565) + return (TRUE); + case RGB555: + _BUILD_SETUP(RGB555) + return (TRUE); + case BGR565: + _BUILD_SETUP(BGR565) + return (TRUE); + case BGR555: + _BUILD_SETUP(BGR555) + return (TRUE); + case GBR565: + _BUILD_SETUP(GBR565) + return (TRUE); + case GBR555: + _BUILD_SETUP(GBR555) + return (TRUE); + case RGB5551: + _BUILD_SETUP(RGB5551) + return (TRUE); + default: + break; + } + return (FALSE); +} +#endif + + +void S9xUpdateScreen () +{ + int32 x2 = 1; + + GFX.S = GFX.Screen; + GFX.r2131 = Memory.FillRAM [0x2131]; + GFX.r212c = Memory.FillRAM [0x212c]; + GFX.r212d = Memory.FillRAM [0x212d]; + GFX.r2130 = Memory.FillRAM [0x2130]; + +#ifdef JP_FIX + + GFX.Pseudo = (Memory.FillRAM [0x2133] & 8) != 0 && + (GFX.r212c & 15) != (GFX.r212d & 15) && + (GFX.r2131 == 0x3f); + +#else + + GFX.Pseudo = (Memory.FillRAM [0x2133] & 8) != 0 && + (GFX.r212c & 15) != (GFX.r212d & 15) && + (GFX.r2131 & 0x3f) == 0; + +#endif + + if (IPPU.OBJChanged) + S9xSetupOBJ (); + + if (PPU.RecomputeClipWindows) + { + ComputeClipWindows (); + PPU.RecomputeClipWindows = FALSE; + } + + GFX.StartY = IPPU.PreviousLine; + if ((GFX.EndY = IPPU.CurrentLine - 1) >= PPU.ScreenHeight) + GFX.EndY = PPU.ScreenHeight - 1; + + // XXX: Check ForceBlank? Or anything else? + //PPU.RangeTimeOver |= GFX.OBJLines[GFX.EndY].RTOFlags; + + uint32 starty = GFX.StartY; + uint32 endy = GFX.EndY; + + /*if (Settings.SupportHiRes && + (PPU.BGMode == 5 || PPU.BGMode == 6 || + //IPPU.Interlace || IPPU.DoubleHeightPixels)) + { + if (PPU.BGMode == 5 || PPU.BGMode == 6|| IPPU.Interlace) + { + IPPU.RenderedScreenWidth = 512; + x2 = 2; + } + if (IPPU.DoubleHeightPixels) + { + starty = GFX.StartY * 2; + endy = GFX.EndY * 2 + 1; + } + if ((PPU.BGMode == 5 || PPU.BGMode == 6) && !IPPU.DoubleWidthPixels) + { + // The game has switched from lo-res to hi-res mode part way down + // the screen. Scale any existing lo-res pixels on screen + if (Settings.SixteenBit) + { +#if defined (USE_GLIDE) || defined (USE_OPENGL) + if ( +#ifdef USE_GLIDE + (Settings.GlideEnable && GFX.Pitch == 512) || +#endif +#ifdef USE_OPENGL + (Settings.OpenGLEnable && GFX.Pitch == 512) || +#endif + 0) + { + // Have to back out of the speed up hack where the low res. + // SNES image was rendered into a 256x239 sized buffer, + // ignoring the true, larger size of the buffer. + for (register int32 y = (int32) starty - 1; y >= 0; y--) + { + register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + 255; + register uint16 *q = (uint16 *) (GFX.Screen + y * GFX.RealPitch) + 510; + for (register int x = 255; x >= 0; x--, p--, q -= 2) + *q = *(q + 1) = *p; + } + + GFX.Pitch = GFX.Pitch2 = GFX.RealPitch; + GFX.PPL = GFX.Pitch >> 1; + GFX.PPLx2 = GFX.Pitch; + GFX.ZPitch = GFX.PPL; + } + else +#endif + for (register uint32 y = 0; y < starty; y++) + { + register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + 255; + register uint16 *q = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + 510; + + for (register int x = 255; x >= 0; x--, p--, q -= 2) + *q = *(q + 1) = *p; + } + } + else + { + for (register uint32 y = 0; y < starty; y++) + { + register uint8 *p = GFX.Screen + y * GFX.Pitch2 + 255; + register uint8 *q = GFX.Screen + y * GFX.Pitch2 + 510; + for (register int x = 255; x >= 0; x--, p--, q -= 2) + *q = *(q + 1) = *p; + } + } + IPPU.DoubleWidthPixels = TRUE; + } + // BJ: And we have to change the height if Interlace gets set, + // too. + if (IPPU.Interlace && !IPPU.DoubleHeightPixels) + { + starty = GFX.StartY * 2; + endy = GFX.EndY * 2 + 1; + IPPU.RenderedScreenHeight = PPU.ScreenHeight << 1; + IPPU.DoubleHeightPixels = TRUE; + GFX.Pitch2 = GFX.RealPitch; + GFX.Pitch = GFX.RealPitch * 2; + if (Settings.SixteenBit) + GFX.PPL = GFX.PPLx2 = GFX.RealPitch; + else + GFX.PPL = GFX.PPLx2 = GFX.RealPitch << 1; + + // The game has switched from non-interlaced to interlaced mode + // part way down the screen. Scale everything. + for (register int32 y = (int32) GFX.StartY - 1; y >= 0; y--) + { + memmove (GFX.Screen + y * 2 * GFX.Pitch2, + GFX.Screen + y * GFX.Pitch2, + GFX.Pitch2); + memmove (GFX.Screen + (y * 2 + 1) * GFX.Pitch2, + GFX.Screen + y * GFX.Pitch2, + GFX.Pitch2); + } + } + + }*/ + + uint32 black = BLACK | (BLACK << 16); + + if (Settings.Transparency && Settings.SixteenBit) + { + if (GFX.Pseudo) + { + GFX.r2131 = 0x5f; + GFX.r212c &= (Memory.FillRAM [0x212d] | 0xf0); + GFX.r212d |= (Memory.FillRAM [0x212c] & 0x0f); + GFX.r2130 |= 2; + } + + if (!PPU.ForcedBlanking && ADD_OR_SUB_ON_ANYTHING && + (GFX.r2130 & 0x30) != 0x30 && + !((GFX.r2130 & 0x30) == 0x10 && IPPU.Clip[1].Count[5] == 0)) + { + struct ClipData *pClip; + + GFX.FixedColour = BUILD_PIXEL (IPPU.XB [PPU.FixedColourRed], + IPPU.XB [PPU.FixedColourGreen], + IPPU.XB [PPU.FixedColourBlue]); + + // Clear the z-buffer, marking areas 'covered' by the fixed + // colour as depth 1. + pClip = &IPPU.Clip [1]; + + // Clear the z-buffer + if (pClip->Count [5]) + { + // Colour window enabled. + for (uint32 y = starty; y <= endy; y++) + { + ZeroMemory (GFX.SubZBuffer + y * GFX.ZPitch, + IPPU.RenderedScreenWidth); + ZeroMemory (GFX.ZBuffer + y * GFX.ZPitch, + IPPU.RenderedScreenWidth); + if (IPPU.Clip [0].Count [5]) + { + uint32 *p = (uint32 *) (GFX.SubScreen + y * GFX.Pitch2); + uint32 *q = (uint32 *) ((uint16 *) p + IPPU.RenderedScreenWidth); + while (p < q) + *p++ = black; + } + for (uint32 c = 0; c < pClip->Count [5]; c++) + { + if (pClip->Right [c][5] > pClip->Left [c][5]) + { + memset (GFX.SubZBuffer + y * GFX.ZPitch + pClip->Left [c][5] * x2, + 1, (pClip->Right [c][5] - pClip->Left [c][5]) * x2); + if (IPPU.Clip [0].Count [5]) + { + // Blast, have to clear the sub-screen to the fixed-colour + // because there is a colour window in effect clipping + // the main screen that will allow the sub-screen + // 'underneath' to show through. + + uint16 *p = (uint16 *) (GFX.SubScreen + y * GFX.Pitch2); + uint16 *q = p + pClip->Right [c][5] * x2; + p += pClip->Left [c][5] * x2; + + while (p < q) + *p++ = (uint16) GFX.FixedColour; + } + } + } + } + } + else + { + for (uint32 y = starty; y <= endy; y++) + { + ZeroMemory (GFX.ZBuffer + y * GFX.ZPitch, + IPPU.RenderedScreenWidth); + memset (GFX.SubZBuffer + y * GFX.ZPitch, 1, + IPPU.RenderedScreenWidth); + + if (IPPU.Clip [0].Count [5]) + { + // Blast, have to clear the sub-screen to the fixed-colour + // because there is a colour window in effect clipping + // the main screen that will allow the sub-screen + // 'underneath' to show through. + + uint32 b = GFX.FixedColour | (GFX.FixedColour << 16); + uint32 *p = (uint32 *) (GFX.SubScreen + y * GFX.Pitch2); + uint32 *q = (uint32 *) ((uint16 *) p + IPPU.RenderedScreenWidth); + + while (p < q) + *p++ = b; + } + } + } + if (ANYTHING_ON_SUB) + { + GFX.DB = GFX.SubZBuffer; + RenderScreen (GFX.SubScreen, TRUE, TRUE, SUB_SCREEN_DEPTH); + } + + if (IPPU.Clip [0].Count [5]) + { + for (uint32 y = starty; y <= endy; y++) + { + register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2); + register uint8 *d = GFX.SubZBuffer + y * GFX.ZPitch; + register uint8 *e = d + IPPU.RenderedScreenWidth; + + while (d < e) + { + if (*d > 1) + *p = *(p + GFX.Delta); + else + *p = BLACK; + d++; + p++; + } + } + } + + GFX.DB = GFX.ZBuffer; + RenderScreen (GFX.Screen, FALSE, FALSE, MAIN_SCREEN_DEPTH); + + if (SUB_OR_ADD(5)) + { + uint32 back = IPPU.ScreenColors [0]; + uint32 Left = 0; + uint32 Right = 256; + uint32 Count; + + pClip = &IPPU.Clip [0]; + for (uint32 y = starty; y <= endy; y++) + { + if (!(Count = pClip->Count [5])) + { + Left = 0; + Right = 256 * x2; + Count = 1; + } + + for (uint32 b = 0; b < Count; b++) + { + if (pClip->Count [5]) + { + Left = pClip->Left [b][5] * x2; + Right = pClip->Right [b][5] * x2; + if (Right <= Left) + continue; + } + + if (GFX.r2131 & 0x80) + { + if (GFX.r2131 & 0x40) + { + // Subtract, halving the result. + register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + Left; + register uint8 *d = GFX.ZBuffer + y * GFX.ZPitch; + register uint8 *s = GFX.SubZBuffer + y * GFX.ZPitch + Left; + register uint8 *e = d + Right; + uint16 back_fixed = COLOR_SUB (back, GFX.FixedColour); + + d += Left; + while (d < e) + { + if (*d == 0) + { + if (*s) + { + if (*s != 1) + *p = COLOR_SUB1_2 (back, *(p + GFX.Delta)); + else + *p = back_fixed; + } + else + *p = (uint16) back; + } + d++; + p++; + s++; + } + } + else + { + // Subtract + register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + Left; + register uint8 *s = GFX.SubZBuffer + y * GFX.ZPitch + Left; + register uint8 *d = GFX.ZBuffer + y * GFX.ZPitch; + register uint8 *e = d + Right; + uint16 back_fixed = COLOR_SUB (back, GFX.FixedColour); + + d += Left; + while (d < e) + { + if (*d == 0) + { + if (*s) + { + if (*s != 1) + *p = COLOR_SUB (back, *(p + GFX.Delta)); + else + *p = back_fixed; + } + else + *p = (uint16) back; + } + d++; + p++; + s++; + } + } + } + else + if (GFX.r2131 & 0x40) + { + register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + Left; + register uint8 *d = GFX.ZBuffer + y * GFX.ZPitch; + register uint8 *s = GFX.SubZBuffer + y * GFX.ZPitch + Left; + register uint8 *e = d + Right; + uint16 back_fixed = COLOR_ADD (back, GFX.FixedColour); + d += Left; + while (d < e) + { + if (*d == 0) + { + if (*s) + { + if (*s != 1) + *p = COLOR_ADD1_2 (back, *(p + GFX.Delta)); + else + *p = back_fixed; + } + else + *p = (uint16) back; + } + d++; + p++; + s++; + } + } + else + if (back != 0) + { + register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + Left; + register uint8 *d = GFX.ZBuffer + y * GFX.ZPitch; + register uint8 *s = GFX.SubZBuffer + y * GFX.ZPitch + Left; + register uint8 *e = d + Right; + uint16 back_fixed = COLOR_ADD (back, GFX.FixedColour); + d += Left; + while (d < e) + { + if (*d == 0) + { + if (*s) + { + if (*s != 1) + *p = COLOR_ADD (back, *(p + GFX.Delta)); + else + *p = back_fixed; + } + else + *p = (uint16) back; + } + d++; + p++; + s++; + } + } + else + { + if (!pClip->Count [5]) + { + // The backdrop has not been cleared yet - so + // copy the sub-screen to the main screen + // or fill it with the back-drop colour if the + // sub-screen is clear. + register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + Left; + register uint8 *d = GFX.ZBuffer + y * GFX.ZPitch; + register uint8 *s = GFX.SubZBuffer + y * GFX.ZPitch + Left; + register uint8 *e = d + Right; + d += Left; + while (d < e) + { + if (*d == 0) + { + if (*s) + { + if (*s != 1) + *p = *(p + GFX.Delta); + else + *p = GFX.FixedColour; + } + else + *p = (uint16) back; + } + d++; + p++; + s++; + } + } + } + } + } + } + else + { + // Subscreen not being added to back + uint32 back = IPPU.ScreenColors [0] | (IPPU.ScreenColors [0] << 16); + pClip = &IPPU.Clip [0]; + + if (pClip->Count [5]) + { + for (uint32 y = starty; y <= endy; y++) + { + for (uint32 b = 0; b < pClip->Count [5]; b++) + { + uint32 Left = pClip->Left [b][5] * x2; + uint32 Right = pClip->Right [b][5] * x2; + uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + Left; + uint8 *d = GFX.ZBuffer + y * GFX.ZPitch; + uint8 *e = d + Right; + d += Left; + + while (d < e) + { + if (*d == 0) + *p = (int16) back; + d++; + p++; + } + } + } + } + else + { + for (uint32 y = starty; y <= endy; y++) + { + uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2); + uint8 *d = GFX.ZBuffer + y * GFX.ZPitch; + uint8 *e = d + 256 * x2; + + while (d < e) + { + if (*d == 0) + *p = (int16) back; + d++; + p++; + } + } + } + } + } + else + { + // 16bit and transparency but currently no transparency effects in + // operation. + + uint32 back = IPPU.ScreenColors [0] | + (IPPU.ScreenColors [0] << 16); + + if (PPU.ForcedBlanking) + back = black; + + if (IPPU.Clip [0].Count[5]) + { + for (uint32 y = starty; y <= endy; y++) + { + uint32 *p = (uint32 *) (GFX.Screen + y * GFX.Pitch2); + uint32 *q = (uint32 *) ((uint16 *) p + IPPU.RenderedScreenWidth); + + while (p < q) + *p++ = black; + + for (uint32 c = 0; c < IPPU.Clip [0].Count [5]; c++) + { + if (IPPU.Clip [0].Right [c][5] > IPPU.Clip [0].Left [c][5]) + { + uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2); + uint16 *q = p + IPPU.Clip [0].Right [c][5] * x2; + p += IPPU.Clip [0].Left [c][5] * x2; + + while (p < q) + *p++ = (uint16) back; + } + } + } + } + else + { + for (uint32 y = starty; y <= endy; y++) + { + uint32 *p = (uint32 *) (GFX.Screen + y * GFX.Pitch2); + uint32 *q = (uint32 *) ((uint16 *) p + IPPU.RenderedScreenWidth); + while (p < q) + *p++ = back; + } + } + if (!PPU.ForcedBlanking) + { + for (uint32 y = starty; y <= endy; y++) + { + ZeroMemory (GFX.ZBuffer + y * GFX.ZPitch, + IPPU.RenderedScreenWidth); + } + GFX.DB = GFX.ZBuffer; + RenderScreen (GFX.Screen, FALSE, TRUE, SUB_SCREEN_DEPTH); + } + } + } + else + { + if (Settings.SixteenBit) + { + uint32 back = IPPU.ScreenColors [0] | (IPPU.ScreenColors [0] << 16); + if (PPU.ForcedBlanking) + back = black; + else + orgSelectTileRenderer (TRUE); + + for (uint32 y = starty; y <= endy; y++) + { + uint32 *p = (uint32 *) (GFX.Screen + y * GFX.Pitch2); + uint32 *q = (uint32 *) ((uint16 *) p + IPPU.RenderedScreenWidth); + while (p < q) + *p++ = back; + } + } + else + { + for (uint32 y = starty; y <= endy; y++) + { + ZeroMemory (GFX.Screen + y * GFX.Pitch2, + IPPU.RenderedScreenWidth); + } + } + if (!PPU.ForcedBlanking) + { + for (uint32 y = starty; y <= endy; y++) + { + ZeroMemory (GFX.ZBuffer + y * GFX.ZPitch, + IPPU.RenderedScreenWidth); + } + GFX.DB = GFX.ZBuffer; + GFX.pCurrentClip = &IPPU.Clip [0]; + +#define FIXCLIP(n)\ + if (GFX.r212c & (1 << (n))) \ + GFX.pCurrentClip = &IPPU.Clip [0]; \ + else \ + GFX.pCurrentClip = &IPPU.Clip [1] + + +#define DISPLAY(n)\ + (!(PPU.BG_Forced & n) && \ + (GFX.r212c & n) || \ + ((GFX.r212d & n) && subadd)) + + uint8 subadd = GFX.r2131 & 0x3f; + + bool8 BG0 = DISPLAY(1); + bool8 BG1 = DISPLAY(2); + bool8 BG2 = DISPLAY(4); + bool8 BG3 = DISPLAY(8); + bool8 OB = DISPLAY(16); + + if (PPU.BGMode <= 1) + { + if (OB) + { + FIXCLIP(4); + orgDrawOBJS (); + } + if (BG0) + { + FIXCLIP(0); + orgDrawBackground (PPU.BGMode, 0, 10, 14); + } + if (BG1) + { + FIXCLIP(1); + orgDrawBackground (PPU.BGMode, 1, 9, 13); + } + if (BG2) + { + FIXCLIP(2); + orgDrawBackground (PPU.BGMode, 2, 3, + PPU.BG3Priority ? 17 : 6); + } + if (BG3 && PPU.BGMode == 0) + { + FIXCLIP(3); + orgDrawBackground (PPU.BGMode, 3, 2, 5); + } + } + else if (PPU.BGMode != 7) + { + if (OB) + { + FIXCLIP(4); + orgDrawOBJS (); + } + if (BG0) + { + FIXCLIP(0); + orgDrawBackground (PPU.BGMode, 0, 5, 13); + } + if (BG1 && PPU.BGMode != 6) + { + FIXCLIP(1); + orgDrawBackground (PPU.BGMode, 1, 2, 9); + } + } + else + { + if (OB) + { + FIXCLIP(4); + orgDrawOBJS (); + } + if (BG0 || ((Memory.FillRAM [0x2133] & 0x40) && BG1)) + { + int bg; + FIXCLIP(0); + if ((Memory.FillRAM [0x2133] & 0x40) && BG1) + { + GFX.Mode7Mask = 0x7f; + GFX.Mode7PriorityMask = 0x80; + Mode7Depths [0] = (BG0?5:1); + Mode7Depths [1] = 9; + bg = 1; + } + else + { + GFX.Mode7Mask = 0xff; + GFX.Mode7PriorityMask = 0; + Mode7Depths [0] = 5; + Mode7Depths [1] = 5; + bg = 0; + } + + if (!Settings.SixteenBit) + orgDrawBGMode7Background16 (GFX.Screen, bg); + else + { + //if (!Settings.Mode7Interpolate) + orgDrawBGMode7Background16 (GFX.Screen, bg); + //else + // DrawBGMode7Background16_i (GFX.Screen, bg); + } + } + } + } + } + if (Settings.SupportHiRes) + { + if (PPU.BGMode != 5 && PPU.BGMode != 6 && IPPU.DoubleWidthPixels) + { + // Mixure of background modes used on screen - scale width + // of all non-mode 5 and 6 pixels. + if (Settings.SixteenBit) + { + for (register uint32 y = starty; y <= endy; y++) + { + register uint16 *p = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + 255; + register uint16 *q = (uint16 *) (GFX.Screen + y * GFX.Pitch2) + 510; + for (register int x = 255; x >= 0; x--, p--, q -= 2) + *q = *(q + 1) = *p; + } + } + else + { + for (register uint32 y = starty; y <= endy; y++) + { + register uint8 *p = GFX.Screen + y * GFX.Pitch2 + 255; + register uint8 *q = GFX.Screen + y * GFX.Pitch2 + 510; + for (register int x = 255; x >= 0; x--, p--, q -= 2) + *q = *(q + 1) = *p; + } + } + } + + // Double the height of the pixels just drawn + //FIX_INTERLACE(GFX.Screen, FALSE, GFX.ZBuffer); + + } + IPPU.PreviousLine = IPPU.CurrentLine; +} + + + + + diff --git a/src/snes4iphone_src/giz_kgsdk.c b/src/snes4iphone_src/giz_kgsdk.c new file mode 100755 index 0000000..2bfa6b4 --- /dev/null +++ b/src/snes4iphone_src/giz_kgsdk.c @@ -0,0 +1,343 @@ + +#include +#include "giz_kgsdk.h" +#include + +unsigned short *framebuffer16[4]={0,0,0,0}; +unsigned char *framebuffer8[4]; +void *GizPrimaryFrameBuffer=NULL; +volatile unsigned short gp2x_palette[512][2]; +int Timer=0; +static int bppMode = 16; +static unsigned int padValues[2]={0,0}; + +//Temp framebuffer +unsigned short frameBufferMemory[320*250]; + +// 1024x8 8x8 font, i love it :) +const unsigned int font8x8[]= {0x0,0x0,0xc3663c18,0x3c2424e7,0xe724243c,0x183c66c3,0xc16f3818,0x18386fc1,0x83f61c18,0x181cf683,0xe7c3993c,0x3c99c3,0x3f7fffff,0xe7cf9f,0x3c99c3e7,0xe7c399,0x3160c080,0x40e1b,0xcbcbc37e, +0x7ec3c3db,0x3c3c3c18,0x81c087e,0x8683818,0x60f0e08,0x81422418,0x18244281,0xbd5a2418,0x18245abd,0x818181ff,0xff8181,0xa1c181ff,0xff8995,0x63633e,0x3e6363,0x606060,0x606060,0x3e60603e,0x3e0303,0x3e60603e,0x3e6060,0x3e636363, +0x606060,0x3e03033e,0x3e6060,0x3e03033e,0x3e6363,0x60603e,0x606060,0x3e63633e,0x3e6363,0x3e63633e,0x3e6060,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x18181818,0x180018,0x666666,0x0,0x367f3600,0x367f36,0x3c067c18, +0x183e60,0x18366600,0x62660c,0xe1c361c,0x6e337b,0x181818,0x0,0x18183870,0x703818,0x18181c0e,0xe1c18,0xff3c6600,0x663c,0x7e181800,0x1818,0x0,0x60c0c00,0x7e000000,0x0,0x0,0x181800,0x18306040,0x2060c,0x6e76663c,0x3c6666,0x18181c18, +0x7e1818,0x3060663c,0x7e0c18,0x3018307e,0x3c6660,0x363c3830,0x30307e,0x603e067e,0x3c6660,0x3e06063c,0x3c6666,0x1830607e,0xc0c0c,0x3c66663c,0x3c6666,0x7c66663c,0x1c3060,0x181800,0x1818,0x181800,0xc1818,0xc183060,0x603018,0x7e0000, +0x7e00,0x30180c06,0x60c18,0x3060663c,0x180018,0x5676663c,0x7c0676,0x66663c18,0x66667e,0x3e66663e,0x3e6666,0x606663c,0x3c6606,0x6666361e,0x1e3666,0x3e06067e,0x7e0606,0x3e06067e,0x60606,0x7606067c,0x7c6666,0x7e666666,0x666666,0x1818183c, +0x3c1818,0x60606060,0x3c6660,0xe1e3666,0x66361e,0x6060606,0x7e0606,0x6b7f7763,0x636363,0x7e7e6e66,0x666676,0x6666663c,0x3c6666,0x3e66663e,0x60606,0x6666663c,0x6c366e,0x3e66663e,0x666636,0x3c06663c,0x3c6660,0x1818187e,0x181818,0x66666666, +0x7c6666,0x66666666,0x183c66,0x6b636363,0x63777f,0x183c6666,0x66663c,0x3c666666,0x181818,0x1830607e,0x7e060c,0x18181878,0x781818,0x180c0602,0x406030,0x1818181e,0x1e1818,0x63361c08,0x0,0x0,0x7f0000,0xc060300,0x0,0x603c0000,0x7c667c,0x663e0606, +0x3e6666,0x63c0000,0x3c0606,0x667c6060,0x7c6666,0x663c0000,0x3c067e,0xc3e0c38,0xc0c0c,0x667c0000,0x3e607c66,0x663e0606,0x666666,0x181c0018,0x3c1818,0x18180018,0xe181818,0x36660606,0x66361e,0x1818181c,0x3c1818,0x7f370000,0x63636b,0x663e0000, +0x666666,0x663c0000,0x3c6666,0x663e0000,0x63e6666,0x667c0000,0x607c6666,0x663e0000,0x60606,0x67c0000,0x3e603c,0x187e1800,0x701818,0x66660000,0x7c6666,0x66660000,0x183c66,0x63630000,0x363e6b,0x3c660000,0x663c18,0x66660000,0x3e607c66,0x307e0000, +0x7e0c18,0xc181870,0x701818,0x18181818,0x18181818,0x3018180e,0xe1818,0x794f0600,0x30}; + +/* +######################## +Graphics functions +######################## + */ + +static __inline__ +void gp_drawPixel8 ( int x, int y, unsigned char c, unsigned char *framebuffer ) +{ + *(framebuffer +(320*y)+x ) = c; +} + +static __inline__ +void gp_drawPixel16 ( int x, int y, unsigned short c, unsigned short *framebuffer ) +{ + *(framebuffer +(320*y)+x ) = c; +} + +static +void set_char8x8_16bpp (int xx,int yy,int offset,unsigned short mode,unsigned short *framebuffer) +{ + unsigned int y, pixel; + offset *= 2; + pixel = font8x8[0 + offset]; + for (y = 0; y < 4; y++) + { + if (pixel&(1<<(0+(y<<3)))) gp_drawPixel16(xx+0, yy+y, mode, framebuffer); + if (pixel&(1<<(1+(y<<3)))) gp_drawPixel16(xx+1, yy+y, mode, framebuffer); + if (pixel&(1<<(2+(y<<3)))) gp_drawPixel16(xx+2, yy+y, mode, framebuffer); + if (pixel&(1<<(3+(y<<3)))) gp_drawPixel16(xx+3, yy+y, mode, framebuffer); + if (pixel&(1<<(4+(y<<3)))) gp_drawPixel16(xx+4, yy+y, mode, framebuffer); + if (pixel&(1<<(5+(y<<3)))) gp_drawPixel16(xx+5, yy+y, mode, framebuffer); + if (pixel&(1<<(6+(y<<3)))) gp_drawPixel16(xx+6, yy+y, mode, framebuffer); + if (pixel&(1<<(7+(y<<3)))) gp_drawPixel16(xx+7, yy+y, mode, framebuffer); + } + pixel = font8x8[1 + offset]; + for (y = 0; y < 4; y++) + { + if (pixel&(1<<(0+(y<<3)))) gp_drawPixel16(xx+0, yy+y+4, mode, framebuffer); + if (pixel&(1<<(1+(y<<3)))) gp_drawPixel16(xx+1, yy+y+4, mode, framebuffer); + if (pixel&(1<<(2+(y<<3)))) gp_drawPixel16(xx+2, yy+y+4, mode, framebuffer); + if (pixel&(1<<(3+(y<<3)))) gp_drawPixel16(xx+3, yy+y+4, mode, framebuffer); + if (pixel&(1<<(4+(y<<3)))) gp_drawPixel16(xx+4, yy+y+4, mode, framebuffer); + if (pixel&(1<<(5+(y<<3)))) gp_drawPixel16(xx+5, yy+y+4, mode, framebuffer); + if (pixel&(1<<(6+(y<<3)))) gp_drawPixel16(xx+6, yy+y+4, mode, framebuffer); + if (pixel&(1<<(7+(y<<3)))) gp_drawPixel16(xx+7, yy+y+4, mode, framebuffer); + + } +} + +static +void set_char8x8_8bpp (int xx,int yy,int offset,unsigned char mode,unsigned char *framebuffer) +{ + unsigned int y, pixel; + offset *= 2; + pixel = font8x8[0 + offset]; + for (y = 0; y < 4; y++) + { + if (pixel&(1<<(0+(y<<3)))) gp_drawPixel8(xx+0, yy+y, mode, framebuffer); + if (pixel&(1<<(1+(y<<3)))) gp_drawPixel8(xx+1, yy+y, mode, framebuffer); + if (pixel&(1<<(2+(y<<3)))) gp_drawPixel8(xx+2, yy+y, mode, framebuffer); + if (pixel&(1<<(3+(y<<3)))) gp_drawPixel8(xx+3, yy+y, mode, framebuffer); + if (pixel&(1<<(4+(y<<3)))) gp_drawPixel8(xx+4, yy+y, mode, framebuffer); + if (pixel&(1<<(5+(y<<3)))) gp_drawPixel8(xx+5, yy+y, mode, framebuffer); + if (pixel&(1<<(6+(y<<3)))) gp_drawPixel8(xx+6, yy+y, mode, framebuffer); + if (pixel&(1<<(7+(y<<3)))) gp_drawPixel8(xx+7, yy+y, mode, framebuffer); + } + pixel = font8x8[1 + offset]; + for (y = 0; y < 4; y++) + { + if (pixel&(1<<(0+(y<<3)))) gp_drawPixel8(xx+0, yy+y+4, mode, framebuffer); + if (pixel&(1<<(1+(y<<3)))) gp_drawPixel8(xx+1, yy+y+4, mode, framebuffer); + if (pixel&(1<<(2+(y<<3)))) gp_drawPixel8(xx+2, yy+y+4, mode, framebuffer); + if (pixel&(1<<(3+(y<<3)))) gp_drawPixel8(xx+3, yy+y+4, mode, framebuffer); + if (pixel&(1<<(4+(y<<3)))) gp_drawPixel8(xx+4, yy+y+4, mode, framebuffer); + if (pixel&(1<<(5+(y<<3)))) gp_drawPixel8(xx+5, yy+y+4, mode, framebuffer); + if (pixel&(1<<(6+(y<<3)))) gp_drawPixel8(xx+6, yy+y+4, mode, framebuffer); + if (pixel&(1<<(7+(y<<3)))) gp_drawPixel8(xx+7, yy+y+4, mode, framebuffer); + + } +} + +void gp_drawString (int x,int y,int len,char *buffer,unsigned short color,void *framebuffer) +{ + int l,base=0; + + for (l=0;l>1 +1: + ;@ first line is perfectly aligned + ldmia r0!,{r2-r11} + stmia r1!,{r2-r11} + ldmia r0!,{r2-r11} + stmia r1!,{r2-r11} + ldmia r0!,{r2-r11} + stmia r1!,{r2-r11} + ldmia r0!,{r2-r11} + stmia r1!,{r2-r11} + ldmia r0!,{r2-r11} + stmia r1!,{r2-r11} + ldmia r0!,{r2-r11} + stmia r1!,{r2-r11} + ldmia r0!,{r2-r11} + stmia r1!,{r2-r11} + ldmia r0!,{r2-r11} + stmia r1!,{r2-r11} + + ldmia r0!,{r2-r11} + stmia r1!,{r2-r11} + ldmia r0!,{r2-r11} + stmia r1!,{r2-r11} + ldmia r0!,{r2-r11} + stmia r1!,{r2-r11} + ldmia r0!,{r2-r11} + stmia r1!,{r2-r11} + ldmia r0!,{r2-r11} + stmia r1!,{r2-r11} + ldmia r0!,{r2-r11} + stmia r1!,{r2-r11} + ldmia r0!,{r2-r11} + stmia r1!,{r2-r11} + ldmia r0!,{r2-r11} + stmia r1!,{r2-r11} + + add r1,r1,#2 + + ldmia r0!,{r2-r6} + strh r2,[r1],#2 + mov lr,#15 +2: + mov r2,r2,lsr#16 + orr r2,r2,r3,lsl#16 + mov r3,r3,lsr#16 + orr r3,r3,r4,lsl#16 + mov r4,r4,lsr#16 + orr r4,r4,r5,lsl#16 + mov r5,r5,lsr#16 + orr r5,r5,r6,lsl#16 + mov r6,r6,lsr#16 + ldmia r0!,{r7-r11} + orr r6,r6,r7,lsl#16 + stmia r1!,{r2-r6} + mov r7,r7,lsr#16 + orr r7,r7,r8,lsl#16 + mov r8,r8,lsr#16 + orr r8,r8,r9,lsl#16 + mov r9,r9,lsr#16 + orr r9,r9,r10,lsl#16 + mov r10,r10,lsr#16 + orr r10,r10,r11,lsl#16 + mov r11,r11,lsr#16 + ldmia r0!,{r2-r6} + orr r11,r11,r2,lsl#16 + stmia r1!,{r7-r11} + subs lr,lr,#1 + bne 2b + + mov r2,r2,lsr#16 + orr r2,r2,r3,lsl#16 + mov r3,r3,lsr#16 + orr r3,r3,r4,lsl#16 + mov r4,r4,lsr#16 + orr r4,r4,r5,lsl#16 + mov r5,r5,lsr#16 + orr r5,r5,r6,lsl#16 + mov r6,r6,lsr#16 + ldmia r0!,{r7-r11} + orr r6,r6,r7,lsl#16 + stmia r1!,{r2-r6} + mov r7,r7,lsr#16 + orr r7,r7,r8,lsl#16 + mov r8,r8,lsr#16 + orr r8,r8,r9,lsl#16 + mov r9,r9,lsr#16 + orr r9,r9,r10,lsl#16 + mov r10,r10,lsr#16 + orr r10,r10,r11,lsl#16 + mov r11,r11,lsr#16 + stmia r1!,{r7-r11} + + subs r12,r12,#1 + bne 1b + + ldmfd sp!,{r4-r12,pc} + + + diff --git a/src/snes4iphone_src/giz_sdk_kgsdk.c b/src/snes4iphone_src/giz_sdk_kgsdk.c new file mode 100755 index 0000000..3cd7ccd --- /dev/null +++ b/src/snes4iphone_src/giz_sdk_kgsdk.c @@ -0,0 +1,343 @@ + +#define DEBUG + +#include +#include +#include +#include "giz_sdk_kgsdk.h" +#include + + +#define SYS_CLK_FREQ 7372800 +unsigned long gp2x_ticks_per_second=7372800/1000; +unsigned long gp2x_dev[5]={0,0,0,0,0}; +unsigned long gp2x_physvram[4]={0,0,0,0}; +unsigned short *framebuffer16[4]={0,0,0,0}; +static unsigned short *framebuffer_mmap[4]={0,0,0,0}; +static int fb_size=(320*240*2)+(16*2); +unsigned short *gp2x_logvram15[2], gp2x_sound_buffer[4+((44100*2)*8)]; //*2=stereo, *4=max buffers +volatile unsigned short *gp2x_memregs; +volatile unsigned long *gp2x_memregl; +volatile unsigned long *gp2x_blitter = NULL; +unsigned int *gp2x_intVectors; +volatile unsigned short gp2x_palette[512][2]; +unsigned char *framebuffer8[4], *gp2x_screen8prev, *gp2x_logvram8[2]; +//pthread_t gp2x_sound_thread=0, gp2x_sound_thread_exit=0; +volatile short *pOutput[8]; +unsigned char InitFramebuffer=0; +int Timer=0; +volatile int SoundThreadFlag=0; +volatile int CurrentSoundBank=0; +int CurrentFrameBuffer=0; +int CurrentFrag=0; +unsigned short frameBufferMemory[320*250]; + +//Global SDL objects + +// 1024x8 8x8 font, i love it :) +const unsigned int font8x8[]= {0x0,0x0,0xc3663c18,0x3c2424e7,0xe724243c,0x183c66c3,0xc16f3818,0x18386fc1,0x83f61c18,0x181cf683,0xe7c3993c,0x3c99c3,0x3f7fffff,0xe7cf9f,0x3c99c3e7,0xe7c399,0x3160c080,0x40e1b,0xcbcbc37e, +0x7ec3c3db,0x3c3c3c18,0x81c087e,0x8683818,0x60f0e08,0x81422418,0x18244281,0xbd5a2418,0x18245abd,0x818181ff,0xff8181,0xa1c181ff,0xff8995,0x63633e,0x3e6363,0x606060,0x606060,0x3e60603e,0x3e0303,0x3e60603e,0x3e6060,0x3e636363, +0x606060,0x3e03033e,0x3e6060,0x3e03033e,0x3e6363,0x60603e,0x606060,0x3e63633e,0x3e6363,0x3e63633e,0x3e6060,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x18181818,0x180018,0x666666,0x0,0x367f3600,0x367f36,0x3c067c18, +0x183e60,0x18366600,0x62660c,0xe1c361c,0x6e337b,0x181818,0x0,0x18183870,0x703818,0x18181c0e,0xe1c18,0xff3c6600,0x663c,0x7e181800,0x1818,0x0,0x60c0c00,0x7e000000,0x0,0x0,0x181800,0x18306040,0x2060c,0x6e76663c,0x3c6666,0x18181c18, +0x7e1818,0x3060663c,0x7e0c18,0x3018307e,0x3c6660,0x363c3830,0x30307e,0x603e067e,0x3c6660,0x3e06063c,0x3c6666,0x1830607e,0xc0c0c,0x3c66663c,0x3c6666,0x7c66663c,0x1c3060,0x181800,0x1818,0x181800,0xc1818,0xc183060,0x603018,0x7e0000, +0x7e00,0x30180c06,0x60c18,0x3060663c,0x180018,0x5676663c,0x7c0676,0x66663c18,0x66667e,0x3e66663e,0x3e6666,0x606663c,0x3c6606,0x6666361e,0x1e3666,0x3e06067e,0x7e0606,0x3e06067e,0x60606,0x7606067c,0x7c6666,0x7e666666,0x666666,0x1818183c, +0x3c1818,0x60606060,0x3c6660,0xe1e3666,0x66361e,0x6060606,0x7e0606,0x6b7f7763,0x636363,0x7e7e6e66,0x666676,0x6666663c,0x3c6666,0x3e66663e,0x60606,0x6666663c,0x6c366e,0x3e66663e,0x666636,0x3c06663c,0x3c6660,0x1818187e,0x181818,0x66666666, +0x7c6666,0x66666666,0x183c66,0x6b636363,0x63777f,0x183c6666,0x66663c,0x3c666666,0x181818,0x1830607e,0x7e060c,0x18181878,0x781818,0x180c0602,0x406030,0x1818181e,0x1e1818,0x63361c08,0x0,0x0,0x7f0000,0xc060300,0x0,0x603c0000,0x7c667c,0x663e0606, +0x3e6666,0x63c0000,0x3c0606,0x667c6060,0x7c6666,0x663c0000,0x3c067e,0xc3e0c38,0xc0c0c,0x667c0000,0x3e607c66,0x663e0606,0x666666,0x181c0018,0x3c1818,0x18180018,0xe181818,0x36660606,0x66361e,0x1818181c,0x3c1818,0x7f370000,0x63636b,0x663e0000, +0x666666,0x663c0000,0x3c6666,0x663e0000,0x63e6666,0x667c0000,0x607c6666,0x663e0000,0x60606,0x67c0000,0x3e603c,0x187e1800,0x701818,0x66660000,0x7c6666,0x66660000,0x183c66,0x63630000,0x363e6b,0x3c660000,0x663c18,0x66660000,0x3e607c66,0x307e0000, +0x7e0c18,0xc181870,0x701818,0x18181818,0x18181818,0x3018180e,0xe1818,0x794f0600,0x30}; + +static int bppMode = 16; +static unsigned int padValues[2]={0,0}; +unsigned int ExistingIntHandler; + + +//SDL_Surface *sdlwrapper_screen; +/* +######################## +Graphics functions +######################## + */ + +static __inline__ +void gp_drawPixel8 ( int x, int y, unsigned char c, unsigned char *framebuffer ) +{ + *(framebuffer +(320*y)+x ) = c; +} + +static __inline__ +void gp_drawPixel16 ( int x, int y, unsigned short c, unsigned short *framebuffer ) +{ + *(framebuffer +(320*y)+x ) = c; +} + +static +void set_char8x8_16bpp (int xx,int yy,int offset,unsigned short mode,unsigned short *framebuffer) +{ + unsigned int y, pixel; + offset *= 2; + pixel = font8x8[0 + offset]; + for (y = 0; y < 4; y++) + { + if (pixel&(1<<(0+(y<<3)))) gp_drawPixel16(xx+0, yy+y, mode, framebuffer); + if (pixel&(1<<(1+(y<<3)))) gp_drawPixel16(xx+1, yy+y, mode, framebuffer); + if (pixel&(1<<(2+(y<<3)))) gp_drawPixel16(xx+2, yy+y, mode, framebuffer); + if (pixel&(1<<(3+(y<<3)))) gp_drawPixel16(xx+3, yy+y, mode, framebuffer); + if (pixel&(1<<(4+(y<<3)))) gp_drawPixel16(xx+4, yy+y, mode, framebuffer); + if (pixel&(1<<(5+(y<<3)))) gp_drawPixel16(xx+5, yy+y, mode, framebuffer); + if (pixel&(1<<(6+(y<<3)))) gp_drawPixel16(xx+6, yy+y, mode, framebuffer); + if (pixel&(1<<(7+(y<<3)))) gp_drawPixel16(xx+7, yy+y, mode, framebuffer); + } + pixel = font8x8[1 + offset]; + for (y = 0; y < 4; y++) + { + if (pixel&(1<<(0+(y<<3)))) gp_drawPixel16(xx+0, yy+y+4, mode, framebuffer); + if (pixel&(1<<(1+(y<<3)))) gp_drawPixel16(xx+1, yy+y+4, mode, framebuffer); + if (pixel&(1<<(2+(y<<3)))) gp_drawPixel16(xx+2, yy+y+4, mode, framebuffer); + if (pixel&(1<<(3+(y<<3)))) gp_drawPixel16(xx+3, yy+y+4, mode, framebuffer); + if (pixel&(1<<(4+(y<<3)))) gp_drawPixel16(xx+4, yy+y+4, mode, framebuffer); + if (pixel&(1<<(5+(y<<3)))) gp_drawPixel16(xx+5, yy+y+4, mode, framebuffer); + if (pixel&(1<<(6+(y<<3)))) gp_drawPixel16(xx+6, yy+y+4, mode, framebuffer); + if (pixel&(1<<(7+(y<<3)))) gp_drawPixel16(xx+7, yy+y+4, mode, framebuffer); + + } +} + +static +void set_char8x8_8bpp (int xx,int yy,int offset,unsigned char mode,unsigned char *framebuffer) +{ + unsigned int y, pixel; + offset *= 2; + pixel = font8x8[0 + offset]; + for (y = 0; y < 4; y++) + { + if (pixel&(1<<(0+(y<<3)))) gp_drawPixel8(xx+0, yy+y, mode, framebuffer); + if (pixel&(1<<(1+(y<<3)))) gp_drawPixel8(xx+1, yy+y, mode, framebuffer); + if (pixel&(1<<(2+(y<<3)))) gp_drawPixel8(xx+2, yy+y, mode, framebuffer); + if (pixel&(1<<(3+(y<<3)))) gp_drawPixel8(xx+3, yy+y, mode, framebuffer); + if (pixel&(1<<(4+(y<<3)))) gp_drawPixel8(xx+4, yy+y, mode, framebuffer); + if (pixel&(1<<(5+(y<<3)))) gp_drawPixel8(xx+5, yy+y, mode, framebuffer); + if (pixel&(1<<(6+(y<<3)))) gp_drawPixel8(xx+6, yy+y, mode, framebuffer); + if (pixel&(1<<(7+(y<<3)))) gp_drawPixel8(xx+7, yy+y, mode, framebuffer); + } + pixel = font8x8[1 + offset]; + for (y = 0; y < 4; y++) + { + if (pixel&(1<<(0+(y<<3)))) gp_drawPixel8(xx+0, yy+y+4, mode, framebuffer); + if (pixel&(1<<(1+(y<<3)))) gp_drawPixel8(xx+1, yy+y+4, mode, framebuffer); + if (pixel&(1<<(2+(y<<3)))) gp_drawPixel8(xx+2, yy+y+4, mode, framebuffer); + if (pixel&(1<<(3+(y<<3)))) gp_drawPixel8(xx+3, yy+y+4, mode, framebuffer); + if (pixel&(1<<(4+(y<<3)))) gp_drawPixel8(xx+4, yy+y+4, mode, framebuffer); + if (pixel&(1<<(5+(y<<3)))) gp_drawPixel8(xx+5, yy+y+4, mode, framebuffer); + if (pixel&(1<<(6+(y<<3)))) gp_drawPixel8(xx+6, yy+y+4, mode, framebuffer); + if (pixel&(1<<(7+(y<<3)))) gp_drawPixel8(xx+7, yy+y+4, mode, framebuffer); + + } +} + +void gp_drawString (int x,int y,int len,char *buffer,unsigned short color,void *framebuffer) +{ +#if 1 + int l,base=0; + + for (l=0;l> 1; +uint32 RGB_LOW_BITS_MASK = (RED_LOW_BIT_MASK_RGB565 | + GREEN_LOW_BIT_MASK_RGB565 | + BLUE_LOW_BIT_MASK_RGB565); +uint32 RGB_HI_BITS_MASK = (RED_HI_BIT_MASK_RGB565 | + GREEN_HI_BIT_MASK_RGB565 | + BLUE_HI_BIT_MASK_RGB565); +uint32 RGB_HI_BITS_MASKx2 = (RED_HI_BIT_MASK_RGB565 | + GREEN_HI_BIT_MASK_RGB565 | + BLUE_HI_BIT_MASK_RGB565) << 1; +uint32 RGB_REMOVE_LOW_BITS_MASK = ~RGB_LOW_BITS_MASK; +uint32 FIRST_COLOR_MASK = FIRST_COLOR_MASK_RGB565; +uint32 SECOND_COLOR_MASK = SECOND_COLOR_MASK_RGB565; +uint32 THIRD_COLOR_MASK = THIRD_COLOR_MASK_RGB565; +uint32 ALPHA_BITS_MASK = ALPHA_BITS_MASK_RGB565; +uint32 FIRST_THIRD_COLOR_MASK = 0; +uint32 TWO_LOW_BITS_MASK = 0; +uint32 HIGH_BITS_SHIFTED_TWO_MASK = 0; + +uint32 current_graphic_format = RGB565; +#endif + +uint8 GetBank = 0; +struct SCheatData Cheat; + +SoundStatus so; +SSoundData SoundData; +int Echo [24000]; +int DummyEchoBuffer [SOUND_BUFFER_SIZE]; +int MixBuffer [SOUND_BUFFER_SIZE]; +int EchoBuffer [SOUND_BUFFER_SIZE]; +int FilterTaps [8]; +unsigned long Z = 0; +int Loop [16]; + +uint16 SignExtend [2] = { + 0x00, 0xff00 +}; + +int HDMA_ModeByteCounts [8] = { + 1, 2, 2, 4, 4, 0, 0, 0 +}; + +uint8 BitShifts[8][4] = +{ + {2, 2, 2, 2}, // 0 + {4, 4, 2, 0}, // 1 + {4, 4, 0, 0}, // 2 + {8, 4, 0, 0}, // 3 + {8, 2, 0, 0}, // 4 + {4, 2, 0, 0}, // 5 + {4, 0, 0, 0}, // 6 + {8, 0, 0, 0} // 7 +}; +uint8 TileShifts[8][4] = +{ + {4, 4, 4, 4}, // 0 + {5, 5, 4, 0}, // 1 + {5, 5, 0, 0}, // 2 + {6, 5, 0, 0}, // 3 + {6, 4, 0, 0}, // 4 + {5, 4, 0, 0}, // 5 + {5, 0, 0, 0}, // 6 + {6, 0, 0, 0} // 7 +}; +uint8 PaletteShifts[8][4] = +{ + {2, 2, 2, 2}, // 0 + {4, 4, 2, 0}, // 1 + {4, 4, 0, 0}, // 2 + {0, 4, 0, 0}, // 3 + {0, 2, 0, 0}, // 4 + {4, 2, 0, 0}, // 5 + {4, 0, 0, 0}, // 6 + {0, 0, 0, 0} // 7 +}; +uint8 PaletteMasks[8][4] = +{ + {7, 7, 7, 7}, // 0 + {7, 7, 7, 0}, // 1 + {7, 7, 0, 0}, // 2 + {0, 7, 0, 0}, // 3 + {0, 7, 0, 0}, // 4 + {7, 7, 0, 0}, // 5 + {7, 0, 0, 0}, // 6 + {0, 0, 0, 0} // 7 +}; +uint8 Depths[8][4] = +{ + {TILE_2BIT, TILE_2BIT, TILE_2BIT, TILE_2BIT}, // 0 + {TILE_4BIT, TILE_4BIT, TILE_2BIT, 0}, // 1 + {TILE_4BIT, TILE_4BIT, 0, 0}, // 2 + {TILE_8BIT, TILE_4BIT, 0, 0}, // 3 + {TILE_8BIT, TILE_2BIT, 0, 0}, // 4 + {TILE_4BIT, TILE_2BIT, 0, 0}, // 5 + {TILE_8BIT, 0, 0, 0}, // 6 + {0, 0, 0, 0} // 7 +}; +uint8 BGSizes [2] = { + 8, 16 +}; +uint16 DirectColourMaps [8][256]; + +long FilterValues[4][2] = +{ + {0, 0}, + {240, 0}, + {488, -240}, + {460, -208} +}; + +int NoiseFreq [32] = { + 0, 16, 21, 25, 31, 42, 50, 63, 84, 100, 125, 167, 200, 250, 333, + 400, 500, 667, 800, 1000, 1300, 1600, 2000, 2700, 3200, 4000, + 5300, 6400, 8000, 10700, 16000, 32000 +}; + +uint32 HeadMask [4] = { +#ifdef LSB_FIRST + 0xffffffff, 0xffffff00, 0xffff0000, 0xff000000 +#else + 0xffffffff, 0x00ffffff, 0x0000ffff, 0x000000ff +#endif +}; + +uint32 TailMask [5] = { +#ifdef LSB_FIRST + 0x00000000, 0x000000ff, 0x0000ffff, 0x00ffffff, 0xffffffff +#else + 0x00000000, 0xff000000, 0xffff0000, 0xffffff00, 0xffffffff +#endif +}; + +START_EXTERN_C +uint8 APUROM [64] = +{ + 0xCD,0xEF,0xBD,0xE8,0x00,0xC6,0x1D,0xD0,0xFC,0x8F,0xAA,0xF4,0x8F, + 0xBB,0xF5,0x78,0xCC,0xF4,0xD0,0xFB,0x2F,0x19,0xEB,0xF4,0xD0,0xFC, + 0x7E,0xF4,0xD0,0x0B,0xE4,0xF5,0xCB,0xF4,0xD7,0x00,0xFC,0xD0,0xF3, + 0xAB,0x01,0x10,0xEF,0x7E,0xF4,0x10,0xEB,0xBA,0xF6,0xDA,0x00,0xBA, + 0xF4,0xC4,0xF4,0xDD,0x5D,0xD0,0xDB,0x1F,0x00,0x00,0xC0,0xFF +}; + +#ifdef NETPLAY_SUPPORT +struct SNetPlay NetPlay; +#endif + +// Raw SPC700 instruction cycle lengths +int32 S9xAPUCycleLengths [256] = +{ + /* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f, */ + /* 00 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 4, 6, 8, + /* 10 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 6, 5, 2, 2, 4, 6, + /* 20 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 4, 5, 4, + /* 30 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 6, 5, 2, 2, 3, 8, + /* 40 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 4, 6, 6, + /* 50 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 4, 5, 2, 2, 4, 3, + /* 60 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 4, 5, 5, + /* 70 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2, 3, 6, + /* 80 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 2, 4, 5, + /* 90 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2,12, 5, + /* a0 */ 3, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 2, 4, 4, + /* b0 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2, 3, 4, + /* c0 */ 3, 8, 4, 5, 4, 5, 4, 7, 2, 5, 6, 4, 5, 2, 4, 9, + /* d0 */ 2, 8, 4, 5, 5, 6, 6, 7, 4, 5, 4, 5, 2, 2, 6, 3, + /* e0 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 4, 5, 3, 4, 3, 4, 3, + /* f0 */ 2, 8, 4, 5, 4, 5, 5, 6, 3, 4, 5, 4, 2, 2, 4, 3 +}; + +// Actual data used by CPU emulation, will be scaled by APUReset routine +// to be relative to the 65c816 instruction lengths. +int32 S9xAPUCycles [256] = +{ + /* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f, */ + /* 00 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 4, 6, 8, + /* 10 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 6, 5, 2, 2, 4, 6, + /* 20 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 4, 5, 4, + /* 30 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 6, 5, 2, 2, 3, 8, + /* 40 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 4, 6, 6, + /* 50 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 4, 5, 2, 2, 4, 3, + /* 60 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 4, 5, 5, + /* 70 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2, 3, 6, + /* 80 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 2, 4, 5, + /* 90 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2,12, 5, + /* a0 */ 3, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 2, 4, 4, + /* b0 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2, 3, 4, + /* c0 */ 3, 8, 4, 5, 4, 5, 4, 7, 2, 5, 6, 4, 5, 2, 4, 9, + /* d0 */ 2, 8, 4, 5, 5, 6, 6, 7, 4, 5, 4, 5, 2, 2, 6, 3, + /* e0 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 4, 5, 3, 4, 3, 4, 3, + /* f0 */ 2, 8, 4, 5, 4, 5, 5, 6, 3, 4, 5, 4, 2, 2, 4, 3 +}; + +#ifndef VAR_CYCLES +uint8 S9xE1M1X1 [256] = { + 8, 6, 8, 4, 5, 3, 5, 6, 3, 2, 2, 4, 6, 4, 6, 5, /* e=1, m=1, x=1 */ + 2, 5, 5, 7, 5, 4, 6, 6, 2, 4, 2, 2, 6, 4, 7, 5, + 6, 6, 8, 4, 3, 3, 5, 6, 4, 2, 2, 5, 4, 4, 6, 5, + 2, 5, 5, 7, 4, 4, 6, 6, 2, 4, 2, 2, 4, 4, 7, 5, + 7, 6, 2, 4, 0, 3, 5, 6, 3, 2, 2, 3, 3, 4, 6, 5, + 2, 5, 5, 7, 0, 4, 6, 6, 2, 4, 3, 2, 4, 4, 7, 5, + 6, 6, 6, 4, 3, 3, 5, 6, 4, 2, 2, 6, 5, 4, 6, 5, + 2, 5, 5, 7, 4, 4, 6, 6, 2, 4, 4, 2, 6, 4, 7, 5, + 2, 6, 3, 4, 3, 3, 3, 6, 2, 2, 2, 3, 4, 4, 4, 5, + 2, 5, 5, 7, 4, 4, 4, 6, 2, 4, 2, 2, 4, 4, 4, 5, + 2, 6, 2, 4, 3, 3, 3, 6, 2, 2, 2, 4, 4, 4, 4, 5, + 2, 5, 5, 7, 4, 4, 4, 6, 2, 4, 2, 2, 4, 4, 4, 5, + 2, 6, 3, 4, 3, 3, 5, 6, 2, 2, 2, 3, 4, 4, 6, 5, + 2, 5, 5, 7, 6, 4, 6, 6, 2, 4, 3, 3, 6, 4, 7, 5, + 2, 6, 3, 4, 3, 3, 5, 6, 2, 2, 2, 3, 4, 4, 6, 5, + 2, 5, 5, 7, 5, 4, 6, 6, 2, 4, 4, 2, 6, 4, 7, 5 +}; + +uint8 S9xE0M1X1 [256] = { + 8, 6, 8, 4, 5, 3, 5, 6, 3, 2, 2, 4, 6, 4, 6, 5, /* e=0, m=1, x=1 */ + 2, 5, 5, 7, 5, 4, 6, 6, 2, 4, 2, 2, 6, 4, 7, 5, + 6, 6, 8, 4, 3, 3, 5, 6, 4, 2, 2, 5, 4, 4, 6, 5, + 2, 5, 5, 7, 4, 4, 6, 6, 2, 4, 2, 2, 4, 4, 7, 5, + 7, 6, 2, 4, 0, 3, 5, 6, 3, 2, 2, 3, 3, 4, 6, 5, + 2, 5, 5, 7, 0, 4, 6, 6, 2, 4, 3, 2, 4, 4, 7, 5, + 6, 6, 6, 4, 3, 3, 5, 6, 4, 2, 2, 6, 5, 4, 6, 5, + 2, 5, 5, 7, 4, 4, 6, 6, 2, 4, 4, 2, 6, 4, 7, 5, + 2, 6, 3, 4, 3, 3, 3, 6, 2, 2, 2, 3, 4, 4, 4, 5, + 2, 5, 5, 7, 4, 4, 4, 6, 2, 4, 2, 2, 4, 4, 4, 5, + 2, 6, 2, 4, 3, 3, 3, 6, 2, 2, 2, 4, 4, 4, 4, 5, + 2, 5, 5, 7, 4, 4, 4, 6, 2, 4, 2, 2, 4, 4, 4, 5, + 2, 6, 3, 4, 3, 3, 5, 6, 2, 2, 2, 3, 4, 4, 6, 5, + 2, 5, 5, 7, 6, 4, 6, 6, 2, 4, 3, 3, 6, 4, 7, 5, + 2, 6, 3, 4, 3, 3, 5, 6, 2, 2, 2, 3, 4, 4, 6, 5, + 2, 5, 5, 7, 5, 4, 6, 6, 2, 4, 4, 2, 6, 4, 7, 5 +}; + +uint8 S9xE0M0X1 [256] = { + 8, 7, 8, 5, 7, 4, 7, 7, 3, 3, 2, 4, 8, 5, 8, 6, /* e=0, m=0, x=1 */ + 2, 6, 6, 8, 7, 5, 8, 7, 2, 5, 2, 2, 8, 5, 9, 6, + 6, 7, 8, 5, 4, 4, 7, 7, 4, 3, 2, 5, 5, 5, 8, 6, + 2, 6, 6, 8, 5, 5, 8, 7, 2, 5, 2, 2, 5, 5, 9, 6, + 7, 7, 2, 5, 0, 4, 7, 7, 4, 3, 2, 3, 3, 5, 8, 6, + 2, 6, 6, 8, 0, 5, 8, 7, 2, 5, 3, 2, 4, 5, 9, 6, + 6, 7, 6, 5, 4, 4, 7, 7, 5, 3, 2, 6, 5, 5, 8, 6, + 2, 6, 6, 8, 5, 5, 8, 7, 2, 5, 4, 2, 6, 5, 9, 6, + 2, 7, 3, 5, 3, 4, 3, 7, 2, 3, 2, 3, 4, 5, 4, 6, + 2, 6, 6, 8, 4, 5, 4, 7, 2, 5, 2, 2, 5, 5, 5, 6, + 2, 7, 2, 5, 3, 4, 3, 7, 2, 3, 2, 4, 4, 5, 4, 6, + 2, 6, 6, 8, 4, 5, 4, 7, 2, 5, 2, 2, 4, 5, 4, 6, + 2, 7, 3, 5, 3, 4, 7, 7, 2, 3, 2, 3, 4, 5, 8, 6, + 2, 6, 6, 8, 6, 5, 8, 7, 2, 5, 3, 3, 6, 5, 9, 6, + 2, 7, 3, 5, 3, 4, 7, 7, 2, 3, 2, 3, 4, 5, 8, 6, + 2, 6, 6, 8, 5, 5, 8, 7, 2, 5, 4, 2, 6, 5, 9, 6 +}; + +uint8 S9xE0M1X0 [256] = { + 8, 6, 8, 4, 5, 3, 5, 6, 3, 2, 2, 4, 6, 4, 6, 5, /* e=0, m=1, x=0 */ + 2, 6, 5, 7, 5, 4, 6, 6, 2, 5, 2, 2, 6, 5, 7, 5, + 6, 6, 8, 4, 3, 3, 5, 6, 4, 2, 2, 5, 4, 4, 6, 5, + 2, 6, 5, 7, 4, 4, 6, 6, 2, 5, 2, 2, 5, 5, 7, 5, + 7, 6, 2, 4, 0, 3, 5, 6, 4, 2, 2, 3, 3, 4, 6, 5, + 2, 6, 5, 7, 0, 4, 6, 6, 2, 5, 4, 2, 4, 5, 7, 5, + 6, 6, 6, 4, 3, 3, 5, 6, 5, 2, 2, 6, 5, 4, 6, 5, + 2, 6, 5, 7, 4, 4, 6, 6, 2, 5, 5, 2, 6, 5, 7, 5, + 2, 6, 3, 4, 4, 3, 4, 6, 2, 2, 2, 3, 5, 4, 5, 5, + 2, 6, 5, 7, 5, 4, 5, 6, 2, 5, 2, 2, 4, 5, 5, 5, + 3, 6, 3, 4, 4, 3, 4, 6, 2, 2, 2, 4, 5, 4, 5, 5, + 2, 6, 5, 7, 5, 4, 5, 6, 2, 5, 2, 2, 5, 5, 5, 5, + 3, 6, 3, 4, 4, 3, 6, 6, 2, 2, 2, 3, 5, 4, 6, 5, + 2, 6, 5, 7, 6, 4, 8, 6, 2, 5, 4, 3, 6, 5, 7, 5, + 3, 6, 3, 4, 4, 3, 6, 6, 2, 2, 2, 3, 5, 4, 6, 5, + 2, 6, 5, 7, 5, 4, 8, 6, 2, 5, 5, 2, 6, 5, 7, 5 +}; + +uint8 S9xE0M0X0 [256] = { + 8, 7, 8, 5, 7, 4, 7, 7, 3, 3, 2, 4, 8, 5, 8, 6, /* e=0, m=0, x=0 */ + 2, 7, 6, 8, 7, 5, 8, 7, 2, 6, 2, 2, 8, 6, 9, 6, + 6, 7, 8, 5, 4, 4, 7, 7, 4, 3, 2, 5, 5, 5, 8, 6, + 2, 7, 6, 8, 5, 5, 8, 7, 2, 6, 2, 2, 6, 6, 9, 6, + 7, 7, 2, 5, 0, 4, 7, 7, 3, 3, 2, 3, 3, 5, 8, 6, + 2, 7, 6, 8, 0, 5, 8, 7, 2, 6, 4, 2, 4, 6, 9, 6, + 6, 7, 6, 5, 4, 4, 7, 7, 4, 3, 2, 6, 5, 5, 8, 6, + 2, 7, 6, 8, 5, 5, 8, 7, 2, 6, 5, 2, 6, 6, 9, 6, + 2, 7, 3, 5, 4, 4, 4, 7, 2, 3, 2, 3, 5, 5, 5, 6, + 2, 7, 6, 8, 5, 5, 5, 7, 2, 6, 2, 2, 5, 6, 6, 6, + 3, 7, 3, 5, 4, 4, 4, 7, 2, 3, 2, 4, 5, 5, 5, 6, + 2, 7, 6, 8, 5, 5, 5, 7, 2, 6, 2, 2, 5, 6, 5, 6, + 3, 7, 3, 5, 4, 4, 7, 7, 2, 3, 2, 3, 5, 5, 8, 6, + 2, 7, 6, 8, 6, 5, 8, 7, 2, 6, 4, 3, 6, 6, 9, 6, + 3, 7, 3, 5, 4, 4, 7, 7, 2, 3, 2, 3, 5, 5, 8, 6, + 2, 7, 6, 8, 5, 5, 8, 7, 2, 6, 5, 2, 6, 6, 9, 6 +}; +#endif + +END_EXTERN_C diff --git a/src/snes4iphone_src/gp2x_highlightbar.c b/src/snes4iphone_src/gp2x_highlightbar.c new file mode 100755 index 0000000..5ef8da8 --- /dev/null +++ b/src/snes4iphone_src/gp2x_highlightbar.c @@ -0,0 +1,341 @@ +///////////////////////////////////////// +// +// Header file for GP32 +// +// convertion of highlightbar.bmp file : +// Width = 16 +// Heigth = 320 +// GP32 Mode = 16 Bits per Pixel +// +// with GP32Converter coded by Edorul : +// http://www.ifrance.com/edorul/ +// edorul@free.fr +// +///////////////////////////////////////// + +#define highlightbar_width 320 +#define highlightbar_height 16 +unsigned short highLightBar[5120]; +unsigned short highLightBarOrig[5120] = { + 0xFFCA, 0xFFCA, 0xFFCA, 0xFFCC, 0xFFCC, 0xFFCC, 0xFFCC, 0xFFCC, 0xFFCC, 0xFFCC, 0xFF8C, 0xFF8C, 0xFF8C, 0xFF8C, 0xFF8C, 0xFF8C, + 0xFF8C, 0xFF8C, 0xFF4C, 0xFF4C, 0xFF4C, 0xFF4E, 0xFF4E, 0xFF4E, 0xFF4E, 0xFF4E, 0xFF4E, 0xFF0E, 0xFF0E, 0xFF0E, 0xFF0E, 0xFF0E, + 0xFF0E, 0xFF0E, 0xFF0E, 0xFF0E, 0xFF0E, 0xFECE, 0xFECE, 0xFED0, 0xFED0, 0xFED0, 0xFED0, 0xFED0, 0xFED0, 0xFED0, 0xFE90, 0xFE90, + 0xFE90, 0xFE90, 0xFE90, 0xFE90, 0xFE90, 0xFE90, 0xFE90, 0xFE50, 0xFE50, 0xFE52, 0xFE52, 0xFE52, 0xFE52, 0xFE52, 0xFE52, 0xFE52, + 0xFE12, 0xFE12, 0xFE12, 0xFE12, 0xFE12, 0xFE12, 0xFE12, 0xFE12, 0xFE12, 0xFE14, 0xFDD4, 0xFDD4, 0xFDD4, 0xFDD4, 0xFDD4, 0xFDD4, + 0xFDD4, 0xFDD4, 0xFDD4, 0xFD94, 0xFD94, 0xFD94, 0xFD94, 0xFD94, 0xFD94, 0xFD94, 0xFD94, 0xFD96, 0xFD56, 0xFD56, 0xFD56, 0xFD56, + 0xFD56, 0xFD56, 0xFD56, 0xFD56, 0xFD56, 0xFD16, 0xFD16, 0xFD16, 0xFD16, 0xFD16, 0xFD16, 0xFD16, 0xFD16, 0xFD18, 0xFD18, 0xFCD8, + 0xFCD8, 0xFCD8, 0xFCD8, 0xFCD8, 0xFCD8, 0xFCD8, 0xFCD8, 0xFCD8, 0xFC98, 0xFC98, 0xFC96, 0xFC96, 0xFC96, 0xFC96, 0xFC96, 0xFC96, + 0xFC56, 0xFC56, 0xFC56, 0xFC56, 0xFC56, 0xFC56, 0xFC56, 0xFC56, 0xFC16, 0xFC16, 0xFC16, 0xFC16, 0xFC14, 0xFC14, 0xFC14, 0xFC14, + 0xFC14, 0xFBD4, 0xFBD4, 0xFBD4, 0xFBD4, 0xFBD4, 0xFBD4, 0xFBD4, 0xFBD4, 0xFB94, 0xFB94, 0xFB94, 0xFB94, 0xFB94, 0xFB92, 0xFB92, + 0xFB92, 0xFB92, 0xFB52, 0xFB52, 0xFB52, 0xFB52, 0xFB52, 0xFB52, 0xFB52, 0xFB52, 0xFB12, 0xFB12, 0xFB12, 0xFB12, 0xFB10, 0xFB10, + 0xFB10, 0xFB10, 0xFAD0, 0xFAD0, 0xFAD0, 0xFAD0, 0xFAD0, 0xFAD0, 0xFAD0, 0xFAD0, 0xFAD0, 0xFA90, 0xFA90, 0xFA90, 0xFA90, 0xFA90, + 0xFA8E, 0xFA8E, 0xFA8E, 0xFA8E, 0xFA4E, 0xFA4E, 0xFA4E, 0xFA4E, 0xFA4E, 0xFA4E, 0xFA4E, 0xFA4E, 0xFA0E, 0xFA0E, 0xFA0E, 0xFA0E, + 0xFA0E, 0xFA0E, 0xFA0C, 0xFA0C, 0xF9CC, 0xF9CC, 0xF9CC, 0xF9CC, 0xF9CC, 0xF9CC, 0xF9CC, 0xF9CC, 0xF9CC, 0xF98C, 0xF98C, 0xF98C, + 0xF98C, 0xF98C, 0xF98C, 0xF98C, 0xF98A, 0xF98A, 0xF94A, 0xF94A, 0xF94A, 0xF94A, 0xF94A, 0xF94A, 0xF94A, 0xF94A, 0xF14A, 0xF14A, + 0xF14A, 0xF14A, 0xF14A, 0xF14A, 0xF14A, 0xF14A, 0xE94A, 0xE94A, 0xE94A, 0xE94A, 0xE94A, 0xE94A, 0xE94A, 0xE94A, 0xE14A, 0xE14A, + 0xE14A, 0xE14A, 0xE14A, 0xE14A, 0xE14A, 0xE14A, 0xD94A, 0xD94A, 0xD94A, 0xD94A, 0xD94A, 0xD94A, 0xD94A, 0xD14A, 0xD14A, 0xD14A, + 0xD14A, 0xD14A, 0xD14A, 0xD14A, 0xD14A, 0xC94A, 0xC94A, 0xC94A, 0xC94A, 0xC94A, 0xC94A, 0xC94A, 0xC94A, 0xC14A, 0xC14A, 0xC14A, + 0xC14A, 0xC14A, 0xC14A, 0xC14A, 0xC14A, 0xC14A, 0xB94A, 0xB94A, 0xB94A, 0xB94A, 0xB94A, 0xB94A, 0xB94A, 0xB94A, 0xB94A, 0xB14A, + 0xB14A, 0xB14A, 0xB14A, 0xB14A, 0xB14A, 0xB14A, 0xB14A, 0xB14A, 0xA94A, 0xA94A, 0xA94A, 0xA94A, 0xA94A, 0xA94A, 0xA94A, 0xA94A, + 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF82, 0xFF42, + 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF04, 0xFF04, 0xFEC4, 0xFEC4, + 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE86, 0xFE86, 0xFE46, 0xFE46, 0xFE46, + 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE06, 0xFE06, 0xFE06, 0xFE06, 0xFE08, 0xFE08, 0xFE08, 0xFE08, 0xFDC8, 0xFDC8, 0xFDC8, + 0xFDC8, 0xFDC8, 0xFDC8, 0xFDC8, 0xFD88, 0xFD88, 0xFD88, 0xFD88, 0xFD8A, 0xFD8A, 0xFD8A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, + 0xFD4A, 0xFD4A, 0xFD4A, 0xFD0A, 0xFD0A, 0xFD0A, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, + 0xFCCC, 0xFCCC, 0xFC8C, 0xFC8C, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, + 0xFC4E, 0xFC0E, 0xFC0E, 0xFC10, 0xFC10, 0xFC0E, 0xFC0E, 0xFC0E, 0xFC0E, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFB8E, + 0xFB8E, 0xFB8E, 0xFB8E, 0xFB8C, 0xFB8C, 0xFB8C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB0C, 0xFB0C, 0xFB0C, + 0xFB0C, 0xFB0A, 0xFB0A, 0xFB0A, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, + 0xFA88, 0xFA88, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA06, 0xFA06, + 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF984, 0xF944, 0xF944, + 0xF944, 0xF944, 0xF944, 0xF944, 0xF944, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF902, 0xF8C2, 0xF8C2, 0xF8C2, 0xF8C2, + 0xF8C2, 0xF8C2, 0xF8C2, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, + 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF000, 0xF000, 0xF000, + 0xF000, 0xF000, 0xF000, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, + 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xC800, 0xC800, 0xC800, + 0xC800, 0xC800, 0xC800, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, + 0xB800, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA000, + 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9000, 0x9000, + 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF82, 0xFF42, + 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF04, 0xFF04, 0xFEC4, 0xFEC4, + 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE86, 0xFE86, 0xFE46, 0xFE46, 0xFE46, + 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE06, 0xFE06, 0xFE06, 0xFE06, 0xFE08, 0xFE08, 0xFE08, 0xFE08, 0xFDC8, 0xFDC8, 0xFDC8, + 0xFDC8, 0xFDC8, 0xFDC8, 0xFDC8, 0xFD88, 0xFD88, 0xFD88, 0xFD88, 0xFD8A, 0xFD8A, 0xFD8A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, + 0xFD4A, 0xFD4A, 0xFD4A, 0xFD0A, 0xFD0A, 0xFD0A, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, + 0xFCCC, 0xFCCC, 0xFC8C, 0xFC8C, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, + 0xFC4E, 0xFC0E, 0xFC0E, 0xFC10, 0xFC10, 0xFC0E, 0xFC0E, 0xFC0E, 0xFC0E, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFB8E, + 0xFB8E, 0xFB8E, 0xFB8E, 0xFB8C, 0xFB8C, 0xFB8C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB0C, 0xFB0C, 0xFB0C, + 0xFB0C, 0xFB0A, 0xFB0A, 0xFB0A, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, + 0xFA88, 0xFA88, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA06, 0xFA06, + 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF984, 0xF944, 0xF944, + 0xF944, 0xF944, 0xF944, 0xF944, 0xF944, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF902, 0xF8C2, 0xF8C2, 0xF8C2, 0xF8C2, + 0xF8C2, 0xF8C2, 0xF8C2, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, + 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF000, 0xF000, 0xF000, + 0xF000, 0xF000, 0xF000, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, + 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xC800, 0xC800, 0xC800, + 0xC800, 0xC800, 0xC800, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, + 0xB800, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA000, + 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9000, 0x9000, + 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF82, 0xFF42, + 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF04, 0xFF04, 0xFEC4, 0xFEC4, + 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE86, 0xFE86, 0xFE46, 0xFE46, 0xFE46, + 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE06, 0xFE06, 0xFE06, 0xFE06, 0xFE08, 0xFE08, 0xFE08, 0xFE08, 0xFDC8, 0xFDC8, 0xFDC8, + 0xFDC8, 0xFDC8, 0xFDC8, 0xFDC8, 0xFD88, 0xFD88, 0xFD88, 0xFD88, 0xFD8A, 0xFD8A, 0xFD8A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, + 0xFD4A, 0xFD4A, 0xFD4A, 0xFD0A, 0xFD0A, 0xFD0A, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, + 0xFCCC, 0xFCCC, 0xFC8C, 0xFC8C, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, + 0xFC4E, 0xFC0E, 0xFC0E, 0xFC10, 0xFC10, 0xFC0E, 0xFC0E, 0xFC0E, 0xFC0E, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFB8E, + 0xFB8E, 0xFB8E, 0xFB8E, 0xFB8C, 0xFB8C, 0xFB8C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB0C, 0xFB0C, 0xFB0C, + 0xFB0C, 0xFB0A, 0xFB0A, 0xFB0A, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, + 0xFA88, 0xFA88, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA06, 0xFA06, + 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF984, 0xF944, 0xF944, + 0xF944, 0xF944, 0xF944, 0xF944, 0xF944, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF902, 0xF8C2, 0xF8C2, 0xF8C2, 0xF8C2, + 0xF8C2, 0xF8C2, 0xF8C2, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, + 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF000, 0xF000, 0xF000, + 0xF000, 0xF000, 0xF000, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, + 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xC800, 0xC800, 0xC800, + 0xC800, 0xC800, 0xC800, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, + 0xB800, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA000, + 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9000, 0x9000, + 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF82, 0xFF42, + 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF04, 0xFF04, 0xFEC4, 0xFEC4, + 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE86, 0xFE86, 0xFE46, 0xFE46, 0xFE46, + 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE06, 0xFE06, 0xFE06, 0xFE06, 0xFE08, 0xFE08, 0xFE08, 0xFE08, 0xFDC8, 0xFDC8, 0xFDC8, + 0xFDC8, 0xFDC8, 0xFDC8, 0xFDC8, 0xFD88, 0xFD88, 0xFD88, 0xFD88, 0xFD8A, 0xFD8A, 0xFD8A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, + 0xFD4A, 0xFD4A, 0xFD4A, 0xFD0A, 0xFD0A, 0xFD0A, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, + 0xFCCC, 0xFCCC, 0xFC8C, 0xFC8C, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, + 0xFC4E, 0xFC0E, 0xFC0E, 0xFC10, 0xFC10, 0xFC0E, 0xFC0E, 0xFC0E, 0xFC0E, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFB8E, + 0xFB8E, 0xFB8E, 0xFB8E, 0xFB8C, 0xFB8C, 0xFB8C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB0C, 0xFB0C, 0xFB0C, + 0xFB0C, 0xFB0A, 0xFB0A, 0xFB0A, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, + 0xFA88, 0xFA88, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA06, 0xFA06, + 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF984, 0xF944, 0xF944, + 0xF944, 0xF944, 0xF944, 0xF944, 0xF944, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF902, 0xF8C2, 0xF8C2, 0xF8C2, 0xF8C2, + 0xF8C2, 0xF8C2, 0xF8C2, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, + 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF000, 0xF000, 0xF000, + 0xF000, 0xF000, 0xF000, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, + 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xC800, 0xC800, 0xC800, + 0xC800, 0xC800, 0xC800, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, + 0xB800, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA000, + 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9000, 0x9000, + 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF82, 0xFF42, + 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF04, 0xFF04, 0xFEC4, 0xFEC4, + 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE86, 0xFE86, 0xFE46, 0xFE46, 0xFE46, + 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE06, 0xFE06, 0xFE06, 0xFE06, 0xFE08, 0xFE08, 0xFE08, 0xFE08, 0xFDC8, 0xFDC8, 0xFDC8, + 0xFDC8, 0xFDC8, 0xFDC8, 0xFDC8, 0xFD88, 0xFD88, 0xFD88, 0xFD88, 0xFD8A, 0xFD8A, 0xFD8A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, + 0xFD4A, 0xFD4A, 0xFD4A, 0xFD0A, 0xFD0A, 0xFD0A, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, + 0xFCCC, 0xFCCC, 0xFC8C, 0xFC8C, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, + 0xFC4E, 0xFC0E, 0xFC0E, 0xFC10, 0xFC10, 0xFC0E, 0xFC0E, 0xFC0E, 0xFC0E, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFB8E, + 0xFB8E, 0xFB8E, 0xFB8E, 0xFB8C, 0xFB8C, 0xFB8C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB0C, 0xFB0C, 0xFB0C, + 0xFB0C, 0xFB0A, 0xFB0A, 0xFB0A, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, + 0xFA88, 0xFA88, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA06, 0xFA06, + 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF984, 0xF944, 0xF944, + 0xF944, 0xF944, 0xF944, 0xF944, 0xF944, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF902, 0xF8C2, 0xF8C2, 0xF8C2, 0xF8C2, + 0xF8C2, 0xF8C2, 0xF8C2, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, + 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF000, 0xF000, 0xF000, + 0xF000, 0xF000, 0xF000, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, + 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xC800, 0xC800, 0xC800, + 0xC800, 0xC800, 0xC800, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, + 0xB800, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA000, + 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9000, 0x9000, + 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF82, 0xFF42, + 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF04, 0xFF04, 0xFEC4, 0xFEC4, + 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE86, 0xFE86, 0xFE46, 0xFE46, 0xFE46, + 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE06, 0xFE06, 0xFE06, 0xFE06, 0xFE08, 0xFE08, 0xFE08, 0xFE08, 0xFDC8, 0xFDC8, 0xFDC8, + 0xFDC8, 0xFDC8, 0xFDC8, 0xFDC8, 0xFD88, 0xFD88, 0xFD88, 0xFD88, 0xFD8A, 0xFD8A, 0xFD8A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, + 0xFD4A, 0xFD4A, 0xFD4A, 0xFD0A, 0xFD0A, 0xFD0A, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, + 0xFCCC, 0xFCCC, 0xFC8C, 0xFC8C, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, + 0xFC4E, 0xFC0E, 0xFC0E, 0xFC10, 0xFC10, 0xFC0E, 0xFC0E, 0xFC0E, 0xFC0E, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFB8E, + 0xFB8E, 0xFB8E, 0xFB8E, 0xFB8C, 0xFB8C, 0xFB8C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB0C, 0xFB0C, 0xFB0C, + 0xFB0C, 0xFB0A, 0xFB0A, 0xFB0A, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, + 0xFA88, 0xFA88, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA06, 0xFA06, + 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF984, 0xF944, 0xF944, + 0xF944, 0xF944, 0xF944, 0xF944, 0xF944, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF902, 0xF8C2, 0xF8C2, 0xF8C2, 0xF8C2, + 0xF8C2, 0xF8C2, 0xF8C2, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, + 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF000, 0xF000, 0xF000, + 0xF000, 0xF000, 0xF000, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, + 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xC800, 0xC800, 0xC800, + 0xC800, 0xC800, 0xC800, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, + 0xB800, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA000, + 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9000, 0x9000, + 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF82, 0xFF42, + 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF04, 0xFF04, 0xFEC4, 0xFEC4, + 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE86, 0xFE86, 0xFE46, 0xFE46, 0xFE46, + 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE06, 0xFE06, 0xFE06, 0xFE06, 0xFE08, 0xFE08, 0xFE08, 0xFE08, 0xFDC8, 0xFDC8, 0xFDC8, + 0xFDC8, 0xFDC8, 0xFDC8, 0xFDC8, 0xFD88, 0xFD88, 0xFD88, 0xFD88, 0xFD8A, 0xFD8A, 0xFD8A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, + 0xFD4A, 0xFD4A, 0xFD4A, 0xFD0A, 0xFD0A, 0xFD0A, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, + 0xFCCC, 0xFCCC, 0xFC8C, 0xFC8C, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, + 0xFC4E, 0xFC0E, 0xFC0E, 0xFC10, 0xFC10, 0xFC0E, 0xFC0E, 0xFC0E, 0xFC0E, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFB8E, + 0xFB8E, 0xFB8E, 0xFB8E, 0xFB8C, 0xFB8C, 0xFB8C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB0C, 0xFB0C, 0xFB0C, + 0xFB0C, 0xFB0A, 0xFB0A, 0xFB0A, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, + 0xFA88, 0xFA88, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA06, 0xFA06, + 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF984, 0xF944, 0xF944, + 0xF944, 0xF944, 0xF944, 0xF944, 0xF944, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF902, 0xF8C2, 0xF8C2, 0xF8C2, 0xF8C2, + 0xF8C2, 0xF8C2, 0xF8C2, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, + 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF000, 0xF000, 0xF000, + 0xF000, 0xF000, 0xF000, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, + 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xC800, 0xC800, 0xC800, + 0xC800, 0xC800, 0xC800, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, + 0xB800, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA000, + 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9000, 0x9000, + 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF82, 0xFF42, + 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF04, 0xFF04, 0xFEC4, 0xFEC4, + 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE86, 0xFE86, 0xFE46, 0xFE46, 0xFE46, + 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE06, 0xFE06, 0xFE06, 0xFE06, 0xFE08, 0xFE08, 0xFE08, 0xFE08, 0xFDC8, 0xFDC8, 0xFDC8, + 0xFDC8, 0xFDC8, 0xFDC8, 0xFDC8, 0xFD88, 0xFD88, 0xFD88, 0xFD88, 0xFD8A, 0xFD8A, 0xFD8A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, + 0xFD4A, 0xFD4A, 0xFD4A, 0xFD0A, 0xFD0A, 0xFD0A, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, + 0xFCCC, 0xFCCC, 0xFC8C, 0xFC8C, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, + 0xFC4E, 0xFC0E, 0xFC0E, 0xFC10, 0xFC10, 0xFC0E, 0xFC0E, 0xFC0E, 0xFC0E, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFB8E, + 0xFB8E, 0xFB8E, 0xFB8E, 0xFB8C, 0xFB8C, 0xFB8C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB0C, 0xFB0C, 0xFB0C, + 0xFB0C, 0xFB0A, 0xFB0A, 0xFB0A, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, + 0xFA88, 0xFA88, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA06, 0xFA06, + 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF984, 0xF944, 0xF944, + 0xF944, 0xF944, 0xF944, 0xF944, 0xF944, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF902, 0xF8C2, 0xF8C2, 0xF8C2, 0xF8C2, + 0xF8C2, 0xF8C2, 0xF8C2, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, + 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF000, 0xF000, 0xF000, + 0xF000, 0xF000, 0xF000, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, + 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xC800, 0xC800, 0xC800, + 0xC800, 0xC800, 0xC800, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, + 0xB800, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA000, + 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9000, 0x9000, + 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF82, 0xFF42, + 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF04, 0xFF04, 0xFEC4, 0xFEC4, + 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE86, 0xFE86, 0xFE46, 0xFE46, 0xFE46, + 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE06, 0xFE06, 0xFE06, 0xFE06, 0xFE08, 0xFE08, 0xFE08, 0xFE08, 0xFDC8, 0xFDC8, 0xFDC8, + 0xFDC8, 0xFDC8, 0xFDC8, 0xFDC8, 0xFD88, 0xFD88, 0xFD88, 0xFD88, 0xFD8A, 0xFD8A, 0xFD8A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, + 0xFD4A, 0xFD4A, 0xFD4A, 0xFD0A, 0xFD0A, 0xFD0A, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, + 0xFCCC, 0xFCCC, 0xFC8C, 0xFC8C, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, + 0xFC4E, 0xFC0E, 0xFC0E, 0xFC10, 0xFC10, 0xFC0E, 0xFC0E, 0xFC0E, 0xFC0E, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFB8E, + 0xFB8E, 0xFB8E, 0xFB8E, 0xFB8C, 0xFB8C, 0xFB8C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB0C, 0xFB0C, 0xFB0C, + 0xFB0C, 0xFB0A, 0xFB0A, 0xFB0A, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, + 0xFA88, 0xFA88, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA06, 0xFA06, + 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF984, 0xF944, 0xF944, + 0xF944, 0xF944, 0xF944, 0xF944, 0xF944, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF902, 0xF8C2, 0xF8C2, 0xF8C2, 0xF8C2, + 0xF8C2, 0xF8C2, 0xF8C2, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, + 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF000, 0xF000, 0xF000, + 0xF000, 0xF000, 0xF000, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, + 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xC800, 0xC800, 0xC800, + 0xC800, 0xC800, 0xC800, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, + 0xB800, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA000, + 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9000, 0x9000, + 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF82, 0xFF42, + 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF04, 0xFF04, 0xFEC4, 0xFEC4, + 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE86, 0xFE86, 0xFE46, 0xFE46, 0xFE46, + 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE06, 0xFE06, 0xFE06, 0xFE06, 0xFE08, 0xFE08, 0xFE08, 0xFE08, 0xFDC8, 0xFDC8, 0xFDC8, + 0xFDC8, 0xFDC8, 0xFDC8, 0xFDC8, 0xFD88, 0xFD88, 0xFD88, 0xFD88, 0xFD8A, 0xFD8A, 0xFD8A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, + 0xFD4A, 0xFD4A, 0xFD4A, 0xFD0A, 0xFD0A, 0xFD0A, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, + 0xFCCC, 0xFCCC, 0xFC8C, 0xFC8C, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, + 0xFC4E, 0xFC0E, 0xFC0E, 0xFC10, 0xFC10, 0xFC0E, 0xFC0E, 0xFC0E, 0xFC0E, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFB8E, + 0xFB8E, 0xFB8E, 0xFB8E, 0xFB8C, 0xFB8C, 0xFB8C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB0C, 0xFB0C, 0xFB0C, + 0xFB0C, 0xFB0A, 0xFB0A, 0xFB0A, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, + 0xFA88, 0xFA88, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA06, 0xFA06, + 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF984, 0xF944, 0xF944, + 0xF944, 0xF944, 0xF944, 0xF944, 0xF944, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF902, 0xF8C2, 0xF8C2, 0xF8C2, 0xF8C2, + 0xF8C2, 0xF8C2, 0xF8C2, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, + 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF000, 0xF000, 0xF000, + 0xF000, 0xF000, 0xF000, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, + 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xC800, 0xC800, 0xC800, + 0xC800, 0xC800, 0xC800, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, + 0xB800, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA000, + 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9000, 0x9000, + 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF82, 0xFF42, + 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF04, 0xFF04, 0xFEC4, 0xFEC4, + 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE86, 0xFE86, 0xFE46, 0xFE46, 0xFE46, + 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE06, 0xFE06, 0xFE06, 0xFE06, 0xFE08, 0xFE08, 0xFE08, 0xFE08, 0xFDC8, 0xFDC8, 0xFDC8, + 0xFDC8, 0xFDC8, 0xFDC8, 0xFDC8, 0xFD88, 0xFD88, 0xFD88, 0xFD88, 0xFD8A, 0xFD8A, 0xFD8A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, + 0xFD4A, 0xFD4A, 0xFD4A, 0xFD0A, 0xFD0A, 0xFD0A, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, + 0xFCCC, 0xFCCC, 0xFC8C, 0xFC8C, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, + 0xFC4E, 0xFC0E, 0xFC0E, 0xFC10, 0xFC10, 0xFC0E, 0xFC0E, 0xFC0E, 0xFC0E, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFB8E, + 0xFB8E, 0xFB8E, 0xFB8E, 0xFB8C, 0xFB8C, 0xFB8C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB0C, 0xFB0C, 0xFB0C, + 0xFB0C, 0xFB0A, 0xFB0A, 0xFB0A, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, + 0xFA88, 0xFA88, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA06, 0xFA06, + 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF984, 0xF944, 0xF944, + 0xF944, 0xF944, 0xF944, 0xF944, 0xF944, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF902, 0xF8C2, 0xF8C2, 0xF8C2, 0xF8C2, + 0xF8C2, 0xF8C2, 0xF8C2, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, + 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF000, 0xF000, 0xF000, + 0xF000, 0xF000, 0xF000, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, + 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xC800, 0xC800, 0xC800, + 0xC800, 0xC800, 0xC800, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, + 0xB800, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA000, + 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9000, 0x9000, + 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF82, 0xFF42, + 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF04, 0xFF04, 0xFEC4, 0xFEC4, + 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE86, 0xFE86, 0xFE46, 0xFE46, 0xFE46, + 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE06, 0xFE06, 0xFE06, 0xFE06, 0xFE08, 0xFE08, 0xFE08, 0xFE08, 0xFDC8, 0xFDC8, 0xFDC8, + 0xFDC8, 0xFDC8, 0xFDC8, 0xFDC8, 0xFD88, 0xFD88, 0xFD88, 0xFD88, 0xFD8A, 0xFD8A, 0xFD8A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, + 0xFD4A, 0xFD4A, 0xFD4A, 0xFD0A, 0xFD0A, 0xFD0A, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, + 0xFCCC, 0xFCCC, 0xFC8C, 0xFC8C, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, + 0xFC4E, 0xFC0E, 0xFC0E, 0xFC10, 0xFC10, 0xFC0E, 0xFC0E, 0xFC0E, 0xFC0E, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFB8E, + 0xFB8E, 0xFB8E, 0xFB8E, 0xFB8C, 0xFB8C, 0xFB8C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB0C, 0xFB0C, 0xFB0C, + 0xFB0C, 0xFB0A, 0xFB0A, 0xFB0A, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, + 0xFA88, 0xFA88, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA06, 0xFA06, + 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF984, 0xF944, 0xF944, + 0xF944, 0xF944, 0xF944, 0xF944, 0xF944, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF902, 0xF8C2, 0xF8C2, 0xF8C2, 0xF8C2, + 0xF8C2, 0xF8C2, 0xF8C2, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, + 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF000, 0xF000, 0xF000, + 0xF000, 0xF000, 0xF000, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, + 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xC800, 0xC800, 0xC800, + 0xC800, 0xC800, 0xC800, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, + 0xB800, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA000, + 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9000, 0x9000, + 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF82, 0xFF42, + 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF04, 0xFF04, 0xFEC4, 0xFEC4, + 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE86, 0xFE86, 0xFE46, 0xFE46, 0xFE46, + 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE06, 0xFE06, 0xFE06, 0xFE06, 0xFE08, 0xFE08, 0xFE08, 0xFE08, 0xFDC8, 0xFDC8, 0xFDC8, + 0xFDC8, 0xFDC8, 0xFDC8, 0xFDC8, 0xFD88, 0xFD88, 0xFD88, 0xFD88, 0xFD8A, 0xFD8A, 0xFD8A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, + 0xFD4A, 0xFD4A, 0xFD4A, 0xFD0A, 0xFD0A, 0xFD0A, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, + 0xFCCC, 0xFCCC, 0xFC8C, 0xFC8C, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, + 0xFC4E, 0xFC0E, 0xFC0E, 0xFC10, 0xFC10, 0xFC0E, 0xFC0E, 0xFC0E, 0xFC0E, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFB8E, + 0xFB8E, 0xFB8E, 0xFB8E, 0xFB8C, 0xFB8C, 0xFB8C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB0C, 0xFB0C, 0xFB0C, + 0xFB0C, 0xFB0A, 0xFB0A, 0xFB0A, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, + 0xFA88, 0xFA88, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA06, 0xFA06, + 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF984, 0xF944, 0xF944, + 0xF944, 0xF944, 0xF944, 0xF944, 0xF944, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF902, 0xF8C2, 0xF8C2, 0xF8C2, 0xF8C2, + 0xF8C2, 0xF8C2, 0xF8C2, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, + 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF000, 0xF000, 0xF000, + 0xF000, 0xF000, 0xF000, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, + 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xC800, 0xC800, 0xC800, + 0xC800, 0xC800, 0xC800, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, + 0xB800, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA000, + 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9000, 0x9000, + 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF82, 0xFF42, + 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF04, 0xFF04, 0xFEC4, 0xFEC4, + 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE86, 0xFE86, 0xFE46, 0xFE46, 0xFE46, + 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE06, 0xFE06, 0xFE06, 0xFE06, 0xFE08, 0xFE08, 0xFE08, 0xFE08, 0xFDC8, 0xFDC8, 0xFDC8, + 0xFDC8, 0xFDC8, 0xFDC8, 0xFDC8, 0xFD88, 0xFD88, 0xFD88, 0xFD88, 0xFD8A, 0xFD8A, 0xFD8A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, + 0xFD4A, 0xFD4A, 0xFD4A, 0xFD0A, 0xFD0A, 0xFD0A, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, + 0xFCCC, 0xFCCC, 0xFC8C, 0xFC8C, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, + 0xFC4E, 0xFC0E, 0xFC0E, 0xFC10, 0xFC10, 0xFC0E, 0xFC0E, 0xFC0E, 0xFC0E, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFB8E, + 0xFB8E, 0xFB8E, 0xFB8E, 0xFB8C, 0xFB8C, 0xFB8C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB0C, 0xFB0C, 0xFB0C, + 0xFB0C, 0xFB0A, 0xFB0A, 0xFB0A, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, + 0xFA88, 0xFA88, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA06, 0xFA06, + 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF984, 0xF944, 0xF944, + 0xF944, 0xF944, 0xF944, 0xF944, 0xF944, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF902, 0xF8C2, 0xF8C2, 0xF8C2, 0xF8C2, + 0xF8C2, 0xF8C2, 0xF8C2, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, + 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF000, 0xF000, 0xF000, + 0xF000, 0xF000, 0xF000, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, + 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xC800, 0xC800, 0xC800, + 0xC800, 0xC800, 0xC800, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, + 0xB800, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA000, + 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9000, 0x9000, + 0xD680, 0xD680, 0xD640, 0xD640, 0xD640, 0xD640, 0xD640, 0xD640, 0xD640, 0xD640, 0xD640, 0xD600, 0xD600, 0xD600, 0xD600, 0xD600, + 0xD600, 0xD600, 0xD602, 0xD602, 0xD602, 0xD5C2, 0xD5C2, 0xD5C2, 0xD5C2, 0xD5C2, 0xD5C2, 0xD5C2, 0xD5C2, 0xD5C2, 0xD582, 0xD582, + 0xD582, 0xD582, 0xD584, 0xD584, 0xD584, 0xD584, 0xD584, 0xD544, 0xD544, 0xD544, 0xD544, 0xD544, 0xD544, 0xD544, 0xD544, 0xD544, + 0xD504, 0xD504, 0xD504, 0xD504, 0xD506, 0xD506, 0xD506, 0xD506, 0xD506, 0xD506, 0xD4C6, 0xD4C6, 0xD4C6, 0xD4C6, 0xD4C6, 0xD4C6, + 0xD4C6, 0xD4C6, 0xD4C6, 0xD486, 0xD486, 0xD486, 0xD488, 0xD488, 0xD488, 0xD488, 0xD488, 0xD448, 0xD448, 0xD448, 0xD448, 0xD448, + 0xD448, 0xD448, 0xD448, 0xD448, 0xD448, 0xD408, 0xD408, 0xD408, 0xD40A, 0xD40A, 0xD40A, 0xD40A, 0xD40A, 0xD40A, 0xD3CA, 0xD3CA, + 0xD3CA, 0xD3CA, 0xD3CA, 0xD3CA, 0xD3CA, 0xD3CA, 0xD3CA, 0xD3CA, 0xD38C, 0xD38C, 0xD38C, 0xD38C, 0xD38C, 0xD38C, 0xD38C, 0xD38C, + 0xD38C, 0xD34C, 0xD34C, 0xD34C, 0xD34C, 0xD34C, 0xD34C, 0xD34C, 0xD34C, 0xD34C, 0xD30C, 0xD30C, 0xD30C, 0xD30C, 0xD30C, 0xD30A, + 0xD30A, 0xD30A, 0xD2CA, 0xD2CA, 0xD2CA, 0xD2CA, 0xD2CA, 0xD2CA, 0xD2CA, 0xD2CA, 0xD2CA, 0xD28A, 0xD28A, 0xD28A, 0xD28A, 0xD28A, + 0xD288, 0xD288, 0xD288, 0xD248, 0xD248, 0xD248, 0xD248, 0xD248, 0xD248, 0xD248, 0xD248, 0xD208, 0xD208, 0xD208, 0xD208, 0xD208, + 0xD208, 0xD208, 0xD206, 0xD206, 0xD1C6, 0xD1C6, 0xD1C6, 0xD1C6, 0xD1C6, 0xD1C6, 0xD1C6, 0xD1C6, 0xD186, 0xD186, 0xD186, 0xD186, + 0xD186, 0xD186, 0xD186, 0xD186, 0xD184, 0xD144, 0xD144, 0xD144, 0xD144, 0xD144, 0xD144, 0xD144, 0xD144, 0xD104, 0xD104, 0xD104, + 0xD104, 0xD104, 0xD104, 0xD104, 0xD104, 0xD104, 0xD0C2, 0xD0C2, 0xD0C2, 0xD0C2, 0xD0C2, 0xD0C2, 0xD0C2, 0xD0C2, 0xD082, 0xD082, + 0xD082, 0xD082, 0xD082, 0xD082, 0xD082, 0xD082, 0xD080, 0xD040, 0xD040, 0xD040, 0xD040, 0xD040, 0xD040, 0xD040, 0xD040, 0xD000, + 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xC800, 0xC800, 0xC800, 0xC800, 0xC800, 0xC800, 0xC800, 0xC800, + 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, + 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA000, + 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, + 0x9000, 0x9000, 0x9000, 0x9000, 0x9000, 0x9000, 0x9000, 0x9000, 0x8800, 0x8800, 0x8800, 0x8800, 0x8800, 0x8800, 0x8800, 0x8800, + 0x8800, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x7800, 0x7800, 0x7800, 0x7800, 0x7800 + +}; diff --git a/src/snes4iphone_src/gp2x_menu_header.c b/src/snes4iphone_src/gp2x_menu_header.c new file mode 100755 index 0000000..cd2a6cb --- /dev/null +++ b/src/snes4iphone_src/gp2x_menu_header.c @@ -0,0 +1,983 @@ +///////////////////////////////////////// +// +// Header file for GP32 +// +// convertion of menu_header.bmp file : +// Width = 320 +// Heigth = 48 +// GP32 Mode = 16 Bits per Pixel +// +// with GP32Converter coded by Edorul : +// http://www.ifrance.com/edorul/ +// edorul@free.fr +// +///////////////////////////////////////// + +#define menu_header_width 320 +#define menu_header_height 48 +unsigned short menuHeader[15360]; +unsigned short menuHeaderOrig[15360] = { + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, + 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, + 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, + 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, + 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, + 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, + 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, + 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, + 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, + 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, + 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, + 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, + 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, + 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, + 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, + 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, + 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, + 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, + 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, + 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, + 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, + 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, + 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, + 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, + 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, + 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, + 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, + 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, + 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, + 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, + 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, + 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, + 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, + 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, + 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, + 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, + 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, + 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, + 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, + 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, + 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, + 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, + 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, + 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, + 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, + 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, + 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, + 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, + 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, + 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, + 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, + 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, + 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, + 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, + 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, + 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, + 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, + 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, + 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, + 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, + 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, + 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, + 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, + 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, + 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, + 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, + 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, + 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, + 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, + 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, + 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, + 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, + 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, + 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, + 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, + 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, + 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, + 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, + 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, + 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, + 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, + 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, + 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, + 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, + 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, + 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, + 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, + 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, + 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, + 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, + 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, + 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, + 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, + 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, + 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, + 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, + 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, + 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, + 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, + 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, + 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xE90C, 0xE90C, 0xE192, 0xE1D4, 0xDA5C, + 0xBC70, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF086, 0xE90C, 0xE192, 0xDA5A, 0xBCB2, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, + 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, + 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, + 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, + 0xAD7C, 0xAD7C, 0xAD7C, 0xBCB2, 0xDA5C, 0xE94E, 0xF086, 0xF044, 0xE8C8, 0xE94E, 0xD29C, 0xBCB2, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, + 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, + 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, + 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, + 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, + 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, + 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, + 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, + 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, + 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, + 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, + 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, + 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xE29C, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF086, 0xDADE, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xC5BA, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xDB20, 0xF086, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF086, 0xDB20, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xF044, 0xCCF2, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCCAE, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xC578, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xC63E, 0xC63E, + 0xC63E, 0xD46C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD46C, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xF044, 0xE258, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xE214, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xCD34, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xC63E, 0xC63E, + 0xC63E, 0xE9D4, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xE29A, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCD78, 0xCCF0, 0xE2DC, 0xF044, 0xF044, + 0xF044, 0xF044, 0xE992, 0xC63E, 0xC63E, 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xC63E, 0xD3E8, 0xE990, 0xC63E, 0xC63E, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCD34, 0xD4AE, 0xE29A, 0xF044, 0xF044, 0xF044, 0xF044, 0xE94C, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xCCF0, 0xE216, 0xF10A, 0xF044, 0xE90C, 0xE216, 0xDB60, 0xC5FC, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xD46E, 0xE992, 0xF0C8, 0xF044, 0xF10A, 0xE256, 0xCD34, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xD4F0, 0xC63E, 0xE258, 0xF044, 0xF044, 0xF044, 0xE94E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xD4AE, 0xE256, 0xF10A, 0xF044, + 0xF086, 0xE94C, 0xDB62, 0xC5FA, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xC63E, 0xC63E, + 0xC63E, 0xE90C, 0xF044, 0xF044, 0xF044, 0xF044, 0xDB62, 0xCD76, 0xDB62, 0xF044, 0xF044, 0xF044, 0xF044, 0xE990, 0xC63E, 0xC63E, + 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xC63E, 0xDBA4, 0xE992, 0xF086, 0xE94E, 0xD428, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xD4AE, 0xE256, 0xF10A, 0xF044, 0xF086, 0xE94C, 0xDB62, 0xC5FA, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63C, 0xDBA4, 0xE256, 0xE94E, 0xF086, 0xE94E, 0xE214, 0xD3E8, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xC63E, 0xC63E, 0xCD34, 0xF044, 0xF044, + 0xF044, 0xF044, 0xE90C, 0xC63E, 0xC63E, 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD46C, 0xF044, 0xF044, 0xC63E, 0xC63E, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xC63E, 0xC63E, 0xCDB6, 0xF044, 0xF044, 0xF044, 0xF044, 0xF10A, 0xC63E, 0xC63E, 0xC63E, + 0xDBE6, 0xF086, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xE94C, 0xCD34, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xDB60, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF0C8, 0xD46C, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xD4F0, 0xC5FC, 0xF086, 0xF044, 0xF044, 0xF044, 0xDBA4, 0xC63E, 0xC63E, 0xC63E, 0xDBA4, 0xF086, 0xF044, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xF10A, 0xCD32, 0xC63E, 0xC63E, 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, + 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCDFA, 0xC63E, 0xC5FC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF0C8, 0xC63E, 0xC63E, + 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD428, 0xF044, 0xF044, 0xF044, 0xF044, 0xF086, 0xD4F0, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xDBA4, 0xF086, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF10A, 0xCD32, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xCDFA, + 0xE94E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xE256, 0xC63C, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xC63E, 0xC63E, 0xCDFC, 0xF044, 0xF044, + 0xF044, 0xF044, 0xE90C, 0xC63E, 0xC63E, 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF0C8, 0xF044, 0xF044, 0xC63E, 0xC63E, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xC63E, 0xC63E, 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xC63E, 0xC63E, 0xCD34, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF0C8, 0xCDFA, 0xC63E, 0xC63E, 0xC63E, 0xD46C, 0xF044, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF086, 0xCDB6, 0xC63E, 0xC63E, 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xDC28, 0xDC28, 0xF044, 0xF044, 0xF044, 0xF044, 0xCDB8, 0xC63E, 0xC63E, 0xD4F0, 0xF086, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF10A, 0xC63C, 0xC63E, 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, + 0xC63E, 0xF0C8, 0xF044, 0xF044, 0xF044, 0xF044, 0xD42A, 0xC63E, 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xC63E, 0xC63E, + 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF0C8, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xE256, 0xC63E, 0xC63E, 0xC63E, + 0xD4F0, 0xF086, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF10A, 0xC63C, 0xC63E, 0xC63E, 0xC63E, 0xE2DC, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xDBA4, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xC67E, 0xC67E, 0xC67E, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xC67E, 0xC67E, 0xC67E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xC67E, 0xC67E, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xC67E, 0xC67E, 0xC67E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xC67E, 0xC67E, 0xE31E, + 0xF044, 0xF044, 0xF044, 0xF044, 0xDC28, 0xDBE6, 0xF044, 0xF044, 0xF044, 0xF044, 0xDB60, 0xC67E, 0xC67E, 0xC67E, 0xE258, 0xF044, + 0xF044, 0xF044, 0xF044, 0xD46C, 0xDBA2, 0xF044, 0xF044, 0xF044, 0xDB20, 0xC67E, 0xC67E, 0xC67E, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xDC28, 0xE9D2, 0xF044, 0xF044, 0xF044, 0xEA14, 0xC67E, 0xC67E, 0xC67E, 0xE258, 0xF044, 0xF044, 0xF044, 0xF044, 0xDC28, + 0xDBE4, 0xF044, 0xF044, 0xF044, 0xF044, 0xDC28, 0xC67E, 0xC67E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, + 0xC67E, 0xE9D2, 0xF044, 0xF044, 0xF044, 0xF044, 0xF0C8, 0xD46A, 0xC67E, 0xCDB6, 0xCDB6, 0xCDB6, 0xCDB6, 0xCDB6, 0xC67E, 0xC67E, + 0xC67E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD4EE, 0xDBE4, 0xF044, 0xF044, 0xF044, 0xF044, 0xE94E, 0xC67E, 0xC67E, 0xC67E, + 0xE258, 0xF044, 0xF044, 0xF044, 0xF044, 0xDC28, 0xDBE4, 0xF044, 0xF044, 0xF044, 0xF044, 0xDC28, 0xC67E, 0xC67E, 0xC67E, 0xE94E, + 0xF044, 0xF044, 0xF044, 0xF044, 0xD42A, 0xDC28, 0xF044, 0xF044, 0xF044, 0xE990, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, + 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, + 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, + 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, + 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, + 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, + 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, + 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, + 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, + 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, + 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7E, 0xCE7E, 0xCE7E, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xCE7E, 0xCE7E, 0xCE7E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7E, 0xCE7E, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7E, 0xCE7E, 0xCDF8, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7E, 0xCE7E, 0xE258, + 0xF044, 0xF044, 0xF044, 0xF044, 0xCE3C, 0xCDF8, 0xF044, 0xF044, 0xF044, 0xF044, 0xE990, 0xCE7E, 0xCE7E, 0xCE7E, 0xE9D0, 0xF044, + 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCDF8, 0xF044, 0xF044, 0xF044, 0xE258, 0xCE7E, 0xCE7E, 0xCE7E, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xE31E, 0xF044, 0xF044, 0xF044, 0xF044, 0xDC28, 0xCE7E, 0xCE7E, 0xCE7E, 0xE94E, 0xF044, 0xF044, 0xF044, 0xF044, 0xCDFA, + 0xCDB6, 0xF044, 0xF044, 0xF044, 0xF044, 0xE29A, 0xCE7E, 0xCE7E, 0xCDB6, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCDB6, 0xCDB6, + 0xCE7E, 0xE2DC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xE29A, 0xCDF8, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, + 0xCE7E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCDF8, 0xCDB6, 0xF044, 0xF044, 0xF044, 0xF044, 0xE90C, 0xCE7E, 0xCE7E, 0xCE7E, + 0xE94E, 0xF044, 0xF044, 0xF044, 0xF044, 0xCDFA, 0xCDB6, 0xF044, 0xF044, 0xF044, 0xF044, 0xE29A, 0xCE7E, 0xCE7E, 0xCE7E, 0xF0C8, + 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7E, 0xCDFA, 0xF044, 0xF044, 0xF044, 0xF0C8, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, + 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, + 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, + 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, + 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, + 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, + 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, + 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, + 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, + 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, 0xCE7C, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xE94E, 0xDC28, 0xD532, 0xCE7C, 0xCE7C, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE3A, 0xD530, 0xE2DA, 0xF044, 0xF044, 0xF044, 0xF044, 0xF10C, 0xCE7C, 0xCE7C, 0xE990, + 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF10C, 0xCE7C, 0xCE7C, 0xCE7C, 0xF10C, 0xF044, + 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xE990, 0xCE7C, 0xCE7C, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xF0C8, 0xF044, 0xF044, 0xF044, 0xF0C8, 0xCE3A, 0xCE7C, 0xCE7C, 0xCE7C, 0xF0C8, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7C, + 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xE9D0, 0xCE7C, 0xCE7C, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCDB6, 0xF0C8, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF0C8, 0xDC6A, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE3C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF086, 0xCE7C, 0xCE7C, 0xCE7C, + 0xF0C8, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xE9D0, 0xCE7C, 0xCE7C, 0xCE7C, 0xF044, + 0xF044, 0xF044, 0xF044, 0xF044, 0xCE3A, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, 0xCE7C, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xDCAC, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xEA14, 0xCE7C, 0xCE7C, 0xF0C8, + 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF086, 0xCE7C, 0xCE7C, 0xCE7C, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF0C8, 0xCE7C, 0xCE7C, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xE298, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7C, + 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF10C, 0xCE7C, 0xCE7C, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xD4EC, 0xF086, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xEA56, 0xCE3A, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, 0xCE7C, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF10C, 0xCE7C, 0xCE7C, 0xCE7C, 0xE94C, + 0xF044, 0xF044, 0xF044, 0xF044, 0xEA14, 0xCDF8, 0xD5B6, 0xD5B6, 0xD5B6, 0xD5B6, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, 0xCE7C, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD5F6, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xE360, 0xCE7C, 0xCE7C, 0xF044, + 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, 0xCE7C, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, 0xD5F6, 0xD5F6, 0xD5F6, 0xD5F6, 0xCE7C, 0xCE7C, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xDCAC, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xD5B4, 0xE9D2, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xE990, 0xD5F8, 0xCE7C, 0xCE7C, + 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, 0xCE7C, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, 0xCE7C, 0xEA14, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF10A, 0xDCAC, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCEBC, 0xCEBC, 0xCEBC, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xCEBC, 0xCEBC, 0xCEBC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD5F8, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xE94E, 0xD67A, 0xCEBC, 0xCEBC, 0xF044, + 0xF044, 0xF044, 0xF044, 0xF044, 0xCEBC, 0xCEBC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCEBC, 0xCEBC, 0xCEBC, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xE3A2, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCEBC, 0xCEBC, 0xCEBC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCEBC, 0xCEBC, + 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xDBE4, 0xF0C8, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xE990, 0xCEBC, 0xCEBC, + 0xCEBC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCEBC, 0xCEBC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCEBC, 0xCEBC, 0xCEBC, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCEBC, 0xCEBC, 0xCEBC, 0xDC26, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xEA98, 0xD638, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, + 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, + 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, + 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, + 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, + 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, + 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, + 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, + 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, + 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, + 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCEBC, 0xCEBC, 0xCEBC, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xCEBC, 0xCEBC, 0xCEBC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF086, 0xE98E, 0xEA98, 0xDC26, 0xD67A, 0xCEBC, 0xCEBC, 0xCEBC, 0xF044, + 0xF044, 0xF044, 0xF044, 0xF044, 0xCEBC, 0xCEBC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCEBC, 0xCEBC, 0xCEBC, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xEA14, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCEBC, 0xCEBC, 0xCEBC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCEBC, 0xCEBC, + 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xD5F6, 0xEA12, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xDCAA, 0xCEBC, + 0xCEBC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCEBC, 0xCEBC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCEBC, 0xCEBC, 0xCEBC, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, + 0xE2DA, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xE990, 0xCE7C, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, + 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, + 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, + 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, + 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, + 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, + 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, + 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, + 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, + 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD5F6, 0xD5F6, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, + 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF0C8, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD5F6, + 0xD5F6, 0xD5F6, 0xD5F6, 0xD5F6, 0xD5F6, 0xD5F6, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xE3E2, 0xF086, 0xF044, 0xF044, 0xF044, 0xF044, 0xEA96, 0xD6BC, + 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD5F6, 0xD5F6, 0xD5F6, 0xD5F6, 0xD5F6, 0xD5F6, 0xD5F6, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xE424, 0xF086, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xE424, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, + 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF086, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xE9D0, 0xF044, 0xF044, 0xF044, 0xF044, 0xDDB2, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, + 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, + 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, 0xE3E4, 0xF044, 0xF044, 0xF044, 0xF044, 0xE990, 0xD6BC, + 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xDD70, 0xF14C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xE9D2, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD67A, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF086, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xF086, + 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF10A, 0xD6BC, 0xD6BC, 0xD6BC, 0xF0C8, 0xF044, + 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF14C, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xE3E4, 0xF044, 0xF044, 0xF044, 0xF044, 0xE3E4, 0xD6BC, 0xD6BC, 0xD6BC, 0xF086, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, + 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, + 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, 0xD5F2, 0xF044, 0xF044, 0xF044, 0xF044, 0xF0C8, 0xD6BC, + 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, + 0xF086, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD67A, 0xEA96, 0xF044, 0xF044, 0xF044, 0xF044, 0xF10A, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xDDF2, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF14C, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xF14C, + 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF14C, 0xD6BC, 0xD6BC, 0xD6BC, 0xE9D0, 0xF044, + 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BA, 0xF044, 0xF044, 0xF044, 0xE98E, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xE4A8, 0xE98E, 0xF044, 0xF044, 0xF044, 0xEA96, 0xD6BC, 0xD6BC, 0xD6BC, 0xF14C, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, + 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF14C, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, + 0xD6BC, 0xF0C8, 0xF044, 0xF044, 0xF044, 0xF044, 0xD636, 0xD6BC, 0xD6BC, 0xDDF4, 0xF044, 0xF044, 0xF044, 0xF044, 0xF0C8, 0xD6BC, + 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, + 0xF14C, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF14C, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, + 0xF044, 0xF044, 0xF044, 0xD6BC, 0xDDF2, 0xF044, 0xF044, 0xF044, 0xF044, 0xF0C6, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD678, 0xDD6E, 0xEA54, 0xF044, 0xF044, + 0xF044, 0xF044, 0xE9D0, 0xD6FA, 0xD6FA, 0xD6FA, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xE98E, + 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BA, 0xD678, 0xF044, 0xF044, 0xF044, 0xF044, 0xEA12, 0xD6FA, 0xD6FA, 0xD6FA, 0xEA96, 0xF044, + 0xF044, 0xF044, 0xF044, 0xD676, 0xDDF4, 0xF044, 0xF044, 0xF044, 0xEA96, 0xD6FA, 0xD6FA, 0xD6FA, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xDD2E, 0xEB1A, 0xF044, 0xF044, 0xF044, 0xF10A, 0xD6FA, 0xD6FA, 0xD6FA, 0xE9D0, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BA, + 0xDE34, 0xF044, 0xF044, 0xF044, 0xF044, 0xE9D0, 0xD6FA, 0xD6FA, 0xD6FA, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BA, 0xD6FA, + 0xD6FA, 0xF14C, 0xF044, 0xF044, 0xF044, 0xF044, 0xEAD8, 0xDE36, 0xDDB0, 0xE9D2, 0xF044, 0xF044, 0xF044, 0xF044, 0xE9D0, 0xD6FA, + 0xD6FA, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6FA, 0xD6FA, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6FA, 0xD6FA, 0xD6FA, + 0xE9D0, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BA, 0xDE34, 0xF044, 0xF044, 0xF044, 0xF044, 0xE9D0, 0xD6FA, 0xD6FA, 0xD6FA, 0xF086, + 0xF044, 0xF044, 0xF044, 0xD6BA, 0xD6BA, 0xF044, 0xF044, 0xF044, 0xF044, 0xE98E, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, + 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, + 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, + 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, + 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, + 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, + 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, + 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, + 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, + 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, + 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xF044, 0xEA54, 0xD6FA, 0xD6FA, 0xD6FA, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xEA56, + 0xF044, 0xF044, 0xF044, 0xF044, 0xE4EA, 0xE4A8, 0xF044, 0xF044, 0xF044, 0xF044, 0xE3A0, 0xD6FA, 0xD6FA, 0xD6FA, 0xE35E, 0xF044, + 0xF044, 0xF044, 0xF044, 0xE424, 0xE424, 0xF044, 0xF044, 0xF044, 0xE466, 0xD6FA, 0xD6FA, 0xD6FA, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xDD6E, 0xE4A8, 0xF044, 0xF044, 0xF044, 0xF044, 0xDDF2, 0xD6FA, 0xD6FA, 0xE35C, 0xF044, 0xF044, 0xF044, 0xF044, 0xDD2C, + 0xE424, 0xF044, 0xF044, 0xF044, 0xF044, 0xE424, 0xD6FA, 0xD6FA, 0xD6FA, 0xF10A, 0xF044, 0xF044, 0xF044, 0xF044, 0xDD2C, 0xDE78, + 0xD6FA, 0xEAD8, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xEB1A, 0xD6FA, + 0xD6FA, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6FA, 0xD6FA, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6FA, 0xD6FA, 0xD6FA, + 0xE35C, 0xF044, 0xF044, 0xF044, 0xF044, 0xDD2C, 0xE424, 0xF044, 0xF044, 0xF044, 0xF044, 0xE424, 0xD6FA, 0xD6FA, 0xD6FA, 0xF14C, + 0xF044, 0xF044, 0xF044, 0xDD2C, 0xE4A8, 0xF044, 0xF044, 0xF044, 0xF044, 0xEA98, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, + 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, + 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, + 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, + 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, + 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, + 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, + 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, + 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, + 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, + 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xF044, 0xDBA0, 0xCE78, 0xCE78, 0xCE78, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xD4EC, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF0C8, 0xCE36, 0xCE78, 0xCE78, 0xCE78, 0xD4EC, 0xF044, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF0C6, 0xCDF4, 0xCE78, 0xCE78, 0xCE78, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xCDB2, 0xCDF4, 0xF044, 0xF044, 0xF044, 0xF044, 0xDC26, 0xCE78, 0xCE78, 0xCDF4, 0xF086, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF10A, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xE94C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, + 0xCE78, 0xD570, 0xF086, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF086, 0xD4EC, 0xCE78, + 0xCE78, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE78, 0xCE78, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE78, 0xCE78, 0xCE78, + 0xCDF4, 0xF086, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF10A, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xE2DA, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xDC66, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, + 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, + 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, + 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, + 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, + 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, + 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, + 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, + 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, + 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, + 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xF0C8, 0xBDB4, 0xBDF8, 0xBDF8, 0xBDF8, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, + 0xDADA, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF086, 0xCC26, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xDADA, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF086, 0xD3E4, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xC570, 0xBDF8, 0xE90A, 0xF044, 0xF044, 0xF044, 0xDA98, 0xBDF8, 0xBDF8, 0xBDF8, 0xCCAA, 0xF0CA, 0xF044, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xE90A, 0xC4EE, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xD360, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, + 0xBDF8, 0xBDF8, 0xCC68, 0xF0C8, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF0C8, 0xD3A2, 0xBDF8, 0xBDF8, + 0xBDF8, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xBDF8, 0xBDF8, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xBDF8, 0xBDF8, 0xBDF8, + 0xBDF8, 0xCCAA, 0xF0CA, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xE90A, 0xC4EE, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xC572, + 0xE90A, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xE1D2, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, + 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, + 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, + 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, + 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, + 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, + 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, + 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, + 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, + 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, + 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xE90A, + 0xD29A, 0xB530, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, + 0xADB6, 0xBC6A, 0xDA14, 0xE94C, 0xF044, 0xF044, 0xE94C, 0xDA56, 0xBCAC, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, + 0xC3A4, 0xE190, 0xF086, 0xF044, 0xF0C8, 0xE1D2, 0xBC6A, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xADB6, 0xADB6, 0xDA56, 0xF044, 0xF044, 0xF044, 0xE90A, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xB530, 0xD2DA, 0xE190, 0xF086, + 0xF086, 0xE18E, 0xD2DA, 0xB532, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xAD74, 0xCB60, 0xE94C, 0xF044, 0xF044, 0xF044, 0xF044, + 0xADB6, 0xADB6, 0xADB6, 0xB530, 0xCB1E, 0xE190, 0xF086, 0xF044, 0xF044, 0xF0C8, 0xE190, 0xD31C, 0xB530, 0xADB6, 0xADB6, 0xADB6, + 0xADB6, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xADB6, 0xADB6, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xADB6, 0xADB6, 0xADB6, + 0xADB6, 0xADB6, 0xB530, 0xD2DA, 0xE190, 0xF086, 0xF086, 0xE18E, 0xD2DA, 0xB532, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, + 0xB574, 0xCB1E, 0xE190, 0xF086, 0xF044, 0xF086, 0xE190, 0xCB1E, 0xAD74, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, + 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, + 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, + 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, + 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, + 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, + 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, + 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, + 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, + 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, + 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, + 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, + 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, + 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, + 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, + 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, + 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, + 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, + 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, + 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, + 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, + 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, + 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, + 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, + 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, + 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, + 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, + 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, + 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, + 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, + 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, + 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, + 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, + 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, + 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, + 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, + 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, + 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, + 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, + 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, + 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, + 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, + 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, + 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, + 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, + 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, + 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, + 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, + 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, + 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, + 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, + 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, + 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, + 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, + 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, + 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, + 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, + 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, + 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, + 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, + 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, + 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, + 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, + 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, + 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, + 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, + 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, + 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, + 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, + 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, + 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, + 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, + 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, + 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, + 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, + 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, + 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, + 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, + 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, + 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, + 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, + 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, + 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, + 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, + 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, + 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, + 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, + 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, + 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, + 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, + 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, + 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, + 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, + 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, + 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, + 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, + 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, + 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, + 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, + 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, + 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, + 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, + 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, + 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, + 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, + 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, + 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, + 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, + 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, + 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, + 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, + 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, + 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, + 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, + 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, + 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, + 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, + 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, + 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, + 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, + 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, + 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, + 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, + 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, + 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, + 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, + 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, + 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, + 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, + 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, + 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, + 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, + 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, + 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, + 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, + 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, + 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, + 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, + 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, + 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, + 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, + 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, + 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, + 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, + 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, + 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, + 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, + 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, + 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, + 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, + 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, + 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, + 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, + 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, + 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, + 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, + 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, + 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, + 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, + 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, + 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, + 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, + 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, + 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, + 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, + 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, + 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, + 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, + 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, + 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, + 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, + 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, + 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, + 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, + 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, + 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, + 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, + 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, + 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, + 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, + 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, + 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, + 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, + 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, + 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, + 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, + 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, + 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, + 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, + 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, + 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, + 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, + 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, + 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, + 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, + 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, + 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, + 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, + 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, + 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, + 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, + 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, + 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, + 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, + 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, + 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, + 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, + 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, + 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, + 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, + 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, + 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, + 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, + 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, + 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, + 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, + 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, + 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, + 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, + 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, + 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, + 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, + 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, + 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, + 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, + 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, + 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, + 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, + 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, + 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, + 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, + 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, + 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, + 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, + 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, + 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, + 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, + 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, + 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, + 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, + 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, + 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, + 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, + 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, + 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, + 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, + 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, + 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, + 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, + 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, + 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, + 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, + 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, + 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, + 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, + 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, + 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, + 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, + 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, + 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, + 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, + 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, + 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, + 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, + 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, + 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, + 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, + 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, + 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, + 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, + 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, + 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, + 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, + 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, + 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, + 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, + 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, + 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, + 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, + 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, + 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, + 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, + 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, + 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, + 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E + +}; + + diff --git a/src/snes4iphone_src/gp2x_menutile.c b/src/snes4iphone_src/gp2x_menutile.c new file mode 100755 index 0000000..943cff9 --- /dev/null +++ b/src/snes4iphone_src/gp2x_menutile.c @@ -0,0 +1,277 @@ +///////////////////////////////////////// +// +// Header file for GP32 +// +// convertion of menutile.bmp file : +// Width = 64 +// Heigth = 64 +// GP32 Mode = 16 Bits per Pixel +// +// with GP32Converter coded by Edorul : +// http://www.ifrance.com/edorul/ +// edorul@free.fr +// +///////////////////////////////////////// + +#define menutile_width 64 +#define menutile_height 64 +unsigned short menuTile[4096]; +unsigned short menuTileOrig[4096] = { + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0xE, 0x14, + 0xA, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x8A0, 0x116E, 0x19F4, 0x2238, 0x21F8, 0x2238, 0x19F8, + 0x11B8, 0x11B8, 0x976, 0xF2, 0x66, 0x14, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x896, 0x19F2, 0x2A78, 0x2A78, 0x2A78, 0x2278, 0x2238, 0x2238, 0x19F8, 0x19F8, + 0x11B8, 0x11B8, 0x1178, 0x978, 0x938, 0x136, 0xF6, 0x66, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x894, 0x21F2, 0x32B6, 0x32B8, 0x2AB8, 0x2A78, 0x227A, 0x227A, 0x1A3A, 0x1A3A, 0x19FA, 0x11FA, + 0x11BA, 0x9BA, 0x97A, 0x97A, 0x13A, 0x138, 0xF8, 0xF6, 0xB4, 0x64, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1968, 0x32F6, 0x32B6, 0x2AB8, 0x2AB8, 0x2AB8, 0x227A, 0x227A, 0x1A7A, 0x1A3C, 0x123C, 0x11FC, 0x9FC, + 0x9BC, 0x9BC, 0x17C, 0x13C, 0x13A, 0x13A, 0xF8, 0xF8, 0xF6, 0xB4, 0xB0, 0x14, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xA, 0x2A32, 0x32F6, 0x32B8, 0x32B8, 0x2AB8, 0x2ABA, 0x22BA, 0x227A, 0x1A7A, 0x1A3C, 0x123C, 0x123C, 0x9FC, 0x9FE, + 0x1BE, 0x17E, 0x17E, 0x13C, 0x13C, 0x13C, 0xFA, 0xF8, 0xF8, 0xB6, 0xB4, 0xB2, 0x60, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4A, 0x32B4, 0x32F6, 0x32F8, 0x32B8, 0x2AB8, 0x22BA, 0x22BA, 0x1ABA, 0x1A7C, 0x127C, 0x127C, 0x123C, 0xA3E, 0x9FE, 0x1BE, + 0x1BE, 0x17E, 0x17E, 0x17E, 0x13C, 0x13C, 0x13A, 0xFA, 0xF8, 0xF6, 0xB4, 0xB4, 0xB2, 0x66, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, + 0x2A74, 0x3AF6, 0x32F8, 0x32F8, 0x2AB8, 0x22BA, 0x22BA, 0x1ABA, 0x1ABC, 0x127C, 0x127C, 0xA7C, 0xA3E, 0x23E, 0x1FE, 0x1BE, + 0x1BE, 0x1BE, 0x17E, 0x17E, 0x17E, 0x13C, 0x13C, 0x13A, 0xF8, 0xF8, 0xB6, 0xB4, 0xB2, 0xB0, 0x1E, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2A30, + 0x3AF6, 0x32F8, 0x32B8, 0x2AB8, 0x22BA, 0x22BA, 0x1ABA, 0x1ABC, 0x12BC, 0x127C, 0xA7E, 0xA7E, 0x23E, 0x23E, 0x1FE, 0x1FE, + 0x1BE, 0x1BE, 0x1BE, 0x17E, 0x17E, 0x13E, 0x13C, 0x13A, 0xFA, 0xF8, 0xF6, 0xB4, 0xB2, 0xB0, 0x6E, 0x18, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1964, 0x3AF6, + 0x32F6, 0x32B8, 0x2AB8, 0x22BA, 0x22BA, 0x1ABA, 0x1ABC, 0x12BC, 0x12BC, 0xABE, 0xA7E, 0x27E, 0x23E, 0x23E, 0x23E, 0x1FE, + 0x1FE, 0x1BE, 0x1BE, 0x17E, 0x17E, 0x17E, 0x13C, 0x13C, 0xFA, 0xF8, 0xF8, 0xB6, 0xB4, 0xB2, 0x6E, 0x6C, + 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4A, 0x32B4, 0x32B6, + 0x32B8, 0x2AB8, 0x2ABA, 0x22BA, 0x1ABA, 0x1ABC, 0x12BC, 0x12BC, 0xABE, 0xABE, 0x2BE, 0x27E, 0x27E, 0x23E, 0x23E, 0x1FE, + 0x1FE, 0x1FE, 0x1BE, 0x1BE, 0x17E, 0x17E, 0x13E, 0x13C, 0x13A, 0xFA, 0xF8, 0xB6, 0xB4, 0xB2, 0xB0, 0x6E, + 0x64, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x21EC, 0x32B6, 0x32B8, + 0x2AB8, 0x2AB8, 0x22BA, 0x1ABA, 0x1ABC, 0x12BC, 0x12BC, 0xABE, 0xABE, 0x2BE, 0x2BE, 0x2BE, 0x27E, 0x27E, 0x23E, 0x23E, + 0x1FE, 0x1FE, 0x1BE, 0x1BE, 0x17E, 0x17E, 0x13E, 0x13C, 0x13A, 0xFA, 0xF8, 0xB6, 0xB4, 0xB2, 0xB0, 0x6E, + 0x6C, 0x12, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4C, 0x32B6, 0x32B6, 0x2AB8, + 0x2AB8, 0x22BA, 0x22BA, 0x1ABC, 0x12BC, 0x12BC, 0xABE, 0xABE, 0x2FE, 0x2FE, 0x2FE, 0x2BE, 0x2BE, 0x27E, 0x27E, 0x23E, + 0x1FE, 0x1FE, 0x1BE, 0x1BE, 0x17E, 0x17E, 0x17E, 0x13C, 0x13C, 0xFA, 0xF8, 0xF6, 0xB4, 0xB2, 0xB0, 0x6E, + 0x6C, 0x24, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1924, 0x32B6, 0x2AB6, 0x2AB8, + 0x22BA, 0x22BA, 0x1ABA, 0x12BC, 0x12BC, 0xABE, 0xABE, 0x2BE, 0x2FE, 0x2FE, 0x2FE, 0x2BE, 0x2BE, 0x27E, 0x27E, 0x23E, + 0x1FE, 0x1FE, 0x1BE, 0x1BE, 0x17E, 0x17E, 0x17E, 0x13C, 0x13C, 0xFA, 0xF8, 0xF6, 0xB4, 0xB2, 0xB0, 0x6E, + 0x6C, 0x6A, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2A32, 0x32B6, 0x2A78, 0x2278, + 0x227A, 0x1A7A, 0x1A7C, 0x127C, 0xA7C, 0xABE, 0x2BE, 0x2BE, 0x2FE, 0x2FE, 0x2FE, 0x2FE, 0x2BE, 0x27E, 0x27E, 0x23E, + 0x1FE, 0x1FE, 0x1BE, 0x1BE, 0x17E, 0x17E, 0x17E, 0x13C, 0x13C, 0xFA, 0xF8, 0xF6, 0xB4, 0xB2, 0xB0, 0x6E, + 0x6C, 0x6A, 0x1A, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x3274, 0x2A76, 0x2A78, 0x227A, + 0x1A7A, 0x1A7C, 0x127C, 0x127C, 0xA7E, 0x27E, 0x27E, 0x2BE, 0x2BE, 0x2FE, 0x2FE, 0x2BE, 0x2BE, 0x27E, 0x27E, 0x23E, + 0x1FE, 0x1FE, 0x1BE, 0x1BE, 0x17E, 0x17E, 0x17E, 0x13C, 0x13C, 0xFA, 0xF8, 0xF6, 0xB4, 0xB2, 0xB0, 0x6E, + 0x6C, 0xAA, 0x864, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x54, 0x3274, 0x2A76, 0x2278, 0x227A, + 0x1A7A, 0x127C, 0x123C, 0xA7E, 0x27E, 0x27E, 0x27E, 0x2BE, 0x2BE, 0x2BE, 0x2BE, 0x2BE, 0x27E, 0x27E, 0x23E, 0x23E, + 0x1FE, 0x1FE, 0x1BE, 0x1BE, 0x17E, 0x17E, 0x13E, 0x13C, 0x13C, 0xFA, 0xF8, 0xB6, 0xB4, 0xB2, 0xB0, 0x6E, + 0x6C, 0x8AA, 0x8A8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x89C, 0x2A76, 0x2A36, 0x2238, 0x1A3A, + 0x1A3C, 0x123C, 0xA3C, 0xA3E, 0x23E, 0x23E, 0x27E, 0x27E, 0x27E, 0x2BE, 0x2BE, 0x27E, 0x27E, 0x27E, 0x23E, 0x23E, + 0x1FE, 0x1FE, 0x1BE, 0x1BE, 0x17E, 0x17E, 0x13E, 0x13C, 0x13C, 0xFA, 0xF8, 0xB6, 0xB4, 0xB2, 0xB0, 0x6E, + 0xAC, 0x8AA, 0x10A8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10E2, 0x2A36, 0x2238, 0x1A38, 0x1A3A, + 0x123C, 0x123C, 0x9FE, 0x1FE, 0x1FE, 0x23E, 0x23E, 0x27E, 0x27E, 0x27E, 0x27E, 0x27E, 0x23E, 0x23E, 0x23E, 0x1FE, + 0x1FE, 0x1BE, 0x1BE, 0x1BE, 0x17E, 0x17E, 0x13E, 0x13C, 0xFA, 0xFA, 0xF8, 0xB6, 0xB4, 0xB2, 0x70, 0xAE, + 0x8AC, 0x8AA, 0x10EA, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8E2, 0x2A36, 0x2238, 0x19F8, 0x11FA, + 0x11FC, 0x9FE, 0x1FE, 0x1FE, 0x1FE, 0x1FE, 0x23E, 0x23E, 0x23E, 0x23E, 0x23E, 0x23E, 0x23E, 0x23E, 0x1FE, 0x1FE, + 0x1FE, 0x1BE, 0x1BE, 0x17E, 0x17E, 0x13E, 0x13C, 0x13C, 0xFA, 0xF8, 0xF8, 0xB6, 0xB4, 0xB2, 0x70, 0xAE, + 0x8AC, 0x10AC, 0x10EA, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x89C, 0x21F6, 0x19F8, 0x19F8, 0x11FA, + 0x9FC, 0x9BE, 0x1BE, 0x1BE, 0x1FE, 0x1FE, 0x1FE, 0x1FE, 0x23E, 0x23E, 0x23E, 0x23E, 0x1FE, 0x1FE, 0x1FE, 0x1FE, + 0x1BE, 0x1BE, 0x17E, 0x17E, 0x17E, 0x13E, 0x13C, 0x13C, 0xFA, 0xF8, 0xB6, 0xB4, 0xB2, 0xB0, 0xB0, 0x8AE, + 0x8AC, 0x10EA, 0x18EA, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x54, 0x21F6, 0x19F8, 0x11B8, 0x11BA, + 0x9BC, 0x1BE, 0x1BE, 0x1BE, 0x1BE, 0x1FE, 0x1FE, 0x1FE, 0x1FE, 0x1FE, 0x1FE, 0x1FE, 0x1FE, 0x1FE, 0x1BE, 0x1BE, + 0x1BE, 0x1BE, 0x17E, 0x17E, 0x13E, 0x13C, 0x13C, 0xFA, 0xFA, 0xF8, 0xB6, 0xB4, 0xB2, 0xB0, 0xAE, 0x8AE, + 0x10EC, 0x10EA, 0x18E8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xC, 0x19B6, 0x19B6, 0x11B8, 0x9BA, + 0x97C, 0x17E, 0x17E, 0x1BE, 0x1BE, 0x1BE, 0x1BE, 0x1FE, 0x1FE, 0x1FE, 0x1FE, 0x1FE, 0x1BE, 0x1BE, 0x1BE, 0x1BE, + 0x17E, 0x17E, 0x17E, 0x17E, 0x13E, 0x13C, 0x13C, 0xFA, 0xF8, 0xF6, 0xB6, 0xB4, 0xB2, 0xB0, 0x8AE, 0x8AE, + 0x10EC, 0x18EA, 0x18E8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1172, 0x19B6, 0x11B8, 0x97A, + 0x17C, 0x17E, 0x17E, 0x17E, 0x17E, 0x1BE, 0x1BE, 0x1BE, 0x1BE, 0x1BE, 0x1BE, 0x1BE, 0x1BE, 0x1BE, 0x1BE, 0x17E, + 0x17E, 0x17E, 0x17E, 0x13E, 0x13C, 0x13C, 0xFA, 0xF8, 0xF8, 0xB6, 0xB4, 0xB2, 0xB0, 0x8B0, 0x8AE, 0x10EE, + 0x18EC, 0x192A, 0x10A0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xA8, 0x1176, 0x1178, 0x97A, + 0x13C, 0x13C, 0x17E, 0x17E, 0x17E, 0x17E, 0x17E, 0x1BE, 0x1BE, 0x1BE, 0x1BE, 0x1BE, 0x17E, 0x17E, 0x17E, 0x17E, + 0x17E, 0x13E, 0x13E, 0x13C, 0x13C, 0xFA, 0xFA, 0xF8, 0xB6, 0xB4, 0xB4, 0xB2, 0xB0, 0x8B0, 0x10EE, 0x10EC, + 0x18EC, 0x212A, 0x850, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x14, 0x1176, 0x976, 0x938, + 0x13A, 0x13C, 0x13C, 0x13E, 0x17E, 0x17E, 0x17E, 0x17E, 0x17E, 0x17E, 0x17E, 0x17E, 0x17E, 0x17E, 0x17E, 0x17E, + 0x13E, 0x13E, 0x13C, 0x13C, 0xFA, 0xFA, 0xF8, 0xF6, 0xB6, 0xB4, 0xB2, 0xB0, 0x8B0, 0x10EE, 0x10EE, 0x18EC, + 0x192C, 0x212A, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xF2, 0x936, 0x138, + 0xFA, 0x13A, 0x13C, 0x13C, 0x13C, 0x13E, 0x17E, 0x17E, 0x17E, 0x17E, 0x17E, 0x17E, 0x17E, 0x13E, 0x13E, 0x13E, + 0x13C, 0x13C, 0x13C, 0xFA, 0xFA, 0xF8, 0xF6, 0xB6, 0xB4, 0xB2, 0xB2, 0x8B0, 0x8F0, 0x10EE, 0x18EC, 0x192C, + 0x212C, 0x10A0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x16, 0xF6, 0xF6, + 0xF8, 0xFA, 0x13A, 0x13A, 0x13C, 0x13C, 0x13C, 0x13C, 0x13E, 0x13E, 0x13E, 0x13E, 0x13C, 0x13C, 0x13C, 0x13C, + 0x13C, 0xFA, 0xFA, 0xFA, 0xF8, 0xF6, 0xB6, 0xB4, 0xB2, 0xB2, 0x8B0, 0x8B0, 0x10EE, 0x18EE, 0x18EC, 0x212C, + 0x212A, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xAA, 0xF6, + 0xF6, 0xF8, 0xF8, 0xFA, 0xFA, 0x13A, 0x13C, 0x13C, 0x13C, 0x13C, 0x13C, 0x13C, 0x13C, 0x13C, 0x13C, 0xFA, + 0xFA, 0xFA, 0xF8, 0xF8, 0xB6, 0xB6, 0xB4, 0xB2, 0xB2, 0x8B0, 0x8B0, 0x10EE, 0x10EE, 0x192E, 0x212C, 0x212C, + 0x1098, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xA, 0xB2, + 0xB6, 0xF6, 0xF8, 0xF8, 0xF8, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, + 0xF8, 0xF8, 0xF8, 0xB6, 0xB6, 0xB4, 0xB2, 0xB2, 0x8B0, 0x8B0, 0x10EE, 0x10EE, 0x18EE, 0x212C, 0x212C, 0x20E6, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, + 0xB2, 0xB4, 0xB6, 0xF6, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xFA, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, + 0xF8, 0xB6, 0xB6, 0xB4, 0xB4, 0xB2, 0xB2, 0x8B0, 0x8B0, 0x10EE, 0x10EE, 0x18EE, 0x192C, 0x212C, 0x2128, 0x2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x14, 0xB2, 0xB4, 0xB4, 0xB6, 0xB6, 0xF6, 0xF6, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF6, 0xB6, 0xB6, + 0xB6, 0xB4, 0xB4, 0xB2, 0xB2, 0xB2, 0x8B0, 0x8B0, 0x10EE, 0x10EE, 0x18EE, 0x192C, 0x212C, 0x212A, 0x4, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x14, 0xB0, 0xB2, 0xB4, 0xB4, 0xB4, 0xB4, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB4, 0xB4, 0xB4, + 0xB4, 0xB2, 0xB2, 0xB2, 0xB0, 0x8B0, 0x8F0, 0x10EE, 0x10EE, 0x18EE, 0x192C, 0x212C, 0x18E8, 0x6, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x6, 0x6A, 0xB2, 0xB2, 0xB2, 0xB2, 0xB4, 0xB4, 0xB4, 0xB4, 0xB4, 0xB2, 0xB2, 0xB2, + 0xB2, 0xB0, 0xB0, 0x8B0, 0x8B0, 0x10EE, 0x10EE, 0x18EE, 0x192E, 0x212C, 0x212C, 0x18E0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x1E, 0xAE, 0xB0, 0xB0, 0xB2, 0xB2, 0xB2, 0xB2, 0xB0, 0xB0, 0xB0, 0xB0, + 0xB0, 0xB0, 0x8AE, 0x8AE, 0x10EE, 0x10EE, 0x18EE, 0x18EC, 0x212C, 0x18EA, 0x854, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x1E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0xAE, 0xAE, + 0x8AE, 0x8AE, 0x8AE, 0x10EE, 0x10EE, 0x18EC, 0x192C, 0x18EA, 0x856, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x16, 0x64, 0x6A, 0x6C, 0x6C, 0xAC, 0x8AC, 0x8AC, + 0x8AC, 0x10EC, 0x10EC, 0x10EC, 0x10A8, 0x85E, 0x12, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x10, 0x14, 0x1A, 0x1C, + 0x18, 0x12, 0xC, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 + +}; diff --git a/src/snes4iphone_src/gp2x_sdk.c b/src/snes4iphone_src/gp2x_sdk.c new file mode 100755 index 0000000..180875b --- /dev/null +++ b/src/snes4iphone_src/gp2x_sdk.c @@ -0,0 +1,725 @@ + +#define DEBUG + +#include +#include +#include +#include +#include +#include +#include +#include +#include "menu.h" +#include "gp2x_sdk.h" +#include "squidgehack.h" +#include + +#define SYS_CLK_FREQ 7372800 + +volatile unsigned short gp2x_palette[512][2]; + +static int fb_size=(320*240*2)+(16*2); +static int mmuHackStatus=0; + +//unsigned long gp2x_ticks_per_second=7372800/1000; +unsigned long gp2x_dev[5]={0,0,0,0,0}; +unsigned long gp2x_physvram[4]={0,0,0,0}; + +unsigned short *framebuffer16[4]={0,0,0,0}; +static unsigned short *framebuffer_mmap[4]={0,0,0,0}; +unsigned short *gp2x_logvram15[2], gp2x_sound_buffer[4+((44100*2)*8)]; //*2=stereo, *4=max buffers +volatile unsigned short *gp2x_memregs; +volatile unsigned long *gp2x_memregl; +volatile unsigned long *gp2x_blitter = NULL; +unsigned int *gp2x_intVectors; +unsigned char *framebuffer8[4], *gp2x_screen8prev, *gp2x_logvram8[2]; + +volatile short *pOutput[8]; +int InitFramebuffer=0; +int Timer=0; +volatile int SoundThreadFlag=0; +volatile int CurrentSoundBank=0; +int CurrentFrameBuffer=0; +int CurrentFrag=0; +unsigned int ExistingIntHandler; +unsigned int VolumeMultiplier = 0x50; + +// 1024x8 8x8 font, i love it :) +const unsigned int font8x8[]= {0x0,0x0,0xc3663c18,0x3c2424e7,0xe724243c,0x183c66c3,0xc16f3818,0x18386fc1,0x83f61c18,0x181cf683,0xe7c3993c,0x3c99c3,0x3f7fffff,0xe7cf9f,0x3c99c3e7,0xe7c399,0x3160c080,0x40e1b,0xcbcbc37e,0x7ec3c3db,0x3c3c3c18,0x81c087e,0x8683818,0x60f0e08,0x81422418,0x18244281,0xbd5a2418,0x18245abd,0x818181ff,0xff8181,0xa1c181ff,0xff8995,0x63633e,0x3e6363,0x606060,0x606060,0x3e60603e,0x3e0303,0x3e60603e,0x3e6060,0x3e636363,0x606060,0x3e03033e,0x3e6060,0x3e03033e,0x3e6363,0x60603e,0x606060,0x3e63633e,0x3e6363,0x3e63633e,0x3e6060,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x18181818,0x180018,0x666666,0x0,0x367f3600,0x367f36,0x3c067c18,0x183e60,0x18366600,0x62660c,0xe1c361c,0x6e337b,0x181818,0x0,0x18183870,0x703818,0x18181c0e,0xe1c18,0xff3c6600,0x663c,0x7e181800,0x1818,0x0,0x60c0c00,0x7e000000,0x0,0x0,0x181800,0x18306040,0x2060c,0x6e76663c,0x3c6666,0x18181c18,0x7e1818,0x3060663c,0x7e0c18,0x3018307e,0x3c6660,0x363c3830,0x30307e,0x603e067e,0x3c6660,0x3e06063c,0x3c6666,0x1830607e,0xc0c0c,0x3c66663c,0x3c6666,0x7c66663c,0x1c3060,0x181800,0x1818,0x181800,0xc1818,0xc183060,0x603018,0x7e0000,0x7e00,0x30180c06,0x60c18,0x3060663c,0x180018,0x5676663c,0x7c0676,0x66663c18,0x66667e,0x3e66663e,0x3e6666,0x606663c,0x3c6606,0x6666361e,0x1e3666,0x3e06067e,0x7e0606,0x3e06067e,0x60606,0x7606067c,0x7c6666,0x7e666666,0x666666,0x1818183c,0x3c1818,0x60606060,0x3c6660,0xe1e3666,0x66361e,0x6060606,0x7e0606,0x6b7f7763,0x636363,0x7e7e6e66,0x666676,0x6666663c,0x3c6666,0x3e66663e,0x60606,0x6666663c,0x6c366e,0x3e66663e,0x666636,0x3c06663c,0x3c6660,0x1818187e,0x181818,0x66666666,0x7c6666,0x66666666,0x183c66,0x6b636363,0x63777f,0x183c6666,0x66663c,0x3c666666,0x181818,0x1830607e,0x7e060c,0x18181878,0x781818,0x180c0602,0x406030,0x1818181e,0x1e1818,0x63361c08,0x0,0x0,0x7f0000,0xc060300,0x0,0x603c0000,0x7c667c,0x663e0606,0x3e6666,0x63c0000,0x3c0606,0x667c6060,0x7c6666,0x663c0000,0x3c067e,0xc3e0c38,0xc0c0c,0x667c0000,0x3e607c66,0x663e0606,0x666666,0x181c0018,0x3c1818,0x18180018,0xe181818,0x36660606,0x66361e,0x1818181c,0x3c1818,0x7f370000,0x63636b,0x663e0000,0x666666,0x663c0000,0x3c6666,0x663e0000,0x63e6666,0x667c0000,0x607c6666,0x663e0000,0x60606,0x67c0000,0x3e603c,0x187e1800,0x701818,0x66660000,0x7c6666,0x66660000,0x183c66,0x63630000,0x363e6b,0x3c660000,0x663c18,0x66660000,0x3e607c66,0x307e0000,0x7e0c18,0xc181870,0x701818,0x18181818,0x18181818,0x3018180e,0xe1818,0x794f0600,0x30}; + +pthread_t gp2x_sound_thread=0, gp2x_sound_thread_exit=0; +struct fb_fix_screeninfo fb0_fixed_info; +struct fb_fix_screeninfo fb1_fixed_info; + +/* +######################## +Graphics functions +######################## + */ + +static void debug(char *text, int pause) +{ + unsigned short bppmode; + bppmode=gp2x_memregs[0x28DA>>1]; + bppmode>>=9; + bppmode<<=3; + + if(bppmode==8) + { + gp_clearFramebuffer8(framebuffer8[currFB],0); + gp_drawString(0,0,strlen(text),text,0x51,framebuffer16[currFB]); + } + else + { + gp_clearFramebuffer8(framebuffer16[currFB],0); + gp_drawString(0,0,strlen(text),text,(unsigned short)RGB(31,31,31),framebuffer16[currFB]); + } + MenuFlip(); + if(pause) MenuPause(); + +} +static __inline__ +void gp_drawPixel8 ( int x, int y, unsigned char c, unsigned char *framebuffer ) +{ + *(framebuffer +(320*y)+x ) = c; +} + +static __inline__ +void gp_drawPixel16 ( int x, int y, unsigned short c, unsigned short *framebuffer ) +{ + *(framebuffer +(320*y)+x ) = c; +} + +static +void set_char8x8_16bpp (int xx,int yy,int offset,unsigned short mode,unsigned short *framebuffer) +{ + unsigned int y, pixel; + offset *= 2; + pixel = font8x8[0 + offset]; + for (y = 0; y < 4; y++) + { + if (pixel&(1<<(0+(y<<3)))) gp_drawPixel16(xx+0, yy+y, mode, framebuffer); + if (pixel&(1<<(1+(y<<3)))) gp_drawPixel16(xx+1, yy+y, mode, framebuffer); + if (pixel&(1<<(2+(y<<3)))) gp_drawPixel16(xx+2, yy+y, mode, framebuffer); + if (pixel&(1<<(3+(y<<3)))) gp_drawPixel16(xx+3, yy+y, mode, framebuffer); + if (pixel&(1<<(4+(y<<3)))) gp_drawPixel16(xx+4, yy+y, mode, framebuffer); + if (pixel&(1<<(5+(y<<3)))) gp_drawPixel16(xx+5, yy+y, mode, framebuffer); + if (pixel&(1<<(6+(y<<3)))) gp_drawPixel16(xx+6, yy+y, mode, framebuffer); + if (pixel&(1<<(7+(y<<3)))) gp_drawPixel16(xx+7, yy+y, mode, framebuffer); + } + pixel = font8x8[1 + offset]; + for (y = 0; y < 4; y++) + { + if (pixel&(1<<(0+(y<<3)))) gp_drawPixel16(xx+0, yy+y+4, mode, framebuffer); + if (pixel&(1<<(1+(y<<3)))) gp_drawPixel16(xx+1, yy+y+4, mode, framebuffer); + if (pixel&(1<<(2+(y<<3)))) gp_drawPixel16(xx+2, yy+y+4, mode, framebuffer); + if (pixel&(1<<(3+(y<<3)))) gp_drawPixel16(xx+3, yy+y+4, mode, framebuffer); + if (pixel&(1<<(4+(y<<3)))) gp_drawPixel16(xx+4, yy+y+4, mode, framebuffer); + if (pixel&(1<<(5+(y<<3)))) gp_drawPixel16(xx+5, yy+y+4, mode, framebuffer); + if (pixel&(1<<(6+(y<<3)))) gp_drawPixel16(xx+6, yy+y+4, mode, framebuffer); + if (pixel&(1<<(7+(y<<3)))) gp_drawPixel16(xx+7, yy+y+4, mode, framebuffer); + + } +} + +static +void set_char8x8_8bpp (int xx,int yy,int offset,unsigned char mode,unsigned char *framebuffer) +{ + unsigned int y, pixel; + offset *= 2; + pixel = font8x8[0 + offset]; + for (y = 0; y < 4; y++) + { + if (pixel&(1<<(0+(y<<3)))) gp_drawPixel8(xx+0, yy+y, mode, framebuffer); + if (pixel&(1<<(1+(y<<3)))) gp_drawPixel8(xx+1, yy+y, mode, framebuffer); + if (pixel&(1<<(2+(y<<3)))) gp_drawPixel8(xx+2, yy+y, mode, framebuffer); + if (pixel&(1<<(3+(y<<3)))) gp_drawPixel8(xx+3, yy+y, mode, framebuffer); + if (pixel&(1<<(4+(y<<3)))) gp_drawPixel8(xx+4, yy+y, mode, framebuffer); + if (pixel&(1<<(5+(y<<3)))) gp_drawPixel8(xx+5, yy+y, mode, framebuffer); + if (pixel&(1<<(6+(y<<3)))) gp_drawPixel8(xx+6, yy+y, mode, framebuffer); + if (pixel&(1<<(7+(y<<3)))) gp_drawPixel8(xx+7, yy+y, mode, framebuffer); + } + pixel = font8x8[1 + offset]; + for (y = 0; y < 4; y++) + { + if (pixel&(1<<(0+(y<<3)))) gp_drawPixel8(xx+0, yy+y+4, mode, framebuffer); + if (pixel&(1<<(1+(y<<3)))) gp_drawPixel8(xx+1, yy+y+4, mode, framebuffer); + if (pixel&(1<<(2+(y<<3)))) gp_drawPixel8(xx+2, yy+y+4, mode, framebuffer); + if (pixel&(1<<(3+(y<<3)))) gp_drawPixel8(xx+3, yy+y+4, mode, framebuffer); + if (pixel&(1<<(4+(y<<3)))) gp_drawPixel8(xx+4, yy+y+4, mode, framebuffer); + if (pixel&(1<<(5+(y<<3)))) gp_drawPixel8(xx+5, yy+y+4, mode, framebuffer); + if (pixel&(1<<(6+(y<<3)))) gp_drawPixel8(xx+6, yy+y+4, mode, framebuffer); + if (pixel&(1<<(7+(y<<3)))) gp_drawPixel8(xx+7, yy+y+4, mode, framebuffer); + + } +} + +void gp_drawString (int x,int y,int len,char *buffer,unsigned short color,void *framebuffer) +{ + int l,base=0; + unsigned short bppmode; + bppmode=gp2x_memregs[0x28DA>>1]; + bppmode>>=9; + bppmode<<=3; + + for (l=0;l>1]; + bppmode>>=9; + bppmode<<=3; + if(bppmode==8) gp_clearFramebuffer8((unsigned char*)framebuffer,(unsigned char)pal); + else gp_clearFramebuffer16((unsigned short*)framebuffer,(unsigned short)pal); +} + + + + +unsigned int gp_getButton(unsigned char enable_diagnals) +{ + unsigned int value=(gp2x_memregs[0x1198>>1] & 0x00FF); + //gp2x_memregs[0x1198>>1] + /* + 0x1FE = UP 1 1111 1110 + 0x17E 1 0111 1110 + 0x17F 1 0111 1111 + 0X13F 1 0011 1111 + 0x1BF = RIGHT 1 1011 1111 + 0X19F 1 1001 1111 + 0X1DF 1 1101 1111 + 0X1CF 1 1100 1111 + 0x1EF = DOWN 1 1110 1111 + 0x1E7 1 1110 0111 + 0x1F7 1 1111 0111 + 0x1F3 1 1111 0011 + 0x1FB = LEFT 1 1111 1011 + 0x1F9 1 1111 1001 + 0x1FD 1 1111 1101 + 0x1FC 1 1111 1100 + + */ + switch(value) + { + //UP + case 0x7E: + case 0xFC: + value = 0xFE; + break; + + //RIGHT + case 0x3F: + case 0x9F: + value = 0xBF; + break; + + //DOWN + case 0xCF: + case 0xE7: + value = 0xEF; + break; + + //LEFT + case 0xF3: + case 0xF9: + value = 0xFB; + break; + } + + if (enable_diagnals) + { + + if(value==0xFD) value=0xFA; + if(value==0xF7) value=0xEB; + if(value==0xDF) value=0xAF; + if(value==0x7F) value=0xBE; + } + + + return ~((gp2x_memregs[0x1184>>1] & 0xFF00) | value | (gp2x_memregs[0x1186>>1] << 16)); +} + +void gp_initGraphics(unsigned short bpp, int flip, int applyMmuHack) +{ + + int x = 0; + unsigned int key = 0; + unsigned int offset = 0; + char buf[256]; + + +#ifdef DEBUG + printf("Entering gp_initGraphics....\r\n"); +#endif + /* + First check that frame buffer memory has not already been setup + */ + if (!InitFramebuffer) + { +#ifdef DEBUG + sprintf(buf, "Initing buffer\r\n"); + printf(buf); +#endif + gp2x_dev[0] = open("/dev/fb0", O_RDWR); + gp2x_dev[1] = open("/dev/fb1", O_RDWR); + gp2x_dev[2] = open("/dev/mem", O_RDWR); + +#ifdef DEBUG + sprintf(buf, "Devices opened\r\n"); + printf(buf); + sprintf(buf, "/dev/fb0: %x \r\n", gp2x_dev[0]); + printf(buf); + sprintf(buf, "/dev/fb1: %x \r\n", gp2x_dev[1]); + printf(buf); + sprintf(buf, "/dev/mem: %x \r\n", gp2x_dev[2]); + printf(buf); +#endif + + gp2x_memregs=(unsigned short *)mmap(0, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, gp2x_dev[2], 0xc0000000); + gp2x_memregl=(unsigned long *)gp2x_memregs; + if (!gp2x_blitter) gp2x_blitter=(unsigned long *)mmap(0, 0x100, PROT_READ|PROT_WRITE, MAP_SHARED, gp2x_dev[2], 0xe0020000); + + if (!framebuffer_mmap[0]) framebuffer_mmap[0]=(void *)mmap(0, fb_size, PROT_READ|PROT_WRITE, MAP_SHARED, gp2x_dev[2], (gp2x_physvram[0]=0x04000000-(0x26000*4) )); + if (!framebuffer_mmap[1]) framebuffer_mmap[1]=(void *)mmap(0, fb_size, PROT_READ|PROT_WRITE, MAP_SHARED, gp2x_dev[2], (gp2x_physvram[1]=0x04000000-(0x26000*3) )); + if (!framebuffer_mmap[2]) framebuffer_mmap[2]=(void *)mmap(0, fb_size, PROT_READ|PROT_WRITE, MAP_SHARED, gp2x_dev[2], (gp2x_physvram[2]=0x04000000-(0x26000*2) )); + if (!framebuffer_mmap[3]) framebuffer_mmap[3]=(void *)mmap(0, fb_size, PROT_READ|PROT_WRITE, MAP_SHARED, gp2x_dev[2], (gp2x_physvram[3]=0x04000000-(0x26000*1) )); + + if (applyMmuHack) + { + printf("Applying MMUHACK..."); fflush(stdout); + mmuHackStatus = mmuhack(); + sprintf(buf, "Done\r\n. MMUHACK returned: %x\r\n", mmuHackStatus); + printf(buf); fflush(stdout); + } + + // offset externally visible buffers by 8 + // this allows DrMD to not worry about clipping + framebuffer16[0]=framebuffer_mmap[0]+8; + framebuffer16[1]=framebuffer_mmap[1]+8; + framebuffer16[2]=framebuffer_mmap[2]+8; + framebuffer16[3]=framebuffer_mmap[3]+8; + //ofset physical buffer as well + gp2x_physvram[0]+=16; + gp2x_physvram[1]+=16; + gp2x_physvram[2]+=16; + gp2x_physvram[3]+=16; + // clear all the framebuffers to black + // otherwise you get crap displayed on the screen the first time + // you start + framebuffer8[0]=(unsigned char*)framebuffer16[0]; + framebuffer8[1]=(unsigned char*)framebuffer16[1]; + framebuffer8[2]=(unsigned char*)framebuffer16[2]; + framebuffer8[3]=(unsigned char*)framebuffer16[3]; + + // Clear the frame buffers + memset(framebuffer16[0],0,320*240*2); + memset(framebuffer16[1],0,320*240*2); + memset(framebuffer16[2],0,320*240*2); + memset(framebuffer16[3],0,320*240*2); + + InitFramebuffer=1; + + //gp2x_memregs[0x0F16>>1] = 0x830a; + //usleep(1000000); + //gp2x_memregs[0x0F58>>1] = 0x100c; + //usleep(1000000); + + + } + + + // Set graphics mode + gp2x_memregs[0x28DA>>1]=(((bpp+1)/8)<<9)|0xAB; /*8/15/16/24bpp...*/ + gp2x_memregs[0x290C>>1]=320*((bpp+1)/8); + + //TV out fix + gp2x_video_RGB_setscaling(320,240); + + // 2d accel + //gp2x_memregs[0x904 >> 1] |= 1<<10; //SYSCLKENREG (System Clock Enable Register) maybe bit 10 is 2d accer + //gp2x_memregs[0x90a >> 1] = 0xffff; // Reset clock timings for all devices + + gp_setFramebuffer(flip,1); + +#ifdef DEBUG + printf("Leaving gp_initGraphics....\r\n"); +#endif +} + +void gp_setFramebuffer(int flip, int sync) +{ + CurrentFrameBuffer=flip; + unsigned int address=(unsigned int)gp2x_physvram[flip]; + unsigned short x=0; + /*switch(sync) + { + case 0: + // No sync + break; + + case 1: + // VSync + while(1) + { + x=gp2x_memregs[0x1182>>1]; + if((x&(1<<4)) == 0) + { + break; + } + } + break; + case 2: + // HSync + while(1) + { + x=gp2x_memregs[0x1182>>1]; + if((x&(1<<5)) == 0) + { + break; + } + } + break; + }*/ + + gp2x_memregs[0x290E>>1]=(unsigned short)(address & 0xffff); + gp2x_memregs[0x2910>>1]=(unsigned short)(address >> 16); + gp2x_memregs[0x2912>>1]=(unsigned short)(address & 0xffff); + gp2x_memregs[0x2914>>1]=(unsigned short)(address >> 16); +} + +void gp2x_video_setpalette(void) +{ + unsigned short *g=(unsigned short *)gp2x_palette; int i=512; + gp2x_memregs[0x2958>>1]=0; + while(i--) gp2x_memregs[0x295A>>1]=*g++; +} + +/* +######################## +Sound functions +######################## + */ +static +void *gp2x_sound_play(void) +{ + //struct timespec ts; ts.tv_sec=0, ts.tv_nsec=1000; + while(! gp2x_sound_thread_exit) + { + Timer++; + CurrentSoundBank++; + + if (CurrentSoundBank >= 8) CurrentSoundBank = 0; + + if (SoundThreadFlag==SOUND_THREAD_SOUND_ON) + { + write(gp2x_dev[3], (void *)pOutput[CurrentSoundBank], gp2x_sound_buffer[1]); + ioctl(gp2x_dev[3], SOUND_PCM_SYNC, 0); + //ts.tv_sec=0, ts.tv_nsec=(gp2x_sound_buffer[3]<<16)|gp2x_sound_buffer[2]; + //nanosleep(&ts, NULL); + } + else + { + write(gp2x_dev[3], (void *)&gp2x_sound_buffer[4], gp2x_sound_buffer[1]); + ioctl(gp2x_dev[3], SOUND_PCM_SYNC, 0); + //ts.tv_sec=0, ts.tv_nsec=(gp2x_sound_buffer[3]<<16)|gp2x_sound_buffer[2]; + //nanosleep(&ts, NULL); + } + } + + return NULL; +} + +void gp2x_sound_play_bank(int bank) +{ + write(gp2x_dev[3], (void *)(&gp2x_sound_buffer[4+(bank*gp2x_sound_buffer[1])]), gp2x_sound_buffer[1]); +} + +void gp2x_sound_sync(void) +{ + ioctl(gp2x_dev[3], SOUND_PCM_SYNC, 0); +} + +void gp2x_sound_volume(int l, int r) +{ + if(!gp2x_dev[4]) + { + gp2x_dev[4] = open("/dev/mixer", O_WRONLY); + } + l=(((l*VolumeMultiplier)/100)<<8)|((r*VolumeMultiplier)/100); //0x5A, 0x60 + ioctl(gp2x_dev[4], SOUND_MIXER_WRITE_PCM, &l); //SOUND_MIXER_WRITE_VOLUME +} + +unsigned long gp2x_timer_read(void) +{ + // Once again another peice of direct hardware access bites the dust + // the code below is broken in firmware 2.1.1 so I've replaced it with a + // to a linux function which seems to work + //return gp2x_memregl[0x0A00>>2]/gp2x_ticks_per_second; + struct timeval tval; // timing + + gettimeofday(&tval, 0); + //tval.tv_usec + //tval.tv_sec + return (tval.tv_sec*1000000)+tval.tv_usec; +} + +int gp_initSound(int rate, int bits, int stereo, int Hz, int frag) +{ + int status; + int i=0; + int nonblocking=1; + unsigned int bufferStart=0; + int result; + char text[256]; + + //Check GP2x model + int fd; + fd=open("/dev/touchscreen/wm97xx", O_RDONLY | O_NOCTTY); + if (fd!=-1) + { + //F200 model + VolumeMultiplier = 0x28; + close(fd); + } + + //int frag=0x00020010; // double buffer - frag size = 1<<0xf = 32768 + + //8 = 256 = 2 fps loss = good sound + //9 = 512 = 1 fps loss = good sound + //A = 1024 = + //f = 32768 = 0 fps loss = bad sound + if ((frag!= CurrentFrag)&&(gp2x_dev[3]!=0)) + { + // Different frag config required + // close device in order to re-adjust + close(gp2x_dev[3]); + gp2x_dev[3]=0; + } + + if (gp2x_dev[3]==0) + { + gp2x_dev[3] = open("/dev/dsp", O_WRONLY); + printf("Opening sound device: %x\r\n",gp2x_dev[3]); + ioctl(gp2x_dev[3], SNDCTL_DSP_SETFRAGMENT, &frag); + CurrentFrag=frag; // save frag config + } + + //ioctl(gp2x_dev[3], SNDCTL_DSP_RESET, 0); + result=ioctl(gp2x_dev[3], SNDCTL_DSP_SPEED, &rate); + if(result==-1) + { + debug("Error setting DSP Speed",1); + return(-1); + } + + result=ioctl(gp2x_dev[3], SNDCTL_DSP_SETFMT, &bits); + if(result==-1) + { + debug("Error setting DSP format",1); + return(-1); + } + + result=ioctl(gp2x_dev[3], SNDCTL_DSP_STEREO, &stereo); + if(result==-1) + { + debug("Error setting DSP format",1); + return(-1); + } + //printf("Disable Blocking: %x\r\n",ioctl(gp2x_dev[3], 0x5421, &nonblocking)); + + gp2x_sound_buffer[1]=(gp2x_sound_buffer[0]=(rate/Hz)) << (stereo + (bits==16)); + gp2x_sound_buffer[2]=(1000000000/Hz)&0xFFFF; + gp2x_sound_buffer[3]=(1000000000/Hz)>>16; + + bufferStart= &gp2x_sound_buffer[4]; + pOutput[0] = (short*)bufferStart+(0*gp2x_sound_buffer[1]); + pOutput[1] = (short*)bufferStart+(1*gp2x_sound_buffer[1]); + pOutput[2] = (short*)bufferStart+(2*gp2x_sound_buffer[1]); + pOutput[3] = (short*)bufferStart+(3*gp2x_sound_buffer[1]); + pOutput[4] = (short*)bufferStart+(4*gp2x_sound_buffer[1]); + pOutput[5] = (short*)bufferStart+(5*gp2x_sound_buffer[1]); + pOutput[6] = (short*)bufferStart+(6*gp2x_sound_buffer[1]); + pOutput[7] = (short*)bufferStart+(7*gp2x_sound_buffer[1]); + + if(!gp2x_sound_thread) + { + pthread_create( &gp2x_sound_thread, NULL, gp2x_sound_play, NULL); + //atexit(gp_Reset); + } + + for(i=0;i<(gp2x_sound_buffer[1]*8);i++) + { + gp2x_sound_buffer[4+i] = 0; + } + + return(0); +} + +void gp_stopSound(void) +{ + unsigned int i=0; + gp2x_sound_thread_exit=1; + printf("Killing Thread\r\n"); + for(i=0;i<(gp2x_sound_buffer[1]*8);i++) + { + gp2x_sound_buffer[4+i] = 0; + } + usleep(100000); + printf("Thread is dead\r\n"); + gp2x_sound_thread=0; + gp2x_sound_thread_exit=0; + CurrentSoundBank=0; +} + + +/* +######################## +System functions +######################## + */ +void gp_Reset(void) +{ + unsigned int i=0; + + + if( gp2x_sound_thread) + { + gp2x_sound_thread_exit=1; + usleep(500); + } + + gp2x_memregs[0x28DA>>1]=0x4AB; + gp2x_memregs[0x290C>>1]=640; + munmap((void *)gp2x_memregs, 0x10000); + + munmap(framebuffer_mmap[0], fb_size); + munmap(framebuffer_mmap[1], fb_size); + munmap(framebuffer_mmap[2], fb_size); + munmap(framebuffer_mmap[3], fb_size); + + if (gp2x_dev[0]) close(gp2x_dev[0]); + if (gp2x_dev[1]) close(gp2x_dev[1]); + if (gp2x_dev[2]) close(gp2x_dev[2]); + if (gp2x_dev[3]) close(gp2x_dev[3]); + if (gp2x_dev[4]) close(gp2x_dev[4]); + + fcloseall(); + + // If MMUHACK was applied succesfully then remove it + if (mmuHackStatus) mmuunhack(); + + chdir("/usr/gp2x"); + execl("gp2xmenu",NULL); +} + +void gp2x_video_RGB_setscaling(int W, int H) +{ + float escalaw,escalah; + int bpp=(gp2x_memregs[0x28DA>>1]>>9)&0x3; + + if(gp2x_memregs[0x2800>>1]&0x100) //TV-Out + { + escalaw=489.0; //RGB Horiz TV (PAL, NTSC) + if (gp2x_memregs[0x2818>>1] == 287) //PAL + escalah=274.0; //RGB Vert TV PAL + else if (gp2x_memregs[0x2818>>1] == 239) //NTSC + escalah=331.0; //RGB Vert TV NTSC + } + else //LCD + { + escalaw=1024.0; //RGB Horiz LCD + escalah=320.0; //RGB Vert LCD + } + + // scale horizontal + gp2x_memregs[0x2906>>1]=(unsigned short)((float)escalaw *(W/320.0)); + // scale vertical + gp2x_memregl[0x2908>>2]=(unsigned long)((float)escalah *bpp *(H/240.0)); +} + +void gp_setCpuspeed(unsigned int MHZ) +{ + unsigned v; + unsigned mdiv,pdiv=3,scale=0; + + MHZ*=1000000; + mdiv=(MHZ*pdiv)/SYS_CLK_FREQ; + mdiv=((mdiv-8)<<8) & 0xff00; + pdiv=((pdiv-2)<<2) & 0xfc; + scale&=3; + v=mdiv | pdiv | scale; + gp2x_memregs[0x910>>1]=v; + +} + +// craigix: --trc 6 --tras 4 --twr 1 --tmrd 1 --trfc 1 --trp 2 --trcd 2 +// set_RAM_Timings(6, 4, 1, 1, 1, 2, 2); +void set_RAM_Timings(int tRC, int tRAS, int tWR, int tMRD, int tRFC, int tRP, int tRCD) +{ + tRC -= 1; tRAS -= 1; tWR -= 1; tMRD -= 1; tRFC -= 1; tRP -= 1; tRCD -= 1; // ??? + gp2x_memregs[0x3802>>1] = ((tMRD & 0xF) << 12) | ((tRFC & 0xF) << 8) | ((tRP & 0xF) << 4) | (tRCD & 0xF); + gp2x_memregs[0x3804>>1] = /*0x9000 |*/ ((tRC & 0xF) << 8) | ((tRAS & 0xF) << 4) | (tWR & 0xF); +} + +void set_gamma(int g100) +{ + float gamma = (float) g100 / 100; + int i; + gamma = 1/gamma; + + //enable gamma + gp2x_memregs[0x2880>>1]&=~(1<<12); + + gp2x_memregs[0x295C>>1]=0; + for(i=0; i<256; i++) + { + unsigned char g; + unsigned short s; + g =(unsigned char)(255.0*pow(i/255.0,gamma)); + s = (g<<8) | g; + gp2x_memregs[0x295E>>1]= s; + gp2x_memregs[0x295E>>1]= g; + } +} + + + + + diff --git a/src/snes4iphone_src/gp2x_sdk.h b/src/snes4iphone_src/gp2x_sdk.h new file mode 100755 index 0000000..dbce4b8 --- /dev/null +++ b/src/snes4iphone_src/gp2x_sdk.h @@ -0,0 +1,67 @@ +#ifndef _GP2X_SDK_H_ +#define _GP2X_SDK_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#define SOUND_THREAD_SOUND_ON 1 +#define SOUND_THREAD_SOUND_OFF 2 +#define SOUND_THREAD_PAUSE 3 + +#define INP_BUTTON_UP (0) +#define INP_BUTTON_LEFT (2) +#define INP_BUTTON_DOWN (4) +#define INP_BUTTON_RIGHT (6) +#define INP_BUTTON_START (8) +#define INP_BUTTON_SELECT (9) +#define INP_BUTTON_L (10) +#define INP_BUTTON_R (11) +#define INP_BUTTON_A (12) +#define INP_BUTTON_B (13) +#define INP_BUTTON_X (14) +#define INP_BUTTON_Y (15) +#define INP_BUTTON_VOL_UP (23) +#define INP_BUTTON_VOL_DOWN (22) +#define INP_BUTTON_STICK_PUSH (27) + +void gp_drawString (int x,int y,int len,char *buffer,unsigned short color,void *framebuffer); +void gp_clearFramebuffer16(unsigned short *framebuffer, unsigned short pal); +void gp_clearFramebuffer8(unsigned char *framebuffer, unsigned char pal); +void gp_clearFramebuffer(void *framebuffer, unsigned int pal); +void gp_setCpuspeed(unsigned int cpuspeed); +void gp_initGraphics(unsigned short bpp, int flip, int applyMmuHack); +void gp_setFramebuffer(int flip, int sync); +void gp2x_video_setpalette(void); +int gp_initSound(int rate, int bits, int stereo, int Hz, int frag); +void gp_stopSound(void); +void gp_Reset(void); +void gp2x_enableIRQ(void); +void gp2x_disableIRQ(void); +void gp2x_sound_volume(int l, int r); +unsigned long gp2x_timer_read(void); +unsigned int gp_getButton(unsigned char enable_diagnals); +void gp2x_video_RGB_setscaling(int W, int H); +void gp2x_sound_play_bank(int bank); +void gp2x_sound_sync(void); +void set_gamma(int g100); +void set_RAM_Timings(int tRC, int tRAS, int tWR, int tMRD, int tRFC, int tRP, int tRCD); + +extern volatile int SoundThreadFlag; +extern volatile int CurrentSoundBank; +extern int CurrentFrameBuffer; +extern volatile short *pOutput[]; +extern unsigned short *framebuffer16[]; +extern unsigned long gp2x_physvram[]; +extern unsigned char *framebuffer8[]; +extern volatile unsigned short gp2x_palette[512][2]; +extern volatile unsigned short *gp2x_memregs; +extern volatile unsigned long *gp2x_memregl; +extern volatile unsigned long *gp2x_blitter; + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/src/snes4iphone_src/gp32_func.h b/src/snes4iphone_src/gp32_func.h new file mode 100755 index 0000000..8ee461d --- /dev/null +++ b/src/snes4iphone_src/gp32_func.h @@ -0,0 +1,13 @@ +#ifndef __gp32_func_h__ +#define __gp32_func_h__ + +extern "C" int funcSADDMULT1616(int a,int b,int c,int d); + +#define SADDMULT1616(res,a,b,c,d) {\ + res=funcSADDMULT1616(a,b,c,d);\ + } +#define SMULT1616(res,a,b) {\ + res=funcSADDMULT1616(a,b,0,0);\ + } + +#endif diff --git a/src/snes4iphone_src/gx.h b/src/snes4iphone_src/gx.h new file mode 100755 index 0000000..0547d30 --- /dev/null +++ b/src/snes4iphone_src/gx.h @@ -0,0 +1,83 @@ + +// The following ifdef block is the standard way of creating macros which make exporting +// from a DLL simpler. All files within this DLL are compiled with the GXDLL_EXPORTS +// symbol defined on the command line. this symbol should not be defined on any project +// that uses this DLL. This way any other project whose source files include this file see +// GXDLL_API functions as being imported from a DLL, wheras this DLL sees symbols +// defined with this macro as being exported. + +#ifdef GXDLL_EXPORTS +#define GXDLL_API __declspec(dllexport) +#else +#define GXDLL_API __declspec(dllimport) +#endif + +struct GXDisplayProperties { + DWORD cxWidth; + DWORD cyHeight; // notice lack of 'th' in the word height. + long cbxPitch; // number of bytes to move right one x pixel - can be negative. + long cbyPitch; // number of bytes to move down one y pixel - can be negative. + long cBPP; // # of bits in each pixel + DWORD ffFormat; // format flags. +}; + +struct GXKeyList { + short vkUp; // key for up + POINT ptUp; // x,y position of key/button. Not on screen but in screen coordinates. + short vkDown; + POINT ptDown; + short vkLeft; + POINT ptLeft; + short vkRight; + POINT ptRight; + short vkA; + POINT ptA; + short vkB; + POINT ptB; + short vkC; + POINT ptC; + short vkStart; + POINT ptStart; +}; + +struct GXScreenRect { + DWORD dwTop; + DWORD dwLeft; + DWORD dwWidth; + DWORD dwHeight; +}; + +GXDLL_API int GXOpenDisplay(HWND hWnd, DWORD dwFlags); +GXDLL_API int GXCloseDisplay(); +GXDLL_API void * GXBeginDraw(); +GXDLL_API int GXEndDraw(); +GXDLL_API int GXOpenInput(); +GXDLL_API int GXCloseInput(); +//The following two lines modified by Dan East to make this header C compatible: +//Added "struct" to the following two prototypes: +GXDLL_API struct GXDisplayProperties GXGetDisplayProperties(); +GXDLL_API struct GXKeyList GXGetDefaultKeys(int iOptions); +GXDLL_API int GXSuspend(); +GXDLL_API int GXResume(); +GXDLL_API int GXSetViewport( DWORD dwTop, DWORD dwHeight, DWORD dwReserved1, DWORD dwReserved2 ); +GXDLL_API BOOL GXIsDisplayDRAMBuffer(); + + +// Although these flags can be unrelated they still +// have unique values. + +#define GX_FULLSCREEN 0x01 // for OpenDisplay() +#define GX_NORMALKEYS 0x02 +#define GX_LANDSCAPEKEYS 0x03 + +#ifndef kfLandscape + #define kfLandscape 0x8 // Screen is rotated 270 degrees + #define kfPalette 0x10 // Pixel values are indexes into a palette + #define kfDirect 0x20 // Pixel values contain actual level information + #define kfDirect555 0x40 // 5 bits each for red, green and blue values in a pixel. + #define kfDirect565 0x80 // 5 red bits, 6 green bits and 5 blue bits per pixel + #define kfDirect888 0x100 // 8 bits each for red, green and blue values in a pixel. + #define kfDirect444 0x200 // 4 red, 4 green, 4 blue + #define kfDirectInverted 0x400 +#endif + diff --git a/src/snes4iphone_src/imgdecmp.h b/src/snes4iphone_src/imgdecmp.h new file mode 100755 index 0000000..d323647 --- /dev/null +++ b/src/snes4iphone_src/imgdecmp.h @@ -0,0 +1,58 @@ +/*---------------------------------------------------------------------------*\ + * + * (c) Copyright Microsoft Corp. 1997-98 All Rights Reserved + * + * module: imgdecmp.h + * date: + * author: jaym + * + * purpose: + * +\*---------------------------------------------------------------------------*/ +#ifndef __IMGDECMP_H__ +#define __IMGDECMP_H__ + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +#include "imgrendr.h" + +typedef void (CALLBACK *PROGRESSFUNC)(IImageRender *pRender, BOOL bComplete, LPARAM lParam); +typedef DWORD (CALLBACK *GETDATAFUNC)(LPSTR szBuffer, DWORD dwBufferMax, LPARAM lParam); + +typedef struct tagDecompressImageInfo { + DWORD dwSize; // Size of this structure + LPBYTE pbBuffer; // Pointer to the buffer to use for data + DWORD dwBufferMax; // Size of the buffer + DWORD dwBufferCurrent; // The amount of data which is current in the buffer + HBITMAP * phBM; // Pointer to the bitmap returned (can be NULL) + IImageRender ** ppImageRender; // Pointer to an IImageRender object (can be NULL) + int iBitDepth; // Bit depth of the output image + LPARAM lParam; // User parameter for callback functions + HDC hdc; // HDC to use for retrieving palettes + int iScale; // Scale factor (1 - 100) + int iMaxWidth; // Maximum width of the output image + int iMaxHeight; // Maxumum height of the output image + GETDATAFUNC pfnGetData; // Callback function to get more data + PROGRESSFUNC pfnImageProgress; // Callback function to notify caller of progress decoding the image + COLORREF crTransparentOverride; // If this color is not (UINT)-1, it will override the + // transparent color in the image with this color. (GIF ONLY) +} DecompressImageInfo; + +#define IMGDECOMP_E_NOIMAGE 0x800b0100 + +COLORREF * +GetHalftonePalette(); + +COLORREF * +Get332Palette(); + +HRESULT +DecompressImageIndirect(DecompressImageInfo *pParams); + +#ifdef __cplusplus +}; +#endif // __cplusplus + +#endif // !__IMGDECMP_H__ diff --git a/src/snes4iphone_src/imgrendr.h b/src/snes4iphone_src/imgrendr.h new file mode 100755 index 0000000..5b05752 --- /dev/null +++ b/src/snes4iphone_src/imgrendr.h @@ -0,0 +1,270 @@ +/* this ALWAYS GENERATED file contains the definitions for the interfaces */ + + +/* File created by MIDL compiler version 3.01.75 */ +/* at Tue Feb 10 13:46:55 1998 + */ +/* Compiler settings for .\imgrendr.idl: + Oicf (OptLev=i2), W1, Zp8, env=Win32, ms_ext, c_ext + error checks: none +*/ +//@@MIDL_FILE_HEADING( ) +#include "rpc.h" +#include "rpcndr.h" +#ifndef COM_NO_WINDOWS_H +#include "windows.h" +#include "ole2.h" +#endif /*COM_NO_WINDOWS_H*/ + +#ifndef __imgrendr_h__ +#define __imgrendr_h__ + +#ifdef __cplusplus +extern "C"{ +#endif + +/* Forward Declarations */ + +#ifndef __IImageRender_FWD_DEFINED__ +#define __IImageRender_FWD_DEFINED__ +typedef interface IImageRender IImageRender; +#endif /* __IImageRender_FWD_DEFINED__ */ + + +/* header files for imported files */ +#include "oaidl.h" +#include "ocidl.h" + +void __RPC_FAR * __RPC_USER MIDL_user_allocate(size_t); +void __RPC_USER MIDL_user_free( void __RPC_FAR * ); + +#ifndef __IImageRender_INTERFACE_DEFINED__ +#define __IImageRender_INTERFACE_DEFINED__ + +/**************************************** + * Generated header for interface: IImageRender + * at Tue Feb 10 13:46:55 1998 + * using MIDL 3.01.75 + ****************************************/ +/* [unique][helpstring][uuid][object] */ + + + +EXTERN_C const IID IID_IImageRender; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + interface DECLSPEC_UUID("59032090-154B-11d1-A9BF-006097DE299B") + IImageRender : public IUnknown + { + public: + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Draw( + HDC hdc, + RECT __RPC_FAR *lpRect) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetBitmap( + HBITMAP __RPC_FAR *phBitmap, + BOOL fTake) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetOrigWidth( + int __RPC_FAR *piWidth) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetOrigHeight( + int __RPC_FAR *piHeight) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetBits( + unsigned char __RPC_FAR *__RPC_FAR *ppbBits) = 0; + + virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE ImageFail( + BOOL __RPC_FAR *pbFail) = 0; + + }; + +#else /* C style interface */ + + typedef struct IImageRenderVtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )( + IImageRender __RPC_FAR * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject); + + ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )( + IImageRender __RPC_FAR * This); + + ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )( + IImageRender __RPC_FAR * This); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Draw )( + IImageRender __RPC_FAR * This, + HDC hdc, + RECT __RPC_FAR *lpRect); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetBitmap )( + IImageRender __RPC_FAR * This, + HBITMAP __RPC_FAR *phBitmap, + BOOL fTake); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetOrigWidth )( + IImageRender __RPC_FAR * This, + int __RPC_FAR *piWidth); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetOrigHeight )( + IImageRender __RPC_FAR * This, + int __RPC_FAR *piHeight); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetBits )( + IImageRender __RPC_FAR * This, + unsigned char __RPC_FAR *__RPC_FAR *ppbBits); + + /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *ImageFail )( + IImageRender __RPC_FAR * This, + BOOL __RPC_FAR *pbFail); + + END_INTERFACE + } IImageRenderVtbl; + + interface IImageRender + { + CONST_VTBL struct IImageRenderVtbl __RPC_FAR *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define IImageRender_QueryInterface(This,riid,ppvObject) \ + (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) + +#define IImageRender_AddRef(This) \ + (This)->lpVtbl -> AddRef(This) + +#define IImageRender_Release(This) \ + (This)->lpVtbl -> Release(This) + + +#define IImageRender_Draw(This,hdc,lpRect) \ + (This)->lpVtbl -> Draw(This,hdc,lpRect) + +#define IImageRender_GetBitmap(This,phBitmap,fTake) \ + (This)->lpVtbl -> GetBitmap(This,phBitmap,fTake) + +#define IImageRender_GetOrigWidth(This,piWidth) \ + (This)->lpVtbl -> GetOrigWidth(This,piWidth) + +#define IImageRender_GetOrigHeight(This,piHeight) \ + (This)->lpVtbl -> GetOrigHeight(This,piHeight) + +#define IImageRender_GetBits(This,ppbBits) \ + (This)->lpVtbl -> GetBits(This,ppbBits) + +#define IImageRender_ImageFail(This,pbFail) \ + (This)->lpVtbl -> ImageFail(This,pbFail) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + +/* [helpstring] */ HRESULT STDMETHODCALLTYPE IImageRender_Draw_Proxy( + IImageRender __RPC_FAR * This, + HDC hdc, + RECT __RPC_FAR *lpRect); + + +void __RPC_STUB IImageRender_Draw_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring] */ HRESULT STDMETHODCALLTYPE IImageRender_GetBitmap_Proxy( + IImageRender __RPC_FAR * This, + HBITMAP __RPC_FAR *phBitmap, + BOOL fTake); + + +void __RPC_STUB IImageRender_GetBitmap_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring] */ HRESULT STDMETHODCALLTYPE IImageRender_GetOrigWidth_Proxy( + IImageRender __RPC_FAR * This, + int __RPC_FAR *piWidth); + + +void __RPC_STUB IImageRender_GetOrigWidth_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring] */ HRESULT STDMETHODCALLTYPE IImageRender_GetOrigHeight_Proxy( + IImageRender __RPC_FAR * This, + int __RPC_FAR *piHeight); + + +void __RPC_STUB IImageRender_GetOrigHeight_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring] */ HRESULT STDMETHODCALLTYPE IImageRender_GetBits_Proxy( + IImageRender __RPC_FAR * This, + unsigned char __RPC_FAR *__RPC_FAR *ppbBits); + + +void __RPC_STUB IImageRender_GetBits_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + +/* [helpstring] */ HRESULT STDMETHODCALLTYPE IImageRender_ImageFail_Proxy( + IImageRender __RPC_FAR * This, + BOOL __RPC_FAR *pbFail); + + +void __RPC_STUB IImageRender_ImageFail_Stub( + IRpcStubBuffer *This, + IRpcChannelBuffer *_pRpcChannelBuffer, + PRPC_MESSAGE _pRpcMessage, + DWORD *_pdwStubPhase); + + + +#endif /* __IImageRender_INTERFACE_DEFINED__ */ + + +/* Additional Prototypes for ALL interfaces */ + +unsigned long __RPC_USER HBITMAP_UserSize( unsigned long __RPC_FAR *, unsigned long , HBITMAP __RPC_FAR * ); +unsigned char __RPC_FAR * __RPC_USER HBITMAP_UserMarshal( unsigned long __RPC_FAR *, unsigned char __RPC_FAR *, HBITMAP __RPC_FAR * ); +unsigned char __RPC_FAR * __RPC_USER HBITMAP_UserUnmarshal(unsigned long __RPC_FAR *, unsigned char __RPC_FAR *, HBITMAP __RPC_FAR * ); +void __RPC_USER HBITMAP_UserFree( unsigned long __RPC_FAR *, HBITMAP __RPC_FAR * ); + +unsigned long __RPC_USER HDC_UserSize( unsigned long __RPC_FAR *, unsigned long , HDC __RPC_FAR * ); +unsigned char __RPC_FAR * __RPC_USER HDC_UserMarshal( unsigned long __RPC_FAR *, unsigned char __RPC_FAR *, HDC __RPC_FAR * ); +unsigned char __RPC_FAR * __RPC_USER HDC_UserUnmarshal(unsigned long __RPC_FAR *, unsigned char __RPC_FAR *, HDC __RPC_FAR * ); +void __RPC_USER HDC_UserFree( unsigned long __RPC_FAR *, HDC __RPC_FAR * ); + +/* end of Additional Prototypes */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/snes4iphone_src/input.c b/src/snes4iphone_src/input.c new file mode 100755 index 0000000..94e48d0 --- /dev/null +++ b/src/snes4iphone_src/input.c @@ -0,0 +1,173 @@ + +#include "menu.h" + +#if defined(__GP2X__) +#include "usbjoy.h" +static struct usbjoy *joys[4]; +static char joyCount = 0; +static int buttonMap[4][32]; +#endif + +struct INPUT Inp; +static int repeatCounter = 0; +int InputInit() +{ + memset(&Inp,0,sizeof(struct INPUT)); +#if defined(__GP2X__) +int i; + for (i=1; i<5; i++) + { + struct usbjoy *joy = joy_open(i); + if(joy != NULL) + { + joys[joyCount] = joy; + memset(buttonMap[joyCount],0,sizeof(buttonMap[joyCount])); + buttonMap[joyCount][0] = (1<numbuttons<10) + { + buttonMap[joyCount][6] = (1<=0x80) held&=0xbf; // Keep looping around + + Inp.held[i]=held; + } + + // Work out some key repeat values: + for (i=0;i<32;i++) + { + char rep=0; + int held=Inp.held[i]; + + if (held==1) + { + // Key has just been pressed again, so set repeat by default + rep=1; + } + else + { + // Now make sure key has been held for a period of time + // before auto toggling the repeat flag + if (held>=0x20) + { + repeatCounter++; + if(repeatCounter>15) + { + rep=1; + repeatCounter=0; + } + } + } + + Inp.repeat[i]=rep; + } + + return 0; +} diff --git a/src/snes4iphone_src/ioapi.c b/src/snes4iphone_src/ioapi.c new file mode 100755 index 0000000..7f20c18 --- /dev/null +++ b/src/snes4iphone_src/ioapi.c @@ -0,0 +1,177 @@ +/* ioapi.c -- IO base function header for compress/uncompress .zip + files using zlib + zip or unzip API + + Version 1.01e, February 12th, 2005 + + Copyright (C) 1998-2005 Gilles Vollant +*/ + +#include +#include +#include + +#include "zlib.h" +#include "ioapi.h" + + + +/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ + +#ifndef SEEK_CUR +#define SEEK_CUR 1 +#endif + +#ifndef SEEK_END +#define SEEK_END 2 +#endif + +#ifndef SEEK_SET +#define SEEK_SET 0 +#endif + +voidpf ZCALLBACK fopen_file_func OF(( + voidpf opaque, + const char* filename, + int mode)); + +uLong ZCALLBACK fread_file_func OF(( + voidpf opaque, + voidpf stream, + void* buf, + uLong size)); + +uLong ZCALLBACK fwrite_file_func OF(( + voidpf opaque, + voidpf stream, + const void* buf, + uLong size)); + +long ZCALLBACK ftell_file_func OF(( + voidpf opaque, + voidpf stream)); + +long ZCALLBACK fseek_file_func OF(( + voidpf opaque, + voidpf stream, + uLong offset, + int origin)); + +int ZCALLBACK fclose_file_func OF(( + voidpf opaque, + voidpf stream)); + +int ZCALLBACK ferror_file_func OF(( + voidpf opaque, + voidpf stream)); + + +voidpf ZCALLBACK fopen_file_func (opaque, filename, mode) + voidpf opaque; + const char* filename; + int mode; +{ + FILE* file = NULL; + const char* mode_fopen = NULL; + if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) + mode_fopen = "rb"; + else + if (mode & ZLIB_FILEFUNC_MODE_EXISTING) + mode_fopen = "r+b"; + else + if (mode & ZLIB_FILEFUNC_MODE_CREATE) + mode_fopen = "wb"; + + if ((filename!=NULL) && (mode_fopen != NULL)) + file = fopen(filename, mode_fopen); + return file; +} + + +uLong ZCALLBACK fread_file_func (opaque, stream, buf, size) + voidpf opaque; + voidpf stream; + void* buf; + uLong size; +{ + uLong ret; + ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream); + return ret; +} + + +uLong ZCALLBACK fwrite_file_func (opaque, stream, buf, size) + voidpf opaque; + voidpf stream; + const void* buf; + uLong size; +{ + uLong ret; + ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream); + return ret; +} + +long ZCALLBACK ftell_file_func (opaque, stream) + voidpf opaque; + voidpf stream; +{ + long ret; + ret = ftell((FILE *)stream); + return ret; +} + +long ZCALLBACK fseek_file_func (opaque, stream, offset, origin) + voidpf opaque; + voidpf stream; + uLong offset; + int origin; +{ + int fseek_origin=0; + long ret; + switch (origin) + { + case ZLIB_FILEFUNC_SEEK_CUR : + fseek_origin = SEEK_CUR; + break; + case ZLIB_FILEFUNC_SEEK_END : + fseek_origin = SEEK_END; + break; + case ZLIB_FILEFUNC_SEEK_SET : + fseek_origin = SEEK_SET; + break; + default: return -1; + } + ret = 0; + fseek((FILE *)stream, offset, fseek_origin); + return ret; +} + +int ZCALLBACK fclose_file_func (opaque, stream) + voidpf opaque; + voidpf stream; +{ + int ret; + ret = fclose((FILE *)stream); + return ret; +} + +int ZCALLBACK ferror_file_func (opaque, stream) + voidpf opaque; + voidpf stream; +{ + int ret; + ret = ferror((FILE *)stream); + return ret; +} + +void fill_fopen_filefunc (pzlib_filefunc_def) + zlib_filefunc_def* pzlib_filefunc_def; +{ + pzlib_filefunc_def->zopen_file = fopen_file_func; + pzlib_filefunc_def->zread_file = fread_file_func; + pzlib_filefunc_def->zwrite_file = fwrite_file_func; + pzlib_filefunc_def->ztell_file = ftell_file_func; + pzlib_filefunc_def->zseek_file = fseek_file_func; + pzlib_filefunc_def->zclose_file = fclose_file_func; + pzlib_filefunc_def->zerror_file = ferror_file_func; + pzlib_filefunc_def->opaque = NULL; +} diff --git a/src/snes4iphone_src/ioapi.h b/src/snes4iphone_src/ioapi.h new file mode 100755 index 0000000..e73a3b2 --- /dev/null +++ b/src/snes4iphone_src/ioapi.h @@ -0,0 +1,75 @@ +/* ioapi.h -- IO base function header for compress/uncompress .zip + files using zlib + zip or unzip API + + Version 1.01e, February 12th, 2005 + + Copyright (C) 1998-2005 Gilles Vollant +*/ + +#ifndef _ZLIBIOAPI_H +#define _ZLIBIOAPI_H + + +#define ZLIB_FILEFUNC_SEEK_CUR (1) +#define ZLIB_FILEFUNC_SEEK_END (2) +#define ZLIB_FILEFUNC_SEEK_SET (0) + +#define ZLIB_FILEFUNC_MODE_READ (1) +#define ZLIB_FILEFUNC_MODE_WRITE (2) +#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3) + +#define ZLIB_FILEFUNC_MODE_EXISTING (4) +#define ZLIB_FILEFUNC_MODE_CREATE (8) + + +#ifndef ZCALLBACK + +#if (defined(WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK) +#define ZCALLBACK CALLBACK +#else +#define ZCALLBACK +#endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode)); +typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size)); +typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size)); +typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream)); +typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin)); +typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream)); +typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream)); + +typedef struct zlib_filefunc_def_s +{ + open_file_func zopen_file; + read_file_func zread_file; + write_file_func zwrite_file; + tell_file_func ztell_file; + seek_file_func zseek_file; + close_file_func zclose_file; + testerror_file_func zerror_file; + voidpf opaque; +} zlib_filefunc_def; + + + +void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def)); + +#define ZREAD(filefunc,filestream,buf,size) ((*((filefunc).zread_file))((filefunc).opaque,filestream,buf,size)) +#define ZWRITE(filefunc,filestream,buf,size) ((*((filefunc).zwrite_file))((filefunc).opaque,filestream,buf,size)) +#define ZTELL(filefunc,filestream) ((*((filefunc).ztell_file))((filefunc).opaque,filestream)) +#define ZSEEK(filefunc,filestream,pos,mode) ((*((filefunc).zseek_file))((filefunc).opaque,filestream,pos,mode)) +#define ZCLOSE(filefunc,filestream) ((*((filefunc).zclose_file))((filefunc).opaque,filestream)) +#define ZERROR(filefunc,filestream) ((*((filefunc).zerror_file))((filefunc).opaque,filestream)) + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/src/snes4iphone_src/iphone_highlightbar.c b/src/snes4iphone_src/iphone_highlightbar.c new file mode 100755 index 0000000..5ef8da8 --- /dev/null +++ b/src/snes4iphone_src/iphone_highlightbar.c @@ -0,0 +1,341 @@ +///////////////////////////////////////// +// +// Header file for GP32 +// +// convertion of highlightbar.bmp file : +// Width = 16 +// Heigth = 320 +// GP32 Mode = 16 Bits per Pixel +// +// with GP32Converter coded by Edorul : +// http://www.ifrance.com/edorul/ +// edorul@free.fr +// +///////////////////////////////////////// + +#define highlightbar_width 320 +#define highlightbar_height 16 +unsigned short highLightBar[5120]; +unsigned short highLightBarOrig[5120] = { + 0xFFCA, 0xFFCA, 0xFFCA, 0xFFCC, 0xFFCC, 0xFFCC, 0xFFCC, 0xFFCC, 0xFFCC, 0xFFCC, 0xFF8C, 0xFF8C, 0xFF8C, 0xFF8C, 0xFF8C, 0xFF8C, + 0xFF8C, 0xFF8C, 0xFF4C, 0xFF4C, 0xFF4C, 0xFF4E, 0xFF4E, 0xFF4E, 0xFF4E, 0xFF4E, 0xFF4E, 0xFF0E, 0xFF0E, 0xFF0E, 0xFF0E, 0xFF0E, + 0xFF0E, 0xFF0E, 0xFF0E, 0xFF0E, 0xFF0E, 0xFECE, 0xFECE, 0xFED0, 0xFED0, 0xFED0, 0xFED0, 0xFED0, 0xFED0, 0xFED0, 0xFE90, 0xFE90, + 0xFE90, 0xFE90, 0xFE90, 0xFE90, 0xFE90, 0xFE90, 0xFE90, 0xFE50, 0xFE50, 0xFE52, 0xFE52, 0xFE52, 0xFE52, 0xFE52, 0xFE52, 0xFE52, + 0xFE12, 0xFE12, 0xFE12, 0xFE12, 0xFE12, 0xFE12, 0xFE12, 0xFE12, 0xFE12, 0xFE14, 0xFDD4, 0xFDD4, 0xFDD4, 0xFDD4, 0xFDD4, 0xFDD4, + 0xFDD4, 0xFDD4, 0xFDD4, 0xFD94, 0xFD94, 0xFD94, 0xFD94, 0xFD94, 0xFD94, 0xFD94, 0xFD94, 0xFD96, 0xFD56, 0xFD56, 0xFD56, 0xFD56, + 0xFD56, 0xFD56, 0xFD56, 0xFD56, 0xFD56, 0xFD16, 0xFD16, 0xFD16, 0xFD16, 0xFD16, 0xFD16, 0xFD16, 0xFD16, 0xFD18, 0xFD18, 0xFCD8, + 0xFCD8, 0xFCD8, 0xFCD8, 0xFCD8, 0xFCD8, 0xFCD8, 0xFCD8, 0xFCD8, 0xFC98, 0xFC98, 0xFC96, 0xFC96, 0xFC96, 0xFC96, 0xFC96, 0xFC96, + 0xFC56, 0xFC56, 0xFC56, 0xFC56, 0xFC56, 0xFC56, 0xFC56, 0xFC56, 0xFC16, 0xFC16, 0xFC16, 0xFC16, 0xFC14, 0xFC14, 0xFC14, 0xFC14, + 0xFC14, 0xFBD4, 0xFBD4, 0xFBD4, 0xFBD4, 0xFBD4, 0xFBD4, 0xFBD4, 0xFBD4, 0xFB94, 0xFB94, 0xFB94, 0xFB94, 0xFB94, 0xFB92, 0xFB92, + 0xFB92, 0xFB92, 0xFB52, 0xFB52, 0xFB52, 0xFB52, 0xFB52, 0xFB52, 0xFB52, 0xFB52, 0xFB12, 0xFB12, 0xFB12, 0xFB12, 0xFB10, 0xFB10, + 0xFB10, 0xFB10, 0xFAD0, 0xFAD0, 0xFAD0, 0xFAD0, 0xFAD0, 0xFAD0, 0xFAD0, 0xFAD0, 0xFAD0, 0xFA90, 0xFA90, 0xFA90, 0xFA90, 0xFA90, + 0xFA8E, 0xFA8E, 0xFA8E, 0xFA8E, 0xFA4E, 0xFA4E, 0xFA4E, 0xFA4E, 0xFA4E, 0xFA4E, 0xFA4E, 0xFA4E, 0xFA0E, 0xFA0E, 0xFA0E, 0xFA0E, + 0xFA0E, 0xFA0E, 0xFA0C, 0xFA0C, 0xF9CC, 0xF9CC, 0xF9CC, 0xF9CC, 0xF9CC, 0xF9CC, 0xF9CC, 0xF9CC, 0xF9CC, 0xF98C, 0xF98C, 0xF98C, + 0xF98C, 0xF98C, 0xF98C, 0xF98C, 0xF98A, 0xF98A, 0xF94A, 0xF94A, 0xF94A, 0xF94A, 0xF94A, 0xF94A, 0xF94A, 0xF94A, 0xF14A, 0xF14A, + 0xF14A, 0xF14A, 0xF14A, 0xF14A, 0xF14A, 0xF14A, 0xE94A, 0xE94A, 0xE94A, 0xE94A, 0xE94A, 0xE94A, 0xE94A, 0xE94A, 0xE14A, 0xE14A, + 0xE14A, 0xE14A, 0xE14A, 0xE14A, 0xE14A, 0xE14A, 0xD94A, 0xD94A, 0xD94A, 0xD94A, 0xD94A, 0xD94A, 0xD94A, 0xD14A, 0xD14A, 0xD14A, + 0xD14A, 0xD14A, 0xD14A, 0xD14A, 0xD14A, 0xC94A, 0xC94A, 0xC94A, 0xC94A, 0xC94A, 0xC94A, 0xC94A, 0xC94A, 0xC14A, 0xC14A, 0xC14A, + 0xC14A, 0xC14A, 0xC14A, 0xC14A, 0xC14A, 0xC14A, 0xB94A, 0xB94A, 0xB94A, 0xB94A, 0xB94A, 0xB94A, 0xB94A, 0xB94A, 0xB94A, 0xB14A, + 0xB14A, 0xB14A, 0xB14A, 0xB14A, 0xB14A, 0xB14A, 0xB14A, 0xB14A, 0xA94A, 0xA94A, 0xA94A, 0xA94A, 0xA94A, 0xA94A, 0xA94A, 0xA94A, + 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF82, 0xFF42, + 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF04, 0xFF04, 0xFEC4, 0xFEC4, + 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE86, 0xFE86, 0xFE46, 0xFE46, 0xFE46, + 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE06, 0xFE06, 0xFE06, 0xFE06, 0xFE08, 0xFE08, 0xFE08, 0xFE08, 0xFDC8, 0xFDC8, 0xFDC8, + 0xFDC8, 0xFDC8, 0xFDC8, 0xFDC8, 0xFD88, 0xFD88, 0xFD88, 0xFD88, 0xFD8A, 0xFD8A, 0xFD8A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, + 0xFD4A, 0xFD4A, 0xFD4A, 0xFD0A, 0xFD0A, 0xFD0A, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, + 0xFCCC, 0xFCCC, 0xFC8C, 0xFC8C, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, + 0xFC4E, 0xFC0E, 0xFC0E, 0xFC10, 0xFC10, 0xFC0E, 0xFC0E, 0xFC0E, 0xFC0E, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFB8E, + 0xFB8E, 0xFB8E, 0xFB8E, 0xFB8C, 0xFB8C, 0xFB8C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB0C, 0xFB0C, 0xFB0C, + 0xFB0C, 0xFB0A, 0xFB0A, 0xFB0A, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, + 0xFA88, 0xFA88, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA06, 0xFA06, + 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF984, 0xF944, 0xF944, + 0xF944, 0xF944, 0xF944, 0xF944, 0xF944, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF902, 0xF8C2, 0xF8C2, 0xF8C2, 0xF8C2, + 0xF8C2, 0xF8C2, 0xF8C2, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, + 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF000, 0xF000, 0xF000, + 0xF000, 0xF000, 0xF000, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, + 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xC800, 0xC800, 0xC800, + 0xC800, 0xC800, 0xC800, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, + 0xB800, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA000, + 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9000, 0x9000, + 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF82, 0xFF42, + 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF04, 0xFF04, 0xFEC4, 0xFEC4, + 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE86, 0xFE86, 0xFE46, 0xFE46, 0xFE46, + 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE06, 0xFE06, 0xFE06, 0xFE06, 0xFE08, 0xFE08, 0xFE08, 0xFE08, 0xFDC8, 0xFDC8, 0xFDC8, + 0xFDC8, 0xFDC8, 0xFDC8, 0xFDC8, 0xFD88, 0xFD88, 0xFD88, 0xFD88, 0xFD8A, 0xFD8A, 0xFD8A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, + 0xFD4A, 0xFD4A, 0xFD4A, 0xFD0A, 0xFD0A, 0xFD0A, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, + 0xFCCC, 0xFCCC, 0xFC8C, 0xFC8C, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, + 0xFC4E, 0xFC0E, 0xFC0E, 0xFC10, 0xFC10, 0xFC0E, 0xFC0E, 0xFC0E, 0xFC0E, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFB8E, + 0xFB8E, 0xFB8E, 0xFB8E, 0xFB8C, 0xFB8C, 0xFB8C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB0C, 0xFB0C, 0xFB0C, + 0xFB0C, 0xFB0A, 0xFB0A, 0xFB0A, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, + 0xFA88, 0xFA88, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA06, 0xFA06, + 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF984, 0xF944, 0xF944, + 0xF944, 0xF944, 0xF944, 0xF944, 0xF944, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF902, 0xF8C2, 0xF8C2, 0xF8C2, 0xF8C2, + 0xF8C2, 0xF8C2, 0xF8C2, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, + 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF000, 0xF000, 0xF000, + 0xF000, 0xF000, 0xF000, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, + 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xC800, 0xC800, 0xC800, + 0xC800, 0xC800, 0xC800, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, + 0xB800, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA000, + 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9000, 0x9000, + 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF82, 0xFF42, + 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF04, 0xFF04, 0xFEC4, 0xFEC4, + 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE86, 0xFE86, 0xFE46, 0xFE46, 0xFE46, + 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE06, 0xFE06, 0xFE06, 0xFE06, 0xFE08, 0xFE08, 0xFE08, 0xFE08, 0xFDC8, 0xFDC8, 0xFDC8, + 0xFDC8, 0xFDC8, 0xFDC8, 0xFDC8, 0xFD88, 0xFD88, 0xFD88, 0xFD88, 0xFD8A, 0xFD8A, 0xFD8A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, + 0xFD4A, 0xFD4A, 0xFD4A, 0xFD0A, 0xFD0A, 0xFD0A, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, + 0xFCCC, 0xFCCC, 0xFC8C, 0xFC8C, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, + 0xFC4E, 0xFC0E, 0xFC0E, 0xFC10, 0xFC10, 0xFC0E, 0xFC0E, 0xFC0E, 0xFC0E, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFB8E, + 0xFB8E, 0xFB8E, 0xFB8E, 0xFB8C, 0xFB8C, 0xFB8C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB0C, 0xFB0C, 0xFB0C, + 0xFB0C, 0xFB0A, 0xFB0A, 0xFB0A, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, + 0xFA88, 0xFA88, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA06, 0xFA06, + 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF984, 0xF944, 0xF944, + 0xF944, 0xF944, 0xF944, 0xF944, 0xF944, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF902, 0xF8C2, 0xF8C2, 0xF8C2, 0xF8C2, + 0xF8C2, 0xF8C2, 0xF8C2, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, + 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF000, 0xF000, 0xF000, + 0xF000, 0xF000, 0xF000, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, + 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xC800, 0xC800, 0xC800, + 0xC800, 0xC800, 0xC800, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, + 0xB800, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA000, + 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9000, 0x9000, + 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF82, 0xFF42, + 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF04, 0xFF04, 0xFEC4, 0xFEC4, + 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE86, 0xFE86, 0xFE46, 0xFE46, 0xFE46, + 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE06, 0xFE06, 0xFE06, 0xFE06, 0xFE08, 0xFE08, 0xFE08, 0xFE08, 0xFDC8, 0xFDC8, 0xFDC8, + 0xFDC8, 0xFDC8, 0xFDC8, 0xFDC8, 0xFD88, 0xFD88, 0xFD88, 0xFD88, 0xFD8A, 0xFD8A, 0xFD8A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, + 0xFD4A, 0xFD4A, 0xFD4A, 0xFD0A, 0xFD0A, 0xFD0A, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, + 0xFCCC, 0xFCCC, 0xFC8C, 0xFC8C, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, + 0xFC4E, 0xFC0E, 0xFC0E, 0xFC10, 0xFC10, 0xFC0E, 0xFC0E, 0xFC0E, 0xFC0E, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFB8E, + 0xFB8E, 0xFB8E, 0xFB8E, 0xFB8C, 0xFB8C, 0xFB8C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB0C, 0xFB0C, 0xFB0C, + 0xFB0C, 0xFB0A, 0xFB0A, 0xFB0A, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, + 0xFA88, 0xFA88, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA06, 0xFA06, + 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF984, 0xF944, 0xF944, + 0xF944, 0xF944, 0xF944, 0xF944, 0xF944, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF902, 0xF8C2, 0xF8C2, 0xF8C2, 0xF8C2, + 0xF8C2, 0xF8C2, 0xF8C2, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, + 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF000, 0xF000, 0xF000, + 0xF000, 0xF000, 0xF000, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, + 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xC800, 0xC800, 0xC800, + 0xC800, 0xC800, 0xC800, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, + 0xB800, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA000, + 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9000, 0x9000, + 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF82, 0xFF42, + 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF04, 0xFF04, 0xFEC4, 0xFEC4, + 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE86, 0xFE86, 0xFE46, 0xFE46, 0xFE46, + 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE06, 0xFE06, 0xFE06, 0xFE06, 0xFE08, 0xFE08, 0xFE08, 0xFE08, 0xFDC8, 0xFDC8, 0xFDC8, + 0xFDC8, 0xFDC8, 0xFDC8, 0xFDC8, 0xFD88, 0xFD88, 0xFD88, 0xFD88, 0xFD8A, 0xFD8A, 0xFD8A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, + 0xFD4A, 0xFD4A, 0xFD4A, 0xFD0A, 0xFD0A, 0xFD0A, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, + 0xFCCC, 0xFCCC, 0xFC8C, 0xFC8C, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, + 0xFC4E, 0xFC0E, 0xFC0E, 0xFC10, 0xFC10, 0xFC0E, 0xFC0E, 0xFC0E, 0xFC0E, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFB8E, + 0xFB8E, 0xFB8E, 0xFB8E, 0xFB8C, 0xFB8C, 0xFB8C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB0C, 0xFB0C, 0xFB0C, + 0xFB0C, 0xFB0A, 0xFB0A, 0xFB0A, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, + 0xFA88, 0xFA88, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA06, 0xFA06, + 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF984, 0xF944, 0xF944, + 0xF944, 0xF944, 0xF944, 0xF944, 0xF944, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF902, 0xF8C2, 0xF8C2, 0xF8C2, 0xF8C2, + 0xF8C2, 0xF8C2, 0xF8C2, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, + 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF000, 0xF000, 0xF000, + 0xF000, 0xF000, 0xF000, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, + 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xC800, 0xC800, 0xC800, + 0xC800, 0xC800, 0xC800, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, + 0xB800, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA000, + 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9000, 0x9000, + 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF82, 0xFF42, + 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF04, 0xFF04, 0xFEC4, 0xFEC4, + 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE86, 0xFE86, 0xFE46, 0xFE46, 0xFE46, + 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE06, 0xFE06, 0xFE06, 0xFE06, 0xFE08, 0xFE08, 0xFE08, 0xFE08, 0xFDC8, 0xFDC8, 0xFDC8, + 0xFDC8, 0xFDC8, 0xFDC8, 0xFDC8, 0xFD88, 0xFD88, 0xFD88, 0xFD88, 0xFD8A, 0xFD8A, 0xFD8A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, + 0xFD4A, 0xFD4A, 0xFD4A, 0xFD0A, 0xFD0A, 0xFD0A, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, + 0xFCCC, 0xFCCC, 0xFC8C, 0xFC8C, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, + 0xFC4E, 0xFC0E, 0xFC0E, 0xFC10, 0xFC10, 0xFC0E, 0xFC0E, 0xFC0E, 0xFC0E, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFB8E, + 0xFB8E, 0xFB8E, 0xFB8E, 0xFB8C, 0xFB8C, 0xFB8C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB0C, 0xFB0C, 0xFB0C, + 0xFB0C, 0xFB0A, 0xFB0A, 0xFB0A, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, + 0xFA88, 0xFA88, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA06, 0xFA06, + 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF984, 0xF944, 0xF944, + 0xF944, 0xF944, 0xF944, 0xF944, 0xF944, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF902, 0xF8C2, 0xF8C2, 0xF8C2, 0xF8C2, + 0xF8C2, 0xF8C2, 0xF8C2, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, + 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF000, 0xF000, 0xF000, + 0xF000, 0xF000, 0xF000, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, + 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xC800, 0xC800, 0xC800, + 0xC800, 0xC800, 0xC800, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, + 0xB800, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA000, + 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9000, 0x9000, + 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF82, 0xFF42, + 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF04, 0xFF04, 0xFEC4, 0xFEC4, + 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE86, 0xFE86, 0xFE46, 0xFE46, 0xFE46, + 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE06, 0xFE06, 0xFE06, 0xFE06, 0xFE08, 0xFE08, 0xFE08, 0xFE08, 0xFDC8, 0xFDC8, 0xFDC8, + 0xFDC8, 0xFDC8, 0xFDC8, 0xFDC8, 0xFD88, 0xFD88, 0xFD88, 0xFD88, 0xFD8A, 0xFD8A, 0xFD8A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, + 0xFD4A, 0xFD4A, 0xFD4A, 0xFD0A, 0xFD0A, 0xFD0A, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, + 0xFCCC, 0xFCCC, 0xFC8C, 0xFC8C, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, + 0xFC4E, 0xFC0E, 0xFC0E, 0xFC10, 0xFC10, 0xFC0E, 0xFC0E, 0xFC0E, 0xFC0E, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFB8E, + 0xFB8E, 0xFB8E, 0xFB8E, 0xFB8C, 0xFB8C, 0xFB8C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB0C, 0xFB0C, 0xFB0C, + 0xFB0C, 0xFB0A, 0xFB0A, 0xFB0A, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, + 0xFA88, 0xFA88, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA06, 0xFA06, + 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF984, 0xF944, 0xF944, + 0xF944, 0xF944, 0xF944, 0xF944, 0xF944, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF902, 0xF8C2, 0xF8C2, 0xF8C2, 0xF8C2, + 0xF8C2, 0xF8C2, 0xF8C2, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, + 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF000, 0xF000, 0xF000, + 0xF000, 0xF000, 0xF000, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, + 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xC800, 0xC800, 0xC800, + 0xC800, 0xC800, 0xC800, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, + 0xB800, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA000, + 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9000, 0x9000, + 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF82, 0xFF42, + 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF04, 0xFF04, 0xFEC4, 0xFEC4, + 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE86, 0xFE86, 0xFE46, 0xFE46, 0xFE46, + 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE06, 0xFE06, 0xFE06, 0xFE06, 0xFE08, 0xFE08, 0xFE08, 0xFE08, 0xFDC8, 0xFDC8, 0xFDC8, + 0xFDC8, 0xFDC8, 0xFDC8, 0xFDC8, 0xFD88, 0xFD88, 0xFD88, 0xFD88, 0xFD8A, 0xFD8A, 0xFD8A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, + 0xFD4A, 0xFD4A, 0xFD4A, 0xFD0A, 0xFD0A, 0xFD0A, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, + 0xFCCC, 0xFCCC, 0xFC8C, 0xFC8C, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, + 0xFC4E, 0xFC0E, 0xFC0E, 0xFC10, 0xFC10, 0xFC0E, 0xFC0E, 0xFC0E, 0xFC0E, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFB8E, + 0xFB8E, 0xFB8E, 0xFB8E, 0xFB8C, 0xFB8C, 0xFB8C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB0C, 0xFB0C, 0xFB0C, + 0xFB0C, 0xFB0A, 0xFB0A, 0xFB0A, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, + 0xFA88, 0xFA88, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA06, 0xFA06, + 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF984, 0xF944, 0xF944, + 0xF944, 0xF944, 0xF944, 0xF944, 0xF944, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF902, 0xF8C2, 0xF8C2, 0xF8C2, 0xF8C2, + 0xF8C2, 0xF8C2, 0xF8C2, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, + 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF000, 0xF000, 0xF000, + 0xF000, 0xF000, 0xF000, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, + 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xC800, 0xC800, 0xC800, + 0xC800, 0xC800, 0xC800, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, + 0xB800, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA000, + 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9000, 0x9000, + 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF82, 0xFF42, + 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF04, 0xFF04, 0xFEC4, 0xFEC4, + 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE86, 0xFE86, 0xFE46, 0xFE46, 0xFE46, + 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE06, 0xFE06, 0xFE06, 0xFE06, 0xFE08, 0xFE08, 0xFE08, 0xFE08, 0xFDC8, 0xFDC8, 0xFDC8, + 0xFDC8, 0xFDC8, 0xFDC8, 0xFDC8, 0xFD88, 0xFD88, 0xFD88, 0xFD88, 0xFD8A, 0xFD8A, 0xFD8A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, + 0xFD4A, 0xFD4A, 0xFD4A, 0xFD0A, 0xFD0A, 0xFD0A, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, + 0xFCCC, 0xFCCC, 0xFC8C, 0xFC8C, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, + 0xFC4E, 0xFC0E, 0xFC0E, 0xFC10, 0xFC10, 0xFC0E, 0xFC0E, 0xFC0E, 0xFC0E, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFB8E, + 0xFB8E, 0xFB8E, 0xFB8E, 0xFB8C, 0xFB8C, 0xFB8C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB0C, 0xFB0C, 0xFB0C, + 0xFB0C, 0xFB0A, 0xFB0A, 0xFB0A, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, + 0xFA88, 0xFA88, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA06, 0xFA06, + 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF984, 0xF944, 0xF944, + 0xF944, 0xF944, 0xF944, 0xF944, 0xF944, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF902, 0xF8C2, 0xF8C2, 0xF8C2, 0xF8C2, + 0xF8C2, 0xF8C2, 0xF8C2, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, + 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF000, 0xF000, 0xF000, + 0xF000, 0xF000, 0xF000, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, + 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xC800, 0xC800, 0xC800, + 0xC800, 0xC800, 0xC800, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, + 0xB800, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA000, + 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9000, 0x9000, + 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF82, 0xFF42, + 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF04, 0xFF04, 0xFEC4, 0xFEC4, + 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE86, 0xFE86, 0xFE46, 0xFE46, 0xFE46, + 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE06, 0xFE06, 0xFE06, 0xFE06, 0xFE08, 0xFE08, 0xFE08, 0xFE08, 0xFDC8, 0xFDC8, 0xFDC8, + 0xFDC8, 0xFDC8, 0xFDC8, 0xFDC8, 0xFD88, 0xFD88, 0xFD88, 0xFD88, 0xFD8A, 0xFD8A, 0xFD8A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, + 0xFD4A, 0xFD4A, 0xFD4A, 0xFD0A, 0xFD0A, 0xFD0A, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, + 0xFCCC, 0xFCCC, 0xFC8C, 0xFC8C, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, + 0xFC4E, 0xFC0E, 0xFC0E, 0xFC10, 0xFC10, 0xFC0E, 0xFC0E, 0xFC0E, 0xFC0E, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFB8E, + 0xFB8E, 0xFB8E, 0xFB8E, 0xFB8C, 0xFB8C, 0xFB8C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB0C, 0xFB0C, 0xFB0C, + 0xFB0C, 0xFB0A, 0xFB0A, 0xFB0A, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, + 0xFA88, 0xFA88, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA06, 0xFA06, + 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF984, 0xF944, 0xF944, + 0xF944, 0xF944, 0xF944, 0xF944, 0xF944, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF902, 0xF8C2, 0xF8C2, 0xF8C2, 0xF8C2, + 0xF8C2, 0xF8C2, 0xF8C2, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, + 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF000, 0xF000, 0xF000, + 0xF000, 0xF000, 0xF000, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, + 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xC800, 0xC800, 0xC800, + 0xC800, 0xC800, 0xC800, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, + 0xB800, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA000, + 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9000, 0x9000, + 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF82, 0xFF42, + 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF04, 0xFF04, 0xFEC4, 0xFEC4, + 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE86, 0xFE86, 0xFE46, 0xFE46, 0xFE46, + 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE06, 0xFE06, 0xFE06, 0xFE06, 0xFE08, 0xFE08, 0xFE08, 0xFE08, 0xFDC8, 0xFDC8, 0xFDC8, + 0xFDC8, 0xFDC8, 0xFDC8, 0xFDC8, 0xFD88, 0xFD88, 0xFD88, 0xFD88, 0xFD8A, 0xFD8A, 0xFD8A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, + 0xFD4A, 0xFD4A, 0xFD4A, 0xFD0A, 0xFD0A, 0xFD0A, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, + 0xFCCC, 0xFCCC, 0xFC8C, 0xFC8C, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, + 0xFC4E, 0xFC0E, 0xFC0E, 0xFC10, 0xFC10, 0xFC0E, 0xFC0E, 0xFC0E, 0xFC0E, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFB8E, + 0xFB8E, 0xFB8E, 0xFB8E, 0xFB8C, 0xFB8C, 0xFB8C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB0C, 0xFB0C, 0xFB0C, + 0xFB0C, 0xFB0A, 0xFB0A, 0xFB0A, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, + 0xFA88, 0xFA88, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA06, 0xFA06, + 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF984, 0xF944, 0xF944, + 0xF944, 0xF944, 0xF944, 0xF944, 0xF944, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF902, 0xF8C2, 0xF8C2, 0xF8C2, 0xF8C2, + 0xF8C2, 0xF8C2, 0xF8C2, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, + 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF000, 0xF000, 0xF000, + 0xF000, 0xF000, 0xF000, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, + 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xC800, 0xC800, 0xC800, + 0xC800, 0xC800, 0xC800, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, + 0xB800, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA000, + 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9000, 0x9000, + 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF82, 0xFF42, + 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF04, 0xFF04, 0xFEC4, 0xFEC4, + 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE86, 0xFE86, 0xFE46, 0xFE46, 0xFE46, + 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE06, 0xFE06, 0xFE06, 0xFE06, 0xFE08, 0xFE08, 0xFE08, 0xFE08, 0xFDC8, 0xFDC8, 0xFDC8, + 0xFDC8, 0xFDC8, 0xFDC8, 0xFDC8, 0xFD88, 0xFD88, 0xFD88, 0xFD88, 0xFD8A, 0xFD8A, 0xFD8A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, + 0xFD4A, 0xFD4A, 0xFD4A, 0xFD0A, 0xFD0A, 0xFD0A, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, + 0xFCCC, 0xFCCC, 0xFC8C, 0xFC8C, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, + 0xFC4E, 0xFC0E, 0xFC0E, 0xFC10, 0xFC10, 0xFC0E, 0xFC0E, 0xFC0E, 0xFC0E, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFB8E, + 0xFB8E, 0xFB8E, 0xFB8E, 0xFB8C, 0xFB8C, 0xFB8C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB0C, 0xFB0C, 0xFB0C, + 0xFB0C, 0xFB0A, 0xFB0A, 0xFB0A, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, + 0xFA88, 0xFA88, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA06, 0xFA06, + 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF984, 0xF944, 0xF944, + 0xF944, 0xF944, 0xF944, 0xF944, 0xF944, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF902, 0xF8C2, 0xF8C2, 0xF8C2, 0xF8C2, + 0xF8C2, 0xF8C2, 0xF8C2, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, + 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF000, 0xF000, 0xF000, + 0xF000, 0xF000, 0xF000, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, + 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xC800, 0xC800, 0xC800, + 0xC800, 0xC800, 0xC800, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, + 0xB800, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA000, + 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9000, 0x9000, + 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF82, 0xFF42, + 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF04, 0xFF04, 0xFEC4, 0xFEC4, + 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE86, 0xFE86, 0xFE46, 0xFE46, 0xFE46, + 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE06, 0xFE06, 0xFE06, 0xFE06, 0xFE08, 0xFE08, 0xFE08, 0xFE08, 0xFDC8, 0xFDC8, 0xFDC8, + 0xFDC8, 0xFDC8, 0xFDC8, 0xFDC8, 0xFD88, 0xFD88, 0xFD88, 0xFD88, 0xFD8A, 0xFD8A, 0xFD8A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, + 0xFD4A, 0xFD4A, 0xFD4A, 0xFD0A, 0xFD0A, 0xFD0A, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, + 0xFCCC, 0xFCCC, 0xFC8C, 0xFC8C, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, + 0xFC4E, 0xFC0E, 0xFC0E, 0xFC10, 0xFC10, 0xFC0E, 0xFC0E, 0xFC0E, 0xFC0E, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFB8E, + 0xFB8E, 0xFB8E, 0xFB8E, 0xFB8C, 0xFB8C, 0xFB8C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB0C, 0xFB0C, 0xFB0C, + 0xFB0C, 0xFB0A, 0xFB0A, 0xFB0A, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, + 0xFA88, 0xFA88, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA06, 0xFA06, + 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF984, 0xF944, 0xF944, + 0xF944, 0xF944, 0xF944, 0xF944, 0xF944, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF902, 0xF8C2, 0xF8C2, 0xF8C2, 0xF8C2, + 0xF8C2, 0xF8C2, 0xF8C2, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, + 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF000, 0xF000, 0xF000, + 0xF000, 0xF000, 0xF000, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, + 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xC800, 0xC800, 0xC800, + 0xC800, 0xC800, 0xC800, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, + 0xB800, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA000, + 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9000, 0x9000, + 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFFC0, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF80, 0xFF82, 0xFF42, + 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF42, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF02, 0xFF04, 0xFF04, 0xFEC4, 0xFEC4, + 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFEC4, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE84, 0xFE86, 0xFE86, 0xFE46, 0xFE46, 0xFE46, + 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE46, 0xFE06, 0xFE06, 0xFE06, 0xFE06, 0xFE08, 0xFE08, 0xFE08, 0xFE08, 0xFDC8, 0xFDC8, 0xFDC8, + 0xFDC8, 0xFDC8, 0xFDC8, 0xFDC8, 0xFD88, 0xFD88, 0xFD88, 0xFD88, 0xFD8A, 0xFD8A, 0xFD8A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, 0xFD4A, + 0xFD4A, 0xFD4A, 0xFD4A, 0xFD0A, 0xFD0A, 0xFD0A, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFD0C, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, 0xFCCC, + 0xFCCC, 0xFCCC, 0xFC8C, 0xFC8C, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC8E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, 0xFC4E, + 0xFC4E, 0xFC0E, 0xFC0E, 0xFC10, 0xFC10, 0xFC0E, 0xFC0E, 0xFC0E, 0xFC0E, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFBCE, 0xFB8E, + 0xFB8E, 0xFB8E, 0xFB8E, 0xFB8C, 0xFB8C, 0xFB8C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB4C, 0xFB0C, 0xFB0C, 0xFB0C, + 0xFB0C, 0xFB0A, 0xFB0A, 0xFB0A, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFACA, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, 0xFA8A, + 0xFA88, 0xFA88, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA48, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA08, 0xFA06, 0xFA06, + 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF9C6, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF986, 0xF984, 0xF944, 0xF944, + 0xF944, 0xF944, 0xF944, 0xF944, 0xF944, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF904, 0xF902, 0xF8C2, 0xF8C2, 0xF8C2, 0xF8C2, + 0xF8C2, 0xF8C2, 0xF8C2, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF882, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, 0xF840, + 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF000, 0xF000, 0xF000, + 0xF000, 0xF000, 0xF000, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE800, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, 0xE000, + 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD800, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xC800, 0xC800, 0xC800, + 0xC800, 0xC800, 0xC800, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, + 0xB800, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA000, + 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9000, 0x9000, + 0xD680, 0xD680, 0xD640, 0xD640, 0xD640, 0xD640, 0xD640, 0xD640, 0xD640, 0xD640, 0xD640, 0xD600, 0xD600, 0xD600, 0xD600, 0xD600, + 0xD600, 0xD600, 0xD602, 0xD602, 0xD602, 0xD5C2, 0xD5C2, 0xD5C2, 0xD5C2, 0xD5C2, 0xD5C2, 0xD5C2, 0xD5C2, 0xD5C2, 0xD582, 0xD582, + 0xD582, 0xD582, 0xD584, 0xD584, 0xD584, 0xD584, 0xD584, 0xD544, 0xD544, 0xD544, 0xD544, 0xD544, 0xD544, 0xD544, 0xD544, 0xD544, + 0xD504, 0xD504, 0xD504, 0xD504, 0xD506, 0xD506, 0xD506, 0xD506, 0xD506, 0xD506, 0xD4C6, 0xD4C6, 0xD4C6, 0xD4C6, 0xD4C6, 0xD4C6, + 0xD4C6, 0xD4C6, 0xD4C6, 0xD486, 0xD486, 0xD486, 0xD488, 0xD488, 0xD488, 0xD488, 0xD488, 0xD448, 0xD448, 0xD448, 0xD448, 0xD448, + 0xD448, 0xD448, 0xD448, 0xD448, 0xD448, 0xD408, 0xD408, 0xD408, 0xD40A, 0xD40A, 0xD40A, 0xD40A, 0xD40A, 0xD40A, 0xD3CA, 0xD3CA, + 0xD3CA, 0xD3CA, 0xD3CA, 0xD3CA, 0xD3CA, 0xD3CA, 0xD3CA, 0xD3CA, 0xD38C, 0xD38C, 0xD38C, 0xD38C, 0xD38C, 0xD38C, 0xD38C, 0xD38C, + 0xD38C, 0xD34C, 0xD34C, 0xD34C, 0xD34C, 0xD34C, 0xD34C, 0xD34C, 0xD34C, 0xD34C, 0xD30C, 0xD30C, 0xD30C, 0xD30C, 0xD30C, 0xD30A, + 0xD30A, 0xD30A, 0xD2CA, 0xD2CA, 0xD2CA, 0xD2CA, 0xD2CA, 0xD2CA, 0xD2CA, 0xD2CA, 0xD2CA, 0xD28A, 0xD28A, 0xD28A, 0xD28A, 0xD28A, + 0xD288, 0xD288, 0xD288, 0xD248, 0xD248, 0xD248, 0xD248, 0xD248, 0xD248, 0xD248, 0xD248, 0xD208, 0xD208, 0xD208, 0xD208, 0xD208, + 0xD208, 0xD208, 0xD206, 0xD206, 0xD1C6, 0xD1C6, 0xD1C6, 0xD1C6, 0xD1C6, 0xD1C6, 0xD1C6, 0xD1C6, 0xD186, 0xD186, 0xD186, 0xD186, + 0xD186, 0xD186, 0xD186, 0xD186, 0xD184, 0xD144, 0xD144, 0xD144, 0xD144, 0xD144, 0xD144, 0xD144, 0xD144, 0xD104, 0xD104, 0xD104, + 0xD104, 0xD104, 0xD104, 0xD104, 0xD104, 0xD104, 0xD0C2, 0xD0C2, 0xD0C2, 0xD0C2, 0xD0C2, 0xD0C2, 0xD0C2, 0xD0C2, 0xD082, 0xD082, + 0xD082, 0xD082, 0xD082, 0xD082, 0xD082, 0xD082, 0xD080, 0xD040, 0xD040, 0xD040, 0xD040, 0xD040, 0xD040, 0xD040, 0xD040, 0xD000, + 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xD000, 0xC800, 0xC800, 0xC800, 0xC800, 0xC800, 0xC800, 0xC800, 0xC800, + 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xC000, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, 0xB800, + 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xB000, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA800, 0xA000, + 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0xA000, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, 0x9800, + 0x9000, 0x9000, 0x9000, 0x9000, 0x9000, 0x9000, 0x9000, 0x9000, 0x8800, 0x8800, 0x8800, 0x8800, 0x8800, 0x8800, 0x8800, 0x8800, + 0x8800, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x7800, 0x7800, 0x7800, 0x7800, 0x7800 + +}; diff --git a/src/snes4iphone_src/iphone_menu_header.c b/src/snes4iphone_src/iphone_menu_header.c new file mode 100755 index 0000000..cd2a6cb --- /dev/null +++ b/src/snes4iphone_src/iphone_menu_header.c @@ -0,0 +1,983 @@ +///////////////////////////////////////// +// +// Header file for GP32 +// +// convertion of menu_header.bmp file : +// Width = 320 +// Heigth = 48 +// GP32 Mode = 16 Bits per Pixel +// +// with GP32Converter coded by Edorul : +// http://www.ifrance.com/edorul/ +// edorul@free.fr +// +///////////////////////////////////////// + +#define menu_header_width 320 +#define menu_header_height 48 +unsigned short menuHeader[15360]; +unsigned short menuHeaderOrig[15360] = { + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, + 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, + 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, + 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, + 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, + 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, + 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, + 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, + 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, + 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, + 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, + 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, + 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, + 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, + 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, + 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, + 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, + 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, + 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, + 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, 0x39E8, + 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, + 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, + 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, + 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, + 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, + 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, + 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, + 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, + 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, + 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, + 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, + 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, + 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, + 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, + 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, + 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, + 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, + 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, + 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, + 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, 0x52AC, + 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, + 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, + 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, + 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, + 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, + 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, + 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, + 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, + 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, + 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, + 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, + 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, + 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, + 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, + 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, + 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, + 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, + 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, + 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, + 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, 0x6330, + 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, + 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, + 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, + 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, + 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, + 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, + 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, + 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, + 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, + 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, + 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, + 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, + 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, + 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, + 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, + 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, + 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, + 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, + 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, + 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, 0x7BF4, + 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, + 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, + 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, + 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, + 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, + 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, + 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, + 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, + 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, + 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, + 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, + 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, + 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, + 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, + 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, + 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, + 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, + 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, + 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, + 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, 0x94B8, + 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xE90C, 0xE90C, 0xE192, 0xE1D4, 0xDA5C, + 0xBC70, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF086, 0xE90C, 0xE192, 0xDA5A, 0xBCB2, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, + 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, + 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, + 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, + 0xAD7C, 0xAD7C, 0xAD7C, 0xBCB2, 0xDA5C, 0xE94E, 0xF086, 0xF044, 0xE8C8, 0xE94E, 0xD29C, 0xBCB2, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, + 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, + 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, + 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, + 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, + 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, + 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, + 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, + 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, + 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, + 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, + 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, + 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, 0xAD7C, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xE29C, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF086, 0xDADE, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xC5BA, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xDB20, 0xF086, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF086, 0xDB20, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xF044, 0xCCF2, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCCAE, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xC578, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xC63E, 0xC63E, + 0xC63E, 0xD46C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD46C, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xF044, 0xE258, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xE214, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xCD34, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xC63E, 0xC63E, + 0xC63E, 0xE9D4, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xE29A, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCD78, 0xCCF0, 0xE2DC, 0xF044, 0xF044, + 0xF044, 0xF044, 0xE992, 0xC63E, 0xC63E, 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xC63E, 0xD3E8, 0xE990, 0xC63E, 0xC63E, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCD34, 0xD4AE, 0xE29A, 0xF044, 0xF044, 0xF044, 0xF044, 0xE94C, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xCCF0, 0xE216, 0xF10A, 0xF044, 0xE90C, 0xE216, 0xDB60, 0xC5FC, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xD46E, 0xE992, 0xF0C8, 0xF044, 0xF10A, 0xE256, 0xCD34, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xD4F0, 0xC63E, 0xE258, 0xF044, 0xF044, 0xF044, 0xE94E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xD4AE, 0xE256, 0xF10A, 0xF044, + 0xF086, 0xE94C, 0xDB62, 0xC5FA, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xC63E, 0xC63E, + 0xC63E, 0xE90C, 0xF044, 0xF044, 0xF044, 0xF044, 0xDB62, 0xCD76, 0xDB62, 0xF044, 0xF044, 0xF044, 0xF044, 0xE990, 0xC63E, 0xC63E, + 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xC63E, 0xDBA4, 0xE992, 0xF086, 0xE94E, 0xD428, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xD4AE, 0xE256, 0xF10A, 0xF044, 0xF086, 0xE94C, 0xDB62, 0xC5FA, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63C, 0xDBA4, 0xE256, 0xE94E, 0xF086, 0xE94E, 0xE214, 0xD3E8, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xC63E, 0xC63E, 0xCD34, 0xF044, 0xF044, + 0xF044, 0xF044, 0xE90C, 0xC63E, 0xC63E, 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD46C, 0xF044, 0xF044, 0xC63E, 0xC63E, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xC63E, 0xC63E, 0xCDB6, 0xF044, 0xF044, 0xF044, 0xF044, 0xF10A, 0xC63E, 0xC63E, 0xC63E, + 0xDBE6, 0xF086, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xE94C, 0xCD34, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xDB60, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF0C8, 0xD46C, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xD4F0, 0xC5FC, 0xF086, 0xF044, 0xF044, 0xF044, 0xDBA4, 0xC63E, 0xC63E, 0xC63E, 0xDBA4, 0xF086, 0xF044, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xF10A, 0xCD32, 0xC63E, 0xC63E, 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, + 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCDFA, 0xC63E, 0xC5FC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF0C8, 0xC63E, 0xC63E, + 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD428, 0xF044, 0xF044, 0xF044, 0xF044, 0xF086, 0xD4F0, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xDBA4, 0xF086, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF10A, 0xCD32, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xCDFA, + 0xE94E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xE256, 0xC63C, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xC63E, 0xC63E, 0xCDFC, 0xF044, 0xF044, + 0xF044, 0xF044, 0xE90C, 0xC63E, 0xC63E, 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF0C8, 0xF044, 0xF044, 0xC63E, 0xC63E, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xC63E, 0xC63E, 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xC63E, 0xC63E, 0xCD34, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF0C8, 0xCDFA, 0xC63E, 0xC63E, 0xC63E, 0xD46C, 0xF044, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF086, 0xCDB6, 0xC63E, 0xC63E, 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xDC28, 0xDC28, 0xF044, 0xF044, 0xF044, 0xF044, 0xCDB8, 0xC63E, 0xC63E, 0xD4F0, 0xF086, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF10A, 0xC63C, 0xC63E, 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, + 0xC63E, 0xF0C8, 0xF044, 0xF044, 0xF044, 0xF044, 0xD42A, 0xC63E, 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xC63E, 0xC63E, + 0xC63E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF0C8, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xE256, 0xC63E, 0xC63E, 0xC63E, + 0xD4F0, 0xF086, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF10A, 0xC63C, 0xC63E, 0xC63E, 0xC63E, 0xE2DC, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xDBA4, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, 0xC63E, + 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xC67E, 0xC67E, 0xC67E, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xC67E, 0xC67E, 0xC67E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xC67E, 0xC67E, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xC67E, 0xC67E, 0xC67E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xC67E, 0xC67E, 0xE31E, + 0xF044, 0xF044, 0xF044, 0xF044, 0xDC28, 0xDBE6, 0xF044, 0xF044, 0xF044, 0xF044, 0xDB60, 0xC67E, 0xC67E, 0xC67E, 0xE258, 0xF044, + 0xF044, 0xF044, 0xF044, 0xD46C, 0xDBA2, 0xF044, 0xF044, 0xF044, 0xDB20, 0xC67E, 0xC67E, 0xC67E, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xDC28, 0xE9D2, 0xF044, 0xF044, 0xF044, 0xEA14, 0xC67E, 0xC67E, 0xC67E, 0xE258, 0xF044, 0xF044, 0xF044, 0xF044, 0xDC28, + 0xDBE4, 0xF044, 0xF044, 0xF044, 0xF044, 0xDC28, 0xC67E, 0xC67E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, + 0xC67E, 0xE9D2, 0xF044, 0xF044, 0xF044, 0xF044, 0xF0C8, 0xD46A, 0xC67E, 0xCDB6, 0xCDB6, 0xCDB6, 0xCDB6, 0xCDB6, 0xC67E, 0xC67E, + 0xC67E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD4EE, 0xDBE4, 0xF044, 0xF044, 0xF044, 0xF044, 0xE94E, 0xC67E, 0xC67E, 0xC67E, + 0xE258, 0xF044, 0xF044, 0xF044, 0xF044, 0xDC28, 0xDBE4, 0xF044, 0xF044, 0xF044, 0xF044, 0xDC28, 0xC67E, 0xC67E, 0xC67E, 0xE94E, + 0xF044, 0xF044, 0xF044, 0xF044, 0xD42A, 0xDC28, 0xF044, 0xF044, 0xF044, 0xE990, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, + 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, + 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, + 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, + 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, + 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, + 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, + 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, + 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, + 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, 0xC67E, + 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7E, 0xCE7E, 0xCE7E, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xCE7E, 0xCE7E, 0xCE7E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7E, 0xCE7E, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7E, 0xCE7E, 0xCDF8, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7E, 0xCE7E, 0xE258, + 0xF044, 0xF044, 0xF044, 0xF044, 0xCE3C, 0xCDF8, 0xF044, 0xF044, 0xF044, 0xF044, 0xE990, 0xCE7E, 0xCE7E, 0xCE7E, 0xE9D0, 0xF044, + 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCDF8, 0xF044, 0xF044, 0xF044, 0xE258, 0xCE7E, 0xCE7E, 0xCE7E, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xE31E, 0xF044, 0xF044, 0xF044, 0xF044, 0xDC28, 0xCE7E, 0xCE7E, 0xCE7E, 0xE94E, 0xF044, 0xF044, 0xF044, 0xF044, 0xCDFA, + 0xCDB6, 0xF044, 0xF044, 0xF044, 0xF044, 0xE29A, 0xCE7E, 0xCE7E, 0xCDB6, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCDB6, 0xCDB6, + 0xCE7E, 0xE2DC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xE29A, 0xCDF8, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, + 0xCE7E, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCDF8, 0xCDB6, 0xF044, 0xF044, 0xF044, 0xF044, 0xE90C, 0xCE7E, 0xCE7E, 0xCE7E, + 0xE94E, 0xF044, 0xF044, 0xF044, 0xF044, 0xCDFA, 0xCDB6, 0xF044, 0xF044, 0xF044, 0xF044, 0xE29A, 0xCE7E, 0xCE7E, 0xCE7E, 0xF0C8, + 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7E, 0xCDFA, 0xF044, 0xF044, 0xF044, 0xF0C8, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, + 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, + 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, + 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, + 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, + 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, + 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, + 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, + 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, + 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, 0xCE7E, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, 0xCE7C, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xE94E, 0xDC28, 0xD532, 0xCE7C, 0xCE7C, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE3A, 0xD530, 0xE2DA, 0xF044, 0xF044, 0xF044, 0xF044, 0xF10C, 0xCE7C, 0xCE7C, 0xE990, + 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF10C, 0xCE7C, 0xCE7C, 0xCE7C, 0xF10C, 0xF044, + 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xE990, 0xCE7C, 0xCE7C, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xF0C8, 0xF044, 0xF044, 0xF044, 0xF0C8, 0xCE3A, 0xCE7C, 0xCE7C, 0xCE7C, 0xF0C8, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7C, + 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xE9D0, 0xCE7C, 0xCE7C, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCDB6, 0xF0C8, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF0C8, 0xDC6A, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE3C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF086, 0xCE7C, 0xCE7C, 0xCE7C, + 0xF0C8, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xE9D0, 0xCE7C, 0xCE7C, 0xCE7C, 0xF044, + 0xF044, 0xF044, 0xF044, 0xF044, 0xCE3A, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, 0xCE7C, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xDCAC, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xEA14, 0xCE7C, 0xCE7C, 0xF0C8, + 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF086, 0xCE7C, 0xCE7C, 0xCE7C, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF0C8, 0xCE7C, 0xCE7C, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xE298, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7C, + 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF10C, 0xCE7C, 0xCE7C, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xD4EC, 0xF086, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xEA56, 0xCE3A, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, 0xCE7C, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF10C, 0xCE7C, 0xCE7C, 0xCE7C, 0xE94C, + 0xF044, 0xF044, 0xF044, 0xF044, 0xEA14, 0xCDF8, 0xD5B6, 0xD5B6, 0xD5B6, 0xD5B6, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, 0xCE7C, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD5F6, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xE360, 0xCE7C, 0xCE7C, 0xF044, + 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, 0xCE7C, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, 0xD5F6, 0xD5F6, 0xD5F6, 0xD5F6, 0xCE7C, 0xCE7C, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xDCAC, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xD5B4, 0xE9D2, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xE990, 0xD5F8, 0xCE7C, 0xCE7C, + 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, 0xCE7C, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE7C, 0xCE7C, 0xCE7C, 0xEA14, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF10A, 0xDCAC, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, 0xCE7C, + 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCEBC, 0xCEBC, 0xCEBC, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xCEBC, 0xCEBC, 0xCEBC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD5F8, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xE94E, 0xD67A, 0xCEBC, 0xCEBC, 0xF044, + 0xF044, 0xF044, 0xF044, 0xF044, 0xCEBC, 0xCEBC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCEBC, 0xCEBC, 0xCEBC, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xE3A2, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCEBC, 0xCEBC, 0xCEBC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCEBC, 0xCEBC, + 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xDBE4, 0xF0C8, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xE990, 0xCEBC, 0xCEBC, + 0xCEBC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCEBC, 0xCEBC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCEBC, 0xCEBC, 0xCEBC, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCEBC, 0xCEBC, 0xCEBC, 0xDC26, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xEA98, 0xD638, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, + 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, + 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, + 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, + 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, + 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, + 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, + 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, + 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, + 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, + 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCEBC, 0xCEBC, 0xCEBC, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xCEBC, 0xCEBC, 0xCEBC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF086, 0xE98E, 0xEA98, 0xDC26, 0xD67A, 0xCEBC, 0xCEBC, 0xCEBC, 0xF044, + 0xF044, 0xF044, 0xF044, 0xF044, 0xCEBC, 0xCEBC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCEBC, 0xCEBC, 0xCEBC, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xEA14, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCEBC, 0xCEBC, 0xCEBC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCEBC, 0xCEBC, + 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xD5F6, 0xEA12, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xDCAA, 0xCEBC, + 0xCEBC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCEBC, 0xCEBC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCEBC, 0xCEBC, 0xCEBC, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, + 0xE2DA, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xE990, 0xCE7C, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, + 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, + 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, + 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, + 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, + 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, + 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, + 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, + 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, + 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, 0xCEBC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD5F6, 0xD5F6, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, + 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF0C8, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD5F6, + 0xD5F6, 0xD5F6, 0xD5F6, 0xD5F6, 0xD5F6, 0xD5F6, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xE3E2, 0xF086, 0xF044, 0xF044, 0xF044, 0xF044, 0xEA96, 0xD6BC, + 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD5F6, 0xD5F6, 0xD5F6, 0xD5F6, 0xD5F6, 0xD5F6, 0xD5F6, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xE424, 0xF086, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xE424, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, + 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF086, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xE9D0, 0xF044, 0xF044, 0xF044, 0xF044, 0xDDB2, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, + 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, + 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, 0xE3E4, 0xF044, 0xF044, 0xF044, 0xF044, 0xE990, 0xD6BC, + 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xDD70, 0xF14C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xE9D2, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD67A, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF086, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xF086, + 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF10A, 0xD6BC, 0xD6BC, 0xD6BC, 0xF0C8, 0xF044, + 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF14C, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xE3E4, 0xF044, 0xF044, 0xF044, 0xF044, 0xE3E4, 0xD6BC, 0xD6BC, 0xD6BC, 0xF086, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, + 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, + 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, 0xD5F2, 0xF044, 0xF044, 0xF044, 0xF044, 0xF0C8, 0xD6BC, + 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, + 0xF086, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD67A, 0xEA96, 0xF044, 0xF044, 0xF044, 0xF044, 0xF10A, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xDDF2, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF14C, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xF14C, + 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF14C, 0xD6BC, 0xD6BC, 0xD6BC, 0xE9D0, 0xF044, + 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BA, 0xF044, 0xF044, 0xF044, 0xE98E, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xE4A8, 0xE98E, 0xF044, 0xF044, 0xF044, 0xEA96, 0xD6BC, 0xD6BC, 0xD6BC, 0xF14C, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, + 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF14C, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, + 0xD6BC, 0xF0C8, 0xF044, 0xF044, 0xF044, 0xF044, 0xD636, 0xD6BC, 0xD6BC, 0xDDF4, 0xF044, 0xF044, 0xF044, 0xF044, 0xF0C8, 0xD6BC, + 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xD6BC, + 0xF14C, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BC, 0xD6BC, 0xF044, 0xF044, 0xF044, 0xF044, 0xF14C, 0xD6BC, 0xD6BC, 0xD6BC, 0xF044, + 0xF044, 0xF044, 0xF044, 0xD6BC, 0xDDF2, 0xF044, 0xF044, 0xF044, 0xF044, 0xF0C6, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, 0xD6BC, + 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD678, 0xDD6E, 0xEA54, 0xF044, 0xF044, + 0xF044, 0xF044, 0xE9D0, 0xD6FA, 0xD6FA, 0xD6FA, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xE98E, + 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BA, 0xD678, 0xF044, 0xF044, 0xF044, 0xF044, 0xEA12, 0xD6FA, 0xD6FA, 0xD6FA, 0xEA96, 0xF044, + 0xF044, 0xF044, 0xF044, 0xD676, 0xDDF4, 0xF044, 0xF044, 0xF044, 0xEA96, 0xD6FA, 0xD6FA, 0xD6FA, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xDD2E, 0xEB1A, 0xF044, 0xF044, 0xF044, 0xF10A, 0xD6FA, 0xD6FA, 0xD6FA, 0xE9D0, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BA, + 0xDE34, 0xF044, 0xF044, 0xF044, 0xF044, 0xE9D0, 0xD6FA, 0xD6FA, 0xD6FA, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BA, 0xD6FA, + 0xD6FA, 0xF14C, 0xF044, 0xF044, 0xF044, 0xF044, 0xEAD8, 0xDE36, 0xDDB0, 0xE9D2, 0xF044, 0xF044, 0xF044, 0xF044, 0xE9D0, 0xD6FA, + 0xD6FA, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6FA, 0xD6FA, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6FA, 0xD6FA, 0xD6FA, + 0xE9D0, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6BA, 0xDE34, 0xF044, 0xF044, 0xF044, 0xF044, 0xE9D0, 0xD6FA, 0xD6FA, 0xD6FA, 0xF086, + 0xF044, 0xF044, 0xF044, 0xD6BA, 0xD6BA, 0xF044, 0xF044, 0xF044, 0xF044, 0xE98E, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, + 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, + 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, + 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, + 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, + 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, + 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, + 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, + 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, + 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, + 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xF044, 0xEA54, 0xD6FA, 0xD6FA, 0xD6FA, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xEA56, + 0xF044, 0xF044, 0xF044, 0xF044, 0xE4EA, 0xE4A8, 0xF044, 0xF044, 0xF044, 0xF044, 0xE3A0, 0xD6FA, 0xD6FA, 0xD6FA, 0xE35E, 0xF044, + 0xF044, 0xF044, 0xF044, 0xE424, 0xE424, 0xF044, 0xF044, 0xF044, 0xE466, 0xD6FA, 0xD6FA, 0xD6FA, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xDD6E, 0xE4A8, 0xF044, 0xF044, 0xF044, 0xF044, 0xDDF2, 0xD6FA, 0xD6FA, 0xE35C, 0xF044, 0xF044, 0xF044, 0xF044, 0xDD2C, + 0xE424, 0xF044, 0xF044, 0xF044, 0xF044, 0xE424, 0xD6FA, 0xD6FA, 0xD6FA, 0xF10A, 0xF044, 0xF044, 0xF044, 0xF044, 0xDD2C, 0xDE78, + 0xD6FA, 0xEAD8, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xEB1A, 0xD6FA, + 0xD6FA, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6FA, 0xD6FA, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xD6FA, 0xD6FA, 0xD6FA, + 0xE35C, 0xF044, 0xF044, 0xF044, 0xF044, 0xDD2C, 0xE424, 0xF044, 0xF044, 0xF044, 0xF044, 0xE424, 0xD6FA, 0xD6FA, 0xD6FA, 0xF14C, + 0xF044, 0xF044, 0xF044, 0xDD2C, 0xE4A8, 0xF044, 0xF044, 0xF044, 0xF044, 0xEA98, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, + 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, + 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, + 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, + 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, + 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, + 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, + 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, + 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, + 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, 0xD6FA, + 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xF044, 0xDBA0, 0xCE78, 0xCE78, 0xCE78, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xD4EC, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF0C8, 0xCE36, 0xCE78, 0xCE78, 0xCE78, 0xD4EC, 0xF044, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF0C6, 0xCDF4, 0xCE78, 0xCE78, 0xCE78, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xCDB2, 0xCDF4, 0xF044, 0xF044, 0xF044, 0xF044, 0xDC26, 0xCE78, 0xCE78, 0xCDF4, 0xF086, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF10A, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xE94C, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, + 0xCE78, 0xD570, 0xF086, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF086, 0xD4EC, 0xCE78, + 0xCE78, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE78, 0xCE78, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xCE78, 0xCE78, 0xCE78, + 0xCDF4, 0xF086, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF10A, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xE2DA, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xDC66, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, + 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, + 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, + 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, + 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, + 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, + 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, + 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, + 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, + 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, 0xCE78, + 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xF0C8, 0xBDB4, 0xBDF8, 0xBDF8, 0xBDF8, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, + 0xDADA, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF086, 0xCC26, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xDADA, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF086, 0xD3E4, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xC570, 0xBDF8, 0xE90A, 0xF044, 0xF044, 0xF044, 0xDA98, 0xBDF8, 0xBDF8, 0xBDF8, 0xCCAA, 0xF0CA, 0xF044, 0xF044, 0xF044, + 0xF044, 0xF044, 0xF044, 0xE90A, 0xC4EE, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xD360, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, + 0xBDF8, 0xBDF8, 0xCC68, 0xF0C8, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF0C8, 0xD3A2, 0xBDF8, 0xBDF8, + 0xBDF8, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xBDF8, 0xBDF8, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xBDF8, 0xBDF8, 0xBDF8, + 0xBDF8, 0xCCAA, 0xF0CA, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xE90A, 0xC4EE, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xC572, + 0xE90A, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xE1D2, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, + 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, + 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, + 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, + 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, + 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, + 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, + 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, + 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, + 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, 0xBDF8, + 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xE90A, + 0xD29A, 0xB530, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, + 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, + 0xADB6, 0xBC6A, 0xDA14, 0xE94C, 0xF044, 0xF044, 0xE94C, 0xDA56, 0xBCAC, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, + 0xC3A4, 0xE190, 0xF086, 0xF044, 0xF0C8, 0xE1D2, 0xBC6A, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xF044, 0xF044, 0xF044, 0xF044, + 0xF044, 0xADB6, 0xADB6, 0xDA56, 0xF044, 0xF044, 0xF044, 0xE90A, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xB530, 0xD2DA, 0xE190, 0xF086, + 0xF086, 0xE18E, 0xD2DA, 0xB532, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xAD74, 0xCB60, 0xE94C, 0xF044, 0xF044, 0xF044, 0xF044, + 0xADB6, 0xADB6, 0xADB6, 0xB530, 0xCB1E, 0xE190, 0xF086, 0xF044, 0xF044, 0xF0C8, 0xE190, 0xD31C, 0xB530, 0xADB6, 0xADB6, 0xADB6, + 0xADB6, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xADB6, 0xADB6, 0xF044, 0xF044, 0xF044, 0xF044, 0xF044, 0xADB6, 0xADB6, 0xADB6, + 0xADB6, 0xADB6, 0xB530, 0xD2DA, 0xE190, 0xF086, 0xF086, 0xE18E, 0xD2DA, 0xB532, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, + 0xB574, 0xCB1E, 0xE190, 0xF086, 0xF044, 0xF086, 0xE190, 0xCB1E, 0xAD74, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, + 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, + 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, + 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, + 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, + 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, + 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, + 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, + 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, + 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, 0xADB6, + 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, + 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, + 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, + 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, + 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, + 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, + 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, + 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, + 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, + 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, + 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, + 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, + 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, + 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, + 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, + 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, + 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, + 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, + 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, + 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, 0xA534, + 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, + 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, + 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, + 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, + 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, + 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, + 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, + 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, + 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, + 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, + 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, + 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, + 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, + 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, + 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, + 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, + 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, + 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, + 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, + 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, 0x94B2, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, 0x8430, + 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, + 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, + 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, + 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, + 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, + 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, + 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, + 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, + 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, + 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, + 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, + 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, + 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, + 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, + 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, + 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, + 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, + 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, + 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, + 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, 0x73EE, + 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, + 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, + 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, + 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, + 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, + 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, + 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, + 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, + 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, + 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, + 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, + 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, + 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, + 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, + 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, + 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, + 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, + 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, + 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, + 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, 0x6B6C, + 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, + 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, + 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, + 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, + 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, + 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, + 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, + 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, + 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, + 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, + 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, + 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, + 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, + 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, + 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, + 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, + 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, + 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, + 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, + 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, 0x5AEA, + 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, + 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, + 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, + 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, + 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, + 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, + 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, + 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, + 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, + 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, + 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, + 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, + 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, + 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, + 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, + 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, + 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, + 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, + 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, + 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, 0x4A6A, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, + 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, + 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, + 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, + 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, + 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, + 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, + 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, + 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, + 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, + 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, + 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, + 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, + 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, + 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, + 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, + 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, + 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, + 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, + 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, 0x31A6, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, 0x2124, + 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, + 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, + 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, + 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, + 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, + 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, + 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, + 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, + 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, + 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, + 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, + 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, + 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, + 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, + 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, + 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, + 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, + 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, + 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, + 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, 0x10A2, + 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, + 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, + 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, + 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, + 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, + 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, + 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, + 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, + 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, + 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, + 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, + 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, + 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, + 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, + 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, + 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, + 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, + 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, + 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, + 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, + 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, + 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, + 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, + 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, + 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, + 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, + 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, + 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, + 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, + 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, + 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, + 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, + 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, + 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, + 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, + 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, + 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, + 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, + 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, 0x18E2, + 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, + 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, + 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, + 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, + 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, + 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, + 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, + 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, + 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, + 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, + 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, + 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, + 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, + 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, + 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, + 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, + 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, + 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, + 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, + 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, 0x2964, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, 0x4228, + 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, + 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, + 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, + 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, + 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, + 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, + 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, + 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, + 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, + 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, + 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, + 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, + 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, + 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, + 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, + 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, + 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, + 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, + 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, + 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, 0x52EA, + 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, + 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, + 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, + 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, + 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, + 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, + 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, + 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, + 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, + 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, + 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, + 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, + 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, + 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, + 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, + 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, + 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, + 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, + 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, + 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, 0x636C, + 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, + 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, + 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, + 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, + 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, + 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, + 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, + 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, + 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, + 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, + 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, + 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, + 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, + 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, + 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, + 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, + 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, + 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, + 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, + 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E, 0x7C2E + +}; + + diff --git a/src/snes4iphone_src/iphone_menutile.c b/src/snes4iphone_src/iphone_menutile.c new file mode 100755 index 0000000..943cff9 --- /dev/null +++ b/src/snes4iphone_src/iphone_menutile.c @@ -0,0 +1,277 @@ +///////////////////////////////////////// +// +// Header file for GP32 +// +// convertion of menutile.bmp file : +// Width = 64 +// Heigth = 64 +// GP32 Mode = 16 Bits per Pixel +// +// with GP32Converter coded by Edorul : +// http://www.ifrance.com/edorul/ +// edorul@free.fr +// +///////////////////////////////////////// + +#define menutile_width 64 +#define menutile_height 64 +unsigned short menuTile[4096]; +unsigned short menuTileOrig[4096] = { + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0xE, 0x14, + 0xA, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x8A0, 0x116E, 0x19F4, 0x2238, 0x21F8, 0x2238, 0x19F8, + 0x11B8, 0x11B8, 0x976, 0xF2, 0x66, 0x14, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x896, 0x19F2, 0x2A78, 0x2A78, 0x2A78, 0x2278, 0x2238, 0x2238, 0x19F8, 0x19F8, + 0x11B8, 0x11B8, 0x1178, 0x978, 0x938, 0x136, 0xF6, 0x66, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x894, 0x21F2, 0x32B6, 0x32B8, 0x2AB8, 0x2A78, 0x227A, 0x227A, 0x1A3A, 0x1A3A, 0x19FA, 0x11FA, + 0x11BA, 0x9BA, 0x97A, 0x97A, 0x13A, 0x138, 0xF8, 0xF6, 0xB4, 0x64, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x1968, 0x32F6, 0x32B6, 0x2AB8, 0x2AB8, 0x2AB8, 0x227A, 0x227A, 0x1A7A, 0x1A3C, 0x123C, 0x11FC, 0x9FC, + 0x9BC, 0x9BC, 0x17C, 0x13C, 0x13A, 0x13A, 0xF8, 0xF8, 0xF6, 0xB4, 0xB0, 0x14, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0xA, 0x2A32, 0x32F6, 0x32B8, 0x32B8, 0x2AB8, 0x2ABA, 0x22BA, 0x227A, 0x1A7A, 0x1A3C, 0x123C, 0x123C, 0x9FC, 0x9FE, + 0x1BE, 0x17E, 0x17E, 0x13C, 0x13C, 0x13C, 0xFA, 0xF8, 0xF8, 0xB6, 0xB4, 0xB2, 0x60, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x4A, 0x32B4, 0x32F6, 0x32F8, 0x32B8, 0x2AB8, 0x22BA, 0x22BA, 0x1ABA, 0x1A7C, 0x127C, 0x127C, 0x123C, 0xA3E, 0x9FE, 0x1BE, + 0x1BE, 0x17E, 0x17E, 0x17E, 0x13C, 0x13C, 0x13A, 0xFA, 0xF8, 0xF6, 0xB4, 0xB4, 0xB2, 0x66, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, + 0x2A74, 0x3AF6, 0x32F8, 0x32F8, 0x2AB8, 0x22BA, 0x22BA, 0x1ABA, 0x1ABC, 0x127C, 0x127C, 0xA7C, 0xA3E, 0x23E, 0x1FE, 0x1BE, + 0x1BE, 0x1BE, 0x17E, 0x17E, 0x17E, 0x13C, 0x13C, 0x13A, 0xF8, 0xF8, 0xB6, 0xB4, 0xB2, 0xB0, 0x1E, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2A30, + 0x3AF6, 0x32F8, 0x32B8, 0x2AB8, 0x22BA, 0x22BA, 0x1ABA, 0x1ABC, 0x12BC, 0x127C, 0xA7E, 0xA7E, 0x23E, 0x23E, 0x1FE, 0x1FE, + 0x1BE, 0x1BE, 0x1BE, 0x17E, 0x17E, 0x13E, 0x13C, 0x13A, 0xFA, 0xF8, 0xF6, 0xB4, 0xB2, 0xB0, 0x6E, 0x18, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1964, 0x3AF6, + 0x32F6, 0x32B8, 0x2AB8, 0x22BA, 0x22BA, 0x1ABA, 0x1ABC, 0x12BC, 0x12BC, 0xABE, 0xA7E, 0x27E, 0x23E, 0x23E, 0x23E, 0x1FE, + 0x1FE, 0x1BE, 0x1BE, 0x17E, 0x17E, 0x17E, 0x13C, 0x13C, 0xFA, 0xF8, 0xF8, 0xB6, 0xB4, 0xB2, 0x6E, 0x6C, + 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4A, 0x32B4, 0x32B6, + 0x32B8, 0x2AB8, 0x2ABA, 0x22BA, 0x1ABA, 0x1ABC, 0x12BC, 0x12BC, 0xABE, 0xABE, 0x2BE, 0x27E, 0x27E, 0x23E, 0x23E, 0x1FE, + 0x1FE, 0x1FE, 0x1BE, 0x1BE, 0x17E, 0x17E, 0x13E, 0x13C, 0x13A, 0xFA, 0xF8, 0xB6, 0xB4, 0xB2, 0xB0, 0x6E, + 0x64, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x21EC, 0x32B6, 0x32B8, + 0x2AB8, 0x2AB8, 0x22BA, 0x1ABA, 0x1ABC, 0x12BC, 0x12BC, 0xABE, 0xABE, 0x2BE, 0x2BE, 0x2BE, 0x27E, 0x27E, 0x23E, 0x23E, + 0x1FE, 0x1FE, 0x1BE, 0x1BE, 0x17E, 0x17E, 0x13E, 0x13C, 0x13A, 0xFA, 0xF8, 0xB6, 0xB4, 0xB2, 0xB0, 0x6E, + 0x6C, 0x12, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4C, 0x32B6, 0x32B6, 0x2AB8, + 0x2AB8, 0x22BA, 0x22BA, 0x1ABC, 0x12BC, 0x12BC, 0xABE, 0xABE, 0x2FE, 0x2FE, 0x2FE, 0x2BE, 0x2BE, 0x27E, 0x27E, 0x23E, + 0x1FE, 0x1FE, 0x1BE, 0x1BE, 0x17E, 0x17E, 0x17E, 0x13C, 0x13C, 0xFA, 0xF8, 0xF6, 0xB4, 0xB2, 0xB0, 0x6E, + 0x6C, 0x24, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1924, 0x32B6, 0x2AB6, 0x2AB8, + 0x22BA, 0x22BA, 0x1ABA, 0x12BC, 0x12BC, 0xABE, 0xABE, 0x2BE, 0x2FE, 0x2FE, 0x2FE, 0x2BE, 0x2BE, 0x27E, 0x27E, 0x23E, + 0x1FE, 0x1FE, 0x1BE, 0x1BE, 0x17E, 0x17E, 0x17E, 0x13C, 0x13C, 0xFA, 0xF8, 0xF6, 0xB4, 0xB2, 0xB0, 0x6E, + 0x6C, 0x6A, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2A32, 0x32B6, 0x2A78, 0x2278, + 0x227A, 0x1A7A, 0x1A7C, 0x127C, 0xA7C, 0xABE, 0x2BE, 0x2BE, 0x2FE, 0x2FE, 0x2FE, 0x2FE, 0x2BE, 0x27E, 0x27E, 0x23E, + 0x1FE, 0x1FE, 0x1BE, 0x1BE, 0x17E, 0x17E, 0x17E, 0x13C, 0x13C, 0xFA, 0xF8, 0xF6, 0xB4, 0xB2, 0xB0, 0x6E, + 0x6C, 0x6A, 0x1A, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x3274, 0x2A76, 0x2A78, 0x227A, + 0x1A7A, 0x1A7C, 0x127C, 0x127C, 0xA7E, 0x27E, 0x27E, 0x2BE, 0x2BE, 0x2FE, 0x2FE, 0x2BE, 0x2BE, 0x27E, 0x27E, 0x23E, + 0x1FE, 0x1FE, 0x1BE, 0x1BE, 0x17E, 0x17E, 0x17E, 0x13C, 0x13C, 0xFA, 0xF8, 0xF6, 0xB4, 0xB2, 0xB0, 0x6E, + 0x6C, 0xAA, 0x864, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x54, 0x3274, 0x2A76, 0x2278, 0x227A, + 0x1A7A, 0x127C, 0x123C, 0xA7E, 0x27E, 0x27E, 0x27E, 0x2BE, 0x2BE, 0x2BE, 0x2BE, 0x2BE, 0x27E, 0x27E, 0x23E, 0x23E, + 0x1FE, 0x1FE, 0x1BE, 0x1BE, 0x17E, 0x17E, 0x13E, 0x13C, 0x13C, 0xFA, 0xF8, 0xB6, 0xB4, 0xB2, 0xB0, 0x6E, + 0x6C, 0x8AA, 0x8A8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x89C, 0x2A76, 0x2A36, 0x2238, 0x1A3A, + 0x1A3C, 0x123C, 0xA3C, 0xA3E, 0x23E, 0x23E, 0x27E, 0x27E, 0x27E, 0x2BE, 0x2BE, 0x27E, 0x27E, 0x27E, 0x23E, 0x23E, + 0x1FE, 0x1FE, 0x1BE, 0x1BE, 0x17E, 0x17E, 0x13E, 0x13C, 0x13C, 0xFA, 0xF8, 0xB6, 0xB4, 0xB2, 0xB0, 0x6E, + 0xAC, 0x8AA, 0x10A8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10E2, 0x2A36, 0x2238, 0x1A38, 0x1A3A, + 0x123C, 0x123C, 0x9FE, 0x1FE, 0x1FE, 0x23E, 0x23E, 0x27E, 0x27E, 0x27E, 0x27E, 0x27E, 0x23E, 0x23E, 0x23E, 0x1FE, + 0x1FE, 0x1BE, 0x1BE, 0x1BE, 0x17E, 0x17E, 0x13E, 0x13C, 0xFA, 0xFA, 0xF8, 0xB6, 0xB4, 0xB2, 0x70, 0xAE, + 0x8AC, 0x8AA, 0x10EA, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8E2, 0x2A36, 0x2238, 0x19F8, 0x11FA, + 0x11FC, 0x9FE, 0x1FE, 0x1FE, 0x1FE, 0x1FE, 0x23E, 0x23E, 0x23E, 0x23E, 0x23E, 0x23E, 0x23E, 0x23E, 0x1FE, 0x1FE, + 0x1FE, 0x1BE, 0x1BE, 0x17E, 0x17E, 0x13E, 0x13C, 0x13C, 0xFA, 0xF8, 0xF8, 0xB6, 0xB4, 0xB2, 0x70, 0xAE, + 0x8AC, 0x10AC, 0x10EA, 0x8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x89C, 0x21F6, 0x19F8, 0x19F8, 0x11FA, + 0x9FC, 0x9BE, 0x1BE, 0x1BE, 0x1FE, 0x1FE, 0x1FE, 0x1FE, 0x23E, 0x23E, 0x23E, 0x23E, 0x1FE, 0x1FE, 0x1FE, 0x1FE, + 0x1BE, 0x1BE, 0x17E, 0x17E, 0x17E, 0x13E, 0x13C, 0x13C, 0xFA, 0xF8, 0xB6, 0xB4, 0xB2, 0xB0, 0xB0, 0x8AE, + 0x8AC, 0x10EA, 0x18EA, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x54, 0x21F6, 0x19F8, 0x11B8, 0x11BA, + 0x9BC, 0x1BE, 0x1BE, 0x1BE, 0x1BE, 0x1FE, 0x1FE, 0x1FE, 0x1FE, 0x1FE, 0x1FE, 0x1FE, 0x1FE, 0x1FE, 0x1BE, 0x1BE, + 0x1BE, 0x1BE, 0x17E, 0x17E, 0x13E, 0x13C, 0x13C, 0xFA, 0xFA, 0xF8, 0xB6, 0xB4, 0xB2, 0xB0, 0xAE, 0x8AE, + 0x10EC, 0x10EA, 0x18E8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xC, 0x19B6, 0x19B6, 0x11B8, 0x9BA, + 0x97C, 0x17E, 0x17E, 0x1BE, 0x1BE, 0x1BE, 0x1BE, 0x1FE, 0x1FE, 0x1FE, 0x1FE, 0x1FE, 0x1BE, 0x1BE, 0x1BE, 0x1BE, + 0x17E, 0x17E, 0x17E, 0x17E, 0x13E, 0x13C, 0x13C, 0xFA, 0xF8, 0xF6, 0xB6, 0xB4, 0xB2, 0xB0, 0x8AE, 0x8AE, + 0x10EC, 0x18EA, 0x18E8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1172, 0x19B6, 0x11B8, 0x97A, + 0x17C, 0x17E, 0x17E, 0x17E, 0x17E, 0x1BE, 0x1BE, 0x1BE, 0x1BE, 0x1BE, 0x1BE, 0x1BE, 0x1BE, 0x1BE, 0x1BE, 0x17E, + 0x17E, 0x17E, 0x17E, 0x13E, 0x13C, 0x13C, 0xFA, 0xF8, 0xF8, 0xB6, 0xB4, 0xB2, 0xB0, 0x8B0, 0x8AE, 0x10EE, + 0x18EC, 0x192A, 0x10A0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xA8, 0x1176, 0x1178, 0x97A, + 0x13C, 0x13C, 0x17E, 0x17E, 0x17E, 0x17E, 0x17E, 0x1BE, 0x1BE, 0x1BE, 0x1BE, 0x1BE, 0x17E, 0x17E, 0x17E, 0x17E, + 0x17E, 0x13E, 0x13E, 0x13C, 0x13C, 0xFA, 0xFA, 0xF8, 0xB6, 0xB4, 0xB4, 0xB2, 0xB0, 0x8B0, 0x10EE, 0x10EC, + 0x18EC, 0x212A, 0x850, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x14, 0x1176, 0x976, 0x938, + 0x13A, 0x13C, 0x13C, 0x13E, 0x17E, 0x17E, 0x17E, 0x17E, 0x17E, 0x17E, 0x17E, 0x17E, 0x17E, 0x17E, 0x17E, 0x17E, + 0x13E, 0x13E, 0x13C, 0x13C, 0xFA, 0xFA, 0xF8, 0xF6, 0xB6, 0xB4, 0xB2, 0xB0, 0x8B0, 0x10EE, 0x10EE, 0x18EC, + 0x192C, 0x212A, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xF2, 0x936, 0x138, + 0xFA, 0x13A, 0x13C, 0x13C, 0x13C, 0x13E, 0x17E, 0x17E, 0x17E, 0x17E, 0x17E, 0x17E, 0x17E, 0x13E, 0x13E, 0x13E, + 0x13C, 0x13C, 0x13C, 0xFA, 0xFA, 0xF8, 0xF6, 0xB6, 0xB4, 0xB2, 0xB2, 0x8B0, 0x8F0, 0x10EE, 0x18EC, 0x192C, + 0x212C, 0x10A0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x16, 0xF6, 0xF6, + 0xF8, 0xFA, 0x13A, 0x13A, 0x13C, 0x13C, 0x13C, 0x13C, 0x13E, 0x13E, 0x13E, 0x13E, 0x13C, 0x13C, 0x13C, 0x13C, + 0x13C, 0xFA, 0xFA, 0xFA, 0xF8, 0xF6, 0xB6, 0xB4, 0xB2, 0xB2, 0x8B0, 0x8B0, 0x10EE, 0x18EE, 0x18EC, 0x212C, + 0x212A, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xAA, 0xF6, + 0xF6, 0xF8, 0xF8, 0xFA, 0xFA, 0x13A, 0x13C, 0x13C, 0x13C, 0x13C, 0x13C, 0x13C, 0x13C, 0x13C, 0x13C, 0xFA, + 0xFA, 0xFA, 0xF8, 0xF8, 0xB6, 0xB6, 0xB4, 0xB2, 0xB2, 0x8B0, 0x8B0, 0x10EE, 0x10EE, 0x192E, 0x212C, 0x212C, + 0x1098, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xA, 0xB2, + 0xB6, 0xF6, 0xF8, 0xF8, 0xF8, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, 0xFA, + 0xF8, 0xF8, 0xF8, 0xB6, 0xB6, 0xB4, 0xB2, 0xB2, 0x8B0, 0x8B0, 0x10EE, 0x10EE, 0x18EE, 0x212C, 0x212C, 0x20E6, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, + 0xB2, 0xB4, 0xB6, 0xF6, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xFA, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, + 0xF8, 0xB6, 0xB6, 0xB4, 0xB4, 0xB2, 0xB2, 0x8B0, 0x8B0, 0x10EE, 0x10EE, 0x18EE, 0x192C, 0x212C, 0x2128, 0x2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x14, 0xB2, 0xB4, 0xB4, 0xB6, 0xB6, 0xF6, 0xF6, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF6, 0xB6, 0xB6, + 0xB6, 0xB4, 0xB4, 0xB2, 0xB2, 0xB2, 0x8B0, 0x8B0, 0x10EE, 0x10EE, 0x18EE, 0x192C, 0x212C, 0x212A, 0x4, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x14, 0xB0, 0xB2, 0xB4, 0xB4, 0xB4, 0xB4, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB4, 0xB4, 0xB4, + 0xB4, 0xB2, 0xB2, 0xB2, 0xB0, 0x8B0, 0x8F0, 0x10EE, 0x10EE, 0x18EE, 0x192C, 0x212C, 0x18E8, 0x6, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x6, 0x6A, 0xB2, 0xB2, 0xB2, 0xB2, 0xB4, 0xB4, 0xB4, 0xB4, 0xB4, 0xB2, 0xB2, 0xB2, + 0xB2, 0xB0, 0xB0, 0x8B0, 0x8B0, 0x10EE, 0x10EE, 0x18EE, 0x192E, 0x212C, 0x212C, 0x18E0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x1E, 0xAE, 0xB0, 0xB0, 0xB2, 0xB2, 0xB2, 0xB2, 0xB0, 0xB0, 0xB0, 0xB0, + 0xB0, 0xB0, 0x8AE, 0x8AE, 0x10EE, 0x10EE, 0x18EE, 0x18EC, 0x212C, 0x18EA, 0x854, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x1E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0x6E, 0xAE, 0xAE, + 0x8AE, 0x8AE, 0x8AE, 0x10EE, 0x10EE, 0x18EC, 0x192C, 0x18EA, 0x856, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x16, 0x64, 0x6A, 0x6C, 0x6C, 0xAC, 0x8AC, 0x8AC, + 0x8AC, 0x10EC, 0x10EC, 0x10EC, 0x10A8, 0x85E, 0x12, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x10, 0x14, 0x1A, 0x1C, + 0x18, 0x12, 0xC, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 + +}; diff --git a/src/snes4iphone_src/iphone_sdk.c b/src/snes4iphone_src/iphone_sdk.c new file mode 100755 index 0000000..59ff543 --- /dev/null +++ b/src/snes4iphone_src/iphone_sdk.c @@ -0,0 +1,379 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#import +#import +#include "iphone_sdk.h" + +enum { GP2X_UP=0x1, GP2X_LEFT=0x4, GP2X_DOWN=0x10, GP2X_RIGHT=0x40, + GP2X_START=1<<8, GP2X_SELECT=1<<9, GP2X_L=1<<10, GP2X_R=1<<11, + GP2X_A=1<<12, GP2X_B=1<<13, GP2X_X=1<<14, GP2X_Y=1<<15, + GP2X_VOL_UP=1<<23, GP2X_VOL_DOWN=1<<22, GP2X_PUSH=1<<27 }; + +const int isStereo = 0; +#define AUDIO_BUFFERS 6 +#define FRAME_SIZE 2048 +#define AUDIO_BUFFER_SIZE soundBufferSize /*(FRAME_SIZE*(isStereo ? 4 : 2))*/ + +extern void app_MuteSound(void); + +typedef struct AQCallbackStruct { + AudioQueueRef queue; + UInt32 frameCount; + AudioQueueBufferRef mBuffers[AUDIO_BUFFERS]; + AudioStreamBasicDescription mDataFormat; +} AQCallbackStruct; + +AQCallbackStruct in; + +extern void updateScreen(); +extern void S9xMixSamplesO (signed short *buffer, int sample_count, int sample_offset); + +unsigned short BaseAddress[320*240]; +int soundBufferSize = 0; +int soundInit = 0; +float __audioVolume = 1.0; +unsigned long gp2x_pad_status = 0; + +int Timer=0; +extern unsigned char *vrambuffer; +extern volatile int __emulation_paused; + +// 1024x8 8x8 font, i love it :) +const unsigned int font8x8[]= {0x0,0x0,0xc3663c18,0x3c2424e7,0xe724243c,0x183c66c3,0xc16f3818,0x18386fc1,0x83f61c18,0x181cf683,0xe7c3993c,0x3c99c3,0x3f7fffff,0xe7cf9f,0x3c99c3e7,0xe7c399,0x3160c080,0x40e1b,0xcbcbc37e, +0x7ec3c3db,0x3c3c3c18,0x81c087e,0x8683818,0x60f0e08,0x81422418,0x18244281,0xbd5a2418,0x18245abd,0x818181ff,0xff8181,0xa1c181ff,0xff8995,0x63633e,0x3e6363,0x606060,0x606060,0x3e60603e,0x3e0303,0x3e60603e,0x3e6060,0x3e636363, +0x606060,0x3e03033e,0x3e6060,0x3e03033e,0x3e6363,0x60603e,0x606060,0x3e63633e,0x3e6363,0x3e63633e,0x3e6060,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x18181818,0x180018,0x666666,0x0,0x367f3600,0x367f36,0x3c067c18, +0x183e60,0x18366600,0x62660c,0xe1c361c,0x6e337b,0x181818,0x0,0x18183870,0x703818,0x18181c0e,0xe1c18,0xff3c6600,0x663c,0x7e181800,0x1818,0x0,0x60c0c00,0x7e000000,0x0,0x0,0x181800,0x18306040,0x2060c,0x6e76663c,0x3c6666,0x18181c18, +0x7e1818,0x3060663c,0x7e0c18,0x3018307e,0x3c6660,0x363c3830,0x30307e,0x603e067e,0x3c6660,0x3e06063c,0x3c6666,0x1830607e,0xc0c0c,0x3c66663c,0x3c6666,0x7c66663c,0x1c3060,0x181800,0x1818,0x181800,0xc1818,0xc183060,0x603018,0x7e0000, +0x7e00,0x30180c06,0x60c18,0x3060663c,0x180018,0x5676663c,0x7c0676,0x66663c18,0x66667e,0x3e66663e,0x3e6666,0x606663c,0x3c6606,0x6666361e,0x1e3666,0x3e06067e,0x7e0606,0x3e06067e,0x60606,0x7606067c,0x7c6666,0x7e666666,0x666666,0x1818183c, +0x3c1818,0x60606060,0x3c6660,0xe1e3666,0x66361e,0x6060606,0x7e0606,0x6b7f7763,0x636363,0x7e7e6e66,0x666676,0x6666663c,0x3c6666,0x3e66663e,0x60606,0x6666663c,0x6c366e,0x3e66663e,0x666636,0x3c06663c,0x3c6660,0x1818187e,0x181818,0x66666666, +0x7c6666,0x66666666,0x183c66,0x6b636363,0x63777f,0x183c6666,0x66663c,0x3c666666,0x181818,0x1830607e,0x7e060c,0x18181878,0x781818,0x180c0602,0x406030,0x1818181e,0x1e1818,0x63361c08,0x0,0x0,0x7f0000,0xc060300,0x0,0x603c0000,0x7c667c,0x663e0606, +0x3e6666,0x63c0000,0x3c0606,0x667c6060,0x7c6666,0x663c0000,0x3c067e,0xc3e0c38,0xc0c0c,0x667c0000,0x3e607c66,0x663e0606,0x666666,0x181c0018,0x3c1818,0x18180018,0xe181818,0x36660606,0x66361e,0x1818181c,0x3c1818,0x7f370000,0x63636b,0x663e0000, +0x666666,0x663c0000,0x3c6666,0x663e0000,0x63e6666,0x667c0000,0x607c6666,0x663e0000,0x60606,0x67c0000,0x3e603c,0x187e1800,0x701818,0x66660000,0x7c6666,0x66660000,0x183c66,0x63630000,0x363e6b,0x3c660000,0x663c18,0x66660000,0x3e607c66,0x307e0000, +0x7e0c18,0xc181870,0x701818,0x18181818,0x18181818,0x3018180e,0xe1818,0x794f0600,0x30}; + +typedef struct GPRECT +{ + int x; + int y; + int w; + int h; +} GPRECT; + +GPRECT gpbuttons[23]; + +#define GPRectMake(x,y,w,h) {x,y,w,h} + +/* +######################## +Graphics functions +######################## + */ + +static __inline__ +void gp_drawPixel8 ( int x, int y, unsigned char c, unsigned char *framebuffer ) +{ + *(framebuffer +(256*y)+x ) = c; +} + +static __inline__ +void gp_drawPixel16 ( int x, int y, unsigned short c, unsigned short *framebuffer ) +{ + *(framebuffer +(256*y)+x ) = c; +} + +static +void set_char8x8_16bpp (int xx,int yy,int offset,unsigned short mode,unsigned short *framebuffer) +{ + unsigned int y, pixel; + offset *= 2; + pixel = font8x8[0 + offset]; + for (y = 0; y < 4; y++) + { + if (pixel&(1<<(0+(y<<3)))) gp_drawPixel16(xx+0, yy+y, mode, framebuffer); + if (pixel&(1<<(1+(y<<3)))) gp_drawPixel16(xx+1, yy+y, mode, framebuffer); + if (pixel&(1<<(2+(y<<3)))) gp_drawPixel16(xx+2, yy+y, mode, framebuffer); + if (pixel&(1<<(3+(y<<3)))) gp_drawPixel16(xx+3, yy+y, mode, framebuffer); + if (pixel&(1<<(4+(y<<3)))) gp_drawPixel16(xx+4, yy+y, mode, framebuffer); + if (pixel&(1<<(5+(y<<3)))) gp_drawPixel16(xx+5, yy+y, mode, framebuffer); + if (pixel&(1<<(6+(y<<3)))) gp_drawPixel16(xx+6, yy+y, mode, framebuffer); + if (pixel&(1<<(7+(y<<3)))) gp_drawPixel16(xx+7, yy+y, mode, framebuffer); + } + pixel = font8x8[1 + offset]; + for (y = 0; y < 4; y++) + { + if (pixel&(1<<(0+(y<<3)))) gp_drawPixel16(xx+0, yy+y+4, mode, framebuffer); + if (pixel&(1<<(1+(y<<3)))) gp_drawPixel16(xx+1, yy+y+4, mode, framebuffer); + if (pixel&(1<<(2+(y<<3)))) gp_drawPixel16(xx+2, yy+y+4, mode, framebuffer); + if (pixel&(1<<(3+(y<<3)))) gp_drawPixel16(xx+3, yy+y+4, mode, framebuffer); + if (pixel&(1<<(4+(y<<3)))) gp_drawPixel16(xx+4, yy+y+4, mode, framebuffer); + if (pixel&(1<<(5+(y<<3)))) gp_drawPixel16(xx+5, yy+y+4, mode, framebuffer); + if (pixel&(1<<(6+(y<<3)))) gp_drawPixel16(xx+6, yy+y+4, mode, framebuffer); + if (pixel&(1<<(7+(y<<3)))) gp_drawPixel16(xx+7, yy+y+4, mode, framebuffer); + + } +} + +static +void set_char8x8_8bpp (int xx,int yy,int offset,unsigned char mode,unsigned char *framebuffer) +{ + unsigned int y, pixel; + offset *= 2; + pixel = font8x8[0 + offset]; + for (y = 0; y < 4; y++) + { + if (pixel&(1<<(0+(y<<3)))) gp_drawPixel8(xx+0, yy+y, mode, framebuffer); + if (pixel&(1<<(1+(y<<3)))) gp_drawPixel8(xx+1, yy+y, mode, framebuffer); + if (pixel&(1<<(2+(y<<3)))) gp_drawPixel8(xx+2, yy+y, mode, framebuffer); + if (pixel&(1<<(3+(y<<3)))) gp_drawPixel8(xx+3, yy+y, mode, framebuffer); + if (pixel&(1<<(4+(y<<3)))) gp_drawPixel8(xx+4, yy+y, mode, framebuffer); + if (pixel&(1<<(5+(y<<3)))) gp_drawPixel8(xx+5, yy+y, mode, framebuffer); + if (pixel&(1<<(6+(y<<3)))) gp_drawPixel8(xx+6, yy+y, mode, framebuffer); + if (pixel&(1<<(7+(y<<3)))) gp_drawPixel8(xx+7, yy+y, mode, framebuffer); + } + pixel = font8x8[1 + offset]; + for (y = 0; y < 4; y++) + { + if (pixel&(1<<(0+(y<<3)))) gp_drawPixel8(xx+0, yy+y+4, mode, framebuffer); + if (pixel&(1<<(1+(y<<3)))) gp_drawPixel8(xx+1, yy+y+4, mode, framebuffer); + if (pixel&(1<<(2+(y<<3)))) gp_drawPixel8(xx+2, yy+y+4, mode, framebuffer); + if (pixel&(1<<(3+(y<<3)))) gp_drawPixel8(xx+3, yy+y+4, mode, framebuffer); + if (pixel&(1<<(4+(y<<3)))) gp_drawPixel8(xx+4, yy+y+4, mode, framebuffer); + if (pixel&(1<<(5+(y<<3)))) gp_drawPixel8(xx+5, yy+y+4, mode, framebuffer); + if (pixel&(1<<(6+(y<<3)))) gp_drawPixel8(xx+6, yy+y+4, mode, framebuffer); + if (pixel&(1<<(7+(y<<3)))) gp_drawPixel8(xx+7, yy+y+4, mode, framebuffer); + + } +} + +void gp_drawString (int x,int y,int len,char *buffer,unsigned short color,void *framebuffer) +{ + int l,base=0; + + for (l=0;lmAudioData; + + outQB->mAudioDataByteSize = AUDIO_BUFFER_SIZE; + AudioQueueSetParameter(outQ, kAudioQueueParam_Volume, __audioVolume); + //fprintf(stderr, "sound_lastlen %d\n", sound_lastlen); + if(__emulation_paused) + { + memset(coreAudioBuffer, 0, AUDIO_BUFFER_SIZE); + } + else + { + S9xMixSamplesO((short*)coreAudioBuffer, (AUDIO_BUFFER_SIZE) / 2, 0); + } + AudioQueueEnqueueBuffer(outQ, outQB, 0, NULL); +} + +int app_OpenSound(int buffersize) { + Float64 sampleRate = 22050.0; + int i; + UInt32 bufferBytes; + + soundBufferSize = buffersize; + + app_MuteSound(); + + soundInit = 0; + + in.mDataFormat.mSampleRate = sampleRate; + in.mDataFormat.mFormatID = kAudioFormatLinearPCM; + in.mDataFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger + | kAudioFormatFlagIsPacked; + in.mDataFormat.mBytesPerPacket = 4; + in.mDataFormat.mFramesPerPacket = isStereo ? 1 : 2; + in.mDataFormat.mBytesPerFrame = isStereo ? 4 : 2; + in.mDataFormat.mChannelsPerFrame = isStereo ? 2 : 1; + in.mDataFormat.mBitsPerChannel = 16; + + + /* Pre-buffer before we turn on audio */ + UInt32 err; + err = AudioQueueNewOutput(&in.mDataFormat, + AQBufferCallback, + NULL, + NULL, + kCFRunLoopCommonModes, + 0, + &in.queue); + + bufferBytes = AUDIO_BUFFER_SIZE; + + for (i=0; imAudioDataByteSize = AUDIO_BUFFER_SIZE; //samples_per_frame * 2; //inData->mDataFormat.mBytesPerFrame; //(inData->frameCount * 4 < (sndOutLen) ? inData->frameCount * 4 : (sndOutLen)); + AudioQueueEnqueueBuffer(in.queue, in.mBuffers[i], 0, NULL); + } + + soundInit = 1; + err = AudioQueueStart(in.queue, NULL); + + return 0; +} + +void app_CloseSound(void) { + if( soundInit == 1 ) + { + AudioQueueDispose(in.queue, true); + soundInit = 0; + } +} + + +void app_MuteSound(void) { + if( soundInit == 1 ) + { + app_CloseSound(); + } +} + +void app_DemuteSound(int buffersize) { + if( soundInit == 0 ) + { + app_OpenSound(buffersize); + } +} diff --git a/src/snes4iphone_src/iphone_sdk.h b/src/snes4iphone_src/iphone_sdk.h new file mode 100755 index 0000000..9b28705 --- /dev/null +++ b/src/snes4iphone_src/iphone_sdk.h @@ -0,0 +1,69 @@ +#ifndef _IPHONE_SDK_H_ +#define _IPHONE_SDK_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#define INP_BUTTON_UP (0) +#define INP_BUTTON_LEFT (2) +#define INP_BUTTON_DOWN (4) +#define INP_BUTTON_RIGHT (6) +#define INP_BUTTON_START (8) +#define INP_BUTTON_SELECT (9) +#define INP_BUTTON_L (10) +#define INP_BUTTON_R (11) +#define INP_BUTTON_HARDLEFT (12) +#define INP_BUTTON_HARDRIGHT (13) +#define INP_BUTTON_HARDDOWN (14) +#define INP_BUTTON_HARDUP (15) +#define INP_BUTTON_L2 (22) +#define INP_BUTTON_R2 (23) +#define INP_BUTTON_STICK_PUSH (27) +#define INP_BUTTON_MENU (31) + +#define SOUND_THREAD_SOUND_ON 1 +#define SOUND_THREAD_SOUND_OFF 2 +#define SOUND_THREAD_PAUSE 3 +#define gp2x_flipscreen() + +void gp_drawString (int x,int y,int len,char *buffer,unsigned short color,void *framebuffer); +void gp_clearFramebuffer16(unsigned short *framebuffer, unsigned short pal); +void gp_setCpuspeed(unsigned int cpuspeed); +void gp_initGraphics(unsigned short bpp, int flip, int applyMmuHack); +void gp_setFramebuffer(int flip, int sync); +void gp2x_video_setpalette(void); +void gp_initSound(int rate, int bits, int stereo, int Hz, int frag); +void gp_stopSound(void); +void gp_Reset(void); +void gp2x_enableIRQ(void); +void gp2x_disableIRQ(void); +void gp2x_sound_volume(int l, int r); +unsigned long gp2x_timer_read(void); +unsigned int gp_getButton(unsigned char enable_diagnals); +void gp2x_video_RGB_setscaling(int W, int H); +void gp2x_sound_play_bank(int bank); +void gp2x_sound_sync(void); +void BlitBufferToScreen(void *bufferFrom, void *bufferTo); +void set_gamma(int g100); +void updateScreen(); +void gp_deinitGraphics(void); + +extern unsigned short *framebuffer16[]; +extern unsigned char *framebuffer8[]; +extern void *GizPrimaryFrameBuffer; +extern volatile unsigned short gp2x_palette[512][2]; + +extern unsigned short* screenbuffer; +extern unsigned short BaseAddress[320*240]; +extern int __emulation_run; +extern int __emulation_saving; + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/src/snes4iphone_src/keycodes.h b/src/snes4iphone_src/keycodes.h new file mode 100755 index 0000000..c721dd6 --- /dev/null +++ b/src/snes4iphone_src/keycodes.h @@ -0,0 +1,108 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#define SCANCODE_K 167 +#define SCANCODE_ESC 197 +#define SCANCODE_CURSORBLOCKRIGHT 175 +#define SCANCODE_CURSORBLOCKLEFT 173 +#define SCANCODE_CURSORBLOCKUP 190 +#define SCANCODE_CURSORBLOCKDOWN 158 +#define SCANCODE_H 165 +#define SCANCODE_N 182 +#define SCANCODE_J 166 +#define SCANCODE_U 150 +#define SCANCODE_ENTER 196 +#define SCANCODE_SPACE 192 +#define SCANCODE_A 160 +#define SCANCODE_V 180 +#define SCANCODE_Q 144 +#define SCANCODE_Z 149 +#define SCANCODE_B 181 +#define SCANCODE_W 145 +#define SCANCODE_S 161 +#define SCANCODE_M 183 +#define SCANCODE_E 146 +#define SCANCODE_X 178 +#define SCANCODE_COMMA 184 +#define SCANCODE_R 147 +#define SCANCODE_D 162 +#define SCANCODE_PERIOD 185 +#define SCANCODE_T 148 +#define SCANCODE_C 179 +#define SCANCODE_SLASH 186 +#define SCANCODE_Y 177 +#define SCANCODE_CURSORRIGHT 206 +#define SCANCODE_CURSORLEFT 207 +#define SCANCODE_CURSORDOWN 205 +#define SCANCODE_CURSORUP 204 +#define SCANCODE_KEYPADENTER 195 +#define SCANCODE_KEYPADPLUS 222 +#define SCANCODE_INSERT 143 +#define SCANCODE_REMOVE 188 +#define SCANCODE_HOME 189 +#define SCANCODE_END 157 +#define SCANCODE_PAGEUP 191 +#define SCANCODE_PAGEDOWN 159 +#define SCANCODE_0 138 +#define SCANCODE_1 129 +#define SCANCODE_2 130 +#define SCANCODE_3 131 +#define SCANCODE_4 132 +#define SCANCODE_5 133 +#define SCANCODE_6 134 +#define SCANCODE_7 135 +#define SCANCODE_8 136 +#define SCANCODE_9 137 +#define SCANCODE_BACKSPACE 193 +#define SCANCODE_F1 208 +#define SCANCODE_F2 209 +#define SCANCODE_F3 210 +#define SCANCODE_F4 211 +#define SCANCODE_F5 212 +#define SCANCODE_F6 213 +#define SCANCODE_F7 214 +#define SCANCODE_F8 215 +#define SCANCODE_F9 216 +#define SCANCODE_F10 217 +#define SCANCODE_F11 198 +#define SCANCODE_F12 223 +#define SCANCODE_P 153 +#define SCANCODE_LESSER 176 +#define SCANCODE_PLUS 155 diff --git a/src/snes4iphone_src/language.h b/src/snes4iphone_src/language.h new file mode 100755 index 0000000..d798c6c --- /dev/null +++ b/src/snes4iphone_src/language.h @@ -0,0 +1,328 @@ +/******************************************************************************* + Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and + Jerremy Koot (jkoot@snes9x.com) + + (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net) + + (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net), + funkyass (funkyass@spam.shaw.ca), + Joel Yliluoma (http://iki.fi/bisqwit/) + Kris Bleakley (codeviolation@hotmail.com), + Matthew Kendora, + Nach (n-a-c-h@users.sourceforge.net), + Peter Bortas (peter@bortas.org) and + zones (kasumitokoduck@yahoo.com) + + C4 x86 assembler and some C emulation code + (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com), + _Demo_ (_demo_@zsnes.com), and Nach + + C4 C++ code + (c) Copyright 2003 Brad Jorsch + + DSP-1 emulator code + (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson, + John Weidman, neviksti (neviksti@hotmail.com), + Kris Bleakley, Andreas Naive + + DSP-2 emulator code + (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and + Lord Nightmare (lord_nightmare@users.sourceforge.net + + OBC1 emulator code + (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and + Kris Bleakley + Ported from x86 assembler to C by sanmaiwashi + + SPC7110 and RTC C++ emulator code + (c) Copyright 2002 Matthew Kendora with research by + zsKnight, John Weidman, and Dark Force + + S-DD1 C emulator code + (c) Copyright 2003 Brad Jorsch with research by + Andreas Naive and John Weidman + + S-RTC C emulator code + (c) Copyright 2001 John Weidman + + ST010 C++ emulator code + (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora + + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + + Super FX C emulator code + (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman + + + SH assembler code partly based on x86 assembler code + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + + + Specific ports contains the works of other authors. See headers in + individual files. + + Snes9x homepage: http://www.snes9x.com + + Permission to use, copy, modify and distribute Snes9x in both binary and + source form, for non-commercial purposes, is hereby granted without fee, + providing that this license information and copyright notice appear with + all copies and any derived work. + + This software is provided 'as-is', without any express or implied + warranty. In no event shall the authors be held liable for any damages + arising from the use of this software. + + Snes9x is freeware for PERSONAL USE only. Commercial users should + seek permission of the copyright holders first. Commercial use includes + charging money for Snes9x or software derived from Snes9x. + + The copyright holders request that bug fixes and improvements to the code + should be forwarded to them so everyone can benefit from the modifications + in future versions. + + Super NES and Super Nintendo Entertainment System are trademarks of + Nintendo Co., Limited and its subsidiary companies. +*******************************************************************************/ + +/* This is where all the GUI text strings will eventually end up */ + +#define WINDOW_TITLE "Snes9X v%s for Windows(NK Custom)" + +#define MY_REG_KEY "Software\\Emulators\\Snes9X" + +#define REG_KEY_VER "1.31" + +#define DISCLAIMER_TEXT "Snes9X v%s for Windows.\r\n" \ + "(c) Copyright 1996 - 2002 Gary Henderson and Jerremy Koot.\r\n" \ + "(c) Copyright 2001- 2004 John Weidman.\r\n" \ + "(c) Copyright 2002 - 2004 blip, Brad Jorsch, funkyass, Joel Yliluoma, Kris Bleakley, Matthew Kendora, Nach, Peter Bortas, zones.\r\n\r\n" \ + "Snes9X is a Super Nintendo Entertainment System\r\n" \ + "emulator that allows you to play most games designed\r\n" \ + "for the SNES on your PC.\r\n\r\n" \ + "Please visit http://www.snes9x.com for\r\n" \ + "up-to-the-minute information and help on Snes9X.\r\n\r\n" \ + "Nintendo is a trade mark." + + +#define APP_NAME "Snes9x" +/* possible global strings */ +#define SNES9X_INFO "Snes9x: Information" +#define SNES9X_WARN "Snes9x: WARNING!" +#define SNES9X_DXS "Snes9X: DirectSound" +#define SNES9X_SNDQ "Snes9X: Sound CPU Question" +#define SNES9X_NP_ERROR "Snes9X: NetPlay Error" +#define BUTTON_OK "&OK" +#define BUTTON_CANCEL "&Cancel" + +/* Gamepad Dialog Strings */ +#define INPUTCONFIG_TITLE "Input Configuration" +#define INPUTCONFIG_JPTOGGLE "Enable" +#define INPUTCONFIG_DIAGTOGGLE "Toggle Diagonals" +/* #define INPUTCONFIG_OK "&OK" */ +/* #define INPUTCONFIG_CANCEL "&Cancel" */ +#define INPUTCONFIG_JPCOMBO "Joypad #%d" +#define INPUTCONFIG_LABEL_UP "Up" +#define INPUTCONFIG_LABEL_DOWN "Down" +#define INPUTCONFIG_LABEL_LEFT "Left" +#define INPUTCONFIG_LABEL_RIGHT "Right" +#define INPUTCONFIG_LABEL_A "A" +#define INPUTCONFIG_LABEL_B "B" +#define INPUTCONFIG_LABEL_X "X" +#define INPUTCONFIG_LABEL_Y "Y" +#define INPUTCONFIG_LABEL_L "L" +#define INPUTCONFIG_LABEL_R "R" +#define INPUTCONFIG_LABEL_START "Start" +#define INPUTCONFIG_LABEL_SELECT "Select" +#define INPUTCONFIG_LABEL_UPLEFT "Up Left" +#define INPUTCONFIG_LABEL_UPRIGHT "Up Right" +#define INPUTCONFIG_LABEL_DOWNRIGHT "Down Right" +#define INPUTCONFIG_LABEL_DOWNLEFT "Down Left" +#define INPUTCONFIG_LABEL_BLUE "Blue means the current key/button is already mapped; Red means it's a Snes9x/Windows reserved key." + +/* gaming buttons and axises */ +#define GAMEDEVICE_JOYNUMPREFIX "(J%d)" +#define GAMEDEVICE_JOYBUTPREFIX "#[%d]" +#define GAMEDEVICE_XNEG "Left" +#define GAMEDEVICE_XPOS "Right" +#define GAMEDEVICE_YPOS "Up" +#define GAMEDEVICE_YNEG "Down" +#define GAMEDEVICE_POVLEFT "POV Left" +#define GAMEDEVICE_POVRIGHT "POV Right" +#define GAMEDEVICE_POVUP "POV Up" +#define GAMEDEVICE_POVDOWN "POV Down" +#define GAMEDEVICE_POVDNLEFT "POV Dn Left" +#define GAMEDEVICE_POVDNRIGHT "POV Dn Right" +#define GAMEDEVICE_POVUPLEFT "POV Up Left" +#define GAMEDEVICE_POVUPRIGHT "POV Up Right" +#define GAMEDEVICE_ZPOS "Z Up" +#define GAMEDEVICE_ZNEG "Z Down" +#define GAMEDEVICE_RPOS "R Up" +#define GAMEDEVICE_RNEG "R Down" +#define GAMEDEVICE_UPOS "U Up" +#define GAMEDEVICE_UNEG "U Down" +#define GAMEDEVICE_VPOS "V Up" +#define GAMEDEVICE_VNEG "V Down" +#define GAMEDEVICE_BUTTON "Button %d" + +/* gaming general */ +#define GAMEDEVICE_DISABLED "Disabled" + +/* gaming keys */ +#define GAMEDEVICE_KEY "#%d" +#define GAMEDEVICE_NUMPADPREFIX "Numpad-%c" +#define GAMEDEVICE_VK_TAB "Tab" +#define GAMEDEVICE_VK_BACK "Backspace" +#define GAMEDEVICE_VK_CLEAR "Delete" +#define GAMEDEVICE_VK_RETURN "Enter" +#define GAMEDEVICE_VK_LSHIFT "LShift" +#define GAMEDEVICE_VK_RSHIFT "RShift" +#define GAMEDEVICE_VK_LCONTROL "LCTRL" +#define GAMEDEVICE_VK_RCONTROL "RCTRL" +#define GAMEDEVICE_VK_LMENU "LAlt" +#define GAMEDEVICE_VK_RMENU "RAlt" +#define GAMEDEVICE_VK_PAUSE "Pause" +#define GAMEDEVICE_VK_CAPITAL "Capslock" +#define GAMEDEVICE_VK_ESCAPE "Disabled" +#define GAMEDEVICE_VK_SPACE "Space" +#define GAMEDEVICE_VK_PRIOR "PgUp" +#define GAMEDEVICE_VK_NEXT "PgDn" +#define GAMEDEVICE_VK_HOME "Home" +#define GAMEDEVICE_VK_END "End" +#define GAMEDEVICE_VK_LEFT "Left" +#define GAMEDEVICE_VK_RIGHT "Right" +#define GAMEDEVICE_VK_UP "Up" +#define GAMEDEVICE_VK_DOWN "Down" +#define GAMEDEVICE_VK_SELECT "Select" +#define GAMEDEVICE_VK_PRINT "Print" +#define GAMEDEVICE_VK_EXECUTE "Execute" +#define GAMEDEVICE_VK_SNAPSHOT "SnapShot" +#define GAMEDEVICE_VK_INSERT "Insert" +#define GAMEDEVICE_VK_DELETE "Delete" +#define GAMEDEVICE_VK_HELP "Help" +#define GAMEDEVICE_VK_LWIN "LWinKey" +#define GAMEDEVICE_VK_RWIN "RWinKey" +#define GAMEDEVICE_VK_APPS "AppKey" +#define GAMEDEVICE_VK_MULTIPLY "Numpad *" +#define GAMEDEVICE_VK_ADD "Numpad +" +#define GAMEDEVICE_VK_SEPARATOR "\\" +#define GAMEDEVICE_VK_OEM_1 "Semi-Colon" +#define GAMEDEVICE_VK_OEM_7 "Apostrophe" +#define GAMEDEVICE_VK_OEM_COMMA "Comma" +#define GAMEDEVICE_VK_OEM_PERIOD "Period" +#define GAMEDEVICE_VK_SUBTRACT "Numpad -" +#define GAMEDEVICE_VK_DECIMAL "Numpad ." +#define GAMEDEVICE_VK_DIVIDE "Numpad /" +#define GAMEDEVICE_VK_NUMLOCK "Num-lock" +#define GAMEDEVICE_VK_SCROLL "Scroll-lock" + +/* evil things I found in WinProc */ + +#define WINPROC_TURBOMODE_ON "Turbo Mode Activated" +#define WINPROC_TURBOMODE_OFF "Turbo Mode Deactivated" +#define WINPROC_TURBOMODE_TEXT "Turbo Mode" +#define WINPROC_HDMA_TEXT "HDMA emulation" +#define WINPROC_BG1 "BG#1" /* Background Layers */ +#define WINPROC_BG2 "BG#2" +#define WINPROC_BG3 "BG#3" +#define WINPROC_BG4 "BG#4" +#define WINPROC_SPRITES "Sprites" +#define WINPROC_PADSWAP "Joypad swapping" +#define WINPROC_CONTROLERS0 "Multiplayer 5 on #0" +#define WINPROC_CONTROLERS1 "Joypad on #0" +#define WINPROC_CONTROLERS2 "Mouse on #1" +#define WINPROC_CONTROLERS3 "Mouse on #0" +#define WINPROC_CONTROLERS4 "Superscope on #1" +#define WINPROC_CONTROLERS5 "Justifier 1 on #1" +#define WINPROC_CONTROLERS6 "Justifier 2 on #1" +#define WINPROC_BGHACK "Background layering hack" +#define WINPROC_MODE7INTER "Mode 7 Interpolation" +#define WINPROC_TRANSPARENCY "Transparency effects" +#define WINPROC_CLIPWIN "Graphic clip windows" +#define WINPROC_PAUSE "Pause" +#define WINPROC_EMUFRAMETIME "Emulated frame time: %dms" +#define WINPROC_AUTOSKIP "Auto Frame Skip" +#define WINPROC_FRAMESKIP "Frame skip: %d" +#define WINPROC_TURBO_R_ON "Turbo R Activated" +#define WINPROC_TURBO_R_OFF "Turbo R Deactivated" +#define WINPROC_TURBO_L_ON "Turbo L Activated" +#define WINPROC_TURBO_L_OFF "Turbo L Deactivated" +#define WINPROC_TURBO_X_ON "Turbo X Activated" +#define WINPROC_TURBO_X_OFF "Turbo X Deactivated" +#define WINPROC_TURBO_Y_ON "Turbo Y Activated" +#define WINPROC_TURBO_Y_OFF "Turbo Y Deactivated" +#define WINPROC_TURBO_A_ON "Turbo A Activated" +#define WINPROC_TURBO_A_OFF "Turbo A Deactivated" +#define WINPROC_TURBO_B_ON "Turbo B Activated" +#define WINPROC_TURBO_B_OFF "Turbo B Deactivated" +#define WINPROC_TURBO_SEL_ON "Turbo Select Activated" +#define WINPROC_TURBO_SEL_OFF "Turbo Select Deactivated" +#define WINPROC_TURBO_START_ON "Turbo Start Activated" +#define WINPROC_TURBO_START_OFF "Turbo Start Deactivated" +#define WINPROC_FILTER_RESTART "You will need to restart Snes9x before the output image\nprocessing option change will take effect." +#define WINPROC_DISCONNECT "Disconnect from the NetPlay server first." +#define WINPROC_NET_RESTART "Your game will be reset after the ROM has been sent due to\nyour 'Sync Using Reset Game' setting.\n\n" +#define WINPROC_INTERPOLATED_SND "Interpolated sound" +#define WINPROC_SYNC_SND "Sync sound" +#define WINPROC_SND_OFF "Disabling the sound CPU emulation will help to improve\nemulation speed but you will not hear any sound effects\nor music. If you later want to re-enable the sound CPU\nemulation you will need to reset your game before it will\ntake effect.\n\nAre you sure this is what you want?" +#define WINPROC_SND_RESTART "You will need to reset your game or load another one\nbefore enabling the sound CPU will take effect." + +/* Emulator Settings */ + +#define EMUSET_TITLE "Emulation Settings" +#define EMUSET_LABEL_FREEZE "Freeze Folder Directory" +#define EMUSET_BROWSE "&Browse..." +#define EMUSET_LABEL_ASRAM "Auto-Save S-RAM" +#define EMUSET_LABEL_ASRAM_TEXT "seconds after last change (0 disables auto-save)" +#define EMUSET_LABEL_SMAX "Skip at most" +#define EMUSET_LABEL_SMAX_TEXT "frames in auto-frame rate mode" +#define EMUSET_LABEL_STURBO "Skip Rendering" +#define EMUSET_LABEL_STURBO_TEXT "frames in Turbo mode" +#define EMUSET_TOGGLE_TURBO "Tab Toggles Turbo" + +/* Netplay Options */ + +#define NPOPT_TITLE "Netplay Options" +#define NPOPT_LABEL_PORTNUM "Socket Port Number" +#define NPOPT_LABEL_PAUSEINTERVAL "Ask Server to Pause when" +#define NPOPT_LABEL_PAUSEINTERVAL_TEXT "frames behind" +#define NPOPT_LABEL_MAXSKIP "Maximum Frame Rate Skip" +#define NPOPT_SYNCBYRESET "Sync By Reset" +#define NPOPT_SENDROM "Send ROM Image to Client on Connect" +#define NPOPT_ACTASSERVER "Act As Server" +#define NPOPT_PORTNUMBLOCK "Port Settings" +#define NPOPT_CLIENTSETTINGSBLOCK "Client Settings" +#define NPOPT_SERVERSETTINGSBLOCK "Server Settings" + +/* Netplay Connect */ + + +#define NPCON_TITLE "Connect to Server" +#define NPCON_LABEL_SERVERADDY "Server Address" +#define NPCON_LABEL_PORTNUM "Port Number" +#define NPCON_CLEARHISTORY "Clear History" + + +/* Movie Messages */ + +#define MOVIE_INFO_REPLAY "Movie replay" +#define MOVIE_INFO_RECORD "Movie record" +#define MOVIE_INFO_RERECORD "Movie re-record" +#define MOVIE_INFO_REWIND "Movie rewind" +#define MOVIE_INFO_STOP "Movie stop" +#define MOVIE_INFO_END "Movie end" +#define MOVIE_INFO_RECORDING_ENABLED "Recording enabled" +#define MOVIE_INFO_RECORDING_DISABLED "Recording disabled" +#define MOVIE_ERR_SNAPSHOT_WRONG_MOVIE "Snapshot not from this movie" +#define MOVIE_ERR_SNAPSHOT_NOT_MOVIE "Not a movie snapshot" +#define MOVIE_ERR_COULD_NOT_OPEN "Could not open movie file." +#define MOVIE_ERR_NOT_FOUND "File not found." +#define MOVIE_ERR_WRONG_FORMAT "File is wrong format." +#define MOVIE_ERR_WRONG_VERSION "File is wrong version." + + +/* AVI Messages */ + +#define AVI_CONFIGURATION_CHANGED "AVI recording stopped (configuration settings changed)." diff --git a/src/snes4iphone_src/loadzip.cpp b/src/snes4iphone_src/loadzip.cpp new file mode 100755 index 0000000..1bbcaac --- /dev/null +++ b/src/snes4iphone_src/loadzip.cpp @@ -0,0 +1,220 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ + +#include "port.h" + +#ifdef UNZIP_SUPPORT +/**********************************************************************************************/ +/* Loadzip.CPP */ +/* This file contains a function for loading a SNES ROM image from a zip file */ +/**********************************************************************************************/ + +#include +#include + +#ifndef NO_INLINE_SET_GET +#define NO_INLINE_SET_GET +#endif + +#include "snes9x.h" +#include "memmap.h" + +#include "unzip.h" +//#include +#include +#include + +bool8 LoadZip(const char* zipname, + int32 *TotalFileSize, + int32 *headers) +{ + *TotalFileSize = 0; + *headers = 0; + + unzFile file = unzOpen(zipname); + if(file == NULL) + return (FALSE); + + // find largest file in zip file (under MAX_ROM_SIZE) + // or a file with extension .1 + char filename[132]; + int filesize = 0; + int port = unzGoToFirstFile(file); + unz_file_info info; + while(port == UNZ_OK) + { + char name[132]; + unzGetCurrentFileInfo(file, &info, name,128, NULL,0, NULL,0); + +#if 0 + int calc_size = info.uncompressed_size / 0x2000; + calc_size *= 0x2000; + if(!(info.uncompressed_size - calc_size == 512 || info.uncompressed_size == calc_size)) + { + port = unzGoToNextFile(file); + continue; + } +#endif + + if(info.uncompressed_size > (CMemory::MAX_ROM_SIZE + 512)) + { + port = unzGoToNextFile(file); + continue; + } + + if ((int) info.uncompressed_size > filesize) + { + strcpy(filename,name); + filesize = info.uncompressed_size; + } + int len = strlen(name); + if(name[len-2] == '.' && name[len-1] == '1') + { + strcpy(filename,name); + filesize = info.uncompressed_size; + break; + } + port = unzGoToNextFile(file); + } + if( !(port == UNZ_END_OF_LIST_OF_FILE || port == UNZ_OK) || filesize == 0) + { + unzClose(file); + return (FALSE); + } + + // Find extension + char tmp[2]; + tmp[0] = tmp[1] = 0; + char *ext = strrchr(filename,'.'); + if(ext) ext++; + else ext = tmp; + + uint8 *ptr = Memory.ROM; + bool8 more = FALSE; + + unzLocateFile(file,filename,1); + unzGetCurrentFileInfo(file, &info, filename,128, NULL,0, NULL,0); + + if( unzOpenCurrentFile(file) != UNZ_OK ) + { + unzClose(file); + return (FALSE); + } + + do + { +// assert(info.uncompressed_size <= CMemory::MAX_ROM_SIZE + 512); + int FileSize = info.uncompressed_size; + + int calc_size = FileSize / 0x2000; + calc_size *= 0x2000; + + int l = unzReadCurrentFile(file,ptr,FileSize); + if(unzCloseCurrentFile(file) == UNZ_CRCERROR) + { + unzClose(file); + return (FALSE); + } + + if(l <= 0 || l != FileSize) + { + unzClose(file); + switch(l) + { + case UNZ_ERRNO: + break; + case UNZ_EOF: + break; + case UNZ_PARAMERROR: + break; + case UNZ_BADZIPFILE: + break; + case UNZ_INTERNALERROR: + break; + case UNZ_CRCERROR: + break; + } + return (FALSE); + } + + if ((FileSize - calc_size == 512 && !Settings.ForceNoHeader) || + Settings.ForceHeader) + { + memmove (ptr, ptr + 512, calc_size); + (*headers)++; + FileSize -= 512; + } + ptr += FileSize; + (*TotalFileSize) += FileSize; + + int len; + if (ptr - Memory.ROM < CMemory::MAX_ROM_SIZE + 0x200 && + (isdigit (ext [0]) && ext [1] == 0 && ext [0] < '9')) + { + more = TRUE; + ext [0]++; + } + else if (ptr - Memory.ROM < CMemory::MAX_ROM_SIZE + 0x200 && + (((len = strlen (filename)) == 7 || len == 8) && + strncasecmp (filename, "sf", 2) == 0 && + isdigit (filename [2]) && isdigit (filename [3]) && isdigit (filename [4]) && + isdigit (filename [5]) && isalpha (filename [len - 1]))) + { + more = TRUE; + filename [len - 1]++; + } + else + more = FALSE; + + if(more) + { + if( unzLocateFile(file,filename,1) != UNZ_OK || + unzGetCurrentFileInfo(file, &info, filename,128, NULL,0, NULL,0) != UNZ_OK || + unzOpenCurrentFile(file) != UNZ_OK) + break; + } + + } while(more); + + unzClose(file); + return (TRUE); +} +#endif diff --git a/src/snes4iphone_src/m3d_func.S b/src/snes4iphone_src/m3d_func.S new file mode 100755 index 0000000..e5507a6 --- /dev/null +++ b/src/snes4iphone_src/m3d_func.S @@ -0,0 +1,93 @@ + + .align 4 + .globl funcSMULT1616 + .globl funcUMULT1616 + .globl funcSMULT32 + .globl funcUMULT32 + .globl funcUADDMULT1616 + .globl funcSADDMULT1616 + .globl funcSADDMULT32 + .globl funcUADDMULT32 + + + +// Int32 funcSMULT1616(Int32 a,Int32 b,Int32 dummy1,Int32 dummy2) +funcSMULT1616: + mov r2,r0 + mov r3,r1 + smull r0,r1,r3,r2 + mov r0,r0,lsr #16 + orr r0,r0,r1,lsl #16 + mov pc,lr + + +// Int32 funcUMULT1616(UInt32 a,UInt32 b,Int32 dummy1,Int32 dummy2) +funcUMULT1616: + mov r2,r0 + mov r3,r1 + umull r0,r1,r3,r2 + mov r0,r0,lsr #16 + orr r0,r0,r1,lsl #16 + mov pc,lr + +// Int32 funcSMULT32(Int32 a,Int32 b,Int32 dummy1,Int32 dummy2) +funcSMULT32: + mov r2,r0 + mov r3,r1 + smull r1,r0,r2,r3 + mov pc,lr + + +// UInt32 funcUMULT32(UInt32 a,UInt32 b,Int32 dummy1,Int32 dummy2) +funcUMULT32: + mov r2,r0 + mov r3,r1 + umull r1,r0,r3,r2 + mov pc,lr + +// UInt32 funcUADDMULT1616(UInt32 a,UInt32 b,UInt32 c,UInt32 d) +funcUADDMULT1616: + stmfd r13!,{r4,r5} + mov r4,r0 + mov r5,r1 + umull r0,r1,r5,r4 + umlal r0,r1,r2,r3 + mov r0,r0,lsr #16 + orr r0,r0,r1,lsl #16 + ldmfd r13!,{r4,r5} + mov pc,lr + +// Int32 funcSADDMULT1616(Int32 a,Int32 b,Int32 c,Int32 d) +funcSADDMULT1616: + stmfd r13!,{r4,r5} + mov r4,r0 + mov r5,r1 + smull r0,r1,r5,r4 + smlal r0,r1,r2,r3 + mov r0,r0,lsr #16 + orr r0,r0,r1,lsl #16 + ldmfd r13!,{r4,r5} + mov pc,lr + +// Int32 funcSADDMULT32(Int32 a,Int32 b,Int32 c,Int32 d) +funcSADDMULT32: + stmfd r13!,{r4,r5} + mov r4,r0 + mov r5,r1 + smull r1,r0,r5,r4 + smlal r1,r0,r2,r3 + ldmfd r13!,{r4,r5} + mov pc,lr + +// UInt32 funcUADDMULT32(UInt32 a,UInt32 b,UInt32 c,UInt32 d) +funcUADDMULT32: + stmfd r13!,{r4,r5} + mov r4,r0 + mov r5,r1 + umull r1,r0,r5,r4 + umlal r1,r0,r2,r3 + ldmfd r13!,{r4,r5} + mov pc,lr + + +.pool diff --git a/src/snes4iphone_src/main.cpp b/src/snes4iphone_src/main.cpp new file mode 100755 index 0000000..e635991 --- /dev/null +++ b/src/snes4iphone_src/main.cpp @@ -0,0 +1,1303 @@ + + +#include +#include +#include +#include +#include +#include + +#ifdef __GIZ__ +#define TIMER_1_SECOND 1000 +#include +#include +#include +#include +#include +#include "giz_kgsdk.h" +#endif + +#ifdef __GP2X__ +#define TIMER_1_SECOND 1000000 +#include "gp2x_sdk.h" +#include "squidgehack.h" +#endif + +#ifdef __IPHONE__ +#include +#include +#define TIMER_1_SECOND 1000 +#include "iphone_sdk.h" + +extern int isMultiTouching; +extern int __transparency; +extern int __speedhack; +extern int __autosave; +extern unsigned long gp2x_fps_debug; +extern int iphone_soundon; +extern volatile int __emulation_paused; +extern "C" void app_DemuteSound(int buffersize); +extern "C" void app_MuteSound(void); + +#endif + +#include "menu.h" +#include "snes9x.h" +#include "memmap.h" +#include "apu.h" +#include "gfx.h" +#include "soundux.h" +#include "snapshot.h" +#include "fxinst.h" +#include "fxemu.h" + +#define EMUVERSION "SquidgeSNES V0.37 01-Jun-06" + +//--------------------------------------------------------------------------- + +extern struct FxInit_s SuperFX; +extern struct FxRegs_s GSU; + +#ifdef __GP2X__ +extern "C" char joy_Count(); +extern "C" int InputClose(); +extern "C" int joy_getButton(int joyNumber); +#endif + +unsigned char gammatab[10][32]={ + {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, + 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F}, + {0x00,0x01,0x02,0x03,0x04,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x10, + 0x11,0x12,0x13,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F}, + {0x00,0x01,0x03,0x04,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11, + 0x12,0x13,0x14,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F}, + {0x00,0x02,0x04,0x06,0x07,0x08,0x09,0x0A,0x0C,0x0D,0x0E,0x0F,0x0F,0x10,0x11,0x12, + 0x13,0x14,0x15,0x16,0x16,0x17,0x18,0x19,0x19,0x1A,0x1B,0x1C,0x1C,0x1D,0x1E,0x1F}, + {0x00,0x03,0x05,0x07,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,0x13,0x14, + 0x14,0x15,0x16,0x17,0x17,0x18,0x19,0x19,0x1A,0x1B,0x1B,0x1C,0x1D,0x1D,0x1E,0x1F}, + {0x00,0x05,0x07,0x09,0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,0x13,0x14,0x14,0x15, + 0x16,0x16,0x17,0x18,0x18,0x19,0x1A,0x1A,0x1B,0x1B,0x1C,0x1C,0x1D,0x1D,0x1E,0x1F}, + {0x00,0x07,0x0A,0x0C,0x0D,0x0E,0x10,0x11,0x12,0x12,0x13,0x14,0x15,0x15,0x16,0x17, + 0x17,0x18,0x18,0x19,0x1A,0x1A,0x1B,0x1B,0x1B,0x1C,0x1C,0x1D,0x1D,0x1E,0x1E,0x1F}, + {0x00,0x0B,0x0D,0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x16,0x17,0x17,0x18,0x18, + 0x19,0x19,0x1A,0x1A,0x1B,0x1B,0x1B,0x1C,0x1C,0x1D,0x1D,0x1D,0x1E,0x1E,0x1E,0x1F}, + {0x00,0x0F,0x11,0x13,0x14,0x15,0x16,0x17,0x17,0x18,0x18,0x19,0x19,0x1A,0x1A,0x1A, + 0x1B,0x1B,0x1B,0x1C,0x1C,0x1C,0x1C,0x1D,0x1D,0x1D,0x1D,0x1E,0x1E,0x1E,0x1E,0x1F}, + {0x00,0x15,0x17,0x18,0x19,0x19,0x1A,0x1A,0x1B,0x1B,0x1B,0x1B,0x1C,0x1C,0x1C,0x1C, + 0x1D,0x1D,0x1D,0x1D,0x1D,0x1D,0x1D,0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,0x1F} +}; + +int32 gp32_fastmode = 1; +int gp32_8bitmode = 0; +int32 gp32_ShowSub = 0; +int gp32_fastsprite = 1; +int gp32_gammavalue = 0; +int squidgetranshack = 0; +uint8 *vrambuffer = NULL; +int globexit = 0; +int sndvolL, sndvolR; +char fps_display[256]; +int samplecount=0; +int enterMenu = 0; +void *currentFrameBuffer; +int16 oldHeight = 0; + +int compute_hex( char *x ) +{ + int v = 0; + while( *x ) + { + v = v * 16; + if( *x>='0' && *x<='9' ) + v = v + (*x - '0'); + if( *x>='A' && *x<='F' ) + v = v + (*x - 'A' + 10); + if( *x>='a' && *x<='f' ) + v = v + (*x - 'a' + 10); + x++; + } + return v; +} + +int compute_hex8( char *x ) +{ + char h[10]; + h[0] = x[0]; + h[1] = x[1]; + h[2] = 0; + return compute_hex( h ); +} + + + + +const uint32 crc32Table[256] = { +0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, +0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, +0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, +0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, +0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, +0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, +0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, +0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, +0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, +0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, +0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, +0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, +0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, +0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, +0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, +0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, +0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, +0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, +0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, +0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, +0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, +0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, +0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, +0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, +0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, +0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, +0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, +0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, +0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, +0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, +0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, +0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, +0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, +0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, +0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, +0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, +0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, +0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, +0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, +0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, +0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, +0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, +0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d +}; + +//CRC32 for char arrays +uint32 caCRC32(uint8 *array, uint32 size, register uint32 crc32) { + for (register uint32 i = 0; i < size; i++) { + crc32 = ((crc32 >> 8) & 0x00FFFFFF) ^ crc32Table[(crc32 ^ array[i]) & 0xFF]; + } + return ~crc32; +} + +void patch(int crc, unsigned char* buffer) +{ + char datFileName[1024]; + sprintf( datFileName, "/Applications/snes4iphone.app/snesadvance.dat"); + + char string[4096]; + char hex[100]; + FILE *fp = fopen( datFileName, "rb" ); + if( fp==NULL ) + { + fprintf(stderr, "No patch superdat found. The game may run slowly or not run at all.\n" ); + return; + } + + sprintf( hex, "%08X", crc ); + + while( !feof( fp ) ) + { + memset( string, 0, 4096 ); + fgets( string, 4095, fp ); + if( string[strlen(string)-1] == 13 || string[strlen(string)-1] == 10 ) + string[strlen(string)-1] = 0; + if( string[strlen(string)-1] == 13 || string[strlen(string)-1] == 10 ) + string[strlen(string)-1] = 0; + + char *ps = 0; + char *s = strtok( string, "|" ); + + + if( s ) + { + // this should be the CRC + // + if( strcmp( s, hex )!=0 ) + { + continue; + } + } + else + continue; + + // CRC matches, so grab the patch + // + int c = 0; + while( s ) + { + ps = s; + + if( c==1 ) + fprintf(stderr, "Game : %s\n", s ); + s = strtok( NULL, "|" ); + c++; + } + + /*printf( "patch = %s\n", ps );*/ + + // ps contains the patch + // + fprintf(stderr, "Patch :\n" ); + s = strtok( ps, "," ); + while( s ) + { + ps = s + (strlen(s)+1); + char *addr = strtok( s, "=" ); + char *val = strtok( NULL, "=" ); + + int iaddr = compute_hex(addr); + while( *val && *(val+1) ) + { + int c = compute_hex8( val ); + buffer[iaddr] = c; + fprintf(stderr, "%08x = %02x\n", iaddr, c ); + iaddr += 1; + val += 2; + } + + s = strtok( ps, "," ); + } + return; + } + fprintf(stderr, "No patch found. The game may run slowly or not run at all.\n" ); + +} + +int os9x_findhacks(int game_crc32){ + int i=0,j; + int _crc32; + char c; + char str[256]; + unsigned int size_snesadvance; + unsigned char *snesadvance; + FILE *f; + + if(!__speedhack) + { + return 0; + } +#ifdef __IPHONE__ + sprintf(str,"/Applications/snes4iphone.app/snesadvance.dat"); +#else + sprintf(str,"%s/snesadvance.dat",currentWorkingDir); +#endif + f=fopen(str,"rb"); + if (!f) return 0; + fseek(f,0,SEEK_END); + size_snesadvance=ftell(f); + fseek(f,0,SEEK_SET); + snesadvance=(unsigned char*)malloc(size_snesadvance); + fread(snesadvance,1,size_snesadvance,f); + fclose(f); + + for (;;) { + //get crc32 + j=i; + while ((i='0')&&(c<='9')) _crc32=(_crc32<<4)|(c-'0'); + else if ((c>='A')&&(c<='F')) _crc32=(_crc32<<4)|(c-'A'+10); + else if ((c>='a')&&(c<='f')) _crc32=(_crc32<<4)|(c-'a'+10); + j++; + } + if (game_crc32==_crc32) { + //int p=0; + for (;;) { + int adr,val; + + i++; + j=i; + while ((i>8)&0xFF; + ROM[adr+1]=val&0xFF; + } else ROM[adr]=val; + //} + + if (snesadvance[i]==0x0D) {free(snesadvance);return 1; } + } + + } + while ((i100) snesMenuOptions.volume=100; + gp2x_sound_volume(snesMenuOptions.volume,snesMenuOptions.volume); + } + else if (joy & (1<100) snesMenuOptions.volume=0; + gp2x_sound_volume(snesMenuOptions.volume,snesMenuOptions.volume); + } + + return val; + } +#endif + + + bool8 S9xReadMousePosition (int /* which1 */, int &/* x */, int & /* y */, + uint32 & /* buttons */) + { + S9xMessage (0,0,"read mouse"); + return (FALSE); + } + + bool8 S9xReadSuperScopePosition (int & /* x */, int & /* y */, + uint32 & /* buttons */) + { + S9xMessage (0,0,"read scope"); + return (FALSE); + } + + const char *S9xGetFilenameInc (const char *e) + { + S9xMessage (0,0,"get filename inc"); + return e; + } + + void S9xSyncSpeed(void) + { + //S9xMessage (0,0,"sync speed"); + } + + const char *S9xBasename (const char *f) + { + const char *p; + + S9xMessage (0,0,"s9x base name"); + + if ((p = strrchr (f, '/')) != NULL || (p = strrchr (f, '\\')) != NULL) + return (p + 1); + + return (f); + } + +}; + +bool8_32 S9xOpenSoundDevice (int mode, bool8_32 stereo, int buffer_size) + { + so.sound_switch = 255; + so.playback_rate = mode; + so.stereo = FALSE;//stereo; + return TRUE; + } + + +void S9xAutoSaveSRAM (void) +{ + //since I can't sync the data, there is no point in even writing the data + //out at this point. Instead I'm now saving the data as the users enter the menu. + S9xSaveSRAM(); + //sync(); can't sync when emulator is running as it causes delays +} + +void S9xLoadSRAM (void) +{ + char path[MAX_PATH]; + + sprintf(path,"%s%s%s",snesSramDir,DIR_SEPERATOR,S9xGetFilename (".srm")); + Memory.LoadSRAM (path); +} + +void S9xSaveSRAM (void) +{ + char path[MAX_PATH]; +#if 0 + if (CPU.SRAMModified) +#endif + { + sprintf(path,"%s%s%s",snesSramDir,DIR_SEPERATOR,S9xGetFilename (".srm")); + Memory.SaveSRAM (path); + sync(); + } +} + +bool JustifierOffscreen(void) +{ + return false; +} + +void JustifierButtons(uint32& justifiers) +{ +} + +static int SnesRomLoad() +{ + char filename[MAX_PATH+1]; + int check; + char text[256]; + FILE *stream=NULL; + + gp_clearFramebuffer16((unsigned short*)vrambuffer,0x0); + sprintf(text,"Loading Rom..."); + gp_drawString(0,0,strlen(text),text,0xFFFF,(unsigned char*)vrambuffer); + MenuFlip(); + S9xReset(); + //Save current rom shortname for save state etc + strcpy(currentRomFilename,romList[currentRomIndex].filename); + + // get full filename + sprintf(filename,"%s%s%s",romDir,DIR_SEPERATOR,currentRomFilename); + + if (!Memory.LoadROM (filename)) + { + sprintf(text,"Loading Rom...Failed"); + gp_drawString(0,0,strlen(text),text,0xFFFF,(unsigned char*)vrambuffer); + MenuFlip(); + MenuPause(); + return 0; + } + + sprintf(text,"Loading Rom...OK!"); + gp_drawString(0,0,strlen(text),text,0xFFFF,(unsigned char*)vrambuffer); + sprintf(text,"Loading Sram"); + gp_drawString(0,8,strlen(text),text,0xFFFF,(unsigned char*)vrambuffer); + MenuFlip(); + + //Memory.LoadSRAM (S9xGetFilename (".srm")); + S9xLoadSRAM(); + + //auto load default config for this rom if one exists + if (LoadMenuOptions(snesOptionsDir, currentRomFilename, MENU_OPTIONS_EXT, (char*)&snesMenuOptions, sizeof(snesMenuOptions),1)) + { + //failed to load options for game, so load the default global ones instead + if (LoadMenuOptions(snesOptionsDir, MENU_OPTIONS_FILENAME, MENU_OPTIONS_EXT, (char*)&snesMenuOptions, sizeof(snesMenuOptions),1)) + { + //failed to load global options, so use default values + SnesDefaultMenuOptions(); + } + } + + gp_clearFramebuffer16((unsigned short*)vrambuffer,0x0); + + return(1); +} + +static int SegAim() +{ +#ifdef __GIZ__ + int aim=FrameworkAudio_GetCurrentBank(); +#endif +#ifdef __GP2X__ + int aim=CurrentSoundBank; +#endif +#ifdef __IPHONE__ + // TODO + int aim=0; +#endif + + aim--; if (aim<0) aim+=8; + + return aim; +} + + + +void _makepath (char *path, const char *, const char *dir, + const char *fname, const char *ext) +{ + if (dir && *dir) + { + strcpy (path, dir); + strcat (path, "/"); + } + else + *path = 0; + strcat (path, fname); + if (ext && *ext) + { + strcat (path, "."); + strcat (path, ext); + } +} + +void _splitpath (const char *path, char *drive, char *dir, char *fname, + char *ext) +{ + *drive = 0; + + char *slash = strrchr (path, '/'); + if (!slash) + slash = strrchr (path, '\\'); + + char *dot = strrchr (path, '.'); + + if (dot && slash && dot < slash) + dot = NULL; + + if (!slash) + { + strcpy (dir, ""); + strcpy (fname, path); + if (dot) + { + *(fname + (dot - path)) = 0; + strcpy (ext, dot + 1); + } + else + strcpy (ext, ""); + } + else + { + strcpy (dir, path); + *(dir + (slash - path)) = 0; + strcpy (fname, slash + 1); + if (dot) + { + *(fname + (dot - slash) - 1) = 0; + strcpy (ext, dot + 1); + } + else + strcpy (ext, ""); + } +} + +// save state file I/O +int (*statef_open)(const char *fname, const char *mode); +int (*statef_read)(void *p, int l); +int (*statef_write)(void *p, int l); +void (*statef_close)(); +static FILE *state_file = 0; + +int state_unc_open(const char *fname, const char *mode) +{ + state_file = fopen(fname, mode); + return (int) state_file; +} + +int state_unc_read(void *p, int l) +{ + return fread(p, 1, l, state_file); +} + +int state_unc_write(void *p, int l) +{ + return fwrite(p, 1, l, state_file); +} + +void state_unc_close() +{ + fclose(state_file); +} + +void delay_us(unsigned long long us_count) +{ + usleep(us_count); +} + +void get_ticks_us(unsigned long long *ticks_return) +{ + struct timeval current_time; + gettimeofday(¤t_time, NULL); + + *ticks_return = + (unsigned long long)current_time.tv_sec * 1000000LL + current_time.tv_usec; +} + +char **g_argv; +#ifdef __IPHONE__ +extern "C" int iphone_main(char* filename) +#else +int main(int argc, char *argv[]) +#endif +{ + unsigned long frameskip_counter = 0; + unsigned long current_frameskip_value = 0; + unsigned long fps = 60; + unsigned long long last_screen_timestamp = 0; + unsigned long long last_frame_interval_timestamp = 0; + unsigned long long last_frame_value_timestamp = 0; + unsigned long interval_skipped_frames = 0; + unsigned long framecount = 0; + unsigned long frames_counted; + unsigned long skipped_frames = 0; + int __saved = 0; + char save_filename[1024]; + unsigned int i = 0; + unsigned int romrunning = 0; + int aim=0, done=0, skip=0, Frames=0, tick=0, efps=0, SaveFrames=0; + unsigned long Timer=0; + int action=0; + int romloaded=0; + char text[256]; + +#ifndef __IPHONE__ + g_argv = argv; +#endif + + // saves + statef_open = state_unc_open; + statef_read = state_unc_read; + statef_write = state_unc_write; + statef_close = state_unc_close; + + +#if defined (__GP2X__) + //getwd(currentWorkingDir); naughty do not use! + getcwd(currentWorkingDir, MAX_PATH); +#else + sprintf(currentWorkingDir, "%s", SYSTEM_DIR); +#endif + sprintf(snesOptionsDir,"%s%s%s",currentWorkingDir,DIR_SEPERATOR,SNES_OPTIONS_DIR); + sprintf(snesSramDir,"%s%s%s",currentWorkingDir,DIR_SEPERATOR,SNES_SRAM_DIR); + sprintf(snesSaveStateDir,"%s%s%s",currentWorkingDir,DIR_SEPERATOR,SNES_SAVESTATE_DIR); + + + InputInit(); // clear input context + + //ensure dirs exist + //should really check if these worked but hey whatever + mkdir(snesOptionsDir,0); + mkdir(snesSramDir,0); + mkdir(snesSaveStateDir,0); +#if 0 + printf("Loading global menu options\r\n"); fflush(stdout); + if (LoadMenuOptions(snesOptionsDir,MENU_OPTIONS_FILENAME,MENU_OPTIONS_EXT,(char*)&snesMenuOptions, sizeof(snesMenuOptions),0)) + { + // Failed to load menu options so default options + printf("Failed to load global options, so using defaults\r\n"); fflush(stdout); + SnesDefaultMenuOptions(); + } + + printf("Loading default rom directory\r\n"); fflush(stdout); + if (LoadMenuOptions(snesOptionsDir,DEFAULT_ROM_DIR_FILENAME,DEFAULT_ROM_DIR_EXT,(char*)snesRomDir, MAX_PATH,0)) + { + // Failed to load options to default rom directory to current working directory + printf("Failed to default rom dir, so using current dir\r\n"); fflush(stdout); + strcpy(snesRomDir,currentWorkingDir); + } +#endif + // Init graphics (must be done before MMUHACK) + gp_initGraphics(16,0,snesMenuOptions.mmuHack); + printf("Init'd graphics.\r\n"); fflush(stdout); +#if defined(__GP2X__) + if (snesMenuOptions.ramSettings) + { + printf("Craigs RAM settings are enabled. Now applying settings..."); fflush(stdout); + // craigix: --trc 6 --tras 4 --twr 1 --tmrd 1 --trfc 1 --trp 2 --trcd 2 + set_RAM_Timings(6, 4, 1, 1, 1, 2, 2); + printf("Done\r\n"); fflush(stdout); + } + else + { + printf("Using normal Ram settings.\r\n"); fflush(stdout); + } + + set_gamma(snesMenuOptions.gamma+100); +#endif + + UpdateMenuGraphicsGamma(); + + // Initialise Snes stuff + //////// + /////// + memset( &IAPU, 0, sizeof( SIAPU ) ); + memset( &CPU, 0, sizeof( SCPUState ) ); + memset( &GFX, 0, sizeof( SGFX ) ); + memset( &SNESGameFixes, 0, sizeof( SSNESGameFixes ) ); + memset( &SuperFX, 0, sizeof( FxInit_s ) ); + memset( &ICPU, 0, sizeof( SICPU ) ); + memset( &DSP1, 0, sizeof( SDSP1 ) ); + memset( &GSU, 0, sizeof( FxRegs_s ) ); + memset( &BG, 0, sizeof( SBG ) ); + memset( &PPU, 0, sizeof( SPPU ) ); + memset( &DMA[0], 0, sizeof( SDMA ) * 8); + memset( &IPPU, 0, sizeof( InternalPPU ) ); + memset( &SA1Registers, 0, sizeof( SSA1Registers ) ); + memset( &SA1, 0, sizeof( SSA1 ) ); + memset( &Settings, 0, sizeof( SSettings ) ); + + // ROM Options + Settings.SDD1Pack = true; + Settings.ForceLoROM = false; + Settings.ForceInterleaved = false; + Settings.ForceNotInterleaved = false; + Settings.ForceInterleaved = false; + Settings.ForceInterleaved2 = false; + Settings.ForcePAL = false; + Settings.ForceNTSC = false; + Settings.ForceHeader = false; + Settings.ForceNoHeader = false; + // Sound options + Settings.SoundSync = 0; + Settings.InterpolatedSound = true; + Settings.SoundEnvelopeHeightReading = true; + Settings.DisableSoundEcho = false; + Settings.DisableMasterVolume = false; + Settings.Mute = FALSE; + Settings.SoundSkipMethod = 0; + Settings.SoundPlaybackRate = 22050; + Settings.SixteenBitSound = true; + Settings.Stereo = false; + Settings.AltSampleDecode = 0;//os9x_sampledecoder; + Settings.ReverseStereo = FALSE; + Settings.SoundBufferSize = 0;//4; + Settings.SoundMixInterval = 0;//20; + Settings.DisableSampleCaching=TRUE; + Settings.FixFrequency = true; + // Tracing options + Settings.TraceDMA = false; + Settings.TraceHDMA = false; + Settings.TraceVRAM = false; + Settings.TraceUnknownRegisters = false; + Settings.TraceDSP = false; + // Joystick options + Settings.SwapJoypads = false; + Settings.JoystickEnabled = false; + // ROM timing options (see also H_Max above) + Settings.PAL = false; + Settings.FrameTimePAL = 20; + Settings.FrameTimeNTSC = 17; + Settings.FrameTime = Settings.FrameTimeNTSC; + // CPU options + Settings.CyclesPercentage = 100; + Settings.Shutdown = true; + Settings.ShutdownMaster = true; + Settings.APUEnabled = (iphone_soundon!=0); + Settings.DisableIRQ = 0; //os9x_DisableIRQ; + Settings.Paused = false; + Settings.H_Max = SNES_CYCLES_PER_SCANLINE; + Settings.HBlankStart = (256 * Settings.H_Max) / SNES_HCOUNTER_MAX; + Settings.SkipFrames=AUTO_FRAMERATE; + // ROM image and peripheral options + Settings.ForceSuperFX = false; + Settings.ForceNoSuperFX = false; + Settings.MultiPlayer5 = true; + Settings.Mouse = true; + Settings.SuperScope = true; + Settings.MultiPlayer5Master = true; + Settings.SuperScopeMaster = true; + Settings.MouseMaster = true; + Settings.SuperFX = false; + // SNES graphics options + Settings.BGLayering = false; + Settings.DisableGraphicWindows = false; + Settings.ForceTransparency = false; + Settings.ForceNoTransparency = false; + Settings.DisableHDMA = 0; //os9x_DisableHDMA; + Settings.Mode7Interpolate = false; + Settings.DisplayFrameRate = false; + + Settings.SixteenBit = 1; + Settings.Transparency = 1; + Settings.SupportHiRes = false; + + Settings.AutoSaveDelay = 5; + Settings.ApplyCheats = true; + + Settings.TurboSkipFrames = 20; + Settings.AutoMaxSkipFrames = 10; + + Settings.ForcedPause = 0; + Settings.StopEmulation = TRUE; + Settings.Paused = FALSE; + Settings.HBlankStart = (256 * Settings.H_Max) / SNES_HCOUNTER_MAX; + + /////////////////// + /////////////////// + + //GFX.RealPitch = GFX.Pitch = 318 * 2; + + GFX.Pitch = SNES_WIDTH * 2; + GFX.RealPitch = SNES_WIDTH * 2; + vrambuffer = (uint8 *) malloc (GFX.RealPitch * 480 * 2); + memset (vrambuffer, 0, GFX.RealPitch*480*2); + GFX.Screen = vrambuffer; // + (640*8) + 64; + + GFX.SubScreen = (uint8 *)malloc(GFX.RealPitch * 480 * 2); + GFX.ZBuffer = (uint8 *)malloc(GFX.RealPitch * 480 * 2); + GFX.SubZBuffer = (uint8 *)malloc(GFX.RealPitch * 480 * 2); + GFX.Delta = (GFX.SubScreen - GFX.Screen) >> 1; + GFX.PPL = GFX.Pitch >> 1; + GFX.PPLx2 = GFX.Pitch; + GFX.ZPitch = GFX.Pitch >> 1; + + if (Settings.ForceNoTransparency) + Settings.Transparency = FALSE; + + if (Settings.Transparency) + Settings.SixteenBit = TRUE; + + Settings.HBlankStart = (256 * Settings.H_Max) / SNES_HCOUNTER_MAX; + + if (!Memory.Init () || !S9xInitAPU()) + erk(); + + //S9xSetRenderPixelFormat (RGB565); + + if (!S9xGraphicsInit ()) + erk(); + + snesMenuOptions.menuVer=SNES_OPTIONS_VER; + snesMenuOptions.frameSkip=5; //preferences.frameSkip; + snesMenuOptions.soundOn=iphone_soundon; + snesMenuOptions.volume=100; + memset(snesMenuOptions.padConfig,0xFF,sizeof(snesMenuOptions.padConfig)); + snesMenuOptions.showFps= (gp2x_fps_debug ? 1 : 0); + snesMenuOptions.gamma=0; + snesMenuOptions.soundRate=2; + snesMenuOptions.cpuSpeed=19; + snesMenuOptions.autoSram=0; + snesMenuOptions.transparency=(__transparency ? 1 : 0); //preferences.transparency; + + + S9xReset(); + +#ifdef __IPHONE__ + if( (!strcasecmp(filename + (strlen(filename)-3), ".sv")) ) + { + unsigned long pos; + sprintf(save_filename, "%s", filename); + pos = strlen(filename)-17; + filename[pos] = '\0'; + __saved = 1; + sprintf(save_filename,"%s%s%s",romDir,DIR_SEPERATOR,save_filename); + } +#endif + //Save current rom shortname for save state etc + strcpy(currentRomFilename,filename); + + // get full filename + sprintf(filename,"%s%s%s",romDir,DIR_SEPERATOR,currentRomFilename); + + if (!Memory.LoadROM (filename)) + { + sprintf(text,"Loading Rom...Failed"); + gp_drawString(0,0,strlen(text),text,0xFFFF,(unsigned char*)vrambuffer); + MenuFlip(); + MenuPause(); + return 0; + } + + sprintf(Memory.ROMFilename, "%s", filename); + + sprintf(text,"Loading Rom...OK!"); + gp_drawString(0,0,strlen(text),text,0xFFFF,(unsigned char*)vrambuffer); + sprintf(text,"Loading Sram"); + gp_drawString(0,8,strlen(text),text,0xFFFF,(unsigned char*)vrambuffer); + + //Memory.LoadSRAM (S9xGetFilename (".srm")); + S9xLoadSRAM(); + + if(os9x_findhacks(Memory.ROMCRC32)) + { + sprintf(text,"Speedhack found! YAY!"); + gp_drawString(0,16,strlen(text),text,0xFFFF,(unsigned char*)vrambuffer); + } + MenuFlip(); + + gp_clearFramebuffer16((unsigned short*)vrambuffer,0x0); + + // any change in configuration? + gp_setCpuspeed(cpuSpeedLookup[snesMenuOptions.cpuSpeed]); + gp_clearFramebuffer16((unsigned short*)vrambuffer,0x0); + gp_clearFramebuffer16((unsigned short*)vrambuffer,0x0); + gp_clearFramebuffer16((unsigned short*)vrambuffer,0x0); + gp_clearFramebuffer16((unsigned short*)vrambuffer,0x0); + + if (snesMenuOptions.transparency) + { + Settings.Transparency = TRUE; + Settings.SixteenBit = TRUE; + } + else + { + Settings.Transparency = FALSE; + Settings.SixteenBit = TRUE; + } + + // TEMP EDIT + //if (!S9xGraphicsInit ()) + // erk(); + + if (snesMenuOptions.renderMode == RENDER_MODE_SCALED) + { + gp2x_video_RGB_setscaling(256,224); + } + + if (strlen(save_filename) > 0) + { + //LOGDEBUG("Loading: %s", save_filename); + LoadStateFile(save_filename); + //LOGDEBUG("Load finished"); + __saved = 2; + } + + S9xSetSoundMute (TRUE); + + CPU.APU_APUExecuting = Settings.APUEnabled = snesMenuOptions.soundOn; + + if (snesMenuOptions.soundOn) + { + //Settings.SoundPlaybackRate=(unsigned int)soundRates[snesMenuOptions.soundRate]; + samplecount=Settings.SoundPlaybackRate/(Settings.PAL ? 50 : 60); + Settings.SixteenBitSound=true; + Settings.Stereo=true; + Settings.SoundBufferSize=samplecount<<(1+(Settings.Stereo?1:0)); + so.stereo = Settings.Stereo; + so.playback_rate = Settings.SoundPlaybackRate; + S9xInitSound(); // (Settings.SoundPlaybackRate, Settings.Stereo, Settings.SoundBufferSize); + S9xSetPlaybackRate(so.playback_rate); + S9xSetSoundMute (FALSE); + app_DemuteSound(Settings.SoundBufferSize); + } + + + const long frame_speed = (Settings.PAL ? Settings.FrameTimePAL : Settings.FrameTimeNTSC); + fps = (Settings.PAL ? 50 : 60); + + int skipcount = 0; + int skipper = 0; + unsigned long tickframe = 0; + unsigned long frame_ticks_total = 0; + while (1) + { + unsigned long frame_ticks; + + Timer=gp2x_timer_read(); + frame_ticks = Timer - tickframe; + frame_ticks_total += frame_ticks; + tickframe = Timer; + Frames++; + + /*if(isMultiTouching != 0) + { + if(frame_ticks > frame_speed-8) // 10+ + { + skipper++; + if(skipper < 4) + { + skipcount++; + IPPU.RenderThisFrame=FALSE; + } + else + { + skipper = 0; + IPPU.RenderThisFrame=TRUE; + } + } + else + { + skipper = 0; + IPPU.RenderThisFrame=TRUE; + } + } + else*/ + { + /*if((int)frame_ticks > frame_speed) // 14+ + { + skipper++; + if(skipper < 4) + { + skipcount++; + IPPU.RenderThisFrame=FALSE; + } + else + { + skipper = 0; + IPPU.RenderThisFrame=TRUE; + } + } + else*/ + { + if(((frame_speed*Frames) > frame_ticks_total)) + { + usleep(((frame_speed*Frames) - frame_ticks_total) * 1000); + //frame_ticks_total = (frame_speed*Frames); + skipper = 0; + IPPU.RenderThisFrame = TRUE; + } + else + { + skipper++; + if(skipper < 10) + { + skipcount++; + IPPU.RenderThisFrame=FALSE; + } + else + { + skipper = 0; + IPPU.RenderThisFrame=TRUE; + } + } + } + } + + if(Timer-tick>=(TIMER_1_SECOND)) + { + fps=Frames; + Frames=0; + tick=Timer; + sprintf(fps_display,"%d %d",fps, skipcount); + skipcount = 0; + frame_ticks_total = 0; + } + + S9xMainLoop (); + + if(__autosave && ++SaveFrames >= 18000 ) + { + char svfilename[1024]; + sprintf(svfilename, "%s-last-autosave.sv", filename); + + gp_drawString(0,0,strlen("autosaving!"),"autosaving",0xFFFF,(unsigned char*)vrambuffer); + MenuFlip(); + SaveStateFile(svfilename); + SaveFrames = 0; + } + + do + { + if( !__emulation_run || __emulation_saving) + { + char buffer[260]; + char svfilename[1024]; + time_t curtime; + struct tm *loctime; + + S9xSaveSRAM(); + + if(__emulation_saving) + { + if(__saved != 0 && __emulation_saving == 2) + { + sprintf(svfilename, "%s", save_filename); + } + else + { + curtime = time (NULL); + loctime = localtime (&curtime); + strftime (buffer, 260, "%y%m%d-%I%M%S", loctime); + sprintf(svfilename, "%s-%s.sv", filename, buffer); + } + SaveStateFile(svfilename); + __emulation_saving = 0; + } + if(!__emulation_run) + { + set_gamma(100); + gp_Reset(); + app_MuteSound(); + gp_deinitGraphics(); + if(vrambuffer != NULL) free(vrambuffer); + vrambuffer = NULL; + S9xGraphicsDeinit(); + S9xDeinitAPU(); + Memory.Deinit(); + pthread_exit(NULL); + break; + } + } + if(__emulation_paused) + { + usleep(16666); + //sched_yield(); + } + } while(__emulation_paused); + } + + return 0; +} diff --git a/src/snes4iphone_src/memcpy.s b/src/snes4iphone_src/memcpy.s new file mode 100755 index 0000000..ce6072e --- /dev/null +++ b/src/snes4iphone_src/memcpy.s @@ -0,0 +1,487 @@ +/* $NetBSD: memcpy.S,v 1.3 1997/11/22 03:27:12 mark Exp $ */ + +/*- +* Copyright (c) 1997 The NetBSD Foundation, Inc. +* All rights reserved. +* +* This code is derived from software contributed to The NetBSD Foundation +* by Neil A. Carson and Mark Brinicombe +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* 3. All advertising materials mentioning features or use of this software +* must display the following acknowledgement: +* This product includes software developed by the NetBSD +* Foundation, Inc. and its contributors. +* 4. Neither the name of The NetBSD Foundation nor the names of its +* contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +* ``AS IS\'\' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +/* This was modified by Jay Monkman to +* save and restore r12. This is necessary for RTEMS. +*/ +/* #include */ + +.globl memcpy +memcpy: +stmfd sp!, {r0, r12, lr} +bl _memcpy +ldmfd sp!, {r0, r12, pc} + + +.globl memove +memmove: +stmfd sp!, {r0, r12, lr} +bl _memcpy +ldmfd sp!, {r0, r12, pc} + + + +/* +* This is one fun bit of code ... +* Some easy listening music is suggested while trying to understand this +* code e.g. Iron Maiden +* +* For anyone attempting to understand it : +* +* The core code is implemented here with simple stubs for memcpy() +* memmove() and bcopy(). +* +* All local labels are prefixed with Lmemcpy_ +* Following the prefix a label starting f is used in the forward copy code +* while a label using b is used in the backwards copy code +* The source and destination addresses determine whether a forward or +* backward copy is performed. +* Separate bits of code are used to deal with the following situations +* for both the forward and backwards copy. +* unaligned source address +* unaligned destination address +* Separate copy routines are used to produce an optimised result for each +* of these cases. +* The copy code will use LDM/STM instructions to copy up to 32 bytes at +* a time where possible. +* +* Note: r12 (aka ip) can be trashed during the function along with +* r0-r3 although r0-r2 have defined uses i.e. src, dest, len through out. +* Additional registers are preserved prior to use i.e. r4, r5 & lr +* +* Apologies for the state of the comments;-) +*/ + + +_memcpy: +/* Determine copy direction */ +cmp r1, r0 +bcc Lmemcpy_backwards + +moveq r0, #0 /* Quick abort for len=0 */ +moveq pc, lr + +stmdb sp!, {r0, lr} /* memcpy() returns dest addr */ +subs r2, r2, #4 +blt Lmemcpy_fl4 /* less than 4 bytes */ +ands r12, r0, #3 +bne Lmemcpy_fdestul /* oh unaligned destination addr */ +ands r12, r1, #3 +bne Lmemcpy_fsrcul /* oh unaligned source addr */ + +Lmemcpy_ft8: +/* We have aligned source and destination */ +subs r2, r2, #8 +blt Lmemcpy_fl12 /* less than 12 bytes (4 from above) */ +subs r2, r2, #0x14 +blt Lmemcpy_fl32 /* less than 32 bytes (12 from above) */ +stmdb sp!, {r4} /* borrow r4 */ + +/* blat 32 bytes at a time */ +/* XXX for really big copies perhaps we should use more registers */ +Lmemcpy_floop32: +ldmia r1!, {r3, r4, r12, lr} +stmia r0!, {r3, r4, r12, lr} +ldmia r1!, {r3, r4, r12, lr} +stmia r0!, {r3, r4, r12, lr} +subs r2, r2, #0x20 +bge Lmemcpy_floop32 + +cmn r2, #0x10 +ldmgeia r1!, {r3, r4, r12, lr} /* blat a remaining 16 bytes */ +stmgeia r0!, {r3, r4, r12, lr} +subge r2, r2, #0x10 +ldmia sp!, {r4} /* return r4 */ + +Lmemcpy_fl32: +adds r2, r2, #0x14 + +/* blat 12 bytes at a time */ +Lmemcpy_floop12: +ldmgeia r1!, {r3, r12, lr} +stmgeia r0!, {r3, r12, lr} +subges r2, r2, #0x0c +bge Lmemcpy_floop12 + +Lmemcpy_fl12: +adds r2, r2, #8 +blt Lmemcpy_fl4 + +subs r2, r2, #4 +ldrlt r3, [r1], #4 +strlt r3, [r0], #4 +ldmgeia r1!, {r3, r12} +stmgeia r0!, {r3, r12} +subge r2, r2, #4 + +Lmemcpy_fl4: +/* less than 4 bytes to go */ +adds r2, r2, #4 +ldmeqia sp!, {r0, pc} /* done */ + +/* copy the crud byte at a time */ +cmp r2, #2 +ldrb r3, [r1], #1 +strb r3, [r0], #1 +ldrgeb r3, [r1], #1 +strgeb r3, [r0], #1 +ldrgtb r3, [r1], #1 +strgtb r3, [r0], #1 +ldmia sp!, {r0, pc} + +/* erg - unaligned destination */ +Lmemcpy_fdestul: +rsb r12, r12, #4 +cmp r12, #2 + +/* align destination with byte copies */ +ldrb r3, [r1], #1 +strb r3, [r0], #1 +ldrgeb r3, [r1], #1 +strgeb r3, [r0], #1 +ldrgtb r3, [r1], #1 +strgtb r3, [r0], #1 +subs r2, r2, r12 +blt Lmemcpy_fl4 /* less the 4 bytes */ + +ands r12, r1, #3 +beq Lmemcpy_ft8 /* we have an aligned source */ + +/* erg - unaligned source */ +/* This is where it gets nasty ... */ +Lmemcpy_fsrcul: +bic r1, r1, #3 +ldr lr, [r1], #4 +cmp r12, #2 +bgt Lmemcpy_fsrcul3 +beq Lmemcpy_fsrcul2 +cmp r2, #0x0c +blt Lmemcpy_fsrcul1loop4 +sub r2, r2, #0x0c +stmdb sp!, {r4, r5} + +Lmemcpy_fsrcul1loop16: +mov r3, lr, lsr #8 +ldmia r1!, {r4, r5, r12, lr} +orr r3, r3, r4, lsl #24 +mov r4, r4, lsr #8 +orr r4, r4, r5, lsl #24 +mov r5, r5, lsr #8 +orr r5, r5, r12, lsl #24 +mov r12, r12, lsr #8 +orr r12, r12, lr, lsl #24 +stmia r0!, {r3-r5, r12} +subs r2, r2, #0x10 +bge Lmemcpy_fsrcul1loop16 +ldmia sp!, {r4, r5} +adds r2, r2, #0x0c +blt Lmemcpy_fsrcul1l4 + +Lmemcpy_fsrcul1loop4: +mov r12, lr, lsr #8 +ldr lr, [r1], #4 +orr r12, r12, lr, lsl #24 +str r12, [r0], #4 +subs r2, r2, #4 +bge Lmemcpy_fsrcul1loop4 + +Lmemcpy_fsrcul1l4: +sub r1, r1, #3 +b Lmemcpy_fl4 + +Lmemcpy_fsrcul2: +cmp r2, #0x0c +blt Lmemcpy_fsrcul2loop4 +sub r2, r2, #0x0c +stmdb sp!, {r4, r5} + +Lmemcpy_fsrcul2loop16: +mov r3, lr, lsr #16 +ldmia r1!, {r4, r5, r12, lr} +orr r3, r3, r4, lsl #16 +mov r4, r4, lsr #16 +orr r4, r4, r5, lsl #16 +mov r5, r5, lsr #16 +orr r5, r5, r12, lsl #16 +mov r12, r12, lsr #16 +orr r12, r12, lr, lsl #16 +stmia r0!, {r3-r5, r12} +subs r2, r2, #0x10 +bge Lmemcpy_fsrcul2loop16 +ldmia sp!, {r4, r5} +adds r2, r2, #0x0c +blt Lmemcpy_fsrcul2l4 + +Lmemcpy_fsrcul2loop4: +mov r12, lr, lsr #16 +ldr lr, [r1], #4 +orr r12, r12, lr, lsl #16 +str r12, [r0], #4 +subs r2, r2, #4 +bge Lmemcpy_fsrcul2loop4 + +Lmemcpy_fsrcul2l4: +sub r1, r1, #2 +b Lmemcpy_fl4 + +Lmemcpy_fsrcul3: +cmp r2, #0x0c +blt Lmemcpy_fsrcul3loop4 +sub r2, r2, #0x0c +stmdb sp!, {r4, r5} + +Lmemcpy_fsrcul3loop16: +mov r3, lr, lsr #24 +ldmia r1!, {r4, r5, r12, lr} +orr r3, r3, r4, lsl #8 +mov r4, r4, lsr #24 +orr r4, r4, r5, lsl #8 +mov r5, r5, lsr #24 +orr r5, r5, r12, lsl #8 +mov r12, r12, lsr #24 +orr r12, r12, lr, lsl #8 +stmia r0!, {r3-r5, r12} +subs r2, r2, #0x10 +bge Lmemcpy_fsrcul3loop16 +ldmia sp!, {r4, r5} +adds r2, r2, #0x0c +blt Lmemcpy_fsrcul3l4 + +Lmemcpy_fsrcul3loop4: +mov r12, lr, lsr #24 +ldr lr, [r1], #4 +orr r12, r12, lr, lsl #8 +str r12, [r0], #4 +subs r2, r2, #4 +bge Lmemcpy_fsrcul3loop4 + +Lmemcpy_fsrcul3l4: +sub r1, r1, #1 +b Lmemcpy_fl4 + +Lmemcpy_backwards: +add r1, r1, r2 +add r0, r0, r2 +subs r2, r2, #4 +blt Lmemcpy_bl4 /* less than 4 bytes */ +ands r12, r0, #3 +bne Lmemcpy_bdestul /* oh unaligned destination addr */ +ands r12, r1, #3 +bne Lmemcpy_bsrcul /* oh unaligned source addr */ + +Lmemcpy_bt8: +/* We have aligned source and destination */ +subs r2, r2, #8 +blt Lmemcpy_bl12 /* less than 12 bytes (4 from above) */ +stmdb sp!, {r4, lr} +subs r2, r2, #0x14 /* less than 32 bytes (12 from above) */ +blt Lmemcpy_bl32 + +/* blat 32 bytes at a time */ +/* XXX for really big copies perhaps we should use more registers */ +Lmemcpy_bloop32: +ldmdb r1!, {r3, r4, r12, lr} +stmdb r0!, {r3, r4, r12, lr} +ldmdb r1!, {r3, r4, r12, lr} +stmdb r0!, {r3, r4, r12, lr} +subs r2, r2, #0x20 +bge Lmemcpy_bloop32 + +Lmemcpy_bl32: +cmn r2, #0x10 +ldmgedb r1!, {r3, r4, r12, lr} /* blat a remaining 16 bytes */ +stmgedb r0!, {r3, r4, r12, lr} +subge r2, r2, #0x10 +adds r2, r2, #0x14 +ldmgedb r1!, {r3, r12, lr} /* blat a remaining 12 bytes */ +stmgedb r0!, {r3, r12, lr} +subge r2, r2, #0x0c +ldmia sp!, {r4, lr} + +Lmemcpy_bl12: +adds r2, r2, #8 +blt Lmemcpy_bl4 +subs r2, r2, #4 +ldrlt r3, [r1, #-4]! +strlt r3, [r0, #-4]! +ldmgedb r1!, {r3, r12} +stmgedb r0!, {r3, r12} +subge r2, r2, #4 + +Lmemcpy_bl4: +/* less than 4 bytes to go */ +adds r2, r2, #4 +moveq pc, lr /* done */ + +/* copy the crud byte at a time */ +cmp r2, #2 +ldrb r3, [r1, #-1]! +strb r3, [r0, #-1]! +ldrgeb r3, [r1, #-1]! +strgeb r3, [r0, #-1]! +ldrgtb r3, [r1, #-1]! +strgtb r3, [r0, #-1]! +mov pc, lr + +/* erg - unaligned destination */ +Lmemcpy_bdestul: +cmp r12, #2 + +/* align destination with byte copies */ +ldrb r3, [r1, #-1]! +strb r3, [r0, #-1]! +ldrgeb r3, [r1, #-1]! +strgeb r3, [r0, #-1]! +ldrgtb r3, [r1, #-1]! +strgtb r3, [r0, #-1]! +subs r2, r2, r12 +blt Lmemcpy_bl4 /* less than 4 bytes to go */ +ands r12, r1, #3 +beq Lmemcpy_bt8 /* we have an aligned source */ + +/* erg - unaligned source */ +/* This is where it gets nasty ... */ +Lmemcpy_bsrcul: +bic r1, r1, #3 +ldr r3, [r1, #0] +cmp r12, #2 +blt Lmemcpy_bsrcul1 +beq Lmemcpy_bsrcul2 +cmp r2, #0x0c +blt Lmemcpy_bsrcul3loop4 +sub r2, r2, #0x0c +stmdb sp!, {r4, r5, lr} + +Lmemcpy_bsrcul3loop16: +mov lr, r3, lsl #8 +ldmdb r1!, {r3-r5, r12} +orr lr, lr, r12, lsr #24 +mov r12, r12, lsl #8 +orr r12, r12, r5, lsr #24 +mov r5, r5, lsl #8 +orr r5, r5, r4, lsr #24 +mov r4, r4, lsl #8 +orr r4, r4, r3, lsr #24 +stmdb r0!, {r4, r5, r12, lr} +subs r2, r2, #0x10 +bge Lmemcpy_bsrcul3loop16 +ldmia sp!, {r4, r5, lr} +adds r2, r2, #0x0c +blt Lmemcpy_bsrcul3l4 + +Lmemcpy_bsrcul3loop4: +mov r12, r3, lsl #8 +ldr r3, [r1, #-4]! +orr r12, r12, r3, lsr #24 +str r12, [r0, #-4]! +subs r2, r2, #4 +bge Lmemcpy_bsrcul3loop4 + +Lmemcpy_bsrcul3l4: +add r1, r1, #3 +b Lmemcpy_bl4 + +Lmemcpy_bsrcul2: +cmp r2, #0x0c +blt Lmemcpy_bsrcul2loop4 +sub r2, r2, #0x0c +stmdb sp!, {r4, r5, lr} + +Lmemcpy_bsrcul2loop16: +mov lr, r3, lsl #16 +ldmdb r1!, {r3-r5, r12} +orr lr, lr, r12, lsr #16 +mov r12, r12, lsl #16 +orr r12, r12, r5, lsr #16 +mov r5, r5, lsl #16 +orr r5, r5, r4, lsr #16 +mov r4, r4, lsl #16 +orr r4, r4, r3, lsr #16 +stmdb r0!, {r4, r5, r12, lr} +subs r2, r2, #0x10 +bge Lmemcpy_bsrcul2loop16 +ldmia sp!, {r4, r5, lr} +adds r2, r2, #0x0c +blt Lmemcpy_bsrcul2l4 + +Lmemcpy_bsrcul2loop4: +mov r12, r3, lsl #16 +ldr r3, [r1, #-4]! +orr r12, r12, r3, lsr #16 +str r12, [r0, #-4]! +subs r2, r2, #4 +bge Lmemcpy_bsrcul2loop4 + +Lmemcpy_bsrcul2l4: +add r1, r1, #2 +b Lmemcpy_bl4 + +Lmemcpy_bsrcul1: +cmp r2, #0x0c +blt Lmemcpy_bsrcul1loop4 +sub r2, r2, #0x0c +stmdb sp!, {r4, r5, lr} + +Lmemcpy_bsrcul1loop32: +mov lr, r3, lsl #24 +ldmdb r1!, {r3-r5, r12} +orr lr, lr, r12, lsr #8 +mov r12, r12, lsl #24 +orr r12, r12, r5, lsr #8 +mov r5, r5, lsl #24 +orr r5, r5, r4, lsr #8 +mov r4, r4, lsl #24 +orr r4, r4, r3, lsr #8 +stmdb r0!, {r4, r5, r12, lr} +subs r2, r2, #0x10 +bge Lmemcpy_bsrcul1loop32 +ldmia sp!, {r4, r5, lr} +adds r2, r2, #0x0c +blt Lmemcpy_bsrcul1l4 + +Lmemcpy_bsrcul1loop4: +mov r12, r3, lsl #24 +ldr r3, [r1, #-4]! +orr r12, r12, r3, lsr #8 +str r12, [r0, #-4]! +subs r2, r2, #4 +bge Lmemcpy_bsrcul1loop4 + +Lmemcpy_bsrcul1l4: +add r1, r1, #1 +b Lmemcpy_bl4 diff --git a/src/snes4iphone_src/memmap.cpp b/src/snes4iphone_src/memmap.cpp new file mode 100755 index 0000000..8e041c8 --- /dev/null +++ b/src/snes4iphone_src/memmap.cpp @@ -0,0 +1,2694 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#include +#include + +#ifdef __linux +//#include +#endif + +#include "snes9x.h" +#include "memmap.h" +#include "cpuexec.h" +#include "ppu.h" +#include "display.h" +#include "cheats.h" +#include "apu.h" +#include "sa1.h" +#include "srtc.h" +#include "sdd1.h" + +#ifndef ZSNES_FX +#include "fxemu.h" +extern struct FxInit_s SuperFX; +#else +START_EXTERN_C +extern uint8 *SFXPlotTable; +END_EXTERN_C +#endif + +static uint8 bytes0x2000 [0x2000]; + +extern char *rom_filename; +extern bool8 LoadZip(const char* , int32 *, int32 *); +extern uint32 caCRC32(uint8 *array, uint32 size, register uint32 crc32 = 0xFFFFFFFF); + +bool8_32 CMemory::AllASCII (uint8 *b, int size) +{ + for (int i = 0; i < size; i++) + { + if (b[i] < 32 || b[i] > 126) + return (FALSE); + } + return (TRUE); +} + +int CMemory::ScoreHiROM (bool8_32 skip_header) +{ + int score = 0; + int o = skip_header ? 0xff00 + 0x200 : 0xff00; + + if ((Memory.ROM [o + 0xdc] + (Memory.ROM [o + 0xdd] << 8) + + Memory.ROM [o + 0xde] + (Memory.ROM [o + 0xdf] << 8)) == 0xffff) + score += 2; + + if (Memory.ROM [o + 0xda] == 0x33) + score += 2; + if ((Memory.ROM [o + 0xd5] & 0xf) < 4) + score += 2; + if (!(Memory.ROM [o + 0xfd] & 0x80)) + score -= 4; + if (CalculatedSize > 1024 * 1024 * 3) + score += 4; + if ((1 << (Memory.ROM [o + 0xd7] - 7)) > 48) + score -= 1; + if (!AllASCII (&Memory.ROM [o + 0xb0], 6)) + score -= 1; + if (!AllASCII (&Memory.ROM [o + 0xc0], ROM_NAME_LEN - 1)) + score -= 1; + + return (score); +} + +int CMemory::ScoreLoROM (bool8_32 skip_header) +{ + int score = 0; + int o = skip_header ? 0x7f00 + 0x200 : 0x7f00; + + if ((Memory.ROM [o + 0xdc] + (Memory.ROM [o + 0xdd] << 8) + + Memory.ROM [o + 0xde] + (Memory.ROM [o + 0xdf] << 8)) == 0xffff) + score += 2; + + if (Memory.ROM [o + 0xda] == 0x33) + score += 2; + if ((Memory.ROM [o + 0xd5] & 0xf) < 4) + score += 2; + if (CalculatedSize <= 1024 * 1024 * 16) + score += 2; + if (!(Memory.ROM [o + 0xfd] & 0x80)) + score -= 4; + if ((1 << (Memory.ROM [o + 0xd7] - 7)) > 48) + score -= 1; + if (!AllASCII (&Memory.ROM [o + 0xb0], 6)) + score -= 1; + if (!AllASCII (&Memory.ROM [o + 0xc0], ROM_NAME_LEN - 1)) + score -= 1; + + return (score); +} + +char *CMemory::Safe (const char *s) +{ + static char *safe = NULL; + static int safe_len = 0; + + int len = strlen (s); + if (!safe || len + 1 > safe_len) + { + if (safe) + free ((char *) safe); + safe = (char *) malloc (safe_len = len + 1); + } + + for (int i = 0; i < len; i++) + { + if (s [i] >= 32 && s [i] < 127) + safe [i] = s[i]; + else + safe [i] = '?'; + } + safe [len] = 0; + return (safe); +} + +/**********************************************************************************************/ +/* Init() */ +/* This function allocates all the memory needed by the emulator */ +/**********************************************************************************************/ +bool8_32 CMemory::Init () +{ + RAM = (uint8 *) malloc (0x20000); + SRAM = (uint8 *) malloc (0x20000); + VRAM = (uint8 *) malloc (0x10000); + ROM = (uint8 *) malloc (MAX_ROM_SIZE + 0x200 + 0x8000); + FillRAM = NULL; + + IPPU.TileCache [TILE_2BIT] = (uint8 *) malloc (MAX_2BIT_TILES * 128); + IPPU.TileCache [TILE_4BIT] = (uint8 *) malloc (MAX_4BIT_TILES * 128); + IPPU.TileCache [TILE_8BIT] = (uint8 *) malloc (MAX_8BIT_TILES * 128); + + IPPU.TileCached [TILE_2BIT] = (uint8 *) malloc (MAX_2BIT_TILES); + IPPU.TileCached [TILE_4BIT] = (uint8 *) malloc (MAX_4BIT_TILES); + IPPU.TileCached [TILE_8BIT] = (uint8 *) malloc (MAX_8BIT_TILES); + + if (!RAM || !SRAM || !VRAM || !ROM || + !IPPU.TileCache [TILE_2BIT] || !IPPU.TileCache [TILE_4BIT] || + !IPPU.TileCache [TILE_8BIT] || !IPPU.TileCached [TILE_2BIT] || + !IPPU.TileCached [TILE_4BIT] || !IPPU.TileCached [TILE_8BIT]) + { + Deinit (); + return (FALSE); + } + + // FillRAM uses first 32K of ROM image area, otherwise space just + // wasted. Might be read by the SuperFX code. + + FillRAM = ROM; + + // Add 0x8000 to ROM image pointer to stop SuperFX code accessing + // unallocated memory (can cause crash on some ports). + ROM += 0x8000; + + C4RAM = ROM + 0x400000 + 8192 * 8; + ::ROM = ROM; + ::SRAM = SRAM; + ::RegRAM = FillRAM; + +#ifdef ZSNES_FX + SFXPlotTable = ROM + 0x400000; +#else + SuperFX.pvRegisters = &Memory.FillRAM [0x3000]; + SuperFX.nRamBanks = 1; + SuperFX.pvRam = ::SRAM; + SuperFX.nRomBanks = (2 * 1024 * 1024) / (32 * 1024); + SuperFX.pvRom = (uint8 *) ROM; +#endif + + ZeroMemory (IPPU.TileCached [TILE_2BIT], MAX_2BIT_TILES); + ZeroMemory (IPPU.TileCached [TILE_4BIT], MAX_4BIT_TILES); + ZeroMemory (IPPU.TileCached [TILE_8BIT], MAX_8BIT_TILES); + + SDD1Data = NULL; + SDD1Index = NULL; + + return (TRUE); +} + +void CMemory::Deinit () +{ + if (RAM) + { + free ((char *) RAM); + RAM = NULL; + } + if (SRAM) + { + free ((char *) SRAM); + SRAM = NULL; + } + if (VRAM) + { + free ((char *) VRAM); + VRAM = NULL; + } + if (ROM) + { + ROM -= 0x8000; + free ((char *) ROM); + ROM = NULL; + } + + if (IPPU.TileCache [TILE_2BIT]) + { + free ((char *) IPPU.TileCache [TILE_2BIT]); + IPPU.TileCache [TILE_2BIT] = NULL; + } + if (IPPU.TileCache [TILE_4BIT]) + { + free ((char *) IPPU.TileCache [TILE_4BIT]); + IPPU.TileCache [TILE_4BIT] = NULL; + } + if (IPPU.TileCache [TILE_8BIT]) + { + free ((char *) IPPU.TileCache [TILE_8BIT]); + IPPU.TileCache [TILE_8BIT] = NULL; + } + + if (IPPU.TileCached [TILE_2BIT]) + { + free ((char *) IPPU.TileCached [TILE_2BIT]); + IPPU.TileCached [TILE_2BIT] = NULL; + } + if (IPPU.TileCached [TILE_4BIT]) + { + free ((char *) IPPU.TileCached [TILE_4BIT]); + IPPU.TileCached [TILE_4BIT] = NULL; + } + if (IPPU.TileCached [TILE_8BIT]) + { + free ((char *) IPPU.TileCached [TILE_8BIT]); + IPPU.TileCached [TILE_8BIT] = NULL; + } + + FreeSDD1Data (); +} + +void CMemory::FreeSDD1Data () +{ + if (SDD1Index) + { + free ((char *) SDD1Index); + SDD1Index = NULL; + } + if (SDD1Data) + { + free ((char *) SDD1Data); + SDD1Data = NULL; + } +} + +/**********************************************************************************************/ +/* checkext() */ +/**********************************************************************************************/ +int checkzip( char * fn ) +{ + int cnt = strlen(fn); + if( ( (fn[cnt-1] == 'p') || (fn[cnt-1] == 'P') ) && + ( (fn[cnt-2] == 'i') || (fn[cnt-2] == 'I') ) && + ( (fn[cnt-3] == 'z') || (fn[cnt-3] == 'Z') ) ){ + return true; + + } + return false; +} + +/**********************************************************************************************/ +/* LoadROM() */ +/* This function loads a Snes-Backup image */ +/**********************************************************************************************/ +#ifdef _SNESPPC +#pragma warning(disable : 4101) +#pragma warning(disable : 4700) +#endif +bool8_32 CMemory::LoadROM (const char *filename) +{ + unsigned long FileSize = 0; + int retry_count = 0; + STREAM ROMFile; + bool8_32 Interleaved = FALSE; + bool8_32 Tales = FALSE; + char dir [_MAX_DIR + 1]; + char drive [_MAX_DRIVE + 1]; + char name [_MAX_FNAME + 1]; + char ext [_MAX_EXT + 1]; + char fname [_MAX_PATH + 1]; + int i; + + memset (&SNESGameFixes, 0, sizeof(SNESGameFixes)); + SNESGameFixes.SRAMInitialValue = 0x60; + + memset (bytes0x2000, 0, 0x2000); + CPU.TriedInterleavedMode2 = FALSE; + + CalculatedSize = 0; +again: +#ifndef _SNESPPC + _splitpath (filename, drive, dir, name, ext); + _makepath (fname, drive, dir, name, ext); +#else + strcpy(fname, filename); +// strupr(fname); +#endif + +#ifdef __WIN32__ + memmove (&ext [0], &ext[1], 4); +#endif + + int32 TotalFileSize = 0; + +#ifdef UNZIP_SUPPORT + + if( checkzip( fname ) ) + { + if (!LoadZip (fname, &TotalFileSize, &HeaderCount)) + return (FALSE); + + strcpy (ROMFilename, fname); + } + else +#endif + { + if ((ROMFile = OPEN_STREAM (fname, "rb")) == NULL) + return (FALSE); + + strcpy (ROMFilename, fname); + + HeaderCount = 0; + uint8 *ptr = ROM; + bool8_32 more = FALSE; + + do + { + FileSize = READ_STREAM (ptr, MAX_ROM_SIZE + 0x200 - (ptr - ROM), ROMFile); + CLOSE_STREAM (ROMFile); + int calc_size = (FileSize / 0x2000) * 0x2000; + + if ((FileSize - calc_size == 512 && !Settings.ForceNoHeader) || + Settings.ForceHeader) + { + memmove (ptr, ptr + 512, calc_size); + HeaderCount++; + FileSize -= 512; + } + ptr += FileSize; + TotalFileSize += FileSize; + + int len; + if (ptr - ROM < MAX_ROM_SIZE + 0x200 && + (isdigit (ext [0]) && ext [1] == 0 && ext [0] < '9')) + { + more = TRUE; + ext [0]++; +#ifdef __WIN32__ + memmove (&ext [1], &ext [0], 4); + ext [0] = '.'; +#endif +#ifndef _SNESPPC + _makepath (fname, drive, dir, name, ext); +#endif + } + else + if (ptr - ROM < MAX_ROM_SIZE + 0x200 && + (((len = strlen (name)) == 7 || len == 8) && + strncasecmp (name, "sf", 2) == 0 && + isdigit (name [2]) && isdigit (name [3]) && isdigit (name [4]) && + isdigit (name [5]) && isalpha (name [len - 1]))) + { + more = TRUE; + name [len - 1]++; +#ifdef __WIN32__ + memmove (&ext [1], &ext [0], 4); + ext [0] = '.'; +#endif +#ifndef _SNESPPC + _makepath (fname, drive, dir, name, ext); +#endif + } + else + more = FALSE; + } while (more && (ROMFile = OPEN_STREAM (fname, "rb")) != NULL); + } + + if (HeaderCount == 0) + S9xMessage (S9X_INFO, S9X_HEADERS_INFO, "No ROM file header found."); + else + { + if (HeaderCount == 1) + S9xMessage (S9X_INFO, S9X_HEADERS_INFO, + "Found ROM file header (and ignored it)."); + else + S9xMessage (S9X_INFO, S9X_HEADERS_INFO, + "Found multiple ROM file headers (and ignored them)."); + } + + CheckForIPSPatch (filename, HeaderCount != 0, TotalFileSize); + int orig_hi_score, orig_lo_score; + int hi_score, lo_score; + + orig_hi_score = hi_score = ScoreHiROM (FALSE); + orig_lo_score = lo_score = ScoreLoROM (FALSE); + + if (HeaderCount == 0 && !Settings.ForceNoHeader && + ((hi_score > lo_score && ScoreHiROM (TRUE) > hi_score) || + (hi_score <= lo_score && ScoreLoROM (TRUE) > lo_score))) + { + memmove (Memory.ROM, Memory.ROM + 512, TotalFileSize - 512); + TotalFileSize -= 512; + S9xMessage (S9X_INFO, S9X_HEADER_WARNING, + "Try specifying the -nhd command line option if the game doesn't work\n"); + } + + CalculatedSize = (TotalFileSize / 0x2000) * 0x2000; + ZeroMemory (ROM + CalculatedSize, MAX_ROM_SIZE - CalculatedSize); + + // Check for cherryroms.com DAIKAIJYUMONOGATARI2 + + if (CalculatedSize == 0x500000 && + strncmp ((const char *)&ROM [0x40ffc0], "DAIKAIJYUMONOGATARI2", 20) == 0 && + strncmp ((const char *)&ROM [0x40ffb0], "18AE6J", 6) == 0 && + memcmp (&ROM[0x40ffb0], &ROM [0xffb0], 0x30)) + { + memmove (&ROM[0x100000], ROM, 0x500000); + memmove (ROM, &ROM[0x500000], 0x100000); + } + + Interleaved = Settings.ForceInterleaved || Settings.ForceInterleaved2; + if (Settings.ForceLoROM || (!Settings.ForceHiROM && lo_score >= hi_score)) + { + LoROM = TRUE; + HiROM = FALSE; + + // Ignore map type byte if not 0x2x or 0x3x + if ((ROM [0x7fd5] & 0xf0) == 0x20 || (ROM [0x7fd5] & 0xf0) == 0x30) + { + switch (ROM [0x7fd5] & 0xf) + { + case 1: + if (strncmp ((char *) &ROM [0x7fc0], "TREASURE HUNTER G", 17) != 0) + Interleaved = TRUE; + break; + case 2: +#if 0 + if (!Settings.ForceLoROM && + strncmp ((char *) &ROM [0x7fc0], "SUPER FORMATION SOCCE", 21) != 0 && + strncmp ((char *) &ROM [0x7fc0], "Star Ocean", 10) != 0) + { + LoROM = FALSE; + HiROM = TRUE; + } +#endif + break; + case 5: + Interleaved = TRUE; + Tales = TRUE; + break; + } + } + } + else + { + if ((ROM [0xffd5] & 0xf0) == 0x20 || (ROM [0xffd5] & 0xf0) == 0x30) + { + switch (ROM [0xffd5] & 0xf) + { + case 0: + case 3: + Interleaved = TRUE; + break; + } + } + LoROM = FALSE; + HiROM = TRUE; + } + + // More + if (!Settings.ForceHiROM && !Settings.ForceLoROM && + !Settings.ForceInterleaved && !Settings.ForceInterleaved2 && + !Settings.ForceNotInterleaved && !Settings.ForcePAL && + !Settings.ForceSuperFX && !Settings.ForceDSP1 && + !Settings.ForceSA1 && !Settings.ForceC4 && + !Settings.ForceSDD1) + { + if (strncmp ((char *) &ROM [0x7fc0], "YUYU NO QUIZ DE GO!GO!", 22) == 0) + { + LoROM = TRUE; + HiROM = FALSE; + Interleaved = FALSE; + } + else + if (strncmp ((char *) &ROM [0x7fc0], "SP MOMOTAROU DENTETSU2", 22) == 0) + { + LoROM = TRUE; + HiROM = FALSE; + Interleaved = FALSE; + } + else + if (CalculatedSize == 0x100000 && + strncmp ((char *) &ROM [0xffc0], "WWF SUPER WRESTLEMANIA", 22) == 0) + { + int cvcount; + + memmove (&ROM[0x100000] , ROM, 0x100000); + for (cvcount = 0; cvcount < 16; cvcount++) + { + memmove (&ROM[0x8000 * cvcount], &ROM[0x10000 * cvcount + 0x100000 + 0x8000], 0x8000); + memmove (&ROM[0x8000 * cvcount + 0x80000], &ROM[0x10000 * cvcount + 0x100000], 0x8000); + } + LoROM = TRUE; + HiROM = FALSE; + ZeroMemory (ROM + CalculatedSize, MAX_ROM_SIZE - CalculatedSize); + } + } + + if (!Settings.ForceNotInterleaved && Interleaved) + { + CPU.TriedInterleavedMode2 = TRUE; + S9xMessage (S9X_INFO, S9X_ROM_INTERLEAVED_INFO, + "ROM image is in interleaved format - converting..."); + + int nblocks = CalculatedSize >> 16; +#if 0 + int step = 64; + + while (nblocks <= step) + step >>= 1; + + nblocks = step; +#endif + uint8 blocks [256]; + + if (Tales) + { + nblocks = 0x60; + for (i = 0; i < 0x40; i += 2) + { + blocks [i + 0] = (i >> 1) + 0x20; + blocks [i + 1] = (i >> 1) + 0x00; + } + for (i = 0; i < 0x80; i += 2) + { + blocks [i + 0x40] = (i >> 1) + 0x80; + blocks [i + 0x41] = (i >> 1) + 0x40; + } + LoROM = FALSE; + HiROM = TRUE; + } + else + if (Settings.ForceInterleaved2) + { + for (i = 0; i < nblocks * 2; i++) + { + blocks [i] = (i & ~0x1e) | ((i & 2) << 2) | ((i & 4) << 2) | + ((i & 8) >> 2) | ((i & 16) >> 2); + } + } + else + { + bool8_32 t = LoROM; + + LoROM = HiROM; + HiROM = t; + + for (i = 0; i < nblocks; i++) + { + blocks [i * 2] = i + nblocks; + blocks [i * 2 + 1] = i; + } + } + + uint8 *tmp = (uint8 *) malloc (0x8000); + if (tmp) + { + for (i = 0; i < nblocks * 2; i++) + { + for (int j = i; j < nblocks * 2; j++) + { + if (blocks [j] == i) + { + memmove (tmp, &ROM [blocks [j] * 0x8000], 0x8000); + memmove (&ROM [blocks [j] * 0x8000], + &ROM [blocks [i] * 0x8000], 0x8000); + memmove (&ROM [blocks [i] * 0x8000], tmp, 0x8000); + uint8 b = blocks [j]; + blocks [j] = blocks [i]; + blocks [i] = b; + break; + } + } + } + free ((char *) tmp); + } + + hi_score = ScoreHiROM (FALSE); + lo_score = ScoreLoROM (FALSE); + + if ((HiROM && + (lo_score >= hi_score || hi_score < 0)) || + (LoROM && + (hi_score > lo_score || lo_score < 0))) + { + if (retry_count == 0) + { + S9xMessage (S9X_INFO, S9X_ROM_CONFUSING_FORMAT_INFO, + "ROM lied about its type! Trying again."); + Settings.ForceNotInterleaved = TRUE; + Settings.ForceInterleaved = FALSE; + retry_count++; + goto again; + } + } + } + FreeSDD1Data (); + InitROM (Tales); + + S9xLoadCheatFile (S9xGetFilename(".cht")); + S9xInitCheatData (); + S9xApplyCheats (); + + S9xReset (); + + return (TRUE); +} + +void S9xDeinterleaveMode2 () +{ + S9xMessage (S9X_INFO, S9X_ROM_INTERLEAVED_INFO, + "ROM image is in interleaved format - converting..."); + + int nblocks = Memory.CalculatedSize >> 15; + int step = 64; + + while (nblocks <= step) + step >>= 1; + + nblocks = step; + uint8 blocks [256]; + int i; + + for (i = 0; i < nblocks * 2; i++) + { + blocks [i] = (i & ~0x1e) | ((i & 2) << 2) | ((i & 4) << 2) | + ((i & 8) >> 2) | ((i & 16) >> 2); + } + + uint8 *tmp = (uint8 *) malloc (0x8000); + + if (tmp) + { + for (i = 0; i < nblocks * 2; i++) + { + for (int j = i; j < nblocks * 2; j++) + { + if (blocks [j] == i) + { + memmove (tmp, &Memory.ROM [blocks [j] * 0x8000], 0x8000); + memmove (&Memory.ROM [blocks [j] * 0x8000], + &Memory.ROM [blocks [i] * 0x8000], 0x8000); + memmove (&Memory.ROM [blocks [i] * 0x8000], tmp, 0x8000); + uint8 b = blocks [j]; + blocks [j] = blocks [i]; + blocks [i] = b; + break; + } + } + } + free ((char *) tmp); + } + Memory.InitROM (FALSE); + S9xReset (); +} + +void CMemory::InitROM (bool8_32 Interleaved) +{ +#ifndef ZSNES_FX + SuperFX.nRomBanks = CalculatedSize >> 15; +#endif + Settings.MultiPlayer5Master = Settings.MultiPlayer5; + Settings.MouseMaster = Settings.Mouse; + Settings.SuperScopeMaster = Settings.SuperScope; + Settings.DSP1Master = Settings.ForceDSP1; + Settings.SuperFX = FALSE; + Settings.SA1 = FALSE; + Settings.C4 = FALSE; + Settings.SDD1 = FALSE; + Settings.SRTC = FALSE; + + ZeroMemory (BlockIsRAM, MEMMAP_NUM_BLOCKS); + ZeroMemory (BlockIsROM, MEMMAP_NUM_BLOCKS); + + ::SRAM = SRAM; + memset (ROMId, 0, 5); + memset (CompanyId, 0, 3); + + if (Memory.HiROM) + { + Memory.SRAMSize = ROM [0xffd8]; + strncpy (ROMName, (char *) &ROM[0xffc0], ROM_NAME_LEN - 1); + ROMSpeed = ROM [0xffd5]; + ROMType = ROM [0xffd6]; + ROMSize = ROM [0xffd7]; + ROMChecksum = ROM [0xffde] + (ROM [0xffdf] << 8); + ROMComplementChecksum = ROM [0xffdc] + (ROM [0xffdd] << 8); + + memmove (ROMId, &ROM [0xffb2], 4); + memmove (CompanyId, &ROM [0xffb0], 2); + + // Try to auto-detect the DSP1 chip + if (!Settings.ForceNoDSP1 && + (ROMType & 0xf) >= 3 && (ROMType & 0xf0) == 0) + Settings.DSP1Master = TRUE; + + Settings.SDD1 = Settings.ForceSDD1; + if ((ROMType & 0xf0) == 0x40) + Settings.SDD1 = !Settings.ForceNoSDD1; + + if (Settings.BS) + BSHiROMMap (); + else + if ((ROMSpeed & ~0x10) == 0x25) + TalesROMMap (Interleaved); + else + if ((ROMSpeed & ~0x10) == 0x22 && + strncmp (ROMName, "Super Street Fighter", 20) != 0) + { + AlphaROMMap (); + } + else + HiROMMap (); + } + else + { + Memory.HiROM = FALSE; + Memory.SRAMSize = ROM [0x7fd8]; + ROMSpeed = ROM [0x7fd5]; + ROMType = ROM [0x7fd6]; + ROMSize = ROM [0x7fd7]; + ROMChecksum = ROM [0x7fde] + (ROM [0x7fdf] << 8); + ROMComplementChecksum = ROM [0x7fdc] + (ROM [0x7fdd] << 8); + memmove (ROMId, &ROM [0x7fb2], 4); + memmove (CompanyId, &ROM [0x7fb0], 2); + + strncpy (ROMName, (char *) &ROM[0x7fc0], ROM_NAME_LEN - 1); + Settings.SuperFX = Settings.ForceSuperFX; + + if ((ROMType & 0xf0) == 0x10) + Settings.SuperFX = !Settings.ForceNoSuperFX; + + // Try to auto-detect the DSP1 chip + if (!Settings.ForceNoDSP1 && + (ROMType & 0xf) >= 3 && (ROMType & 0xf0) == 0) + Settings.DSP1Master = TRUE; + + Settings.SDD1 = Settings.ForceSDD1; + if ((ROMType & 0xf0) == 0x40) + Settings.SDD1 = !Settings.ForceNoSDD1; + + if (Settings.SDD1) + S9xLoadSDD1Data (); + + Settings.C4 = Settings.ForceC4; + if ((ROMType & 0xf0) == 0xf0 && + (strncmp (ROMName, "MEGAMAN X", 9) == 0 || + strncmp (ROMName, "ROCKMAN X", 9) == 0)) + { + Settings.C4 = !Settings.ForceNoC4; + } + + if (Settings.SuperFX) + { + //::SRAM = ROM + 1024 * 1024 * 4; + SuperFXROMMap (); + Settings.MultiPlayer5Master = FALSE; + //Settings.MouseMaster = FALSE; + //Settings.SuperScopeMaster = FALSE; + Settings.DSP1Master = FALSE; + Settings.SA1 = FALSE; + Settings.C4 = FALSE; + Settings.SDD1 = FALSE; + } + else + if (Settings.ForceSA1 || + (!Settings.ForceNoSA1 && (ROMSpeed & ~0x10) == 0x23 && + (ROMType & 0xf) > 3 && (ROMType & 0xf0) == 0x30)) + { + Settings.SA1 = TRUE; + Settings.MultiPlayer5Master = FALSE; + //Settings.MouseMaster = FALSE; + //Settings.SuperScopeMaster = FALSE; + Settings.DSP1Master = FALSE; + Settings.C4 = FALSE; + Settings.SDD1 = FALSE; + SA1ROMMap (); + } + else + if ((ROMSpeed & ~0x10) == 0x25) + TalesROMMap (Interleaved); + else + if (strncmp ((char *) &Memory.ROM [0x7fc0], "SOUND NOVEL-TCOOL", 17) == 0 || + strncmp ((char *) &Memory.ROM [0x7fc0], "DERBY STALLION 96", 17) == 0) + { + LoROM24MBSMap (); + Settings.DSP1Master = FALSE; + } + else + if (strncmp ((char *) &Memory.ROM [0x7fc0], "THOROUGHBRED BREEDER3", 21) == 0 || + strncmp ((char *) &Memory.ROM [0x7fc0], "RPG-TCOOL 2", 11) == 0) + { + SRAM512KLoROMMap (); + Settings.DSP1Master = FALSE; + } + else + if (strncmp ((char *) &Memory.ROM [0x7fc0], "DEZAEMON ", 10) == 0) + { + Settings.DSP1Master = FALSE; + SRAM1024KLoROMMap (); + } + else + if (strncmp ((char *) &Memory.ROM [0x7fc0], "ADD-ON BASE CASSETE", 19) == 0) + { + Settings.MultiPlayer5Master = FALSE; + Settings.MouseMaster = FALSE; + Settings.SuperScopeMaster = FALSE; + Settings.DSP1Master = FALSE; + SufamiTurboLoROMMap(); + Memory.SRAMSize = 3; + } + else + if ((ROMSpeed & ~0x10) == 0x22 && + strncmp (ROMName, "Super Street Fighter", 20) != 0) + { + AlphaROMMap (); + } + else + LoROMMap (); + } + + int power2 = 0; + int size = CalculatedSize; + + while (size >>= 1) + power2++; + + size = 1 << power2; + uint32 remainder = CalculatedSize - size; + + uint32 sum1 = 0; + uint32 sum2 = 0; + + int i; + + for (i = 0; i < size; i++) + sum1 += ROM [i]; + + for (i = 0; i < (int) remainder; i++) + sum2 += ROM [size + i]; + + if (remainder) + { + //for Tengai makyou + if (CalculatedSize == 0x500000 && Memory.HiROM && + strncmp ((const char *)&ROM[0xffb0], "18AZ", 4) == 0 && + !memcmp(&ROM[0xffd5], "\x3a\xf9\x0d\x03\x00\x33\x00", 7)) + sum1 += sum2; + else + sum1 += sum2 * (size / remainder); + } + + sum1 &= 0xffff; + + //now take a CRC32 + ROMCRC32 = caCRC32(&ROM[0], CalculatedSize); + + if (Settings.ForceNTSC) + Settings.PAL = FALSE; + else + if (Settings.ForcePAL) + Settings.PAL = TRUE; + else + if (Memory.HiROM) + // Country code + Settings.PAL = ROM [0xffd9] >= 2; + else + Settings.PAL = ROM [0x7fd9] >= 2; + + if (Settings.PAL) + { + Settings.FrameTime = Settings.FrameTimePAL; + Memory.ROMFramesPerSecond = 50; + } + else + { + Settings.FrameTime = Settings.FrameTimeNTSC; + Memory.ROMFramesPerSecond = 60; + } + + ROMName[ROM_NAME_LEN - 1] = 0; + if (strlen (ROMName)) + { + char *p = ROMName + strlen (ROMName) - 1; + + while (p > ROMName && *(p - 1) == ' ') + p--; + *p = 0; + } + + if (Settings.SuperFX) + { + CPU.Memory_SRAMMask = 0xffff; + Memory.SRAMSize = 16; + } + else + { + CPU.Memory_SRAMMask = Memory.SRAMSize ? + ((1 << (Memory.SRAMSize + 3)) * 128) - 1 : 0; + } + + IAPU.OneCycle = ONE_APU_CYCLE; + Settings.Shutdown = Settings.ShutdownMaster; + + SetDSP = &DSP1SetByte; + GetDSP = &DSP1GetByte; + + ApplyROMFixes (); + sprintf (ROMName, "%s", Safe (ROMName)); + sprintf (ROMId, "%s", Safe (ROMId)); + sprintf (CompanyId, "%s", Safe (CompanyId)); + + sprintf (String, "\"%s\" [%s] %s, %s, Type: %s, Mode: %s, TV: %s, S-RAM: %s, ROMId: %s Company: %2.2s", + ROMName, + (ROMChecksum + ROMComplementChecksum != 0xffff || + ROMChecksum != sum1) ? "bad checksum" : "checksum ok", + MapType (), + Size (), + KartContents (), + MapMode (), + TVStandard (), + StaticRAMSize (), + ROMId, + CompanyId); + + S9xMessage (S9X_INFO, S9X_ROM_INFO, String); +} + +bool8_32 CMemory::LoadSRAM (const char *filename) +{ + int size = Memory.SRAMSize ? + (1 << (Memory.SRAMSize + 3)) * 128 : 0; + + memset (SRAM, SNESGameFixes.SRAMInitialValue, 0x20000); + + if (size > 0x20000) + size = 0x20000; + + if (size) + { + FILE *file; + if ((file = fopen(filename, "rb"))) + { + int len = fread ((char*) ::SRAM, 1, 0x20000, file); + fclose (file); + if (len - size == 512) + { + // S-RAM file has a header - remove it + memmove (::SRAM, ::SRAM + 512, size); + } + if (len == size + SRTC_SRAM_PAD) + { + S9xSRTCPostLoadState (); + S9xResetSRTC (); + rtc.index = -1; + rtc.mode = MODE_READ; + } + else + S9xHardResetSRTC (); + + return (TRUE); + } + S9xHardResetSRTC (); + return (FALSE); + } + if (Settings.SDD1) + S9xSDD1LoadLoggedData (); + + return (TRUE); +} + +bool8_32 CMemory::SaveSRAM (const char *filename) +{ + int size = Memory.SRAMSize ? + (1 << (Memory.SRAMSize + 3)) * 128 : 0; + if (Settings.SRTC) + { + size += SRTC_SRAM_PAD; + S9xSRTCPreSaveState (); + } + + if (Settings.SDD1) + S9xSDD1SaveLoggedData (); + + if (size > 0x20000) + size = 0x20000; + + if (size && *Memory.ROMFilename) + { + FILE *file; + if ((file = fopen (filename, "wb"))) + { + fwrite ((char *) ::SRAM, size, 1, file); + fclose (file); +#if defined(__linux) + chown (filename, getuid (), getgid ()); +#endif + return (TRUE); + } + } + return (FALSE); +} + +void CMemory::FixROMSpeed () +{ + int c; + + for (c = 0x800; c < 0x1000; c++) + { + if (BlockIsROM [c]) + MemorySpeed [c] = (uint8) CPU.FastROMSpeed; + } +} + +void CMemory::WriteProtectROM () +{ + memmove ((void *) WriteMap, (void *) Map, sizeof (Map)); + for (int c = 0; c < 0x1000; c++) + { + if (BlockIsROM [c]) + WriteMap [c] = (uint8 *) MAP_NONE; + } +} + +void CMemory::MapRAM () +{ + int c; + + // Banks 7e->7f, RAM + for (c = 0; c < 16; c++) + { + Map [c + 0x7e0] = RAM; + Map [c + 0x7f0] = RAM + 0x10000; + BlockIsRAM [c + 0x7e0] = TRUE; + BlockIsRAM [c + 0x7f0] = TRUE; + BlockIsROM [c + 0x7e0] = FALSE; + BlockIsROM [c + 0x7f0] = FALSE; + } + + // Banks 70->77, S-RAM + for (c = 0; c < 0x80; c++) + { + Map [c + 0x700] = (uint8 *) MAP_LOROM_SRAM; + BlockIsRAM [c + 0x700] = TRUE; + BlockIsROM [c + 0x700] = FALSE; + } +} + +void CMemory::MapExtraRAM () +{ + int c; + + // Banks 7e->7f, RAM + for (c = 0; c < 16; c++) + { + Map [c + 0x7e0] = RAM; + Map [c + 0x7f0] = RAM + 0x10000; + BlockIsRAM [c + 0x7e0] = TRUE; + BlockIsRAM [c + 0x7f0] = TRUE; + BlockIsROM [c + 0x7e0] = FALSE; + BlockIsROM [c + 0x7f0] = FALSE; + } + + // Banks 70->73, S-RAM + for (c = 0; c < 16; c++) + { + Map [c + 0x700] = ::SRAM; + Map [c + 0x710] = ::SRAM + 0x8000; + Map [c + 0x720] = ::SRAM + 0x10000; + Map [c + 0x730] = ::SRAM + 0x18000; + + BlockIsRAM [c + 0x700] = TRUE; + BlockIsROM [c + 0x700] = FALSE; + BlockIsRAM [c + 0x710] = TRUE; + BlockIsROM [c + 0x710] = FALSE; + BlockIsRAM [c + 0x720] = TRUE; + BlockIsROM [c + 0x720] = FALSE; + BlockIsRAM [c + 0x730] = TRUE; + BlockIsROM [c + 0x730] = FALSE; + } +} + +void CMemory::LoROMMap () +{ + int c; + int i; + + // Banks 00->3f and 80->bf + for (c = 0; c < 0x400; c += 16) + { + Map [c + 0] = Map [c + 0x800] = RAM; + Map [c + 1] = Map [c + 0x801] = RAM; + BlockIsRAM [c + 0] = BlockIsRAM [c + 0x800] = TRUE; + BlockIsRAM [c + 1] = BlockIsRAM [c + 0x801] = TRUE; + + Map [c + 2] = Map [c + 0x802] = (uint8 *) MAP_PPU; + Map [c + 3] = Map [c + 0x803] = (uint8 *) MAP_PPU; + Map [c + 4] = Map [c + 0x804] = (uint8 *) MAP_CPU; + Map [c + 5] = Map [c + 0x805] = (uint8 *) MAP_CPU; + if (Settings.DSP1Master) + { + Map [c + 6] = Map [c + 0x806] = (uint8 *) MAP_DSP; + Map [c + 7] = Map [c + 0x807] = (uint8 *) MAP_DSP; + } + else + if (Settings.C4) + { + Map [c + 6] = Map [c + 0x806] = (uint8 *) MAP_C4; + Map [c + 7] = Map [c + 0x807] = (uint8 *) MAP_C4; + } + else + { + Map [c + 6] = Map [c + 0x806] = (uint8 *) bytes0x2000 - 0x6000; + Map [c + 7] = Map [c + 0x807] = (uint8 *) bytes0x2000 - 0x6000; + } + + for (i = c + 8; i < c + 16; i++) + { + Map [i] = Map [i + 0x800] = &ROM [(c << 11) % CalculatedSize] - 0x8000; + BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE; + } + + for (i = c; i < c + 16; i++) + { + int ppu = i & 15; + + MemorySpeed [i] = + MemorySpeed [i + 0x800] = ppu >= 2 && ppu <= 3 ? ONE_CYCLE : SLOW_ONE_CYCLE; + } + } + + if (Settings.DSP1Master) + { + // Banks 30->3f and b0->bf + for (c = 0x300; c < 0x400; c += 16) + { + for (i = c + 8; i < c + 16; i++) + { + Map [i] = Map [i + 0x800] = (uint8 *) MAP_DSP; + BlockIsROM [i] = BlockIsROM [i + 0x800] = FALSE; + } + } + } + + // Banks 40->7f and c0->ff + for (c = 0; c < 0x400; c += 16) + { + for (i = c; i < c + 8; i++) + Map [i + 0x400] = Map [i + 0xc00] = &ROM [(c << 11) % CalculatedSize]; + + for (i = c + 8; i < c + 16; i++) + Map [i + 0x400] = Map [i + 0xc00] = &ROM [((c << 11) + 0x200000) % CalculatedSize - 0x8000]; + + for (i = c; i < c + 16; i++) + { + MemorySpeed [i + 0x400] = MemorySpeed [i + 0xc00] = SLOW_ONE_CYCLE; + BlockIsROM [i + 0x400] = BlockIsROM [i + 0xc00] = TRUE; + } + } + + if (Settings.DSP1Master) + { + for (c = 0; c < 0x100; c++) + { + Map [c + 0xe00] = (uint8 *) MAP_DSP; + MemorySpeed [c + 0xe00] = SLOW_ONE_CYCLE; + BlockIsROM [c + 0xe00] = FALSE; + } + } + MapRAM (); + WriteProtectROM (); +} + +void CMemory::HiROMMap () +{ + int c; + int i; + + // Banks 00->3f and 80->bf + for (c = 0; c < 0x400; c += 16) + { + Map [c + 0] = Map [c + 0x800] = RAM; + BlockIsRAM [c + 0] = BlockIsRAM [c + 0x800] = TRUE; + Map [c + 1] = Map [c + 0x801] = RAM; + BlockIsRAM [c + 1] = BlockIsRAM [c + 0x801] = TRUE; + + Map [c + 2] = Map [c + 0x802] = (uint8 *) MAP_PPU; + Map [c + 3] = Map [c + 0x803] = (uint8 *) MAP_PPU; + Map [c + 4] = Map [c + 0x804] = (uint8 *) MAP_CPU; + Map [c + 5] = Map [c + 0x805] = (uint8 *) MAP_CPU; + if (Settings.DSP1Master) + { + Map [c + 6] = Map [c + 0x806] = (uint8 *) MAP_DSP; + Map [c + 7] = Map [c + 0x807] = (uint8 *) MAP_DSP; + } + else + { + Map [c + 6] = Map [c + 0x806] = (uint8 *) MAP_NONE; + Map [c + 7] = Map [c + 0x807] = (uint8 *) MAP_NONE; + } + + for (i = c + 8; i < c + 16; i++) + { + Map [i] = Map [i + 0x800] = &ROM [(c << 12) % CalculatedSize]; + BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE; + } + + for (i = c; i < c + 16; i++) + { + int ppu = i & 15; + + MemorySpeed [i] = + MemorySpeed [i + 0x800] = ppu >= 2 && ppu <= 3 ? ONE_CYCLE : SLOW_ONE_CYCLE; + } + } + + // Banks 30->3f and b0->bf, address ranges 6000->7fff is S-RAM. + for (c = 0; c < 16; c++) + { + Map [0x306 + (c << 4)] = (uint8 *) MAP_HIROM_SRAM; + Map [0x307 + (c << 4)] = (uint8 *) MAP_HIROM_SRAM; + Map [0xb06 + (c << 4)] = (uint8 *) MAP_HIROM_SRAM; + Map [0xb07 + (c << 4)] = (uint8 *) MAP_HIROM_SRAM; + BlockIsRAM [0x306 + (c << 4)] = TRUE; + BlockIsRAM [0x307 + (c << 4)] = TRUE; + BlockIsRAM [0xb06 + (c << 4)] = TRUE; + BlockIsRAM [0xb07 + (c << 4)] = TRUE; + } + + // Banks 40->7f and c0->ff + for (c = 0; c < 0x400; c += 16) + { + for (i = c; i < c + 16; i++) + { + Map [i + 0x400] = Map [i + 0xc00] = &ROM [(c << 12) % CalculatedSize]; + MemorySpeed [i + 0x400] = MemorySpeed [i + 0xc00] = SLOW_ONE_CYCLE; + BlockIsROM [i + 0x400] = BlockIsROM [i + 0xc00] = TRUE; + } + } + + MapRAM (); + WriteProtectROM (); +} + +void CMemory::TalesROMMap (bool8_32 Interleaved) +{ + int c; + int i; + + uint32 OFFSET0 = 0x400000; + uint32 OFFSET1 = 0x400000; + uint32 OFFSET2 = 0x000000; + + if (Interleaved) + { + OFFSET0 = 0x000000; + OFFSET1 = 0x000000; + OFFSET2 = 0x200000; + } + + // Banks 00->3f and 80->bf + for (c = 0; c < 0x400; c += 16) + { + Map [c + 0] = Map [c + 0x800] = RAM; + Map [c + 1] = Map [c + 0x801] = RAM; + BlockIsRAM [c + 0] = BlockIsRAM [c + 0x800] = TRUE; + BlockIsRAM [c + 1] = BlockIsRAM [c + 0x801] = TRUE; + + Map [c + 2] = Map [c + 0x802] = (uint8 *) MAP_PPU; + Map [c + 3] = Map [c + 0x803] = (uint8 *) MAP_PPU; + Map [c + 4] = Map [c + 0x804] = (uint8 *) MAP_CPU; + Map [c + 5] = Map [c + 0x805] = (uint8 *) MAP_CPU; + Map [c + 6] = Map [c + 0x806] = (uint8 *) MAP_NONE; + Map [c + 7] = Map [c + 0x807] = (uint8 *) MAP_NONE; + for (i = c + 8; i < c + 16; i++) + { + Map [i] = &ROM [((c << 12) + OFFSET0) % CalculatedSize]; + Map [i + 0x800] = &ROM [((c << 12) + OFFSET0) % CalculatedSize]; + BlockIsROM [i] = TRUE; + BlockIsROM [i + 0x800] = TRUE; + } + + for (i = c; i < c + 16; i++) + { + int ppu = i & 15; + + MemorySpeed [i] = + MemorySpeed [i + 0x800] = ppu >= 2 && ppu <= 3 ? ONE_CYCLE : SLOW_ONE_CYCLE; + } + } + + // Banks 30->3f and b0->bf, address ranges 6000->7ffff is S-RAM. + for (c = 0; c < 16; c++) + { + Map [0x306 + (c << 4)] = (uint8 *) MAP_HIROM_SRAM; + Map [0x307 + (c << 4)] = (uint8 *) MAP_HIROM_SRAM; + Map [0xb06 + (c << 4)] = (uint8 *) MAP_HIROM_SRAM; + Map [0xb07 + (c << 4)] = (uint8 *) MAP_HIROM_SRAM; + BlockIsRAM [0x306 + (c << 4)] = TRUE; + BlockIsRAM [0x307 + (c << 4)] = TRUE; + BlockIsRAM [0xb06 + (c << 4)] = TRUE; + BlockIsRAM [0xb07 + (c << 4)] = TRUE; + } + + // Banks 40->7f and c0->ff + for (c = 0; c < 0x400; c += 16) + { + for (i = c; i < c + 8; i++) + { + Map [i + 0x400] = &ROM [((c << 12) + OFFSET1) % CalculatedSize]; + Map [i + 0x408] = &ROM [((c << 12) + OFFSET1) % CalculatedSize]; + Map [i + 0xc00] = &ROM [((c << 12) + OFFSET2) % CalculatedSize]; + Map [i + 0xc08] = &ROM [((c << 12) + OFFSET2) % CalculatedSize]; + BlockIsROM [i + 0x400] = TRUE; + BlockIsROM [i + 0x408] = TRUE; + BlockIsROM [i + 0xc00] = TRUE; + BlockIsROM [i + 0xc08] = TRUE; + MemorySpeed [i + 0x400] = MemorySpeed [i + 0xc00] = SLOW_ONE_CYCLE; + MemorySpeed [i + 0x408] = MemorySpeed [i + 0xc08] = SLOW_ONE_CYCLE; + } + } + MapRAM (); + WriteProtectROM (); +} + +void CMemory::AlphaROMMap () +{ + int c; + int i; + + // Banks 00->3f and 80->bf + for (c = 0; c < 0x400; c += 16) + { + Map [c + 0] = Map [c + 0x800] = RAM; + Map [c + 1] = Map [c + 0x801] = RAM; + BlockIsRAM [c + 0] = BlockIsRAM [c + 0x800] = TRUE; + BlockIsRAM [c + 1] = BlockIsRAM [c + 0x801] = TRUE; + + Map [c + 2] = Map [c + 0x802] = (uint8 *) MAP_PPU; + Map [c + 3] = Map [c + 0x803] = (uint8 *) MAP_PPU; + Map [c + 4] = Map [c + 0x804] = (uint8 *) MAP_CPU; + Map [c + 5] = Map [c + 0x805] = (uint8 *) MAP_CPU; + Map [c + 6] = Map [c + 0x806] = (uint8 *) MAP_DSP; + Map [c + 7] = Map [c + 0x807] = (uint8 *) MAP_DSP; + + for (i = c + 8; i < c + 16; i++) + { + Map [i] = Map [i + 0x800] = &ROM [c << 11] - 0x8000; + BlockIsROM [i] = TRUE; + } + + for (i = c; i < c + 16; i++) + { + int ppu = i & 15; + + MemorySpeed [i] = + MemorySpeed [i + 0x800] = ppu >= 2 && ppu <= 3 ? ONE_CYCLE : SLOW_ONE_CYCLE; + } + } + + // Banks 40->7f and c0->ff + + for (c = 0; c < 0x400; c += 16) + { + for (i = c; i < c + 16; i++) + { + Map [i + 0x400] = &ROM [(c << 12) % CalculatedSize]; + Map [i + 0xc00] = &ROM [(c << 12) % CalculatedSize]; + MemorySpeed [i + 0x400] = MemorySpeed [i + 0xc00] = SLOW_ONE_CYCLE; + BlockIsROM [i + 0x400] = BlockIsROM [i + 0xc00] = TRUE; + } + } + + MapRAM (); + WriteProtectROM (); +} + +void CMemory::SuperFXROMMap () +{ + int c; + int i; + + // Banks 00->3f and 80->bf + for (c = 0; c < 0x400; c += 16) + { + Map [c + 0] = Map [c + 0x800] = RAM; + Map [c + 1] = Map [c + 0x801] = RAM; + BlockIsRAM [c + 0] = BlockIsRAM [c + 0x800] = TRUE; + BlockIsRAM [c + 1] = BlockIsRAM [c + 0x801] = TRUE; + + Map [c + 2] = Map [c + 0x802] = (uint8 *) MAP_PPU; + Map [c + 3] = Map [c + 0x803] = (uint8 *) MAP_PPU; + Map [c + 4] = Map [c + 0x804] = (uint8 *) MAP_CPU; + Map [c + 5] = Map [c + 0x805] = (uint8 *) MAP_CPU; + Map [c + 6] = Map [c + 0x806] = (uint8 *) MAP_DSP; + Map [c + 7] = Map [c + 0x807] = (uint8 *) MAP_DSP; + for (i = c + 8; i < c + 16; i++) + { + Map [i] = Map [i + 0x800] = &ROM [c << 11] - 0x8000; + BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE; + } + + for (i = c; i < c + 8; i++) + { + int ppu = i & 15; + + MemorySpeed [i] = + MemorySpeed [i + 0x800] = ppu >= 2 && ppu <= 3 ? ONE_CYCLE : SLOW_ONE_CYCLE; + } + } + + // Banks 40->7f and c0->ff + for (c = 0; c < 0x400; c += 16) + { + for (i = c; i < c + 16; i++) + { + Map [i + 0x400] = Map [i + 0xc00] = &ROM [(c << 12) % CalculatedSize]; + MemorySpeed [i + 0x400] = MemorySpeed [i + 0xc00] = SLOW_ONE_CYCLE; + BlockIsROM [i + 0x400] = BlockIsROM [i + 0xc00] = TRUE; + } + } + + // Banks 7e->7f, RAM + for (c = 0; c < 16; c++) + { + Map [c + 0x7e0] = RAM; + Map [c + 0x7f0] = RAM + 0x10000; + BlockIsRAM [c + 0x7e0] = TRUE; + BlockIsRAM [c + 0x7f0] = TRUE; + BlockIsROM [c + 0x7e0] = FALSE; + BlockIsROM [c + 0x7f0] = FALSE; + } + + // Banks 70->71, S-RAM + for (c = 0; c < 32; c++) + { + Map [c + 0x700] = ::SRAM + (((c >> 4) & 1) << 16); + BlockIsRAM [c + 0x700] = TRUE; + BlockIsROM [c + 0x700] = FALSE; + } + + // Banks 00->3f and 80->bf address ranges 6000->7fff is RAM. + for (c = 0; c < 0x40; c++) + { + Map [0x006 + (c << 4)] = (uint8 *) ::SRAM - 0x6000; + Map [0x007 + (c << 4)] = (uint8 *) ::SRAM - 0x6000; + Map [0x806 + (c << 4)] = (uint8 *) ::SRAM - 0x6000; + Map [0x807 + (c << 4)] = (uint8 *) ::SRAM - 0x6000; + BlockIsRAM [0x006 + (c << 4)] = TRUE; + BlockIsRAM [0x007 + (c << 4)] = TRUE; + BlockIsRAM [0x806 + (c << 4)] = TRUE; + BlockIsRAM [0x807 + (c << 4)] = TRUE; + } + // Replicate the first 2Mb of the ROM at ROM + 2MB such that each 32K + // block is repeated twice in each 64K block. + for (c = 0; c < 64; c++) + { + memmove (&ROM [0x200000 + c * 0x10000], &ROM [c * 0x8000], 0x8000); + memmove (&ROM [0x208000 + c * 0x10000], &ROM [c * 0x8000], 0x8000); + } + + WriteProtectROM (); +} + +void CMemory::SA1ROMMap () +{ + int c; + int i; + + // Banks 00->3f and 80->bf + for (c = 0; c < 0x400; c += 16) + { + Map [c + 0] = Map [c + 0x800] = RAM; + Map [c + 1] = Map [c + 0x801] = RAM; + BlockIsRAM [c + 0] = BlockIsRAM [c + 0x800] = TRUE; + BlockIsRAM [c + 1] = BlockIsRAM [c + 0x801] = TRUE; + + Map [c + 2] = Map [c + 0x802] = (uint8 *) MAP_PPU; + Map [c + 3] = Map [c + 0x803] = (uint8 *) &Memory.FillRAM [0x3000] - 0x3000; + Map [c + 4] = Map [c + 0x804] = (uint8 *) MAP_CPU; + Map [c + 5] = Map [c + 0x805] = (uint8 *) MAP_CPU; + Map [c + 6] = Map [c + 0x806] = (uint8 *) MAP_BWRAM; + Map [c + 7] = Map [c + 0x807] = (uint8 *) MAP_BWRAM; + for (i = c + 8; i < c + 16; i++) + { + Map [i] = Map [i + 0x800] = &ROM [c << 11] - 0x8000; + BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE; + } + + for (i = c; i < c + 16; i++) + { + int ppu = i & 15; + + MemorySpeed [i] = + MemorySpeed [i + 0x800] = ppu >= 2 && ppu <= 3 ? ONE_CYCLE : SLOW_ONE_CYCLE; + } + } + + // Banks 40->7f + for (c = 0; c < 0x400; c += 16) + { + for (i = c; i < c + 16; i++) + Map [i + 0x400] = (uint8 *) &SRAM [(c << 12) & 0x1ffff]; + + for (i = c; i < c + 16; i++) + { + MemorySpeed [i + 0x400] = SLOW_ONE_CYCLE; + BlockIsROM [i + 0x400] = FALSE; + } + } + + // c0->ff + for (c = 0; c < 0x400; c += 16) + { + for (i = c; i < c + 16; i++) + { + Map [i + 0xc00] = &ROM [(c << 12) % CalculatedSize]; + MemorySpeed [i + 0xc00] = SLOW_ONE_CYCLE; + BlockIsROM [i + 0xc00] = TRUE; + } + } + + for (c = 0; c < 16; c++) + { + Map [c + 0x7e0] = RAM; + Map [c + 0x7f0] = RAM + 0x10000; + BlockIsRAM [c + 0x7e0] = TRUE; + BlockIsRAM [c + 0x7f0] = TRUE; + BlockIsROM [c + 0x7e0] = FALSE; + BlockIsROM [c + 0x7f0] = FALSE; + } + WriteProtectROM (); + + // Now copy the map and correct it for the SA1 CPU. + memmove ((void *) SA1.WriteMap, (void *) WriteMap, sizeof (WriteMap)); + memmove ((void *) SA1.Map, (void *) Map, sizeof (Map)); + + // Banks 00->3f and 80->bf + for (c = 0; c < 0x400; c += 16) + { + SA1.Map [c + 0] = SA1.Map [c + 0x800] = &Memory.FillRAM [0x3000]; + SA1.Map [c + 1] = SA1.Map [c + 0x801] = (uint8 *) MAP_NONE; + SA1.WriteMap [c + 0] = SA1.WriteMap [c + 0x800] = &Memory.FillRAM [0x3000]; + SA1.WriteMap [c + 1] = SA1.WriteMap [c + 0x801] = (uint8 *) MAP_NONE; + } + + // Banks 60->6f + for (c = 0; c < 0x100; c++) + SA1.Map [c + 0x600] = SA1.WriteMap [c + 0x600] = (uint8 *) MAP_BWRAM_BITMAP; + + BWRAM = SRAM; +} + +void CMemory::LoROM24MBSMap () +{ + int c; + int i; + + // Banks 00->3f and 80->bf + for (c = 0; c < 0x400; c += 16) + { + Map [c + 0] = Map [c + 0x800] = RAM; + Map [c + 1] = Map [c + 0x801] = RAM; + BlockIsRAM [c + 0] = BlockIsRAM [c + 0x800] = TRUE; + BlockIsRAM [c + 1] = BlockIsRAM [c + 0x801] = TRUE; + + Map [c + 2] = Map [c + 0x802] = (uint8 *) MAP_PPU; + Map [c + 3] = Map [c + 0x803] = (uint8 *) MAP_PPU; + Map [c + 4] = Map [c + 0x804] = (uint8 *) MAP_CPU; + Map [c + 5] = Map [c + 0x805] = (uint8 *) MAP_CPU; + Map [c + 6] = Map [c + 0x806] = (uint8 *) MAP_NONE; + Map [c + 7] = Map [c + 0x807] = (uint8 *) MAP_NONE; + + for (i = c + 8; i < c + 16; i++) + { + Map [i] = Map [i + 0x800] = &ROM [c << 11] - 0x8000; + BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE; + } + + for (i = c; i < c + 16; i++) + { + int ppu = i & 15; + + MemorySpeed [i] = + MemorySpeed [i + 0x800] = ppu >= 2 && ppu <= 3 ? ONE_CYCLE : SLOW_ONE_CYCLE; + } + } + + // Banks 00->3f and 80->bf + for (c = 0; c < 0x200; c += 16) + { + Map [c + 0x800] = RAM; + Map [c + 0x801] = RAM; + BlockIsRAM [c + 0x800] = TRUE; + BlockIsRAM [c + 0x801] = TRUE; + + Map [c + 0x802] = (uint8 *) MAP_PPU; + Map [c + 0x803] = (uint8 *) MAP_PPU; + Map [c + 0x804] = (uint8 *) MAP_CPU; + Map [c + 0x805] = (uint8 *) MAP_CPU; + Map [c + 0x806] = (uint8 *) MAP_NONE; + Map [c + 0x807] = (uint8 *) MAP_NONE; + + for (i = c + 8; i < c + 16; i++) + { + Map [i + 0x800] = &ROM [c << 11] - 0x8000 + 0x200000; + BlockIsROM [i + 0x800] = TRUE; + } + + for (i = c; i < c + 16; i++) + { + int ppu = i & 15; + + MemorySpeed [i + 0x800] = ppu >= 2 && ppu <= 3 ? ONE_CYCLE : SLOW_ONE_CYCLE; + } + } + + // Banks 40->7f and c0->ff + for (c = 0; c < 0x400; c += 16) + { + for (i = c; i < c + 8; i++) + Map [i + 0x400] = Map [i + 0xc00] = &ROM [(c << 11) + 0x200000]; + + for (i = c + 8; i < c + 16; i++) + Map [i + 0x400] = Map [i + 0xc00] = &ROM [(c << 11) + 0x200000 - 0x8000]; + + for (i = c; i < c + 16; i++) + { + MemorySpeed [i + 0x400] = MemorySpeed [i + 0xc00] = SLOW_ONE_CYCLE; + BlockIsROM [i + 0x400] = BlockIsROM [i + 0xc00] = TRUE; + } + } + + MapExtraRAM (); + WriteProtectROM (); +} + +void CMemory::SufamiTurboLoROMMap () +{ + int c; + int i; + + // Banks 00->3f and 80->bf + for (c = 0; c < 0x400; c += 16) + { + Map [c + 0] = Map [c + 0x800] = RAM; + Map [c + 1] = Map [c + 0x801] = RAM; + BlockIsRAM [c + 0] = BlockIsRAM [c + 0x800] = TRUE; + BlockIsRAM [c + 1] = BlockIsRAM [c + 0x801] = TRUE; + + Map [c + 2] = Map [c + 0x802] = (uint8 *) MAP_PPU; + Map [c + 3] = Map [c + 0x803] = (uint8 *) MAP_PPU; + Map [c + 4] = Map [c + 0x804] = (uint8 *) MAP_CPU; + Map [c + 5] = Map [c + 0x805] = (uint8 *) MAP_CPU; + if (Settings.DSP1Master) + { + Map [c + 6] = Map [c + 0x806] = (uint8 *) MAP_DSP; + Map [c + 7] = Map [c + 0x807] = (uint8 *) MAP_DSP; + } + else + { + Map [c + 6] = Map [c + 0x806] = (uint8 *) MAP_NONE; + Map [c + 7] = Map [c + 0x807] = (uint8 *) MAP_NONE; + } + for (i = c + 8; i < c + 16; i++) + { + Map [i] = Map [i + 0x800] = &ROM [c << 11] - 0x8000; + BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE; + } + + for (i = c; i < c + 16; i++) + { + int ppu = i & 15; + + MemorySpeed [i] = + MemorySpeed [i + 0x800] = ppu >= 2 && ppu <= 3 ? ONE_CYCLE : SLOW_ONE_CYCLE; + } + } + + if (Settings.DSP1Master) + { + // Banks 30->3f and b0->bf + for (c = 0x300; c < 0x400; c += 16) + { + for (i = c + 8; i < c + 16; i++) + { + Map [i] = Map [i + 0x800] = (uint8 *) MAP_DSP; + BlockIsROM [i] = BlockIsROM [i + 0x800] = FALSE; + } + } + } + + // Banks 40->7f and c0->ff + for (c = 0; c < 0x400; c += 16) + { + for (i = c; i < c + 8; i++) + Map [i + 0x400] = Map [i + 0xc00] = &ROM [(c << 11) + 0x200000]; + + for (i = c + 8; i < c + 16; i++) + Map [i + 0x400] = Map [i + 0xc00] = &ROM [(c << 11) + 0x200000 - 0x8000]; + + for (i = c; i < c + 16; i++) + { + MemorySpeed [i + 0x400] = MemorySpeed [i + 0xc00] = SLOW_ONE_CYCLE; + BlockIsROM [i + 0x400] = BlockIsROM [i + 0xc00] = TRUE; + } + } + + if (Settings.DSP1Master) + { + for (c = 0; c < 0x100; c++) + { + Map [c + 0xe00] = (uint8 *) MAP_DSP; + MemorySpeed [c + 0xe00] = SLOW_ONE_CYCLE; + BlockIsROM [c + 0xe00] = FALSE; + } + } + + // Banks 7e->7f, RAM + for (c = 0; c < 16; c++) + { + Map [c + 0x7e0] = RAM; + Map [c + 0x7f0] = RAM + 0x10000; + BlockIsRAM [c + 0x7e0] = TRUE; + BlockIsRAM [c + 0x7f0] = TRUE; + BlockIsROM [c + 0x7e0] = FALSE; + BlockIsROM [c + 0x7f0] = FALSE; + } + + // Banks 60->67, S-RAM + for (c = 0; c < 0x80; c++) + { + Map [c + 0x600] = (uint8 *) MAP_LOROM_SRAM; + BlockIsRAM [c + 0x600] = TRUE; + BlockIsROM [c + 0x600] = FALSE; + } + + WriteProtectROM (); +} + +void CMemory::SRAM512KLoROMMap () +{ + int c; + int i; + + // Banks 00->3f and 80->bf + for (c = 0; c < 0x400; c += 16) + { + Map [c + 0] = Map [c + 0x800] = RAM; + Map [c + 1] = Map [c + 0x801] = RAM; + BlockIsRAM [c + 0] = BlockIsRAM [c + 0x800] = TRUE; + BlockIsRAM [c + 1] = BlockIsRAM [c + 0x801] = TRUE; + + Map [c + 2] = Map [c + 0x802] = (uint8 *) MAP_PPU; + Map [c + 3] = Map [c + 0x803] = (uint8 *) MAP_PPU; + Map [c + 4] = Map [c + 0x804] = (uint8 *) MAP_CPU; + Map [c + 5] = Map [c + 0x805] = (uint8 *) MAP_CPU; + Map [c + 6] = Map [c + 0x806] = (uint8 *) MAP_NONE; + Map [c + 7] = Map [c + 0x807] = (uint8 *) MAP_NONE; + + for (i = c + 8; i < c + 16; i++) + { + Map [i] = Map [i + 0x800] = &ROM [c << 11] - 0x8000; + BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE; + } + + for (i = c; i < c + 16; i++) + { + int ppu = i & 15; + + MemorySpeed [i] = + MemorySpeed [i + 0x800] = ppu >= 2 && ppu <= 3 ? ONE_CYCLE : SLOW_ONE_CYCLE; + } + } + + // Banks 40->7f and c0->ff + for (c = 0; c < 0x400; c += 16) + { + for (i = c; i < c + 8; i++) + Map [i + 0x400] = Map [i + 0xc00] = &ROM [(c << 11) + 0x200000]; + + for (i = c + 8; i < c + 16; i++) + Map [i + 0x400] = Map [i + 0xc00] = &ROM [(c << 11) + 0x200000 - 0x8000]; + + for (i = c; i < c + 16; i++) + { + MemorySpeed [i + 0x400] = MemorySpeed [i + 0xc00] = SLOW_ONE_CYCLE; + BlockIsROM [i + 0x400] = BlockIsROM [i + 0xc00] = TRUE; + } + } + + MapExtraRAM (); + WriteProtectROM (); +} + +void CMemory::SRAM1024KLoROMMap () +{ + int c; + int i; + + // Banks 00->3f and 80->bf + for (c = 0; c < 0x400; c += 16) + { + Map [c + 0] = Map [c + 0x800] = Map [c + 0x400] = Map [c + 0xc00] = RAM; + Map [c + 1] = Map [c + 0x801] = Map [c + 0x401] = Map [c + 0xc01] = RAM; + BlockIsRAM [c + 0] = BlockIsRAM [c + 0x800] = BlockIsRAM [c + 0x400] = BlockIsRAM [c + 0xc00] = TRUE; + BlockIsRAM [c + 1] = BlockIsRAM [c + 0x801] = BlockIsRAM [c + 0x401] = BlockIsRAM [c + 0xc01] = TRUE; + + Map [c + 2] = Map [c + 0x802] = Map [c + 0x402] = Map [c + 0xc02] = (uint8 *) MAP_PPU; + Map [c + 3] = Map [c + 0x803] = Map [c + 0x403] = Map [c + 0xc03] = (uint8 *) MAP_PPU; + Map [c + 4] = Map [c + 0x804] = Map [c + 0x404] = Map [c + 0xc04] = (uint8 *) MAP_CPU; + Map [c + 5] = Map [c + 0x805] = Map [c + 0x405] = Map [c + 0xc05] = (uint8 *) MAP_CPU; + Map [c + 6] = Map [c + 0x806] = Map [c + 0x406] = Map [c + 0xc06] = (uint8 *) MAP_NONE; + Map [c + 7] = Map [c + 0x807] = Map [c + 0x407] = Map [c + 0xc07] = (uint8 *) MAP_NONE; + for (i = c + 8; i < c + 16; i++) + { + Map [i] = Map [i + 0x800] = Map [i + 0x400] = Map [i + 0xc00] = &ROM [c << 11] - 0x8000; + BlockIsROM [i] = BlockIsROM [i + 0x800] = BlockIsROM [i + 0x400] = BlockIsROM [i + 0xc00] = TRUE; + } + + for (i = c; i < c + 16; i++) + { + int ppu = i & 15; + + MemorySpeed [i] = MemorySpeed [i + 0x800] = + MemorySpeed [i + 0x400] = MemorySpeed [i + 0xc00] = ppu >= 2 && ppu <= 3 ? ONE_CYCLE : SLOW_ONE_CYCLE; + } + } + + MapExtraRAM (); + WriteProtectROM (); +} + +void CMemory::BSHiROMMap () +{ + int c; + int i; + + // Banks 00->3f and 80->bf + for (c = 0; c < 0x400; c += 16) + { + Map [c + 0] = Map [c + 0x800] = RAM; + BlockIsRAM [c + 0] = BlockIsRAM [c + 0x800] = TRUE; + Map [c + 1] = Map [c + 0x801] = RAM; + BlockIsRAM [c + 1] = BlockIsRAM [c + 0x801] = TRUE; + + Map [c + 2] = Map [c + 0x802] = (uint8 *) MAP_PPU; + Map [c + 3] = Map [c + 0x803] = (uint8 *) MAP_PPU; + Map [c + 4] = Map [c + 0x804] = (uint8 *) MAP_CPU; + // XXX: How large is SRAM?? + Map [c + 5] = Map [c + 0x805] = (uint8 *) SRAM; + BlockIsRAM [c + 5] = BlockIsRAM [c + 0x805] = TRUE; + Map [c + 6] = Map [c + 0x806] = (uint8 *) MAP_NONE; + Map [c + 7] = Map [c + 0x807] = (uint8 *) MAP_NONE; + + for (i = c + 8; i < c + 16; i++) + { + Map [i] = Map [i + 0x800] = &ROM [(c << 12) % CalculatedSize]; + BlockIsROM [i] = BlockIsROM [i + 0x800] = TRUE; + } + + for (i = c; i < c + 16; i++) + { + int ppu = i & 15; + + MemorySpeed [i] = + MemorySpeed [i + 0x800] = ppu >= 2 && ppu <= 3 ? ONE_CYCLE : SLOW_ONE_CYCLE; + } + } + + // Banks 60->7d offset 0000->7fff & 60->7f offset 8000->ffff PSRAM + // XXX: How large is PSRAM? + for (c = 0x600; c < 0x7e0; c += 16) + { + for (i = c; i < c + 8; i++) + { + Map [i] = &ROM [0x400000 + (c << 11)]; + BlockIsRAM [i] = TRUE; + } + for (i = c + 8; i < c + 16; i++) + { + Map [i] = &ROM [0x400000 + (c << 11) - 0x8000]; + BlockIsRAM [i] = TRUE; + } + } + + // Banks 40->7f and c0->ff + for (c = 0; c < 0x400; c += 16) + { + for (i = c; i < c + 16; i++) + { + Map [i + 0x400] = Map [i + 0xc00] = &ROM [(c << 12) % CalculatedSize]; + MemorySpeed [i + 0x400] = MemorySpeed [i + 0xc00] = SLOW_ONE_CYCLE; + BlockIsROM [i + 0x400] = BlockIsROM [i + 0xc00] = TRUE; + } + } + + MapRAM (); + WriteProtectROM (); +} + +const char *CMemory::TVStandard () +{ + return (Settings.PAL ? "PAL" : "NTSC"); +} + +const char *CMemory::Speed () +{ + return (ROMSpeed & 0x10 ? "120ns" : "200ns"); +} + +const char *CMemory::MapType () +{ + return (HiROM ? "HiROM" : "LoROM"); +} + +const char *CMemory::StaticRAMSize () +{ + static char tmp [20]; + + if (Memory.SRAMSize > 16) + return ("Corrupt"); + sprintf (tmp, "%dKb", (CPU.Memory_SRAMMask + 1) / 1024); + return (tmp); +} + +const char *CMemory::Size () +{ + static char tmp [20]; + + if (ROMSize < 7 || ROMSize - 7 > 23) + return ("Corrupt"); + sprintf (tmp, "%dMbits", 1 << (ROMSize - 7)); + return (tmp); +} + +const char *CMemory::KartContents () +{ + static char tmp [30]; + static const char *CoPro [16] = { + "DSP1", "SuperFX", "OBC1", "SA-1", "S-DD1", "S-RTC", "CoPro#6", + "CoPro#7", "CoPro#8", "CoPro#9", "CoPro#10", "CoPro#11", "CoPro#12", + "CoPro#13", "CoPro#14", "CoPro-Custom" + }; + static const char *Contents [3] = { + "ROM", "ROM+RAM", "ROM+RAM+BAT" + }; + if (ROMType == 0) + return ("ROM only"); + + sprintf (tmp, "%s", Contents [(ROMType & 0xf) % 3]); + + if ((ROMType & 0xf) >= 3) + sprintf (tmp, "%s+%s", tmp, CoPro [(ROMType & 0xf0) >> 4]); + + return (tmp); +} + +const char *CMemory::MapMode () +{ + static char tmp [4]; + sprintf (tmp, "%02x", ROMSpeed & ~0x10); + return (tmp); +} + +const char *CMemory::ROMID () +{ + return (ROMId); +} + +void CMemory::ApplyROMFixes () +{ + DSP1.version = 0; + if (strncmp(ROMName, "DUNGEON MASTER", 14) == 0) + { + DSP1.version = 1; + SetDSP=&DSP2SetByte; + GetDSP=&DSP2GetByte; + } + + // Enable S-RTC (Real Time Clock) emulation for Dai Kaijyu Monogatari 2 + Settings.SRTC = ((ROMType & 0xf0) >> 4) == 5; + + Settings.StrikeGunnerOffsetHack = strcmp (ROMName, "STRIKE GUNNER") == 0 ? 7 : 0; + + CPU.NMITriggerPoint = 4; + if (strcmp (ROMName, "CACOMA KNIGHT") == 0) + CPU.NMITriggerPoint = 25; + + // These games complain if the multi-player adaptor is 'connected' + if (strcmp (ROMName, "TETRIS&Dr.MARIO") == 0 || + strcmp (ROMName, "JIGSAW PARTY") == 0 || + strcmp (ROMName, "SUPER PICROSS") == 0 || + strcmp (ROMName, "KIRBY NO KIRA KIZZU") == 0 || + strcmp (ROMName, "BLOCK") == 0 || + strncmp (ROMName, "SUPER BOMBLISS", 14) == 0 || + strcmp (ROMId, "ABOJ") == 0) + { + Settings.MultiPlayer5Master = FALSE; + Settings.MouseMaster = FALSE; + Settings.SuperScopeMaster = FALSE; + } + + // Games which spool sound samples between the SNES and sound CPU using + // H-DMA as the sample is playing. + if (strcmp (ROMName, "EARTHWORM JIM 2") == 0 || + strcmp (ROMName, "PRIMAL RAGE") == 0 || + strcmp (ROMName, "CLAY FIGHTER") == 0 || + strcmp (ROMName, "ClayFighter 2") == 0 || + strncasecmp (ROMName, "MADDEN", 6) == 0 || + strncmp (ROMName, "NHL", 3) == 0 || + strcmp (ROMName, "WeaponLord") == 0) + { + Settings.Shutdown = FALSE; + } + + + // Stunt Racer FX + if (strcmp (ROMId, "CQ ") == 0 || + // Illusion of Gaia + strncmp (ROMId, "JG", 2) == 0 || + strcmp (ROMName, "GAIA GENSOUKI 1 JPN") == 0) + { + IAPU.OneCycle = 13; + Settings.APUEnabled |= 2; + CPU.APU_APUExecuting |= 2; + } + + // RENDERING RANGER R2 + if (strcmp (ROMId, "AVCJ") == 0 || + // Star Ocean + strncmp (ROMId, "ARF", 3) == 0 || + // Tales of Phantasia + strncmp (ROMId, "ATV", 3) == 0 || + // Act Raiser 1 & 2 + strncasecmp (ROMName, "ActRaiser", 9) == 0 || + // Soulblazer + strcmp (ROMName, "SOULBLAZER - 1 USA") == 0 || + strcmp (ROMName, "SOULBLADER - 1") == 0 || + strncmp (ROMName, "SOULBLAZER 1",12) == 0 || + // Terranigma + strncmp (ROMId, "AQT", 3) == 0 || + // Robotrek + strncmp (ROMId, "E9 ", 3) == 0 || + strcmp (ROMName, "SLAP STICK 1 JPN") == 0 || + // ZENNIHON PURORESU2 + strncmp (ROMId, "APR", 3) == 0 || + // Bomberman 4 + strncmp (ROMId, "A4B", 3) == 0 || + // UFO KAMEN YAKISOBAN + strncmp (ROMId, "Y7 ", 3) == 0 || + strncmp (ROMId, "Y9 ", 3) == 0 || + // Panic Bomber World + strncmp (ROMId, "APB", 3) == 0 || + ((strncmp (ROMName, "Parlor", 6) == 0 || + strcmp (ROMName, "HEIWA Parlor!Mini8") == 0 || + strncmp (ROMName, "SANKYO Fever! ̨°ÊÞ°!", 21) == 0) && + strcmp (CompanyId, "A0") == 0) || + strcmp (ROMName, "DARK KINGDOM") == 0 || + strcmp (ROMName, "ZAN3 SFC") == 0 || + strcmp (ROMName, "HIOUDEN") == 0 || + strcmp (ROMName, "ÃüɳÀ") == 0 || + strcmp (ROMName, "FORTUNE QUEST") == 0 || + strcmp (ROMName, "FISHING TO BASSING") == 0 || + strncmp (ROMName, "TokyoDome '95Battle 7", 21) == 0 || + strcmp (ROMName, "OHMONO BLACKBASS") == 0) + { + IAPU.OneCycle = 15; + // notaz: strangely enough, these games work properly with my hack enabled + Settings.APUEnabled |= 2; + CPU.APU_APUExecuting |= 2; + } + + if (strcmp (ROMName, "BATMAN--REVENGE JOKER") == 0) + { + Memory.HiROM = FALSE; + Memory.LoROM = TRUE; + LoROMMap (); + } + Settings.StarfoxHack = strcmp (ROMName, "STAR FOX") == 0 || + strcmp (ROMName, "STAR WING") == 0; + Settings.WinterGold = strcmp (ROMName, "FX SKIING NINTENDO 96") == 0 || + strcmp (ROMName, "DIRT RACER") == 0 || + strcmp (ROMName, "Stunt Race FX") == 0 || + Settings.StarfoxHack; + Settings.ChuckRock = strcmp (ROMName, "CHUCK ROCK") == 0; + Settings.Dezaemon = strcmp (ROMName, "DEZAEMON") == 0; + + if (strcmp (ROMName, "RADICAL DREAMERS") == 0 || + strcmp (ROMName, "TREASURE CONFLIX") == 0) + { + int c; + + for (c = 0; c < 0x80; c++) + { + Map [c + 0x700] = ROM + 0x200000 + 0x1000 * (c & 0xf0); + BlockIsRAM [c + 0x700] = TRUE; + BlockIsROM [c + 0x700] = FALSE; + } + for (c = 0; c < 0x400; c += 16) + { + Map [c + 5] = Map [c + 0x805] = ROM + 0x300000; + BlockIsRAM [c + 5] = BlockIsRAM [c + 0x805] = TRUE; + } + WriteProtectROM (); + } + + Settings.H_Max = (SNES_CYCLES_PER_SCANLINE * + Settings.CyclesPercentage) / 100; + + if (strcmp (ROMId, "ASRJ") == 0 && Settings.CyclesPercentage == 100) + // Street Racer + Settings.H_Max = (SNES_CYCLES_PER_SCANLINE * 95) / 100; + + // Power Rangers Fight + if (strncmp (ROMId, "A3R", 3) == 0 || + // Clock Tower + strncmp (ROMId, "AJE", 3) == 0) + Settings.H_Max = (SNES_CYCLES_PER_SCANLINE * 103) / 100; + + if (strcmp (ROMId, "AWVP") == 0 || strcmp (ROMId, "AWVE") == 0 || + strcmp (ROMId, "AWVJ") == 0) + { + // Wrestlemania Arcade +#if 0 + if (Settings.CyclesPercentage == 100) + Settings.H_Max = (SNES_CYCLES_PER_SCANLINE * 140) / 100; // Fixes sound +#endif + Settings.WrestlemaniaArcade = TRUE; + } + // Theme Park - disable offset-per-tile mode. + if (strcmp (ROMId, "ATQP") == 0) + Settings.WrestlemaniaArcade = TRUE; + + if (strncmp (ROMId, "A3M", 3) == 0 && Settings.CyclesPercentage == 100) + // Mortal Kombat 3. Fixes cut off speech sample + Settings.H_Max = (SNES_CYCLES_PER_SCANLINE * 110) / 100; + + if (strcmp (ROMName, "\x0bd\x0da\x0b2\x0d4\x0b0\x0bd\x0de") == 0 && + Settings.CyclesPercentage == 100) + Settings.H_Max = (SNES_CYCLES_PER_SCANLINE * 101) / 100; + + if (strcmp (ROMName, "WILD TRAX") == 0 || + strcmp (ROMName, "YOSSY'S ISLAND") == 0 || + strcmp (ROMName, "YOSHI'S ISLAND") == 0) + CPU.TriedInterleavedMode2 = TRUE; + + // Start Trek: Deep Sleep 9 + if (strncmp (ROMId, "A9D", 3) == 0 && Settings.CyclesPercentage == 100) + Settings.H_Max = (SNES_CYCLES_PER_SCANLINE * 110) / 100; + + Settings.APURAMInitialValue = 0xff; + + if (strcmp (ROMName, "·­³Ô¸¥Ò¶ÞÃÃþ²") == 0 || + strcmp (ROMName, "KENTOUOU WORLDCHAMPIO") == 0 || + strcmp (ROMName, "TKO SUPERCHAMPIONSHIP") == 0 || + strcmp (ROMName, "TKO SUPER CHAMPIONSHI") == 0 || + strcmp (ROMName, "IHATOVO STORY") == 0 || + strcmp (ROMName, "WANDERERS FROM YS") == 0 || + strcmp (ROMName, "SUPER GENTYOUHISHI") == 0 || + // Panic Bomber World + strncmp (ROMId, "APB", 3) == 0) + { + Settings.APURAMInitialValue = 0; + } + + Settings.DaffyDuck = strcmp (ROMName, "DAFFY DUCK: MARV MISS") == 0; + Settings.HBlankStart = (256 * Settings.H_Max) / SNES_HCOUNTER_MAX; + + SA1.WaitAddress = NULL; + SA1.WaitByteAddress1 = NULL; + SA1.WaitByteAddress2 = NULL; + + /* Bass Fishing */ + if (strcmp (ROMId, "ZBPJ") == 0) + { + SA1.WaitAddress = SA1.Map [0x0093f1 >> MEMMAP_SHIFT] + 0x93f1; + SA1.WaitByteAddress1 = FillRAM + 0x304a; + } + /* DAISENRYAKU EXPERTWW2 */ + if (strcmp (ROMId, "AEVJ") == 0) + { + SA1.WaitAddress = SA1.Map [0x0ed18d >> MEMMAP_SHIFT] + 0xd18d; + SA1.WaitByteAddress1 = FillRAM + 0x3000; + } + /* debjk2 */ + if (strcmp (ROMId, "A2DJ") == 0) + { + SA1.WaitAddress = SA1.Map [0x008b62 >> MEMMAP_SHIFT] + 0x8b62; + } + /* Dragon Ballz HD */ + if (strcmp (ROMId, "AZIJ") == 0) + { + SA1.WaitAddress = SA1.Map [0x008083 >> MEMMAP_SHIFT] + 0x8083; + SA1.WaitByteAddress1 = FillRAM + 0x3020; + } + /* SFC SDGUNDAMGNEXT */ + if (strcmp (ROMId, "ZX3J") == 0) + { + SA1.WaitAddress = SA1.Map [0x0087f2 >> MEMMAP_SHIFT] + 0x87f2; + SA1.WaitByteAddress1 = FillRAM + 0x30c4; + } + /* ShougiNoHanamichi */ + if (strcmp (ROMId, "AARJ") == 0) + { + SA1.WaitAddress = SA1.Map [0xc1f85a >> MEMMAP_SHIFT] + 0xf85a; + SA1.WaitByteAddress1 = SRAM + 0x0c64; + SA1.WaitByteAddress2 = SRAM + 0x0c66; + } + /* KATO HIFUMI9DAN SYOGI */ + if (strcmp (ROMId, "A23J") == 0) + { + SA1.WaitAddress = SA1.Map [0xc25037 >> MEMMAP_SHIFT] + 0x5037; + SA1.WaitByteAddress1 = SRAM + 0x0c06; + SA1.WaitByteAddress2 = SRAM + 0x0c08; + } + /* idaten */ + if (strcmp (ROMId, "AIIJ") == 0) + { + SA1.WaitAddress = SA1.Map [0xc100be >> MEMMAP_SHIFT] + 0x00be; + SA1.WaitByteAddress1 = SRAM + 0x1002; + SA1.WaitByteAddress2 = SRAM + 0x1004; + } + /* igotais */ + if (strcmp (ROMId, "AITJ") == 0) + { + SA1.WaitAddress = SA1.Map [0x0080b7 >> MEMMAP_SHIFT] + 0x80b7; + } + /* J96 DREAM STADIUM */ + if (strcmp (ROMId, "AJ6J") == 0) + { + SA1.WaitAddress = SA1.Map [0xc0f74a >> MEMMAP_SHIFT] + 0xf74a; + } + /* JumpinDerby */ + if (strcmp (ROMId, "AJUJ") == 0) + { + SA1.WaitAddress = SA1.Map [0x00d926 >> MEMMAP_SHIFT] + 0xd926; + } + /* JKAKINOKI SHOUGI */ + if (strcmp (ROMId, "AKAJ") == 0) + { + SA1.WaitAddress = SA1.Map [0x00f070 >> MEMMAP_SHIFT] + 0xf070; + } + /* HOSHI NO KIRBY 3 & KIRBY'S DREAM LAND 3 JAP & US */ + if (strcmp (ROMId, "AFJJ") == 0 || strcmp (ROMId, "AFJE") == 0) + { + SA1.WaitAddress = SA1.Map [0x0082d4 >> MEMMAP_SHIFT] + 0x82d4; + SA1.WaitByteAddress1 = SRAM + 0x72a4; + } + /* KIRBY SUPER DELUXE JAP */ + if (strcmp (ROMId, "AKFJ") == 0) + { + SA1.WaitAddress = SA1.Map [0x008c93 >> MEMMAP_SHIFT] + 0x8c93; + SA1.WaitByteAddress1 = FillRAM + 0x300a; + SA1.WaitByteAddress2 = FillRAM + 0x300e; + } + /* KIRBY SUPER DELUXE US */ + if (strcmp (ROMId, "AKFE") == 0) + { + SA1.WaitAddress = SA1.Map [0x008cb8 >> MEMMAP_SHIFT] + 0x8cb8; + SA1.WaitByteAddress1 = FillRAM + 0x300a; + SA1.WaitByteAddress2 = FillRAM + 0x300e; + } + /* SUPER MARIO RPG JAP & US */ + if (strcmp (ROMId, "ARWJ") == 0 || strcmp (ROMId, "ARWE") == 0) + { + SA1.WaitAddress = SA1.Map [0xc0816f >> MEMMAP_SHIFT] + 0x816f; + SA1.WaitByteAddress1 = FillRAM + 0x3000; + } + /* marvelous.zip */ + if (strcmp (ROMId, "AVRJ") == 0) + { + SA1.WaitAddress = SA1.Map [0x0085f2 >> MEMMAP_SHIFT] + 0x85f2; + SA1.WaitByteAddress1 = FillRAM + 0x3024; + } + /* AUGUSTA3 MASTERS NEW */ + if (strcmp (ROMId, "AO3J") == 0) + { + SA1.WaitAddress = SA1.Map [0x00dddb >> MEMMAP_SHIFT] + 0xdddb; + SA1.WaitByteAddress1 = FillRAM + 0x37b4; + } + /* OSHABERI PARODIUS */ + if (strcmp (ROMId, "AJOJ") == 0) + { + SA1.WaitAddress = SA1.Map [0x8084e5 >> MEMMAP_SHIFT] + 0x84e5; + } + /* PANIC BOMBER WORLD */ + if (strcmp (ROMId, "APBJ") == 0) + { + SA1.WaitAddress = SA1.Map [0x00857a >> MEMMAP_SHIFT] + 0x857a; + } + /* PEBBLE BEACH NEW */ + if (strcmp (ROMId, "AONJ") == 0) + { + SA1.WaitAddress = SA1.Map [0x00df33 >> MEMMAP_SHIFT] + 0xdf33; + SA1.WaitByteAddress1 = FillRAM + 0x37b4; + } + /* PGA EUROPEAN TOUR */ + if (strcmp (ROMId, "AEPE") == 0) + { + SA1.WaitAddress = SA1.Map [0x003700 >> MEMMAP_SHIFT] + 0x3700; + SA1.WaitByteAddress1 = FillRAM + 0x3102; + } + /* PGA TOUR 96 */ + if (strcmp (ROMId, "A3GE") == 0) + { + SA1.WaitAddress = SA1.Map [0x003700 >> MEMMAP_SHIFT] + 0x3700; + SA1.WaitByteAddress1 = FillRAM + 0x3102; + } + /* POWER RANGERS 4 */ + if (strcmp (ROMId, "A4RE") == 0) + { + SA1.WaitAddress = SA1.Map [0x009899 >> MEMMAP_SHIFT] + 0x9899; + SA1.WaitByteAddress1 = FillRAM + 0x3000; + } + /* PACHISURO PALUSUPE */ + if (strcmp (ROMId, "AGFJ") == 0) + { + // Never seems to turn on the SA-1! + } + /* SD F1 GRAND PRIX */ + if (strcmp (ROMId, "AGFJ") == 0) + { + SA1.WaitAddress = SA1.Map [0x0181bc >> MEMMAP_SHIFT] + 0x81bc; + } + /* SHOUGI MARJONG */ + if (strcmp (ROMId, "ASYJ") == 0) + { + SA1.WaitAddress = SA1.Map [0x00f2cc >> MEMMAP_SHIFT] + 0xf2cc; + SA1.WaitByteAddress1 = SRAM + 0x7ffe; + SA1.WaitByteAddress2 = SRAM + 0x7ffc; + } + /* shogisai2 */ + if (strcmp (ROMId, "AX2J") == 0) + { + SA1.WaitAddress = SA1.Map [0x00d675 >> MEMMAP_SHIFT] + 0xd675; + } + + /* SHINING SCORPION */ + if (strcmp (ROMId, "A4WJ") == 0) + { + SA1.WaitAddress = SA1.Map [0xc048be >> MEMMAP_SHIFT] + 0x48be; + } + /* SHIN SHOUGI CLUB */ + if (strcmp (ROMId, "AHJJ") == 0) + { + SA1.WaitAddress = SA1.Map [0xc1002a >> MEMMAP_SHIFT] + 0x002a; + SA1.WaitByteAddress1 = SRAM + 0x0806; + SA1.WaitByteAddress2 = SRAM + 0x0808; + } + + // Additional game fixes by sanmaiwashi ... + if (strcmp (ROMName, "SFX ŲĶÞÃÀÞÑÓɶÞÀØ 1") == 0) + { + bytes0x2000 [0xb18] = 0x4c; + bytes0x2000 [0xb19] = 0x4b; + bytes0x2000 [0xb1a] = 0xea; + } + + if (strcmp (ROMName, "GOGO ACKMAN3") == 0 || + strcmp (ROMName, "HOME ALONE") == 0) + { + // Banks 00->3f and 80->bf + for (int c = 0; c < 0x400; c += 16) + { + Map [c + 6] = Map [c + 0x806] = SRAM; + Map [c + 7] = Map [c + 0x807] = SRAM; + BlockIsROM [c + 6] = BlockIsROM [c + 0x806] = FALSE; + BlockIsROM [c + 7] = BlockIsROM [c + 0x807] = FALSE; + BlockIsRAM [c + 6] = BlockIsRAM [c + 0x806] = TRUE; + BlockIsRAM [c + 7] = BlockIsRAM [c + 0x807] = TRUE; + } + WriteProtectROM (); + } + + if (strncmp (ROMName, "SWORD WORLD SFC", 15) == 0 || + strcmp (ROMName, "SFC ¶ÒÃײÀÞ°") == 0) + { + IAPU.OneCycle = 15; + SNESGameFixes.NeedInit0x2137 = TRUE; + Settings.APUEnabled |= 2; + CPU.APU_APUExecuting |= 2; + } + + if (strncmp (ROMName, "SHIEN THE BLADE CHASE", 21) == 0) + SNESGameFixes.Old_Read0x4200 = TRUE; + + if (strcmp (ROMName, "ºÞ¼Þ× ¶²¼Þ­³ÀÞ²¹¯¾Ã") == 0) + SNESGameFixes.NeedInit0x2137 = TRUE; + + if (strcmp (ROMName, "UMIHARAKAWASE") == 0) + SNESGameFixes.umiharakawaseFix = TRUE; + + if (strcmp (ROMName, "ALIENS vs. PREDATOR") == 0) + SNESGameFixes.alienVSpredetorFix = TRUE; + + if (strcmp (ROMName, "demon's blazon") == 0 || + strcmp (ROMName, "demon's crest") == 0 || + strcmp (ROMName, "ROCKMAN X") == 0 || + strcmp (ROMName, "MEGAMAN X") == 0) + { + + // CAPCOM's protect + // Banks 0x808000, 0x408000 are mirroring. + for (int c = 0; c < 8; c++) + Map [0x408 + c] = ROM - 0x8000; + } + + if (strcmp (ROMName, "½°Ȩ̂߰ýÀ") == 0 || + strcmp (ROMName, "½°Ȩ̂߰ýÀ 2") == 0 || + strcmp (ROMName, "ZENKI TENCHIMEIDOU") == 0 || + strcmp (ROMName, "GANBA LEAGUE") == 0) + { + SNESGameFixes.APU_OutPorts_ReturnValueFix = TRUE; + } + + // HITOMI3 + if (strcmp (ROMName, "HITOMI3") == 0) + { + Memory.SRAMSize = 1; + CPU.Memory_SRAMMask = Memory.SRAMSize ? + ((1 << (Memory.SRAMSize + 3)) * 128) - 1 : 0; + } + + if (strcmp (ROMName, "goemon 4") == 0) + SNESGameFixes.SRAMInitialValue = 0x00; + + if (strcmp (ROMName, "PACHISLO ¹Ã·­³") == 0) + SNESGameFixes._0x213E_ReturnValue = 1; + + if (strcmp (ROMName, "»Þ ð¼Þ¬à ijʲÃÞÃ") == 0) + SNESGameFixes.TouhaidenControllerFix = TRUE; + + if (strcmp (ROMName, "DRAGON KNIGHT 4") == 0) + { + // Banks 70->7e, S-RAM + for (int c = 0; c < 0xe0; c++) + { + Map [c + 0x700] = (uint8 *) MAP_LOROM_SRAM; + BlockIsRAM [c + 0x700] = TRUE; + BlockIsROM [c + 0x700] = FALSE; + } + WriteProtectROM (); + } + + if (strncmp (ROMName, "LETs PACHINKO(", 14) == 0) + { + IAPU.OneCycle = 15; + Settings.APUEnabled |= 2; + CPU.APU_APUExecuting |= 2; + if (!Settings.ForceNTSC && !Settings.ForcePAL) + { + Settings.PAL = FALSE; + Settings.FrameTime = Settings.FrameTimeNTSC; + Memory.ROMFramesPerSecond = 60; + } + } + + if (strcmp (ROMName, "FURAI NO SIREN") == 0) + SNESGameFixes.SoundEnvelopeHeightReading2 = TRUE; +#if 0 + if(strcmp (ROMName, "XBAND JAPANESE MODEM") == 0) + { + for (c = 0x200; c < 0x400; c += 16) + { + for (int i = c; i < c + 16; i++) + { + Map [i + 0x400] = Map [i + 0xc00] = &ROM[c * 0x1000]; + MemorySpeed [i + 0x400] = MemorySpeed [i + 0xc00] = 8; + BlockIsRAM [i + 0x400] = BlockIsRAM [i + 0xc00] = TRUE; + BlockIsROM [i + 0x400] = BlockIsROM [i + 0xc00] = FALSE; + } + } + WriteProtectROM (); + } +#endif + +#define RomPatch(adr,ov,nv) \ +if (ROM [adr] == ov) \ + ROM [adr] = nv + + // Love Quest + if (strcmp (ROMName, "LOVE QUEST") == 0) + { + RomPatch (0x1385ec, 0xd0, 0xea); + RomPatch (0x1385ed, 0xb2, 0xea); + } + + // Nangoku Syonen Papuwa Kun + if (strcmp (ROMName, "NANGOKUSYONEN PAPUWA") == 0) + RomPatch (0x1f0d1, 0xa0, 0x6b); + + // Tetsuwan Atom + if (strcmp (ROMName, "Tetsuwan Atom") == 0) + { + RomPatch (0xe24c5, 0x90, 0xea); + RomPatch (0xe24c6, 0xf3, 0xea); + } + + // Oda Nobunaga + if (strcmp (ROMName, "SFC ODA NOBUNAGA") == 0) + { + RomPatch (0x7497, 0x80, 0xea); + RomPatch (0x7498, 0xd5, 0xea); + } + + // Super Batter Up + if (strcmp (ROMName, "Super Batter Up") == 0) + { + RomPatch (0x27ae0, 0xd0, 0xea); + RomPatch (0x27ae1, 0xfa, 0xea); + } + + // Super Professional Baseball 2 + if (strcmp (ROMName, "SUPER PRO. BASE BALL2") == 0) + { + RomPatch (0x1e4, 0x50, 0xea); + RomPatch (0x1e5, 0xfb, 0xea); + } +} + +// Read variable size MSB int from a file +static long ReadInt (FILE *f, unsigned nbytes) +{ + long v = 0; + while (nbytes--) + { + int c = fgetc(f); + if (c == EOF) + return -1; + v = (v << 8) | (c & 0xFF); + } + return (v); +} + +#define IPS_EOF 0x00454F46l + +void CMemory::CheckForIPSPatch (const char *rom_filename, bool8_32 header, + int32 &rom_size) +{ + char dir [_MAX_DIR + 1]; + char drive [_MAX_DRIVE + 1]; + char name [_MAX_FNAME + 1]; + char ext [_MAX_EXT + 1]; + char fname [_MAX_PATH + 1]; + FILE *patch_file = NULL; + long offset = header ? 512 : 0; + + if (!(patch_file = fopen(S9xGetFilename (".ips"), "rb"))) return; + + if (fread (fname, 1, 5, patch_file) != 5 || strncmp (fname, "PATCH", 5) != 0) + { + fclose (patch_file); + return; + } + + int32 ofs; + + for (;;) + { + long len; + long rlen; + int rchar; + + ofs = ReadInt (patch_file, 3); + if (ofs == -1) + goto err_eof; + + if (ofs == IPS_EOF) + break; + + ofs -= offset; + + len = ReadInt (patch_file, 2); + if (len == -1) + goto err_eof; + + /* Apply patch block */ + if (len) + { + if (ofs + len > MAX_ROM_SIZE) + goto err_eof; + + while (len--) + { + rchar = fgetc (patch_file); + if (rchar == EOF) + goto err_eof; + ROM [ofs++] = (uint8) rchar; + } + if (ofs > rom_size) + rom_size = ofs; + } + else + { + rlen = ReadInt (patch_file, 2); + if (rlen == -1) + goto err_eof; + + rchar = fgetc (patch_file); + if (rchar == EOF) + goto err_eof; + + if (ofs + rlen > MAX_ROM_SIZE) + goto err_eof; + + while (rlen--) + ROM [ofs++] = (uint8) rchar; + + if (ofs > rom_size) + rom_size = ofs; + } + } + + // Check if ROM image needs to be truncated + ofs = ReadInt (patch_file, 3); + if (ofs != -1 && ofs - offset < rom_size) + { + // Need to truncate ROM image + rom_size = ofs - offset; + } + fclose (patch_file); + return; + +err_eof: + if (patch_file) + fclose (patch_file); +} + +#undef INLINE +#define INLINE +#include "getset.h" diff --git a/src/snes4iphone_src/memmap.h b/src/snes4iphone_src/memmap.h new file mode 100755 index 0000000..4854419 --- /dev/null +++ b/src/snes4iphone_src/memmap.h @@ -0,0 +1,200 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#ifndef _memmap_h_ +#define _memmap_h_ + +#include "snes9x.h" + +#ifdef FAST_LSB_WORD_ACCESS +#define READ_WORD(s) (*(uint16 *) (s)) +#define READ_DWORD(s) (*(uint32 *) (s)) +#define WRITE_WORD(s, d) (*(uint16 *) (s) = (d) +#define WRITE_DWORD(s, d) (*(uint32 *) (s) = (d) +#else +#define READ_WORD(s) ( *(uint8 *) (s) |\ + (*((uint8 *) (s) + 1) << 8)) +#define READ_DWORD(s) ( *(uint8 *) (s) |\ + (*((uint8 *) (s) + 1) << 8) |\ + (*((uint8 *) (s) + 2) << 16) |\ + (*((uint8 *) (s) + 3) << 24)) +#define WRITE_WORD(s, d) *(uint8 *) (s) = (d), \ + *((uint8 *) (s) + 1) = (d) >> 8 +#define WRITE_DWORD(s, d) *(uint8 *) (s) = (uint8) (d), \ + *((uint8 *) (s) + 1) = (uint8) ((d) >> 8),\ + *((uint8 *) (s) + 2) = (uint8) ((d) >> 16),\ + *((uint8 *) (s) + 3) = (uint8) ((d) >> 24) +#define WRITE_3WORD(s, d) *(uint8 *) (s) = (uint8) (d), \ + *((uint8 *) (s) + 1) = (uint8) ((d) >> 8),\ + *((uint8 *) (s) + 2) = (uint8) ((d) >> 16) +#define READ_3WORD(s) ( *(uint8 *) (s) |\ + (*((uint8 *) (s) + 1) << 8) |\ + (*((uint8 *) (s) + 2) << 16)) + +#endif + +#define MEMMAP_BLOCK_SIZE (0x1000) +#define MEMMAP_NUM_BLOCKS (0x1000000 / MEMMAP_BLOCK_SIZE) +#define MEMMAP_BLOCKS_PER_BANK (0x10000 / MEMMAP_BLOCK_SIZE) +#define MEMMAP_SHIFT 12 +#define MEMMAP_MASK (MEMMAP_BLOCK_SIZE - 1) +#define MEMMAP_MAX_SDD1_LOGGED_ENTRIES (0x10000 / 8) + +class CMemory { +public: + bool8_32 LoadROM (const char *); + void InitROM (bool8_32); + bool8_32 LoadSRAM (const char *); + bool8_32 SaveSRAM (const char *); + bool8_32 Init (); + void Deinit (); + void FreeSDD1Data (); + + void WriteProtectROM (); + void FixROMSpeed (); + void MapRAM (); + void MapExtraRAM (); + char *Safe (const char *); + + void LoROMMap (); + void LoROM24MBSMap (); + void SRAM512KLoROMMap (); + void SRAM1024KLoROMMap (); + void SufamiTurboLoROMMap (); + void HiROMMap (); + void SuperFXROMMap (); + void TalesROMMap (bool8_32); + void AlphaROMMap (); + void SA1ROMMap (); + void BSHiROMMap (); + bool8_32 AllASCII (uint8 *b, int size); + int ScoreHiROM (bool8_32 skip_header); + int ScoreLoROM (bool8_32 skip_header); + void ApplyROMFixes (); + void CheckForIPSPatch (const char *rom_filename, bool8_32 header, + int32 &rom_size); + + const char *TVStandard (); + const char *Speed (); + const char *StaticRAMSize (); + const char *MapType (); + const char *MapMode (); + const char *KartContents (); + const char *Size (); + const char *Headers (); + const char *ROMID (); + const char *CompanyID (); + + enum { + MAP_PPU, MAP_CPU, MAP_DSP, MAP_LOROM_SRAM, MAP_HIROM_SRAM, + MAP_NONE, MAP_DEBUG, MAP_C4, MAP_BWRAM, MAP_BWRAM_BITMAP, + MAP_BWRAM_BITMAP2, MAP_SA1RAM, MAP_LAST + }; + enum { MAX_ROM_SIZE = 0x600000 }; + + uint8 *RAM; + uint8 *ROM; + uint8 *VRAM; + uint8 *SRAM; + uint8 *BWRAM; + uint8 *FillRAM; + uint8 *C4RAM; + bool8_32 HiROM; + bool8_32 LoROM; + uint16 SRAMMask; + uint8 SRAMSize; + uint8 *Map [MEMMAP_NUM_BLOCKS]; + uint8 *WriteMap [MEMMAP_NUM_BLOCKS]; + uint8 MemorySpeed [MEMMAP_NUM_BLOCKS]; + uint8 BlockIsRAM [MEMMAP_NUM_BLOCKS]; + uint8 BlockIsROM [MEMMAP_NUM_BLOCKS]; + char ROMName [ROM_NAME_LEN]; + char ROMId [5]; + char CompanyId [3]; + uint8 ROMSpeed; + uint8 ROMType; + uint8 ROMSize; + int32 ROMFramesPerSecond; + int32 HeaderCount; + uint32 CalculatedSize; + uint32 CalculatedChecksum; + uint32 ROMChecksum; + uint32 ROMComplementChecksum; + uint8 *SDD1Index; + uint8 *SDD1Data; + uint32 SDD1Entries; + uint32 SDD1LoggedDataCountPrev; + uint32 SDD1LoggedDataCount; + uint8 SDD1LoggedData [MEMMAP_MAX_SDD1_LOGGED_ENTRIES]; +#ifndef _SNESPPC + char ROMFilename [_MAX_PATH]; +#else + char ROMFilename [1024]; +#endif + uint32 ROMCRC32; +}; + +START_EXTERN_C +extern CMemory Memory; +extern uint8 *SRAM; +extern uint8 *ROM; +extern uint8 *RegRAM; +void S9xDeinterleaveMode2 (); +void S9xSaveSRAM (void); +END_EXTERN_C + +void S9xAutoSaveSRAM (); + +#ifdef NO_INLINE_SET_GET +uint8 S9xGetByte (uint32 Address, struct SCPUState *); +uint16 S9xGetWord (uint32 Address, struct SCPUState *); +void S9xSetByte (uint8 Byte, uint32 Address, struct SCPUState * ); +void S9xSetWord (uint16 Byte, uint32 Address, struct SCPUState *); +void S9xSetPCBase (uint32 Address, struct SCPUState *); +uint8 *S9xGetMemPointer (uint32 Address); +uint8 *GetBasePointer (uint32 Address); +#else +#ifndef INLINE +#define INLINE __inline +#endif +#include "getset.h" +#endif // NO_INLINE_SET_GET + +#endif // _memmap_h_ diff --git a/src/snes4iphone_src/memset.s b/src/snes4iphone_src/memset.s new file mode 100755 index 0000000..3689117 --- /dev/null +++ b/src/snes4iphone_src/memset.s @@ -0,0 +1,51 @@ + .text + .global gp2x_memset; + .type gp2x_memset,%function + .align 4; + +gp2x_memset: + mov a4, a1 + cmp a3, $8 @ at least 8 bytes to do? + blt 2f + orr a2, a2, a2, lsl $8 + orr a2, a2, a2, lsl $16 +1: + tst a4, $3 @ aligned yet? + strneb a2, [a4], $1 + subne a3, a3, $1 + bne 1b + mov ip, a2 +1: + cmp a3, $8 @ 8 bytes still to do? + blt 2f + stmia a4!, {a2, ip} + sub a3, a3, $8 + cmp a3, $8 @ 8 bytes still to do? + blt 2f + stmia a4!, {a2, ip} + sub a3, a3, $8 + cmp a3, $8 @ 8 bytes still to do? + blt 2f + stmia a4!, {a2, ip} + sub a3, a3, $8 + cmp a3, $8 @ 8 bytes still to do? + stmgeia a4!, {a2, ip} + subge a3, a3, $8 + bge 1b +2: + movs a3, a3 @ anything left? + moveq pc, lr @ nope + rsb a3, a3, $7 + add pc, pc, a3, lsl $2 + mov r0, r0 + strb a2, [a4], $1 + strb a2, [a4], $1 + strb a2, [a4], $1 + strb a2, [a4], $1 + strb a2, [a4], $1 + strb a2, [a4], $1 + strb a2, [a4], $1 + mov pc, lr + +.size gp2x_memset,.-gp2x_memset; + diff --git a/src/snes4iphone_src/menu.c b/src/snes4iphone_src/menu.c new file mode 100755 index 0000000..bdf2060 --- /dev/null +++ b/src/snes4iphone_src/menu.c @@ -0,0 +1,1818 @@ + +#include "menu.h" + +char romDir[MAX_PATH+1]; +char snesRomDir[MAX_PATH+1]; + +DIRDATA dir; + +unsigned short cpuSpeedLookup[40]={ + 10,20, 30, 40, 50, + 60,70, 80, 90,100, + 110,120,130,144,150, + 160,170,180,190,200, + 210,220,230,240,250, + 260,270,280,290,300, + 310,320,330,340,350, + 360,370,380,390,400}; +extern unsigned char *vrambuffer; +extern volatile int timer; +static int menutileXscroll=0; +static int menutileYscroll=0; +static int headerDone[4]; // variable that records if header graphics have been rendered or not +int quickSavePresent=0; + +struct ROM_LIST_RECORD romList[MAX_ROMS]; +struct SNES_MENU_OPTIONS snesMenuOptions; + +static int romCount; +int currentRomIndex=2; +char currentRomFilename[MAX_PATH+1]=""; +int currFB=0; +int prevFB=0; +int currentEmuMode=EMU_MODE_SNES; + +char currentWorkingDir[MAX_PATH+1]; +char snesOptionsDir[MAX_PATH+1]; +char snesSramDir[MAX_PATH+1]; +char snesSaveStateDir[MAX_PATH+1]; +float soundRates[5]={8250.0,11025.0,16500.0,22050.0,44100.0}; +char menutext[256][50]; + +struct SAVE_STATE saveState[10]; // holds the filenames for the savestate and "inuse" flags +char saveStateName[MAX_PATH+MAX_PATH+2]; // holds the last filename to be scanned for save states + +unsigned char gammaConv[32*29]={ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 0, 2, 3, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 24, 25, 26, 27, 28, 29, 29, 30, 31, + 0, 3, 5, 7, 8, 9, 10, 11, 13, 14, 15, 16, 16, 17, 18, 19, 20, 21, 22, 22, 23, 24, 25, 25, 26, 27, 28, 28, 29, 30, 30, 31, + 0, 4, 6, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 20, 21, 22, 23, 23, 24, 25, 25, 26, 27, 27, 28, 29, 29, 30, 30, 31, + 0, 6, 8, 10, 11, 12, 14, 15, 16, 17, 18, 18, 19, 20, 21, 22, 22, 23, 24, 24, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31, + 0, 7, 9, 11, 12, 14, 15, 16, 17, 18, 19, 20, 20, 21, 22, 22, 23, 24, 24, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31, 31, + 0, 8, 10, 12, 14, 15, 16, 17, 18, 19, 20, 20, 21, 22, 23, 23, 24, 24, 25, 25, 26, 27, 27, 28, 28, 28, 29, 29, 30, 30, 31, 31, + 0, 9, 11, 13, 15, 16, 17, 18, 19, 20, 21, 21, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 29, 30, 30, 31, 31, + 0, 10, 12, 14, 16, 17, 18, 19, 20, 21, 21, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 28, 29, 29, 30, 30, 30, 31, 31, + 0, 11, 13, 15, 17, 18, 19, 20, 20, 21, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 27, 28, 28, 29, 29, 29, 30, 30, 30, 31, 31, + 0, 12, 14, 16, 17, 18, 19, 20, 21, 22, 22, 23, 24, 24, 25, 25, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29, 30, 30, 30, 31, 31, + 0, 12, 15, 17, 18, 19, 20, 21, 22, 22, 23, 24, 24, 25, 25, 26, 26, 26, 27, 27, 28, 28, 28, 29, 29, 29, 30, 30, 30, 30, 31, 31, + 0, 13, 16, 17, 19, 20, 21, 21, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29, 30, 30, 30, 30, 31, 31, + 0, 14, 16, 18, 19, 20, 21, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 31, 31, 31, + 0, 14, 17, 18, 20, 21, 22, 22, 23, 24, 24, 25, 25, 26, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29, 30, 30, 30, 30, 31, 31, 31, + 0, 15, 17, 19, 20, 21, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, 31, 31, 31, + 0, 16, 18, 19, 21, 22, 22, 23, 24, 24, 25, 25, 26, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, 31, 31, 31, + 0, 16, 18, 20, 21, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, 30, 31, 31, 31, + 0, 17, 19, 20, 21, 22, 23, 24, 24, 25, 25, 26, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, 30, 31, 31, 31, + 0, 17, 19, 21, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, 30, 31, 31, 31, + 0, 17, 20, 21, 22, 23, 24, 24, 25, 25, 26, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 31, 31, 31, + 0, 18, 20, 21, 22, 23, 24, 24, 25, 25, 26, 26, 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, 30, 30, 31, 31, 31, + 0, 18, 20, 22, 23, 23, 24, 25, 25, 26, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 31, 31, 31, 31, + 0, 19, 21, 22, 23, 24, 24, 25, 25, 26, 26, 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 31, 31, 31, 31, + 0, 19, 21, 22, 23, 24, 25, 25, 26, 26, 26, 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, + 0, 19, 21, 22, 23, 24, 25, 25, 26, 26, 27, 27, 27, 27, 28, 28, 28, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, + 0, 20, 22, 23, 24, 24, 25, 25, 26, 26, 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, + 0, 20, 22, 23, 24, 24, 25, 26, 26, 26, 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, + 0, 20, 22, 23, 24, 25, 25, 26, 26, 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31}; + + +void UpdateMenuGraphicsGamma(void) +{ + unsigned int currPix=0; + unsigned short pixel=0; + unsigned char R,G,B; + for(currPix=0;currPix<15360;currPix++) + { + // md 0000 bbb0 ggg0 rrr0 + // gp rrrr rggg ggbb bbbi + pixel=menuHeaderOrig[currPix]; + R=(pixel>>11)&0x1F; // 0000 0RRR - 3 bits Red + G=(pixel>>6)&0x1F; + B=(pixel>>1)&0x1F; + + // Do gamma correction + R=gammaConv[R+(0<<5)]; + G=gammaConv[G+(0<<5)]; + B=gammaConv[B+(0<<5)]; + + pixel=RGB(R,G,B); + menuHeader[currPix]=pixel; + } + for(currPix=0;currPix<5120;currPix++) + { + // md 0000 bbb0 ggg0 rrr0 + // gp rrrr rggg ggbb bbbi + pixel=highLightBarOrig[currPix]; + R=(pixel>>11)&0x1F; // 0000 0RRR - 3 bits Red + G=(pixel>>6)&0x1F; + B=(pixel>>1)&0x1F; + + // Do gamma correction + R=gammaConv[R+(0<<5)]; + G=gammaConv[G+(0<<5)]; + B=gammaConv[B+(0<<5)]; + + pixel=RGB(R,G,B); + highLightBar[currPix]=pixel; + + } + + for(currPix=0;currPix<(MENU_TILE_WIDTH*MENU_TILE_HEIGHT);currPix++) + { + // md 0000 bbb0 ggg0 rrr0 + // gp rrrr rggg ggbb bbbi + pixel=menuTileOrig[currPix]; + R=(pixel>>11)&0x1F; // 0000 0RRR - 3 bits Red + G=(pixel>>6)&0x1F; + B=(pixel>>1)&0x1F; + + // Do gamma correction + R=gammaConv[R+(0<<5)]; + G=gammaConv[G+(0<<5)]; + B=gammaConv[B+(0<<5)]; + + pixel=RGB(R,G,B); + menuTile[currPix]=pixel; + + } +} + +void SnesDefaultMenuOptions(void) +{ + // no options file loaded, so set to defaults + snesMenuOptions.menuVer=SNES_OPTIONS_VER; + snesMenuOptions.frameSkip=0; + snesMenuOptions.soundOn = 1; + snesMenuOptions.volume=100; + memset(snesMenuOptions.padConfig,0xFF,sizeof(snesMenuOptions.padConfig)); + snesMenuOptions.showFps=1; + snesMenuOptions.gamma=0; + snesMenuOptions.soundRate=2; + snesMenuOptions.cpuSpeed=19; +} + +int LoadMenuOptions(char *path, char *filename, char *ext, char *optionsmem, int maxsize, int showMessage) +{ + char fullFilename[MAX_PATH+MAX_PATH+1]; + char _filename[MAX_PATH+1]; + char _ext[MAX_PATH+1]; + FILE *stream; + int size=0; + char text[50]; + + sprintf(text,"Loading..."); + //Sometimes the on screen messages are not required + if (showMessage) + { + PrintBar(prevFB,240-16); + gp_drawString(40,228,strlen(text),text,(unsigned short)RGB(0,0,0),(unsigned short*)vrambuffer); + } + + SplitFilename(filename, _filename, _ext); + sprintf(fullFilename,"%s%s%s.%s",path,DIR_SEPERATOR,_filename,ext); + stream=fopen(fullFilename,"rb"); + if(stream) + { + // File exists do try to load it + fseek(stream,0,SEEK_END); + size=ftell(stream); + if (size>maxsize) size=maxsize; + fseek(stream,0,SEEK_SET); + fread(optionsmem, 1, size, stream); + fclose(stream); + return(0); + } + else + { + return(1); + } +} + +int SaveMenuOptions(char *path, char *filename, char *ext, char *optionsmem, int maxsize, int showMessage) +{ + char fullFilename[MAX_PATH+MAX_PATH+1]; + char _filename[MAX_PATH+1]; + char _ext[MAX_PATH+1]; + FILE *stream; + char text[50]; + + sprintf(text,"Saving..."); + //Sometimes the on screen messages are not required + if (showMessage) + { + PrintBar(prevFB,240-16); + gp_drawString(40,228,strlen(text),text,(unsigned short)RGB(0,0,0),(unsigned short*)vrambuffer); + } + + SplitFilename(filename, _filename, _ext); + sprintf(fullFilename,"%s%s%s.%s",path,DIR_SEPERATOR,_filename,ext); + stream=fopen(fullFilename,"wb"); + if(stream) + { + fwrite(optionsmem, 1, maxsize, stream); + fclose(stream); + sync(); + return(0); + } + else + { + return(1); + } +} + +int DeleteMenuOptions(char *path, char *filename, char *ext, int showMessage) +{ + char fullFilename[MAX_PATH+MAX_PATH+1]; + char _filename[MAX_PATH+1]; + char _ext[MAX_PATH+1]; + char text[50]; + + sprintf(text,"Deleting..."); + //Sometimes the on screen messages are not required + if (showMessage) + { + PrintBar(prevFB,240-16); + gp_drawString(40,228,strlen(text),text,(unsigned short)RGB(0,0,0),(unsigned short*)vrambuffer); + } + + SplitFilename(filename, _filename, _ext); + sprintf(fullFilename,"%s%s%s.%s",path,DIR_SEPERATOR,_filename,ext); + remove(fullFilename); + sync(); + return(0); +} + +#ifdef __GIZ__ +void sync(void) +{ +} +#endif + +static void WaitForButtonsUp(void) +{ + int i=0,j=0,z=0; + + for(i=0;i<100;i++) + { + while(1) + { + InputUpdate(0); + z=0; + for (j=0;j<32;j++) + { + if (Inp.held[j]) z=1; + } + if (z==0) break; + } + } +} + +void MenuPause() +{ + int i=0,j=0,z=0; + // wait for keys to be released + for(i=0;i<100;i++) // deal with keybounce by checking a few times + { + while(1) + { + InputUpdate(0); + z=0; + for (j=0;j<32;j++) + { + if (Inp.held[j]) z=1; + } + if (z==0) break; + } + } + + for(i=0;i<100;i++) // deal with keybounce by checking a few times + { + while(1) + { + InputUpdate(0); + z=0; + for (j=0;j<32;j++) + { + if (Inp.held[j]) z=1; + } + if (z==1) break; + } + } +} +#if defined (__GP2X__) +void MenuFlip() +{ + prevFB=currFB; + gp_setFramebuffer(currFB,1); + currFB++; + currFB&=3; +} +#endif +#if defined (__GIZ__) +void MenuFlip() +{ + prevFB=currFB=0; + gp_setFramebuffer(currFB,0); +} +#endif +#if defined (__IPHONE__) +void MenuFlip() +{ + prevFB=currFB=0; + gp_setFramebuffer(currFB,0); +} +#endif + +void SplitFilename(char *wholeFilename, char *filename, char *ext) +{ + int len=strlen(wholeFilename); + int i=0,y=-1; + + ext[0]=0; + filename[0]=0; + //Check given string is not null + if (len<=0) + { + return; + } + y=-1; + for(i=len-2;i>0;i--) + { + if (wholeFilename[i]=='.') + { + y=i; + break; + } + } + + if (y>=0) + { + memcpy(filename,wholeFilename,y); + filename[y]=0; // change "." to zero to end string + memcpy(ext,wholeFilename+y+1,len-(y+1)); + //ext[len-(y+1)+1]=0; + ext[len-(y+1)]=0; + } + else + { + strcpy(filename,wholeFilename); + } +} + + +int MessageBox(char *message1,char *message2,char *message3,int mode) +{ + int select=0; + int subaction=-1; + int len=0; + while(subaction==-1) + { + InputUpdate(0); + if (Inp.repeat[INP_BUTTON_UP]) + { + select^=1; // Up + } + if (Inp.repeat[INP_BUTTON_DOWN]) + { + select^=1; // Down + } + if ((Inp.held[INP_BUTTON_MENU_SELECT]==1) || (Inp.held[INP_BUTTON_MENU_CANCEL]==1)) + { + subaction=select; + } + PrintTile(currFB); + PrintTitle(currFB); + len=strlen(message1); + if(len>39)len=39; + gp_drawString(8,50,len,message1,(unsigned short)RGB(31,31,31),(unsigned short*)vrambuffer); + len=strlen(message2); + if(len>39)len=39; + gp_drawString(8,60,len,message2,(unsigned short)RGB(31,31,31),(unsigned short*)vrambuffer); + len=strlen(message3); + if(len>39)len=39; + gp_drawString(8,70,len,message3,(unsigned short)RGB(31,31,31),(unsigned short*)vrambuffer); + switch(mode) + { + case 0: // yes no input + if(select==0) + { + PrintBar(currFB, 120-4); + gp_drawString(8,120,3,"YES",(unsigned short)RGB(0,0,0),(unsigned short*)vrambuffer); + gp_drawString(8,140,2,"NO",(unsigned short)RGB(31,31,31),(unsigned short*)vrambuffer); + } + else + { + PrintBar(currFB, 140-4); + gp_drawString(8,120,3,"YES",(unsigned short)RGB(31,31,31),(unsigned short*)vrambuffer); + gp_drawString(8,140,2,"NO",(unsigned short)RGB(0,0,0),(unsigned short*)vrambuffer); + + } + break; + } + MenuFlip(); + } + return(subaction); +} + +static +int deleterom(int romindex) +{ + char text[MAX_PATH+1]; + char fullfilename[MAX_PATH+MAX_PATH+1]; + int x; + FILE *stream=NULL; + + PrintTile(currFB); + PrintTitle(currFB); + MenuFlip(); + + sprintf(text,"Deleting Rom.."); + gp_drawString(8,50,strlen(text),text,(unsigned short)RGB(31,31,31),(unsigned short*)vrambuffer); + + sprintf(text,"%s",romList[romindex].filename); + x=strlen(text); + if(x>40) x=40; + gp_drawString(0,60,x,text,(unsigned short)RGB(31,31,31),(unsigned short*)vrambuffer); + + sprintf(fullfilename,"%s%s%s",romDir,DIR_SEPERATOR,romList[romindex].filename); + remove(fullfilename); + sync(); + + sprintf(text,"Updating Rom List.."); + gp_drawString(8,70,strlen(text),text,(unsigned short)RGB(31,31,31),(unsigned short*)vrambuffer); + for(x=romindex;x 5) + { + tileCounter=0; + menutileXscroll++; + if(menutileXscroll>=MENU_TILE_WIDTH) menutileXscroll=0; + + menutileYscroll++; + if(menutileYscroll>=MENU_TILE_HEIGHT) menutileYscroll=0; + } + return; +} + +void PrintTitle(int flip) +{ + unsigned short *framebuffer = (unsigned short*)vrambuffer; + unsigned short *graphics = (unsigned short*)menuHeader; + unsigned int x,y; + char text[256]; + //If header already drawn for this layer exit + if (headerDone[flip]) return; + + for (y=0; y<48; y++) + { + for (x=0; x<320; x++) + { + *framebuffer++ = *graphics++; + } + } + + sprintf(text,"%s",DRSNES_VERSION); + gp_drawString(175,15,strlen(text),text,(unsigned short)RGB(0,0,31),(unsigned short*)vrambuffer); + headerDone[currFB] = 1; +} + +void PrintBar(int flip, unsigned int givenY) +{ + unsigned int *framebuffer1 = NULL; + unsigned int *graphics1 = (unsigned int *)highLightBar; + unsigned int x,y; + + framebuffer1 = (unsigned int*)(unsigned short*)vrambuffer+(givenY*160); + for (y=0; y<16; y++) + { + for (x=0; x<160; x++) + { + *framebuffer1++ = *graphics1++; + } + } +} + +static int StringCompare(char *string1, char *string2) +{ + int i=0; + char c1=0,c2=0; + while(1) + { + c1=string1[i]; + c2=string2[i]; + // check for string end + + if ((c1 == 0) && (c2 == 0)) return 0; + if (c1 == 0) return 1; + if (c2 == 0) return -1; + + if ((c1 >= 0x61)&&(c1<=0x7A)) c1-=0x20; + if ((c2 >= 0x61)&&(c2<=0x7A)) c2-=0x20; + if (c1>c2) + return 1; + else if (c1d_name[0] != '.') + { +#if defined(__GP2X__) || defined(__IPHONE__) + if (de->d_type == 4) // Directory + { +#endif +#ifdef __GIZ__ + // Because windows GNU library does not return the file type + // property I will have to try and open each file as a directory instead + sprintf(dirCheck,"%s%s%s",romDir,DIR_SEPERATOR,de->d_name); + CharToWChar(wc, dirCheck); + hTest=FindFirstFileW(wc, &fileInfo); + if (fileInfo.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) + { +#endif + for (i=3;i<=(romCount+1);i++) + { + if (romList[i].filename[0] == 0) // string is empty so shove new value in + { + strcpy(romList[i].filename,de->d_name); + romList[i].type=FILE_TYPE_DIRECTORY;//de->d_type; + break; + } + else + { + if ((StringCompare(romList[i].filename,de->d_name) > 0) || + (romList[i].type != FILE_TYPE_DIRECTORY)) + { + // new entry is lower than current string so move all entries up one and insert + // new value in + for (j=romCount;j>=i;j--) + { + strcpy(romList[j+1].filename,romList[j].filename); + romList[j+1].type=romList[j].type; + } + strcpy(romList[i].filename,de->d_name); + romList[i].type=FILE_TYPE_DIRECTORY;//de->d_type; + break; + } + } + } + dirCount++; + romCount++; + } + else // File + { + // only interested in Zip and SMC files + SplitFilename(de->d_name,_filename,_ext); + if ((StringCompare(_ext,"zip") == 0) || + (StringCompare(_ext,"smc") == 0) || + (StringCompare(_ext,"sfc") == 0)) + { + for (i=3+dirCount;i<=(romCount+1);i++) + { + if (romList[i].filename[0] == 0) // string is empty so shove new value in + { + strcpy(romList[i].filename,de->d_name); + romList[i].type=FILE_TYPE_FILE;//de->d_type; + break; + } + else + { + if (StringCompare(romList[i].filename,de->d_name) > 0) + { + // new entry is lower than current string so move all entries up one and insert + // new value in + for (j=romCount;j>=i;j--) + { + strcpy(romList[j+1].filename,romList[j].filename); + romList[j+1].type=romList[j].type; + } + strcpy(romList[i].filename,de->d_name); + romList[i].type=FILE_TYPE_FILE;//de->d_type; + break; + } + } + } + romCount++; + } + } + + + if (romCount > MAX_ROMS) + { + PrintTile(currFB); + PrintTitle(currFB); + sprintf(text,"Max rom limit exceeded! %d max",MAX_ROMS); + gp_drawString(8,120,strlen(text),text,(unsigned short)RGB(31,31,31),(unsigned short*)vrambuffer); + sprintf(text,"Please reduce number of roms"); + gp_drawString(8,130,strlen(text),text,(unsigned short)RGB(31,31,31),(unsigned short*)vrambuffer); + MenuFlip(); + MenuPause(); + return MAX_ROMS; + } + } + } + closedir(d); + } + //gp_setCpuspeed(MENU_CPU_SPEED); + return romCount; +} + +int FileSelect(int mode) +{ + char text[256]; + int romname_length; + int action=0; + int smooth=0; + unsigned short color=0; + int i=0; + int focus=2; + int menuExit=0; + int scanstart=0,scanend=0; + char directorySeparator[2] = DIR_SEPERATOR; // used for char comparison; + + FileScan(); + if(focus<2) focus=2; // default menu to non menu item + // just to stop directory scan being started + smooth=focus<<8; + + while (menuExit==0) + { + InputUpdate(0); + + // Change which rom is focused on: + if (Inp.repeat[INP_BUTTON_UP]) + { + focus--; // Up + } + if (Inp.repeat[INP_BUTTON_DOWN]) + { + focus++; // Down + } + + if (Inp.held[INP_BUTTON_MENU_CANCEL]==1 ) {action=0; menuExit=1;} + + if (Inp.repeat[INP_BUTTON_LEFT] || Inp.repeat[INP_BUTTON_RIGHT] ) + { + if (Inp.repeat[INP_BUTTON_LEFT]) + { + focus-=12; + smooth=(focus<<8)-1; + } + else if (Inp.repeat[INP_BUTTON_RIGHT]) + { + focus+=12; + smooth=(focus<<8)-1; + } + + if (focus>romCount-1) + { + focus=romCount-1; + smooth=(focus<<8)-1; + } + else if (focus<0) + { + focus=0; + smooth=(focus<<8)-1; + } + } + + if (focus>romCount-1) + { + focus=0; + smooth=(focus<<8)-1; + } + else if (focus<0) + { + focus=romCount-1; + smooth=(focus<<8)-1; + } + + if (Inp.held[INP_BUTTON_MENU_SELECT]==1) + { + if(focus==0) + { + action=0; + menuExit=1; + } + else if(focus==1) + { + // up a directory + //Remove a directory from RomPath and rescan + for(i=strlen(romDir)-1;i>0;i--) // don't want to change first char in screen + { + if(romDir[i] == directorySeparator[0]) + { + romDir[i] = 0; + break; + } + } + FileScan(); + focus=2; // default menu to non menu item + // just to stop directory scan being started + smooth=focus<<8; + } + else if(focus==2) + { + // nothing blank entry + } + else + { + // normal file or dir selected + if (romList[focus].type == FILE_TYPE_DIRECTORY) + { + sprintf(romDir,"%s%s%s",romDir,DIR_SEPERATOR,romList[focus].filename); + FileScan(); + focus=2; // default menu to non menu item + // just to stop directory scan being started + smooth=focus<<8; + } + else + { + // user has selected a rom, so load it + currentRomIndex=focus; + quickSavePresent=0; // reset any quick saves + action=1; + menuExit=1; + } + } + } + + if (Inp.held[INP_BUTTON_MENU_DELETE]==1) + { + if(focus>2) + { + //delete current rom + if (romList[focus].type != FILE_TYPE_DIRECTORY) + { + sprintf(text,"%s",romList[focus].filename); + + if(MessageBox("Are you sure you want to delete",text,"",0)==0) + { + deleterom(focus); + } + } + } + } + + // Draw screen: + PrintTile(currFB); + PrintTitle(currFB); + if(mode==0) gp_drawString(6,35,10,"Select Rom",(unsigned short)RGB(31,0,0),(unsigned short*)vrambuffer); + if(mode==1) gp_drawString(6,35,10,"Delete Rom",(unsigned short)RGB(31,0,0),(unsigned short*)vrambuffer); + + smooth=smooth*7+(focus<<8); smooth>>=3; + + scanstart=focus-15; + if (scanstart<0) scanstart=0; + scanend = focus+15; + if (scanend>romCount) scanend=romCount; + + for (i=scanstart;i>4); + x=8; + y+=112; + if (y<=48 || y>=232) continue; + + if (i==focus) + { + color=(unsigned short)RGB(0,0,0); + PrintBar(currFB,y-4); + } + else + { + color=(unsigned short)RGB(31,31,31); + } + + // Draw Directory icon if current entry is a directory + if(romList[i].type == FILE_TYPE_DIRECTORY) + { + gp_drawString(x-8,y,1,"+",color,(unsigned short*)vrambuffer); + } + + romname_length=strlen(romList[i].filename); + if(romname_length>39) romname_length=39; + gp_drawString(x,y,romname_length,romList[i].filename,color,(unsigned short*)vrambuffer); + } + + MenuFlip(); + } + + return action; +} + +static void ScanSaveStates(char *romname) +{ + FILE *stream; + int i=0; + char savename[MAX_PATH+1]; + char filename[MAX_PATH+1]; + char ext[MAX_PATH+1]; + + if(!strcmp(romname,saveStateName)) return; // is current save state rom so exit + + SplitFilename(romname,filename,ext); + + sprintf(savename,"%s.%s",filename,SAVESTATE_EXT); + + for(i=0;i<10;i++) + { + /* + need to build a save state filename + all saves are held in current working directory (snesSaveStateDir) + save filename has following format + shortname(minus file ext) + SV + saveno ( 0 to 9 ) + */ + sprintf(saveState[i].filename,"%s%d",savename,i); + sprintf(saveState[i].fullFilename,"%s%s%s",snesSaveStateDir,DIR_SEPERATOR,saveState[i].filename); + stream=(FILE*)fopen(saveState[i].fullFilename,"rb"); + if(stream) + { + // we have a savestate + saveState[i].inUse = 1; + fclose(stream); + } + else + { + // no save state + saveState[i].inUse = 0; + } + } + strcpy(saveStateName,romname); // save the last scanned romname +} + +void LoadStateFile(char *filename) +{ + S9xUnfreezeGame(filename); +} + +void SaveStateFile(char *filename) +{ + S9xFreezeGame(filename); + sync(); +} + +static int SaveStateSelect(int mode) +{ + char text[128]; + int action=11; + int saveno=0; + + if(currentRomIndex<=2) + { + // no rom loaded + // display error message and exit + return(0); + } + + memset(&headerDone,0,sizeof(headerDone)); + ScanSaveStates(currentRomFilename); + + while (action!=0&&action!=100) + { + InputUpdate(0); + if(Inp.held[INP_BUTTON_UP]==1) {saveno--; action=1;} + if(Inp.held[INP_BUTTON_DOWN]==1) {saveno++; action=1;} + if(saveno<-1) saveno=9; + if(saveno>9) saveno=-1; + + if(Inp.held[INP_BUTTON_MENU_CANCEL]==1) action=0; // exit + else if((Inp.held[INP_BUTTON_MENU_SELECT]==1)&&(saveno==-1)) action=0; // exit + else if((Inp.held[INP_BUTTON_MENU_SELECT]==1)&&(mode==0)&&((action==2)||(action==5))) action=6; // pre-save mode + else if((Inp.held[INP_BUTTON_MENU_SELECT]==1)&&(mode==1)&&(action==5)) action=8; // pre-load mode + else if((Inp.held[INP_BUTTON_MENU_SELECT]==1)&&(mode==2)&&(action==5)) + { + if(MessageBox("Are you sure you want to delete","this save?","",0)==0) action=13; //delete slot with no preview + } + //else if((Inp.held[INP_BUTTON_R]==1)&&(action==12)) action=3; // preview slot mode + else if((Inp.held[INP_BUTTON_MENU_SELECT]==1)&&(mode==1)&&(action==12)) action=8; //load slot with no preview + else if((Inp.held[INP_BUTTON_MENU_SELECT]==1)&&(mode==0)&&(action==12)) action=6; //save slot with no preview + else if((Inp.held[INP_BUTTON_MENU_SELECT]==1)&&(mode==2)&&(action==12)) + { + if(MessageBox("Are you sure you want to delete","this save?","",0)==0) action=13; //delete slot with no preview + } + + PrintTile(currFB); + PrintTitle(currFB); + if(mode==SAVESTATE_MODE_SAVE) gp_drawString(6,35,10,"Save State",(unsigned short)RGB(31,0,0),(unsigned short*)vrambuffer); + if(mode==SAVESTATE_MODE_LOAD) gp_drawString(6,35,10,"Load State",(unsigned short)RGB(31,0,0),(unsigned short*)vrambuffer); + if(mode==SAVESTATE_MODE_DELETE) gp_drawString(6,35,12,"Delete State",(unsigned short)RGB(31,0,0),(unsigned short*)vrambuffer); + sprintf(text,"Press UP and DOWN to change save slot"); + gp_drawString(12,230,strlen(text),text,(unsigned short)RGB(31,15,5),(unsigned short*)vrambuffer); + + if(saveno==-1) + { + if(action!=10&&action!=0) + { + action=10; + } + } + else + { + PrintBar(currFB,60-4); + sprintf(text,"SLOT %d",saveno); + gp_drawString(136,60,strlen(text),text,(unsigned short)RGB(31,31,31),(unsigned short*)vrambuffer); + } + + switch(action) + { + case 1: + //gp_drawString(112,145,14,"Checking....",(unsigned short)RGB(31,31,31),(unsigned short*)vrambuffer); + break; + case 2: + gp_drawString(144,145,4,"FREE",(unsigned short)RGB(31,31,31),(unsigned short*)vrambuffer); + break; + case 3: + gp_drawString(104,145,14,"Previewing....",(unsigned short)RGB(31,31,31),(unsigned short*)vrambuffer); + break; + case 4: + gp_drawString(88,145,18,"Previewing....fail",(unsigned short)RGB(31,31,31),(unsigned short*)vrambuffer); + break; + case 5: + gp_drawString(112,145,17, "Not gonna happen!",(unsigned short)RGB(31,31,31),(unsigned short*)vrambuffer); + if(mode==1) gp_drawString((320-(strlen(MENU_TEXT_LOAD_SAVESTATE)<<3))>>1,210,strlen(MENU_TEXT_LOAD_SAVESTATE), MENU_TEXT_LOAD_SAVESTATE,(unsigned short)RGB(31,31,31),(unsigned short*)vrambuffer); + else if(mode==0) gp_drawString((320-(strlen(MENU_TEXT_OVERWRITE_SAVESTATE)<<3))>>1,210,strlen(MENU_TEXT_OVERWRITE_SAVESTATE), MENU_TEXT_OVERWRITE_SAVESTATE,(unsigned short)RGB(31,31,31),(unsigned short*)vrambuffer); + else if(mode==2) gp_drawString((320-(strlen(MENU_TEXT_DELETE_SAVESTATE)<<3))>>1,210,strlen(MENU_TEXT_DELETE_SAVESTATE), MENU_TEXT_DELETE_SAVESTATE,(unsigned short)RGB(31,31,31),(unsigned short*)vrambuffer); + break; + case 6: + gp_drawString(124,145,9,"Saving...",(unsigned short)RGB(31,31,31),(unsigned short*)vrambuffer); + break; + case 7: + gp_drawString(124,145,14,"Saving...Fail!",(unsigned short)RGB(31,31,31),(unsigned short*)vrambuffer); + break; + case 8: + gp_drawString(116,145,11,"loading....",(unsigned short)RGB(31,31,31),(unsigned short*)vrambuffer); + break; + case 9: + gp_drawString(116,145,15,"loading....Fail",(unsigned short)RGB(31,31,31),(unsigned short*)vrambuffer); + break; + case 10: + PrintBar(currFB,145-4); + gp_drawString(104,145,14,"Return To Menu",(unsigned short)RGB(31,31,31),(unsigned short*)vrambuffer); + break; + case 12: + gp_drawString(124,145,9,"Slot used",(unsigned short)RGB(31,31,31),(unsigned short*)vrambuffer); + //gp_drawString((320-(strlen(MENU_TEXT_PREVIEW_SAVESTATE)<<3))>>1,165,strlen(MENU_TEXT_PREVIEW_SAVESTATE),MENU_TEXT_PREVIEW_SAVESTATE,(unsigned short)RGB(31,31,31),(unsigned short*)vrambuffer); + if(mode==1) gp_drawString((320-(strlen(MENU_TEXT_LOAD_SAVESTATE)<<3))>>1,175,strlen(MENU_TEXT_LOAD_SAVESTATE), MENU_TEXT_LOAD_SAVESTATE,(unsigned short)RGB(31,31,31),(unsigned short*)vrambuffer); + else if(mode==0) gp_drawString((320-(strlen(MENU_TEXT_OVERWRITE_SAVESTATE)<<3))>>1,175,strlen(MENU_TEXT_OVERWRITE_SAVESTATE), MENU_TEXT_OVERWRITE_SAVESTATE,(unsigned short)RGB(31,31,31),(unsigned short*)vrambuffer); + else if(mode==2) gp_drawString((320-(strlen(MENU_TEXT_DELETE_SAVESTATE)<<3))>>1,175,strlen(MENU_TEXT_DELETE_SAVESTATE), MENU_TEXT_DELETE_SAVESTATE,(unsigned short)RGB(31,31,31),(unsigned short*)vrambuffer); + break; + case 13: + gp_drawString(116,145,11,"Deleting....",(unsigned short)RGB(31,31,31),(unsigned short*)vrambuffer); + break; + } + + MenuFlip(); + + switch(action) + { + case 1: + if(saveState[saveno].inUse) + { + action=12; + } + else + { + action=2; + } + break; + case 3: + LoadStateFile(saveState[saveno].fullFilename); + action=5; + break; + case 6: + SaveStateFile(saveState[saveno].fullFilename); + saveState[saveno].inUse=1; + action=1; + break; + case 7: + action=1; + break; + case 8: + LoadStateFile(saveState[saveno].fullFilename); + action=100; // loaded ok so exit + break; + case 9: + action=1; + break; + case 11: + action=1; + break; + case 13: + remove(saveState[saveno].fullFilename); + sync(); + saveState[saveno].inUse = 0; + action=1; + break; + } + } + memset(&headerDone,0,sizeof(headerDone)); + return(action); +} + +static +void RenderMenu(char *menuName, int menuCount, int menuSmooth, int menufocus) +{ + + int i=0; + char text[50]; + unsigned short color=0; + PrintTile(currFB); + PrintTitle(currFB); + + gp_drawString(6,35,strlen(menuName),menuName,(unsigned short)RGB(31,0,0),(unsigned short*)vrambuffer); + + // RRRRRGGGGGBBBBBI gp32 color format + for (i=0;i>4); + x=8; + y+=112; + + if (y<=48 || y>=232) continue; + + if (i==menufocus) + { + color=(unsigned short)RGB(0,0,0); + PrintBar(currFB,y-4); + } + else + { + color=(unsigned short)RGB(31,31,31); + } + + sprintf(text,"%s",menutext[i]); + gp_drawString(x,y,strlen(text),text,color,(unsigned short*)vrambuffer); + } + +} + +static +int LoadRomMenu(void) +{ + int menuExit=0,menuCount=LOAD_ROM_MENU_COUNT,menufocus=0,menuSmooth=0; + int action=0; + int subaction=0; + + memset(&headerDone,0,sizeof(headerDone)); + strcpy(romDir,snesRomDir); + subaction=FileSelect(0); + memset(&headerDone,0,sizeof(headerDone)); + if(subaction) + { + action=EVENT_LOAD_SNES_ROM; + menuExit=1; + } + + return action; +} + +static +int SaveStateMenu(void) +{ + int menuExit=0,menuCount=SAVESTATE_MENU_COUNT,menufocus=0,menuSmooth=0; + int action=0; + int subaction=0; + + memset(&headerDone,0,sizeof(headerDone)); + + //Update + sprintf(menutext[SAVESTATE_MENU_LOAD],"Load State"); + sprintf(menutext[SAVESTATE_MENU_SAVE],"Save State"); + sprintf(menutext[SAVESTATE_MENU_DELETE],"Delete State"); + sprintf(menutext[SAVESTATE_MENU_RETURN],"Back"); + + while (!menuExit) + { + InputUpdate(0); + + // Change which rom is focused on: + if (Inp.repeat[INP_BUTTON_UP]) menufocus--; // Up + if (Inp.repeat[INP_BUTTON_DOWN]) menufocus++; // Down + + if (Inp.held[INP_BUTTON_MENU_CANCEL]==1 ) menuExit=1; + + if (menufocus>menuCount-1) + { + menufocus=0; + menuSmooth=(menufocus<<8)-1; + } + else if (menufocus<0) + { + menufocus=menuCount-1; + menuSmooth=(menufocus<<8)-1; + } + + if (Inp.held[INP_BUTTON_MENU_SELECT]==1) + { + switch(menufocus) + { + case SAVESTATE_MENU_LOAD: + subaction=SaveStateSelect(SAVESTATE_MODE_LOAD); + if(subaction==100) + { + menuExit=1; + action=100; + } + break; + case SAVESTATE_MENU_SAVE: + SaveStateSelect(SAVESTATE_MODE_SAVE); + break; + case SAVESTATE_MENU_DELETE: + SaveStateSelect(SAVESTATE_MODE_DELETE); + break; + case SAVESTATE_MENU_RETURN: + menuExit=1; + break; + } + } + // Draw screen: + menuSmooth=menuSmooth*7+(menufocus<<8); menuSmooth>>=3; + RenderMenu("Save States", menuCount,menuSmooth,menufocus); + MenuFlip(); + + } + + return action; +} + +static +int SramMenu(void) +{ + int menuExit=0,menuCount=SRAM_MENU_COUNT,menufocus=0,menuSmooth=0; + int action=0; + int subaction=0; + char *srammem=NULL; + + + memset(&headerDone,0,sizeof(headerDone)); + + //Update + sprintf(menutext[SRAM_MENU_LOAD],"Load SRAM"); + sprintf(menutext[SRAM_MENU_SAVE],"Save SRAM"); + sprintf(menutext[SRAM_MENU_DELETE],"Delete SRAM"); + sprintf(menutext[SRAM_MENU_RETURN],"Back"); + + while (!menuExit) + { + InputUpdate(0); + + // Change which rom is focused on: + if (Inp.repeat[INP_BUTTON_UP]) menufocus--; // Up + if (Inp.repeat[INP_BUTTON_DOWN]) menufocus++; // Down + + if (Inp.held[INP_BUTTON_MENU_CANCEL]==1 ) menuExit=1; + + if (menufocus>menuCount-1) + { + menufocus=0; + menuSmooth=(menufocus<<8)-1; + } + else if (menufocus<0) + { + menufocus=menuCount-1; + menuSmooth=(menufocus<<8)-1; + } + + if (Inp.held[INP_BUTTON_MENU_SELECT]==1) + { + switch(menufocus) + { + case SRAM_MENU_LOAD: + //LoadSram(snesSramDir,currentRomFilename,SRAM_FILE_EXT,(char*)&sram); + break; + case SRAM_MENU_SAVE: + //SaveSram(snesSramDir,currentRomFilename,SRAM_FILE_EXT,(char*)&sram); + break; + case SRAM_MENU_DELETE: + //DeleteSram(snesSramDir,currentRomFilename,SRAM_FILE_EXT); + break; + case SRAM_MENU_RETURN: + menuExit=1; + break; + } + } + // Draw screen: + menuSmooth=menuSmooth*7+(menufocus<<8); menuSmooth>>=3; + RenderMenu("SRAM", menuCount,menuSmooth,menufocus); + MenuFlip(); + + } + + return action; +} + +static +void SNESOptionsUpdateText(int menu_index) +{ + switch(menu_index) + { + case SNES_MENU_SOUND: + switch(snesMenuOptions.soundOn) + { + case 0: + sprintf(menutext[SNES_MENU_SOUND],"Sound: OFF"); + break; + case 1: + sprintf(menutext[SNES_MENU_SOUND],"Sound: ON"); + break; + } + break; + + case SNES_MENU_SOUND_RATE: + sprintf(menutext[SNES_MENU_SOUND_RATE],"Sound Rate: %d",(unsigned int)soundRates[snesMenuOptions.soundRate]); + break; + + case SNES_MENU_CPUSPEED: + sprintf(menutext[SNES_MENU_CPUSPEED],"Cpu Speed: %d",(unsigned int)cpuSpeedLookup[snesMenuOptions.cpuSpeed]); + break; + + case SNES_MENU_SOUND_VOL: + sprintf(menutext[SNES_MENU_SOUND_VOL],"Volume: %d",snesMenuOptions.volume); + break; + + case SNES_MENU_FRAMESKIP: + switch(snesMenuOptions.frameSkip) + { + case 0: + sprintf(menutext[SNES_MENU_FRAMESKIP],"Frameskip: AUTO"); + break; + default: + sprintf(menutext[SNES_MENU_FRAMESKIP],"Frameskip: %d",snesMenuOptions.frameSkip-1); + break; + } + break; + + case SNES_MENU_FPS: + switch(snesMenuOptions.showFps) + { + case 0: + sprintf(menutext[SNES_MENU_FPS],"Show FPS: OFF"); + break; + case 1: + sprintf(menutext[SNES_MENU_FPS],"Show FPS: ON"); + break; + } + break; + + case SNES_MENU_GAMMA: + sprintf(menutext[SNES_MENU_GAMMA],"Brightness: %d",snesMenuOptions.gamma+100); + break; + + case SNES_MENU_TRANSPARENCY: + switch(snesMenuOptions.transparency) + { + case 0: + sprintf(menutext[SNES_MENU_TRANSPARENCY],"Transparencies: OFF"); + break; + case 1: + sprintf(menutext[SNES_MENU_TRANSPARENCY],"Transparencies: ON"); + break; + } + break; + + case SNES_MENU_LOAD_GLOBAL: + sprintf(menutext[SNES_MENU_LOAD_GLOBAL],"Load Global Settings"); + break; + + case SNES_MENU_SAVE_GLOBAL: + sprintf(menutext[SNES_MENU_SAVE_GLOBAL],"Save Global Settings"); + break; + + case SNES_MENU_DELETE_GLOBAL: + sprintf(menutext[SNES_MENU_DELETE_GLOBAL],"Delete Global Settings"); + break; + + case SNES_MENU_LOAD_CURRENT: + sprintf(menutext[SNES_MENU_LOAD_CURRENT],"Load Settings For Current Game"); + break; + + case SNES_MENU_SAVE_CURRENT: + sprintf(menutext[SNES_MENU_SAVE_CURRENT],"Save Settings For Current Game"); + break; + + case SNES_MENU_DELETE_CURRENT: + sprintf(menutext[SNES_MENU_DELETE_CURRENT],"Delete Settings For Current Game"); + break; + + case SNES_MENU_SET_ROMDIR: + sprintf(menutext[SNES_MENU_SET_ROMDIR],"Save Current Rom Directory"); + break; + + case SNES_MENU_RETURN: + sprintf(menutext[SNES_MENU_RETURN],"Back"); + break; + + case SNES_MENU_RENDER_MODE: + switch(snesMenuOptions.renderMode) + { + case RENDER_MODE_UNSCALED: + sprintf(menutext[SNES_MENU_RENDER_MODE],"Render Mode: Unscaled"); + break; + case RENDER_MODE_SCALED: + sprintf(menutext[SNES_MENU_RENDER_MODE],"Render Mode: Scaled"); + break; + default: + sprintf(menutext[SNES_MENU_RENDER_MODE],"Render Mode: Unscaled"); + break; + } + break; + + case SNES_MENU_ACTION_BUTTONS: + switch(snesMenuOptions.actionButtons) + { + case 0: + sprintf(menutext[SNES_MENU_ACTION_BUTTONS],"Action Buttons: Normal"); + break; + case 1: + sprintf(menutext[SNES_MENU_ACTION_BUTTONS],"Action Buttons: Swapped"); + break; + } + break; + case SNES_MENU_AUTO_SAVE_SRAM: + switch(snesMenuOptions.autoSram) + { + case 0: + sprintf(menutext[SNES_MENU_AUTO_SAVE_SRAM],"Saving SRAM: Manual"); + break; + case 1: + sprintf(menutext[SNES_MENU_AUTO_SAVE_SRAM],"Saving SRAM: Automatic"); + break; + } + break; + case SNES_MENU_RAM_SETTINGS: + switch(snesMenuOptions.ramSettings) + { + case 0: + sprintf(menutext[SNES_MENU_RAM_SETTINGS],"RAM timing (Restart Required): NORMAL"); + break; + case 1: + sprintf(menutext[SNES_MENU_RAM_SETTINGS],"RAM timing (Restart Required): CRAIG"); + break; + } + break; + case SNES_MENU_MMU_HACK: + switch(snesMenuOptions.mmuHack) + { + case 0: + sprintf(menutext[SNES_MENU_MMU_HACK],"MMU Hack (Restart Required): OFF"); + break; + case 1: + sprintf(menutext[SNES_MENU_MMU_HACK],"MMU Hack (Restart Required): ON"); + break; + } + break; + } +} + +static +void SNESOptionsUpdateText_All() +{ + SNESOptionsUpdateText(SNES_MENU_SOUND); + SNESOptionsUpdateText(SNES_MENU_SOUND_RATE); + SNESOptionsUpdateText(SNES_MENU_CPUSPEED); + SNESOptionsUpdateText(SNES_MENU_SOUND_VOL); + SNESOptionsUpdateText(SNES_MENU_FRAMESKIP); + SNESOptionsUpdateText(SNES_MENU_FPS); + SNESOptionsUpdateText(SNES_MENU_GAMMA); + SNESOptionsUpdateText(SNES_MENU_TRANSPARENCY); + SNESOptionsUpdateText(SNES_MENU_LOAD_GLOBAL); + SNESOptionsUpdateText(SNES_MENU_SAVE_GLOBAL); + SNESOptionsUpdateText(SNES_MENU_DELETE_GLOBAL); + SNESOptionsUpdateText(SNES_MENU_LOAD_CURRENT); + SNESOptionsUpdateText(SNES_MENU_SAVE_CURRENT); + SNESOptionsUpdateText(SNES_MENU_DELETE_CURRENT); + SNESOptionsUpdateText(SNES_MENU_SET_ROMDIR); + SNESOptionsUpdateText(SNES_MENU_RETURN); + SNESOptionsUpdateText(SNES_MENU_ACTION_BUTTONS); + SNESOptionsUpdateText(SNES_MENU_RENDER_MODE); + SNESOptionsUpdateText(SNES_MENU_AUTO_SAVE_SRAM); + SNESOptionsUpdateText(SNES_MENU_RAM_SETTINGS); + SNESOptionsUpdateText(SNES_MENU_MMU_HACK); +} + +static +int SNESOptionsMenu(void) +{ + int menuExit=0,menuCount=SNES_MENU_COUNT,menufocus=0,menuSmooth=0; + int action=0; + int subaction=0; + + memset(&headerDone,0,sizeof(headerDone)); + + //Update all items + SNESOptionsUpdateText_All(); + + while (!menuExit) + { + InputUpdate(0); + + // Change which rom is focused on: + if (Inp.repeat[INP_BUTTON_UP]) menufocus--; // Up + if (Inp.repeat[INP_BUTTON_DOWN]) menufocus++; // Down + + if (Inp.held[INP_BUTTON_MENU_CANCEL]==1 ) menuExit=1; + + if (menufocus>menuCount-1) + { + menufocus=0; + menuSmooth=(menufocus<<8)-1; + } + else if (menufocus<0) + { + menufocus=menuCount-1; + menuSmooth=(menufocus<<8)-1; + } + + if (Inp.held[INP_BUTTON_LEFT]==1|| + Inp.held[INP_BUTTON_RIGHT]==1|| + Inp.repeat[INP_BUTTON_LEFT]|| + Inp.repeat[INP_BUTTON_RIGHT]) + { + switch(menufocus) + { + case SNES_MENU_SOUND: + snesMenuOptions.soundOn^=1; + SNESOptionsUpdateText(SNES_MENU_SOUND); + break; + case SNES_MENU_SOUND_RATE: + if (Inp.held[INP_BUTTON_RIGHT]==1||Inp.repeat[INP_BUTTON_RIGHT]) + { + snesMenuOptions.soundRate++; + if(snesMenuOptions.soundRate>4) snesMenuOptions.soundRate=0; + } + else + { + snesMenuOptions.soundRate--; + if(snesMenuOptions.soundRate>4) snesMenuOptions.soundRate=4; + } + SNESOptionsUpdateText(SNES_MENU_SOUND_RATE); + break; + case SNES_MENU_SOUND_VOL: + if (Inp.held[INP_BUTTON_RIGHT]==1||Inp.repeat[INP_BUTTON_RIGHT]) + { + snesMenuOptions.volume+=1; + if(snesMenuOptions.volume>100) snesMenuOptions.volume=0; + } + else + { + snesMenuOptions.volume-=1; + if(snesMenuOptions.volume>100) snesMenuOptions.volume=100; + } + SNESOptionsUpdateText(SNES_MENU_SOUND_VOL); + break; + case SNES_MENU_CPUSPEED: + if (Inp.held[INP_BUTTON_RIGHT]==1||Inp.repeat[INP_BUTTON_RIGHT]) + { + snesMenuOptions.cpuSpeed++; + if(snesMenuOptions.cpuSpeed>40) snesMenuOptions.cpuSpeed=0; + } + else + { + snesMenuOptions.cpuSpeed--; + if(snesMenuOptions.cpuSpeed>40) snesMenuOptions.cpuSpeed=0; + } + SNESOptionsUpdateText(SNES_MENU_CPUSPEED); + break; + case SNES_MENU_FRAMESKIP: + if (Inp.held[INP_BUTTON_RIGHT]==1||Inp.repeat[INP_BUTTON_RIGHT]) + { + snesMenuOptions.frameSkip++; + if(snesMenuOptions.frameSkip>6) snesMenuOptions.frameSkip=0; + } + else + { + snesMenuOptions.frameSkip--; + if(snesMenuOptions.frameSkip>6) snesMenuOptions.frameSkip=6; + } + SNESOptionsUpdateText(SNES_MENU_FRAMESKIP); + break; + case SNES_MENU_FPS: + snesMenuOptions.showFps^=1; + SNESOptionsUpdateText(SNES_MENU_FPS); + break; + case SNES_MENU_GAMMA: + if (Inp.held[INP_BUTTON_RIGHT]==1||Inp.repeat[INP_BUTTON_RIGHT]) + { + snesMenuOptions.gamma++; + if(snesMenuOptions.gamma>100) snesMenuOptions.gamma=100; + } + else + { + snesMenuOptions.gamma--; + if(snesMenuOptions.gamma<-100) snesMenuOptions.gamma=-100; + } + set_gamma(snesMenuOptions.gamma+100); + SNESOptionsUpdateText(SNES_MENU_GAMMA); + break; + case SNES_MENU_ACTION_BUTTONS: + snesMenuOptions.actionButtons^=1; + SNESOptionsUpdateText(SNES_MENU_ACTION_BUTTONS); + break; + case SNES_MENU_TRANSPARENCY: + snesMenuOptions.transparency^=1; + SNESOptionsUpdateText(SNES_MENU_TRANSPARENCY); + break; + case SNES_MENU_RENDER_MODE: + snesMenuOptions.renderMode^=1; + SNESOptionsUpdateText(SNES_MENU_RENDER_MODE); + break; + case SNES_MENU_AUTO_SAVE_SRAM: + snesMenuOptions.autoSram^=1; + SNESOptionsUpdateText(SNES_MENU_AUTO_SAVE_SRAM); + break; + case SNES_MENU_RAM_SETTINGS: + snesMenuOptions.ramSettings^=1; + SNESOptionsUpdateText(SNES_MENU_RAM_SETTINGS); + break; + case SNES_MENU_MMU_HACK: + snesMenuOptions.mmuHack^=1; + SNESOptionsUpdateText(SNES_MENU_MMU_HACK); + break; + } + } + if (Inp.held[INP_BUTTON_MENU_SELECT]==1) + { + switch(menufocus) + { + case SNES_MENU_LOAD_GLOBAL: + LoadMenuOptions(snesOptionsDir, MENU_OPTIONS_FILENAME, MENU_OPTIONS_EXT, (char*)&snesMenuOptions, sizeof(snesMenuOptions),1); + SNESOptionsUpdateText_All(); + break; + case SNES_MENU_SAVE_GLOBAL: + SaveMenuOptions(snesOptionsDir, MENU_OPTIONS_FILENAME, MENU_OPTIONS_EXT, (char*)&snesMenuOptions, sizeof(snesMenuOptions),1); + break; + case SNES_MENU_DELETE_GLOBAL: + DeleteMenuOptions(snesOptionsDir,MENU_OPTIONS_FILENAME,MENU_OPTIONS_EXT,1); + break; + case SNES_MENU_LOAD_CURRENT: + if(currentRomFilename[0]!=0) + { + LoadMenuOptions(snesOptionsDir, currentRomFilename, MENU_OPTIONS_EXT, (char*)&snesMenuOptions, sizeof(snesMenuOptions),1); + SNESOptionsUpdateText_All(); + } + break; + case SNES_MENU_SAVE_CURRENT: + if(currentRomFilename[0]!=0) + { + SaveMenuOptions(snesOptionsDir, currentRomFilename, MENU_OPTIONS_EXT, (char*)&snesMenuOptions, sizeof(snesMenuOptions),1); + } + break; + case SNES_MENU_DELETE_CURRENT: + if(currentRomFilename[0]!=0) + { + DeleteMenuOptions(snesOptionsDir, currentRomFilename, MENU_OPTIONS_EXT,1); + } + break; + case SNES_MENU_SET_ROMDIR: + SaveMenuOptions(snesOptionsDir, DEFAULT_ROM_DIR_FILENAME, DEFAULT_ROM_DIR_EXT, romDir, strlen(romDir),1); + strcpy(snesRomDir,romDir); + break; + case SNES_MENU_RETURN: + menuExit=1; + break; + } + } + // Draw screen: + menuSmooth=menuSmooth*7+(menufocus<<8); menuSmooth>>=3; + RenderMenu("SNES Options", menuCount,menuSmooth,menufocus); + MenuFlip(); + + } + + return action; +} + +static +void MainMenuUpdateText(void) +{ + sprintf(menutext[MAIN_MENU_ROM_SELECT],"Select Rom"); + sprintf(menutext[MAIN_MENU_MANAGE_SAVE_STATE],"Manage Save States"); + sprintf(menutext[MAIN_MENU_SAVE_SRAM],"Save SRAM"); + sprintf(menutext[MAIN_MENU_SNES_OPTIONS],"SNES Options"); + sprintf(menutext[MAIN_MENU_RESET_GAME ],"Reset Game"); + sprintf(menutext[MAIN_MENU_EXIT_APP],"Exit Application"); + sprintf(menutext[MAIN_MENU_RETURN],"Return To Game"); +} + + +int MainMenu(int prevaction) +{ + int menuExit=0,menuCount=MAIN_MENU_COUNT,menufocus=0,menuSmooth=0; + int action=prevaction; + int subaction=0; + + gp_setCpuspeed(MENU_CPU_SPEED); + + gp_initGraphics(16,currFB,snesMenuOptions.mmuHack); + gp_clearFramebuffer16((unsigned short*)vrambuffer,0x0); + MenuFlip(); + gp2x_video_RGB_setscaling(320,240); + + memset(&headerDone,0,sizeof(headerDone)); + MainMenuUpdateText(); + + while (!menuExit) + { + InputUpdate(0); + + // Change which rom is focused on: + if (Inp.repeat[INP_BUTTON_UP]) menufocus--; // Up + if (Inp.repeat[INP_BUTTON_DOWN]) menufocus++; // Down + + if (Inp.held[INP_BUTTON_MENU_CANCEL]==1 ) + { + if(currentRomFilename[0]!=0) + { + menuExit=1; + } + } + + if (menufocus>menuCount-1) + { + menufocus=0; + menuSmooth=(menufocus<<8)-1; + } + else if (menufocus<0) + { + menufocus=menuCount-1; + menuSmooth=(menufocus<<8)-1; + } + + if (Inp.held[INP_BUTTON_MENU_SELECT]==1) + { + switch(menufocus) + { + case MAIN_MENU_ROM_SELECT: + memset(&headerDone,0,sizeof(headerDone)); + subaction=LoadRomMenu(); + memset(&headerDone,0,sizeof(headerDone)); + if(subaction) + { + action=subaction; + menuExit=1; + } + MainMenuUpdateText(); + break; + + case MAIN_MENU_MANAGE_SAVE_STATE: + if(currentRomFilename[0]!=0) + { + memset(&headerDone,0,sizeof(headerDone)); + subaction=SaveStateMenu(); + if (subaction==100) + { + menuExit=1; + } + memset(&headerDone,0,sizeof(headerDone)); + } + MainMenuUpdateText(); + break; + case MAIN_MENU_SAVE_SRAM: +#if 0 // TEMP EDIT + if(currentRomFilename[0]!=0) + { + S9xSaveSRAM(); + } +#endif + break; + case MAIN_MENU_SNES_OPTIONS: + + memset(&headerDone,0,sizeof(headerDone)); + subaction=SNESOptionsMenu(); + memset(&headerDone,0,sizeof(headerDone)); + MainMenuUpdateText(); + break; + case MAIN_MENU_RESET_GAME : + if(currentRomFilename[0]!=0) + { + switch(currentEmuMode) + { + case EMU_MODE_SNES: + action=EVENT_RESET_SNES_ROM; + menuExit=1; + break; + } + } + break; + case MAIN_MENU_RETURN: + if(currentRomFilename[0]!=0) + { + menuExit=1; + } + break; + case MAIN_MENU_EXIT_APP: + action=EVENT_EXIT_APP; + menuExit=1; + break; + } + } + // Draw screen: + menuSmooth=menuSmooth*7+(menufocus<<8); menuSmooth>>=3; + RenderMenu("Main Menu (visit www.zodttd.com)", menuCount,menuSmooth,menufocus); + MenuFlip(); + + } + + WaitForButtonsUp(); + + return action; +} + + + diff --git a/src/snes4iphone_src/menu.h b/src/snes4iphone_src/menu.h new file mode 100755 index 0000000..756ceea --- /dev/null +++ b/src/snes4iphone_src/menu.h @@ -0,0 +1,338 @@ +#ifndef _MENU_H_ +#define _MENU_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +#include +#include + +#ifdef __GIZ__ +#include +#include +#include +#include +#include +#include "giz_kgsdk.h" + +#define DIR_SEPERATOR "\\" +#define SYSTEM_DIR "\\SD Card\\DrPocketSnes" +#endif + +#ifdef __GP2X__ +#include "gp2x_sdk.h" + +#define DIR_SEPERATOR "/" +#define SYSTEM_DIR "/mnt/sd/DrPocketSnes" +#endif + +#ifdef __IPHONE__ +#include "iphone_sdk.h" + +#define DIR_SEPERATOR "/" +#define SYSTEM_DIR "/var/mobile/Media/ROMs/SNES" +#endif + + +#define SNES_OPTIONS_DIR "options" +#define SNES_SRAM_DIR "" +#define SNES_SAVESTATE_DIR "" + +#define ROM_LIST_FILENAME "romlist.bin" +#define SRAM_FILE_EXT "srm" +#define SAVESTATE_EXT "sv" +#define MENU_OPTIONS_FILENAME "menu" +#define MENU_OPTIONS_EXT "opt" +#define DEFAULT_ROM_DIR_FILENAME "romdir" +#define DEFAULT_ROM_DIR_EXT "opt" + + +//define emulation modes +#define EMU_MODE_NONE 0 +#define EMU_MODE_SNES 1 + +#define SAVESTATE_MODE_SAVE 0 +#define SAVESTATE_MODE_LOAD 1 +#define SAVESTATE_MODE_DELETE 2 + +#define SNES_OPTIONS_VER 1 +#define DRSNES_VERSION "snes4iphone v0.3.5" + +#define ROM_SIZE 0x500000 //ssf2(40mbits) +#define RGB(r,g,b) ((r) << 11 | (g) << 6 | (b) << 0 ) +#define MAX_ROMS 3000 +#define MAX_CPU 39 +#define MAX_PATH 255 + +#define MENU_CPU_SPEED 100 +#define MENU_FAST_CPU_SPEED 200 + +#define FILE_TYPE_FILE 0 +#define FILE_TYPE_DIRECTORY 1 + +#define MAIN_MENU_RETURN 0 +#define MAIN_MENU_ROM_SELECT 1 +#define MAIN_MENU_MANAGE_SAVE_STATE 2 +#define MAIN_MENU_SAVE_SRAM 3 +#define MAIN_MENU_SNES_OPTIONS 4 +#define MAIN_MENU_RESET_GAME 5 +#define MAIN_MENU_EXIT_APP 6 +#define MAIN_MENU_COUNT 7 + +#define LOAD_ROM_MENU_SNES 0 +#define LOAD_ROM_MENU_RETURN 1 +#define LOAD_ROM_MENU_COUNT 2 + +#define SNES_MENU_SOUND 0 +#define SNES_MENU_SOUND_RATE 1 +#define SNES_MENU_SOUND_VOL 2 +#define SNES_MENU_CPUSPEED 3 +#define SNES_MENU_FRAMESKIP 4 +#define SNES_MENU_ACTION_BUTTONS 5 +#define SNES_MENU_FPS 6 +#define SNES_MENU_GAMMA 7 +#define SNES_MENU_TRANSPARENCY 8 +#define SNES_MENU_RENDER_MODE 9 +#define SNES_MENU_RAM_SETTINGS 10 +#define SNES_MENU_MMU_HACK 11 +#define SNES_MENU_AUTO_SAVE_SRAM 12 +#define SNES_MENU_LOAD_GLOBAL 13 +#define SNES_MENU_SAVE_GLOBAL 14 +#define SNES_MENU_DELETE_GLOBAL 15 +#define SNES_MENU_LOAD_CURRENT 16 +#define SNES_MENU_SAVE_CURRENT 17 +#define SNES_MENU_DELETE_CURRENT 18 +#define SNES_MENU_SET_ROMDIR 19 +#define SNES_MENU_RETURN 20 +#define SNES_MENU_COUNT 21 + +#define SAVESTATE_MENU_LOAD 0 +#define SAVESTATE_MENU_SAVE 1 +#define SAVESTATE_MENU_DELETE 2 +#define SAVESTATE_MENU_RETURN 3 +#define SAVESTATE_MENU_COUNT 4 + +#define SRAM_MENU_LOAD 0 +#define SRAM_MENU_SAVE 1 +#define SRAM_MENU_DELETE 2 +#define SRAM_MENU_RETURN 3 +#define SRAM_MENU_COUNT 4 + +#define EVENT_EXIT_APP 1 +#define EVENT_LOAD_SNES_ROM 2 +#define EVENT_RUN_SNES_ROM 3 +#define EVENT_RESET_SNES_ROM 4 + +#define RENDER_MODE_UNSCALED 0 +#define RENDER_MODE_SCALED 1 + +#define MENU_TILE_WIDTH 64 +#define MENU_TILE_HEIGHT 64 + +#define GP32_GCC + +#ifdef __GIZ__ +#define INP_BUTTON_MENU_SELECT INP_BUTTON_PLAY +#define INP_BUTTON_MENU_CANCEL INP_BUTTON_STOP +#define INP_BUTTON_MENU_ENTER INP_BUTTON_BRIGHT +#define INP_BUTTON_MENU_DELETE INP_BUTTON_REWIND +#define INP_BUTTON_MENU_QUICKSAVE1 INP_BUTTON_R +#define INP_BUTTON_MENU_QUICKSAVE2 INP_BUTTON_BRIGHT +#define INP_BUTTON_MENU_QUICKLOAD1 INP_BUTTON_L +#define INP_BUTTON_MENU_QUICKLOAD2 INP_BUTTON_BRIGHT + +//Menu Text +#define MENU_TEXT_LOAD_SAVESTATE "Press Play to load" +#define MENU_TEXT_OVERWRITE_SAVESTATE "Press Play to overwrite" +#define MENU_TEXT_DELETE_SAVESTATE "Press Play to delete" +#define MENU_TEXT_PREVIEW_SAVESTATE "Press R to preview" +#endif + +#ifdef __GP2X__ +#define INP_BUTTON_MENU_SELECT INP_BUTTON_B +#define INP_BUTTON_MENU_CANCEL INP_BUTTON_X +#define INP_BUTTON_MENU_ENTER INP_BUTTON_SELECT +#define INP_BUTTON_MENU_DELETE INP_BUTTON_SELECT +#define INP_BUTTON_MENU_QUICKSAVE1 INP_BUTTON_R +#define INP_BUTTON_MENU_QUICKSAVE2 INP_BUTTON_SELECT +#define INP_BUTTON_MENU_QUICKLOAD1 INP_BUTTON_L +#define INP_BUTTON_MENU_QUICKLOAD2 INP_BUTTON_SELECT + + +//Menu Text +#define MENU_TEXT_LOAD_SAVESTATE "Press B to load" +#define MENU_TEXT_OVERWRITE_SAVESTATE "Press B to overwrite" +#define MENU_TEXT_DELETE_SAVESTATE "Press B to delete" +#define MENU_TEXT_PREVIEW_SAVESTATE "Press Y to preview" +#endif + +#ifdef __IPHONE__ +#define INP_BUTTON_MENU_SELECT INP_BUTTON_HARDLEFT +#define INP_BUTTON_MENU_CANCEL INP_BUTTON_HARDDOWN +#define INP_BUTTON_MENU_ENTER INP_BUTTON_SELECT +#define INP_BUTTON_MENU_DELETE INP_BUTTON_SELECT +#define INP_BUTTON_MENU_QUICKSAVE1 INP_BUTTON_R +#define INP_BUTTON_MENU_QUICKSAVE2 INP_BUTTON_SELECT +#define INP_BUTTON_MENU_QUICKLOAD1 INP_BUTTON_L +#define INP_BUTTON_MENU_QUICKLOAD2 INP_BUTTON_SELECT + + +//Menu Text +#define MENU_TEXT_LOAD_SAVESTATE "Press B to load" +#define MENU_TEXT_OVERWRITE_SAVESTATE "Press B to overwrite" +#define MENU_TEXT_DELETE_SAVESTATE "Press B to delete" +#define MENU_TEXT_PREVIEW_SAVESTATE "Press Y to preview" +#endif + +typedef struct { + char name[MAX_ROMS][MAX_PATH]; // 128 entrys,16 Bytes long + int size[MAX_ROMS]; +} DIRDATA; + +//Graphics - moved to objects because they get updated with current gamma setting +extern unsigned short menuHeader[]; +extern unsigned short menuHeaderOrig[]; +extern unsigned short highLightBar[]; +extern unsigned short highLightBarOrig[]; +extern unsigned short menuTile[]; +extern unsigned short menuTileOrig[]; + +extern unsigned char padConfig[]; +extern float soundRates[]; +extern char currentWorkingDir[]; +extern char snesOptionsDir[]; +extern char snesSramDir[]; +extern char snesSaveStateDir[]; +extern unsigned char gammaConv[]; +extern char lastSaveName[]; +extern short *soundBuffer; +extern unsigned char *RomData; +extern int currentEmuMode; +extern int lastStage; +extern int currFB; +extern int prevFB; +extern int saveStateSize; +extern int romLoaded; +extern int frames,taken; // Frames and 60hz ticks +extern char showFps; +extern char soundRate; +extern char soundOn; + +void LoadStateFile(char *filename); +void SaveStateFile(char *filename); +void UpdateMenuGraphicsGamma(void); +int RoundDouble(double val); +void ClearScreen(unsigned int *buffer,unsigned int data); +void LoadSram(char *path,char *romname,char *ext,char *srammem); +void SaveSram(char *path,char *romname,char *ext,char *srammem); +void DeleteSram(char *path,char *romname,char *ext); +int SaveMenuOptions(char *path, char *filename, char *ext, char *optionsmem, int maxsize, int showMessage); +int LoadMenuOptions(char *path, char *filename, char *ext, char *optionsmem, int maxsize, int showMessage); +int DeleteMenuOptions(char *path, char *filename, char *ext, int showMessage); +void SnesDefaultMenuOptions(void); +#ifdef __GIZ__ +void sync(void); +#endif +// menu.cpp +void MenuPause(void); +void MenuFlip(void); +void SplitFilename(char *wholeFilename, char *filename, char *ext); +int FileSelect(int mode); +int MainMenu(int prevAction); +void PrintTitle(int flip); +void PrintTile(int flip); +void PrintBar(int flip, unsigned int givenY); + +int FileScan(); +extern void loadStateFile(char *filename); +extern int quickSavePresent; +extern unsigned short cpuSpeedLookup[]; +extern float gammaLookup[]; + +struct ROM_LIST_RECORD +{ + char filename[MAX_PATH+1]; + char type; +}; + +extern struct ROM_LIST_RECORD romList[]; +extern int currentRomIndex; +extern char currentRomFilename[]; +extern char romDir[]; +extern char snesRomDir[]; + +struct SNES_MENU_OPTIONS +{ + unsigned char menuVer; + unsigned char frameSkip; + unsigned char soundOn; + unsigned char cpuSpeed; + unsigned char padConfig[32]; + unsigned char tripleBuffer; + unsigned char forceRegion; + unsigned char showFps; + signed char gamma; + unsigned char lcdver; + unsigned char stereo; + unsigned char soundRate; + unsigned char autoSram; + unsigned char renderMode; + unsigned char volume; + unsigned char actionButtons; + unsigned char transparency; + unsigned char ramSettings; + unsigned char mmuHack; + unsigned char spare13; + unsigned char spare14; + unsigned char spare15; + unsigned char spare16; + unsigned char spare17; + unsigned char spare18; + unsigned char spare19; + unsigned char spare1A; + unsigned char spare1B; + unsigned char spare1C; + unsigned char spare1D; + unsigned char spare1E; + unsigned char spare1F; +}; + +extern struct SNES_MENU_OPTIONS snesMenuOptions; + +struct SAVE_STATE +{ + char filename[MAX_PATH+1]; + char fullFilename[MAX_PATH+1]; + unsigned int inUse; +}; + + +extern struct SAVE_STATE saveState[]; // holds the filenames for the savestate and "inuse" flags +extern char saveStateName[]; + +// Input.cpp +struct INPUT +{ + unsigned int held[32]; + unsigned int repeat[32]; +}; +extern struct INPUT Inp; + +int InputInit(); +int InputUpdate(int EnableDiagnals); + +#ifdef __cplusplus +} +#endif + +#endif /* _MENU_H_ */ + + + + + diff --git a/src/snes4iphone_src/menu_header.bmp b/src/snes4iphone_src/menu_header.bmp new file mode 100755 index 0000000..6066978 Binary files /dev/null and b/src/snes4iphone_src/menu_header.bmp differ diff --git a/src/snes4iphone_src/menu_header.psp b/src/snes4iphone_src/menu_header.psp new file mode 100755 index 0000000..48fccc6 Binary files /dev/null and b/src/snes4iphone_src/menu_header.psp differ diff --git a/src/snes4iphone_src/messages.h b/src/snes4iphone_src/messages.h new file mode 100755 index 0000000..96ef8d1 --- /dev/null +++ b/src/snes4iphone_src/messages.h @@ -0,0 +1,82 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#ifndef _messages_h_ +#define _messages_h_ + +/* Types of message sent to S9xMessage routine */ +enum { + S9X_TRACE, + S9X_DEBUG, + S9X_WARNING, + S9X_INFO, + S9X_ERROR, + S9X_FATAL_ERROR +}; + +/* Individual message numbers */ +enum { + S9X_ROM_INFO, + S9X_HEADERS_INFO, + S9X_ROM_CONFUSING_FORMAT_INFO, + S9X_ROM_INTERLEAVED_INFO, + S9X_SOUND_DEVICE_OPEN_FAILED, + S9X_APU_STOPPED, + S9X_USAGE, + S9X_GAME_GENIE_CODE_ERROR, + S9X_ACTION_REPLY_CODE_ERROR, + S9X_GOLD_FINGER_CODE_ERROR, + S9X_DEBUG_OUTPUT, + S9X_DMA_TRACE, + S9X_HDMA_TRACE, + S9X_WRONG_FORMAT, + S9X_WRONG_VERSION, + S9X_ROM_NOT_FOUND, + S9X_FREEZE_FILE_NOT_FOUND, + S9X_PPU_TRACE, + S9X_TRACE_DSP1, + S9X_FREEZE_ROM_NAME, + S9X_HEADER_WARNING, + S9X_NETPLAY_NOT_SERVER, + S9X_FREEZE_FILE_INFO, + S9X_TURBO_MODE +}; + +#endif diff --git a/src/snes4iphone_src/misc.s b/src/snes4iphone_src/misc.s new file mode 100755 index 0000000..1ef2e58 --- /dev/null +++ b/src/snes4iphone_src/misc.s @@ -0,0 +1,181 @@ +@ vim:filetype=armasm + +@ Generic memory routines. +@ (c) Copyright 2007, Grazvydas "notaz" Ignotas + + +.global memcpy16 @ unsigned short *dest, unsigned short *src, int count + +memcpy16: + eor r3, r0, r1 + tst r3, #2 + bne mcp16_cant_align + + tst r0, #2 + ldrneh r3, [r1], #2 + subne r2, r2, #1 + strneh r3, [r0], #2 + + subs r2, r2, #4 + bmi mcp16_fin + +mcp16_loop: + ldmia r1!, {r3,r12} + subs r2, r2, #4 + stmia r0!, {r3,r12} + bpl mcp16_loop + +mcp16_fin: + tst r2, #2 + ldrne r3, [r1], #4 + strne r3, [r0], #4 + ands r2, r2, #1 + bxeq lr + +mcp16_cant_align: + ldrh r3, [r1], #2 + subs r2, r2, #1 + strh r3, [r0], #2 + bne mcp16_cant_align + + bx lr + + + +@ 0x12345678 -> 0x34127856 +@ r4=temp, lr=0x00ff00ff +.macro bswap reg + and r4, \reg, lr + and \reg, lr, \reg, lsr #8 + orr \reg, \reg, r4, lsl #8 +.endm + + +@ dest must be halfword aligned, src can be unaligned +.global memcpy16bswap @ unsigned short *dest, void *src, int count + +memcpy16bswap: + tst r1, #1 + bne mcp16bs_cant_align2 + + eor r3, r0, r1 + tst r3, #2 + bne mcp16bs_cant_align + + tst r0, #2 + beq mcp16bs_aligned + ldrh r3, [r1], #2 + sub r2, r2, #1 + orr r3, r3, r3, lsl #16 + mov r3, r3, lsr #8 + strh r3, [r0], #2 + +mcp16bs_aligned: + stmfd sp!, {r4,lr} + mov lr, #0xff + orr lr, lr, lr, lsl #16 + + subs r2, r2, #4 + bmi mcp16bs_fin4 + +mcp16bs_loop: + ldmia r1!, {r3,r12} + subs r2, r2, #4 + bswap r3 + bswap r12 + stmia r0!, {r3,r12} + bpl mcp16bs_loop + +mcp16bs_fin4: + tst r2, #2 + beq mcp16bs_fin2 + ldr r3, [r1], #4 + bswap r3 + str r3, [r0], #4 + +mcp16bs_fin2: + ldmfd sp!, {r4,lr} + ands r2, r2, #1 + bxeq lr + +mcp16bs_cant_align: + ldrh r3, [r1], #2 + subs r2, r2, #1 + orr r3, r3, r3, lsl #16 + mov r3, r3, lsr #8 + strh r3, [r0], #2 + bne mcp16bs_cant_align + bx lr + + @ worst case +mcp16bs_cant_align2: + ldrb r3, [r1], #1 + ldrb r12,[r1], #1 + subs r2, r2, #1 + mov r3, r3, lsl #8 + orr r3, r3, r12 + strh r3, [r0], #2 + bne mcp16bs_cant_align2 + bx lr + + + +.global memcpy32 @ int *dest, int *src, int count + +memcpy32: + stmfd sp!, {r4,lr} + + subs r2, r2, #4 + bmi mcp32_fin + +mcp32_loop: + ldmia r1!, {r3,r4,r12,lr} + subs r2, r2, #4 + stmia r0!, {r3,r4,r12,lr} + bpl mcp32_loop + +mcp32_fin: + tst r2, #3 + ldmeqfd sp!, {r4,pc} + tst r2, #1 + ldrne r3, [r1], #4 + strne r3, [r0], #4 + +mcp32_no_unal1: + tst r2, #2 + ldmneia r1!, {r3,r12} + ldmfd sp!, {r4,lr} + stmneia r0!, {r3,r12} + bx lr + + + +.global memset32 @ int *dest, int c, int count + +memset32: + stmfd sp!, {lr} + + mov r3, r1 + subs r2, r2, #4 + bmi mst32_fin + + mov r12,r1 + mov lr, r1 + +mst32_loop: + subs r2, r2, #4 + stmia r0!, {r1,r3,r12,lr} + bpl mst32_loop + +mst32_fin: + tst r2, #1 + strne r1, [r0], #4 + + tst r2, #2 + stmneia r0!, {r1,r3} + + ldmfd sp!, {lr} + bx lr + + + diff --git a/src/snes4iphone_src/missing.h b/src/snes4iphone_src/missing.h new file mode 100755 index 0000000..804f8b5 --- /dev/null +++ b/src/snes4iphone_src/missing.h @@ -0,0 +1,114 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#ifndef _MISSING_H_ +#define _MISSING_H_ + +struct HDMA +{ + uint8 used; + uint8 bbus_address; + uint8 abus_bank; + uint16 abus_address; + uint8 indirect_address; + uint8 force_table_address_write; + uint8 force_table_address_read; + uint8 line_count_write; + uint8 line_count_read; +}; + +struct Missing +{ + uint8 emulate6502; + uint8 decimal_mode; + uint8 mv_8bit_index; + uint8 mv_8bit_acc; + uint8 interlace; + uint8 lines_239; + uint8 pseudo_512; + struct HDMA hdma [8]; + uint8 modes [8]; + uint8 mode7_fx; + uint8 mode7_flip; + uint8 mode7_bgmode; + uint8 direct; + uint8 matrix_multiply; + uint8 oam_read; + uint8 vram_read; + uint8 cgram_read; + uint8 wram_read; + uint8 dma_read; + uint8 vram_inc; + uint8 vram_full_graphic_inc; + uint8 virq; + uint8 hirq; + uint16 virq_pos; + uint16 hirq_pos; + uint8 h_v_latch; + uint8 h_counter_read; + uint8 v_counter_read; + uint8 fast_rom; + uint8 window1 [6]; + uint8 window2 [6]; + uint8 sprite_priority_rotation; + uint8 subscreen; + uint8 subscreen_add; + uint8 subscreen_sub; + uint8 fixed_colour_add; + uint8 fixed_colour_sub; + uint8 mosaic; + uint8 sprite_double_height; + uint8 dma_channels; + uint8 dma_this_frame; + uint8 oam_address_read; + uint8 bg_offset_read; + uint8 matrix_read; + uint8 hdma_channels; + uint8 hdma_this_frame; + uint16 unknownppu_read; + uint16 unknownppu_write; + uint16 unknowncpu_read; + uint16 unknowncpu_write; + uint16 unknowndsp_read; + uint16 unknowndsp_write; +}; + +EXTERN_C struct Missing missing; +#endif diff --git a/src/snes4iphone_src/mmuhack.c b/src/snes4iphone_src/mmuhack.c new file mode 100755 index 0000000..00bc8e1 --- /dev/null +++ b/src/snes4iphone_src/mmuhack.c @@ -0,0 +1,344 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern int errno; + +int memfd; + +void *trymmap (void *start, size_t length, int prot, int flags, int fd, off_t offset) +{ + char *p; + int aa; + + //printf ("mmap(%X, %X, %X, %X, %X, %X) ... ", (unsigned int)start, length, prot, flags, fd, (unsigned int)offset); + p = mmap (start, length, prot, flags, fd, offset); + if (p == (char *)0xFFFFFFFF) + { + aa = errno; + printf ("failed mmap(%X, %X, %X, %X, %X, %X) errno = %d\n", (unsigned int)start, length, prot, flags, fd, (unsigned int)offset, aa); + } + else + { + //printf ("OK! (%X)\n", (unsigned int)p); + } + + return p; +} + +unsigned char initphys (void) +{ + memfd = open("/dev/mem", O_RDWR); + if (memfd == -1) + { + printf ("Open failed\n"); + return 0; + } + + printf ("/dev/mem opened successfully - fd = %d\n", memfd); + + return 1; +} + +void closephys (void) +{ + close (memfd); +} + +int myuname(char *buffer) +{ + asm volatile ("swi #0x90007a"); +} + +void DecodeCoarse (unsigned int indx, unsigned int sa) +{ + unsigned int cpt[256]; + unsigned int dom = (sa >> 5) & 15; + unsigned int temp; + unsigned int i = 0; + unsigned int wb = 0; + + sa &= 0xfffffc00; + indx *= 1048576; + + //printf (" > %08X\n", sa); + //printf ("%d\n", + lseek (memfd, sa, SEEK_SET); + memset (cpt, 0, 256*4); + temp = read (memfd, cpt, 256*4); + //printf ("%d\n", temp); + if (temp != 256*4) + { + printf (" # Bad read\n"); + return; + } + + //printf ("%08X %08X %08X %08X\n", cpt[0], cpt[4], cpt[8], cpt[12]); + + for (i = 0; i < 256; i ++) + { + if (cpt[i]) + { + switch (cpt[i] & 3) + { + case 0: + //printf (" -- [%08X] Invalid --\n", cpt[i]); + break; + case 1: + printf (" VA: %08X PA: %08X - %08X A: %d %d %d %d D: %d C: %d B: %d\n", indx, + cpt[i] & 0xFFFF0000, (cpt[i] & 0xFFFF0000) | 0xFFFF, + (cpt[i] >> 10) & 3, (cpt[i] >> 8) & 3, (cpt[i] >> 6) & 3, + (cpt[i] >> 4) & 3, dom, (cpt[i] >> 3) & 1, (cpt[i] >> 2) & 1); + break; + case 2: + printf (" VA: %08X PA: %08X - %08X A: %d %d %d %d D: %d C: %d B: %d\n", indx, + cpt[i] & 0xfffff000, (cpt[i] & 0xfffff000) | 0xFFF, + (cpt[i] >> 10) & 3, (cpt[i] >> 8) & 3, (cpt[i] >> 6) & 3, + (cpt[i] >> 4) & 3, dom, (cpt[i] >> 3) & 1, (cpt[i] >> 2) & 1); + // This is where we look for any virtual addresses that map to physical address 0x03000000 and + // alter the cachable and bufferable bits... + /*if (((cpt[i] & 0xffff0000) == 0x03000000) && ((cpt[i] & 12)==0)) + { + //printf("c and b bits not set, overwriting\n"); + cpt[i] |= 0xFFC; + wb = 1; + }*/ + if (((cpt[i] & 0xff000000) == 0x02000000) ) + { + //printf("SOUND c and b bits not set, overwriting\n"); + if((cpt[i] & 12)==0) { + cpt[i] |= 0xFFC; + wb++; + } + } + //if ((a>=0x31 && a<=0x36) && ((cpt[i] & 12)==0)) + if (((cpt[i] & 0xff000000) == 0x03000000) ) + { + //printf("SDL c and b bits not set, overwriting\n"); + if((cpt[i] & 12)==0) { + cpt[i] |= 0xFFC; + wb++; + } + } + break; + case 3: + //printf (" -- [%08X/%d] Unsupported --\n", cpt[i],cpt[i] & 3); + break; + default: + //printf (" -- [%08X/%d] Unknown --\n", cpt[i], cpt[i] & 3); + break; + } + } + indx += 4096; + } + //printf ("%08X %08X %08X %08X\n", cpt[0], cpt[4], cpt[8], cpt[12]); + if (wb) + { + //printf("Hacking cpt\n"); + lseek (memfd, sa, SEEK_SET); + temp = write (memfd, cpt, 256*4); + printf("%d bytes written, %s\n", temp, temp == 1024 ? "yay!" : "oh fooble :(!"); + } +} + +void dumppgtable (unsigned int ttb) +{ + unsigned int pgtable[4096]; + char *desctypes[] = {"Invalid", "Coarse", "Section", "Fine"}; + + memset (pgtable, 0, 4096*4); + lseek (memfd, ttb, SEEK_SET); + read (memfd, pgtable, 4096*4); + + int i; + for (i = 0; i < 4096; i ++) + { + int temp; + + if (pgtable[i]) + { + printf ("Indx: %d VA: %08X Type: %d [%s] \n", i, i * 1048576, pgtable[i] & 3, desctypes[pgtable[i]&3]); + switch (pgtable[i]&3) + { + case 0: + //printf (" -- Invalid --\n"); + break; + case 1: + DecodeCoarse(i, pgtable[i]); + break; + case 2: + temp = pgtable[i] & 0xFFF00000; + //printf (" PA: %08X - %08X A: %d D: %d C: %d B: %d\n", temp, temp | 0xFFFFF, + // (pgtable[i] >> 10) & 3, (pgtable[i] >> 5) & 15, (pgtable[i] >> 3) & 1, + // (pgtable[i] >> 2) & 1); + + break; + case 3: + printf (" -- Unsupported! --\n"); + break; + } + } + } +} + +void benchmark (void *memptr) +{ + int starttime = time (NULL); + int a,b,c,d; + volatile unsigned int *pp = (unsigned int *) memptr; + + while (starttime == time (NULL)); + + printf ("\n\nmemory benchmark of volatile VA: %08X\n\nread test\n", memptr); + for (d = 0; d < 3; d ++) + { + starttime = time (NULL); + b = 0; + c = 0; + while (starttime == time (NULL)) + { + for (a = 0; a < 20000; a ++) + { + b += pp[a]; + } + c ++; + } + printf ("Count is %d. %dMB/sec\n", c, (c * 20000)/1024/1024); + } + + printf ("write test\n"); + for (d = 0; d < 3; d ++) + { + starttime = time (NULL); + b = 0; + c = 0; + while (starttime == time (NULL)) + { + for (a = 0; a < 20000; a ++) + { + pp[a] = 0x37014206; + } + c ++; + } + printf ("Count is %d. %dMB/sec\n", c, (c * 20000)/1024/1024); + } + + printf ("combined test (read, write back)\n"); + for (d = 0; d < 3; d ++) + { + starttime = time (NULL); + b = 0; + c = 0; + while (starttime == time (NULL)) + { + for (a = 0; a < 20000; a ++) + { + pp[a] += 0x55017601; + } + c ++; + } + printf ("Count is %d. %dMB/sec\n", c, (c * 20000)/1024/1024); + } + + printf ("test complete\n"); +} + +void hackpgtable (void) +{ + unsigned int oldc1, oldc2, oldc3, oldc4; + unsigned int newc1 = 0xee120f10, newc2 = 0xe12fff1e; + unsigned int ttb, ttx; + char name[256]; + + // We need to execute a "MRC p15, 0, r0, c2, c0, 0", to get the pointer to the translation table base, but we can't + // do this in user mode, so we have to patch the kernel to get it to run it for us in supervisor mode. We do this + // at the moment by overwriting the sys_newuname function and then calling it. + + lseek (memfd, 0x6ec00, SEEK_SET); // fixme: We should ask the kernel for this address rather than assuming it... + read (memfd, &oldc1, 4); + read (memfd, &oldc2, 4); + read (memfd, &oldc3, 4); + read (memfd, &oldc4, 4); + + printf ("0:%08X %08X\n", oldc1, oldc2); + + lseek (memfd, 0x6ec00, SEEK_SET); + write (memfd, &newc1, 4); + write (memfd, &newc2, 4); + + ttb = myuname(name); + + lseek (memfd, 0x6ec00, SEEK_SET); + write (memfd, &oldc1, 4); + write (memfd, &oldc2, 4); + + printf ("1:%08X\n", ttb); + + //printf ("Restored contents\n"); + + // We now have the translation table base ! Walk the table looking for our allocation and hack it :) + dumppgtable(ttb); + + // Now drain the write buffer and flush the tlb caches. Something else we can't do in user mode... + unsigned int tlbc1 = 0xe3a00000; // mov r0, #0 + unsigned int tlbc2 = 0xee070f9a; // mcr 15, 0, r0, cr7, cr10, 4 + unsigned int tlbc3 = 0xee080f17; // mcr 15, 0, r0, cr8, cr7, 0 + unsigned int tlbc4 = 0xe1a0f00e; // mov pc, lr + + lseek (memfd, 0x6ec00, SEEK_SET); + write (memfd, &tlbc1, 4); + write (memfd, &tlbc2, 4); + write (memfd, &tlbc3, 4); + write (memfd, &tlbc4, 4); + + ttx = myuname(name); + + //printf ("Return from uname: %08X\n", ttx); + + lseek (memfd, 0x6ec00, SEEK_SET); + write (memfd, &oldc1, 4); + write (memfd, &oldc2, 4); + write (memfd, &oldc3, 4); + write (memfd, &oldc4, 4); + + //printf ("Restored contents\n"); + + //printf ("Pagetable after modification!\n"); + //printf ("-------------------------------\n"); + //dumppgtable(ttb); +} + +/*int +main( int argc, char* argv[] ) +{ + if (!initphys()) + return 0; + + volatile unsigned int *myBuf = trymmap((void *)0, 65536, PROT_READ | PROT_WRITE, MAP_SHARED, memfd, 0x03000000); + volatile unsigned int *secbuf = (unsigned int *)malloc (204800); + + //memset ((void *)myBuf, 0x55, 65536); + //memset ((void *)secbuf, 0x55, 65536); + + printf("mmaped 0x03000000 buffer @ VA: %08X malloc'd buffer @ VA: %08X\n", myBuf, secbuf); + + hackpgtable(); + + //benchmark ((void*)myBuf); + //benchmark ((void*)secbuf); + +///////////////////////////////////////////////////////////////////////////////////////////////////////////// + printf ("\n\nCleaning up...\n"); + printf ("Closing files...\n"); + close (memfd); + printf ("Exiting...\n"); + + return 0; +} */ \ No newline at end of file diff --git a/src/snes4iphone_src/movie.cpp b/src/snes4iphone_src/movie.cpp new file mode 100755 index 0000000..518cd82 --- /dev/null +++ b/src/snes4iphone_src/movie.cpp @@ -0,0 +1,786 @@ +/******************************************************************************* + Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and + Jerremy Koot (jkoot@snes9x.com) + + (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net) + + (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net), + funkyass (funkyass@spam.shaw.ca), + Joel Yliluoma (http://iki.fi/bisqwit/) + Kris Bleakley (codeviolation@hotmail.com), + Matthew Kendora, + Nach (n-a-c-h@users.sourceforge.net), + Peter Bortas (peter@bortas.org) and + zones (kasumitokoduck@yahoo.com) + + C4 x86 assembler and some C emulation code + (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com), + _Demo_ (_demo_@zsnes.com), and Nach + + C4 C++ code + (c) Copyright 2003 Brad Jorsch + + DSP-1 emulator code + (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson, + John Weidman, neviksti (neviksti@hotmail.com), + Kris Bleakley, Andreas Naive + + DSP-2 emulator code + (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and + Lord Nightmare (lord_nightmare@users.sourceforge.net + + OBC1 emulator code + (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and + Kris Bleakley + Ported from x86 assembler to C by sanmaiwashi + + SPC7110 and RTC C++ emulator code + (c) Copyright 2002 Matthew Kendora with research by + zsKnight, John Weidman, and Dark Force + + S-DD1 C emulator code + (c) Copyright 2003 Brad Jorsch with research by + Andreas Naive and John Weidman + + S-RTC C emulator code + (c) Copyright 2001 John Weidman + + ST010 C++ emulator code + (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora + + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + + Super FX C emulator code + (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman + + + SH assembler code partly based on x86 assembler code + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + + Input recording/playback code + (c) Copyright 2004 blip + + Specific ports contains the works of other authors. See headers in + individual files. + + Snes9x homepage: http://www.snes9x.com + + Permission to use, copy, modify and distribute Snes9x in both binary and + source form, for non-commercial purposes, is hereby granted without fee, + providing that this license information and copyright notice appear with + all copies and any derived work. + + This software is provided 'as-is', without any express or implied + warranty. In no event shall the authors be held liable for any damages + arising from the use of this software. + + Snes9x is freeware for PERSONAL USE only. Commercial users should + seek permission of the copyright holders first. Commercial use includes + charging money for Snes9x or software derived from Snes9x. + + The copyright holders request that bug fixes and improvements to the code + should be forwarded to them so everyone can benefit from the modifications + in future versions. + + Super NES and Super Nintendo Entertainment System are trademarks of + Nintendo Co., Limited and its subsidiary companies. +*******************************************************************************/ +#include "port.h" +#include +#ifdef HAVE_STRINGS_H +#include +#endif +#include +#include + +#if defined(__unix) || defined(__linux) || defined(__sun) || defined(__DJGPP) +#include +#include +#include +#endif +#include + +#ifdef WIN32 +#include +#ifndef W_OK +#define W_OK 2 +#endif +#endif + +#include "movie.h" +#include "snes9x.h" +#include "cpuexec.h" +#include "snapshot.h" + +#define SMV_MAGIC 0x1a564d53 // SMV0x1a +#define SMV_VERSION 1 +#define SMV_HEADER_SIZE 32 +#define CONTROLLER_DATA_SIZE 2 +#define BUFFER_GROWTH_SIZE 4096 + +enum MovieState +{ + MOVIE_STATE_NONE=0, + MOVIE_STATE_PLAY, + MOVIE_STATE_RECORD +}; + +static struct SMovie +{ + enum MovieState State; + char Filename [_MAX_PATH]; + FILE* File; + uint32 SaveStateOffset; + uint32 ControllerDataOffset; + uint32 MovieId; + uint32 CurrentFrame; + uint32 MaxFrame; + uint32 RerecordCount; + uint8 ControllersMask; + uint8 Opts; + bool8 ReadOnly; + uint32 BytesPerFrame; + uint8* InputBuffer; + uint32 InputBufferSize; + uint8* InputBufferPtr; + bool8 FrameDisplay; + char FrameDisplayString[256]; +} Movie; + +/* + For illustration: +struct MovieFileHeader +{ + uint32 magic; // SMV0x1a + uint32 version; + uint32 uid; // used to match savestates to a particular movie + uint32 rerecord_count; + uint32 length_frames; + uint8 flags[4]; + uint32 offset_to_savestate; // smvs have an embedded savestate + uint32 offset_to_controller_data; + // after the header comes extra metadata + // sizeof(metadata) = offset_to_savestate - sizeof(MovieFileHeader) +}; +*/ + +static int bytes_per_frame() +{ + int i; + int num_controllers; + + num_controllers=0; + for(i=0; i<5; ++i) + { + if(Movie.ControllersMask & (1<>8)&0xff); + ptr[2]=(uint8)((v>>16)&0xff); + ptr[3]=(uint8)((v>>24)&0xff); + ptr += 4; +} + +static void Write16(uint16 v, uint8*& ptr) +{ + ptr[0]=(uint8)(v&0xff); + ptr[1]=(uint8)((v>>8)&0xff); + ptr += 2; +} + +static int read_movie_header(FILE* fd, SMovie* movie) +{ + uint8 header[SMV_HEADER_SIZE]; + if(fread(header, 1, SMV_HEADER_SIZE, fd) != SMV_HEADER_SIZE) + return WRONG_FORMAT; + + const uint8* ptr=header; + uint32 magic=Read32(ptr); + if(magic!=SMV_MAGIC) + return WRONG_FORMAT; + + uint32 version=Read32(ptr); + if(version!=SMV_VERSION) + return WRONG_VERSION; + + movie->MovieId=Read32(ptr); + movie->RerecordCount=Read32(ptr); + movie->MaxFrame=Read32(ptr); + + movie->ControllersMask=*ptr++; + movie->Opts=*ptr++; + ptr += 2; + + movie->SaveStateOffset=Read32(ptr); + movie->ControllerDataOffset=Read32(ptr); + + return SUCCESS; +} + +static void write_movie_header(FILE* fd, const SMovie* movie) +{ + uint8 header[SMV_HEADER_SIZE]; + uint8* ptr=header; + + Write32(SMV_MAGIC, ptr); + Write32(SMV_VERSION, ptr); + Write32(movie->MovieId, ptr); + Write32(movie->RerecordCount, ptr); + Write32(movie->MaxFrame, ptr); + + *ptr++=movie->ControllersMask; + *ptr++=movie->Opts; + *ptr++=0; + *ptr++=0; + + Write32(movie->SaveStateOffset, ptr); + Write32(movie->ControllerDataOffset, ptr); + + fwrite(header, 1, SMV_HEADER_SIZE, fd); +} + +static void flush_movie() +{ + fseek(Movie.File, 0, SEEK_SET); + write_movie_header(Movie.File, &Movie); + fseek(Movie.File, Movie.ControllerDataOffset, SEEK_SET); + fwrite(Movie.InputBuffer, 1, Movie.BytesPerFrame*(Movie.MaxFrame+1), Movie.File); +} + +static void change_state(MovieState new_state) +{ + if(new_state==Movie.State) + return; + + if(Movie.State==MOVIE_STATE_RECORD) + { + flush_movie(); + } + + Movie.State=new_state; + + if(new_state==MOVIE_STATE_NONE) + { + fclose(Movie.File); + Movie.File=NULL; + // FIXME: truncate movie to MaxFrame length + /* truncate() could be used, if it's certain + * that the savestate block is never after + * the controller data block. It is not guaranteed + * by the format. + */ + } +} + +static void reserve_buffer_space(uint32 space_needed) +{ + if(space_needed > Movie.InputBufferSize) + { + uint32 ptr_offset = Movie.InputBufferPtr - Movie.InputBuffer; + uint32 alloc_chunks = space_needed / BUFFER_GROWTH_SIZE; + Movie.InputBufferSize = BUFFER_GROWTH_SIZE * (alloc_chunks+1); + Movie.InputBuffer = (uint8*)realloc(Movie.InputBuffer, Movie.InputBufferSize); + Movie.InputBufferPtr = Movie.InputBuffer + ptr_offset; + } +} + +static void read_frame_controller_data() +{ + int i; + for(i=0; i<5; ++i) + { + if(Movie.ControllersMask & (1<MOVIE_MAX_METADATA) + { + metadata_length=MOVIE_MAX_METADATA; + } + + Movie.MovieId=(uint32)time(NULL); + Movie.RerecordCount=0; + Movie.MaxFrame=0; + Movie.SaveStateOffset=SMV_HEADER_SIZE+(sizeof(uint16)*metadata_length); + Movie.ControllerDataOffset=0; + Movie.ControllersMask=controllers_mask; + Movie.Opts=opts; + if(Settings.PAL) + { + Movie.Opts |= MOVIE_OPT_PAL; + } + else + { + Movie.Opts &= ~MOVIE_OPT_PAL; + } + + write_movie_header(fd, &Movie); + + // convert wchar_t metadata string/array to a uint16 array + if(metadata_length>0) + { + uint8 meta_buf[MOVIE_MAX_METADATA * sizeof(uint16)]; + int i; + + for(i=0; i>8)&0xff); + } + + fwrite(meta_buf, sizeof(uint16), metadata_length, fd); + } + + // write snapshot + fn=dup(fileno(fd)); + fclose(fd); + + // lseek(fn, Movie.SaveStateOffset, SEEK_SET); + if(!(stream=REOPEN_STREAM(fn, "ab"))) + return FILE_NOT_FOUND; + + if(opts & MOVIE_OPT_FROM_RESET) + { + S9xReset(); + // save only SRAM for a from-reset snapshot + WRITE_STREAM(SRAM, 0x20000, stream); + } + else + { + S9xFreezeToStream(stream); + } + CLOSE_STREAM(stream); + + if(!(fd=fopen(filename, "rb+"))) + return FILE_NOT_FOUND; + + fseek(fd, 0, SEEK_END); + Movie.ControllerDataOffset=(uint32)ftell(fd); + + // write "baseline" controller data + Movie.File=fd; + Movie.BytesPerFrame=bytes_per_frame(); + Movie.InputBufferPtr=Movie.InputBuffer; + write_frame_controller_data(); + + strncpy(Movie.Filename, filename, _MAX_PATH); + Movie.Filename[_MAX_PATH-1]='\0'; + Movie.CurrentFrame=0; + Movie.ReadOnly=false; + change_state(MOVIE_STATE_RECORD); + + S9xMessage(S9X_INFO, S9X_MOVIE_INFO, MOVIE_INFO_RECORD); + return SUCCESS; +#endif +} + +void S9xMovieUpdate () +{ + switch(Movie.State) + { + case MOVIE_STATE_PLAY: + if(Movie.CurrentFrame>=Movie.MaxFrame) + { + change_state(MOVIE_STATE_NONE); + S9xMessage(S9X_INFO, S9X_MOVIE_INFO, MOVIE_INFO_END); + return; + } + else + { + if(Movie.FrameDisplay) + { + sprintf(Movie.FrameDisplayString, "Playing frame: %d", Movie.CurrentFrame); + S9xMessage (S9X_INFO, S9X_MOVIE_INFO, Movie.FrameDisplayString); + } + read_frame_controller_data(); + ++Movie.CurrentFrame; + } + break; + + case MOVIE_STATE_RECORD: + { + if(Movie.FrameDisplay) + { + sprintf(Movie.FrameDisplayString, "Recording frame: %d", Movie.CurrentFrame); + S9xMessage (S9X_INFO, S9X_MOVIE_INFO, Movie.FrameDisplayString); + } + write_frame_controller_data(); + ++Movie.CurrentFrame; + Movie.MaxFrame=Movie.CurrentFrame; + fwrite((Movie.InputBufferPtr - Movie.BytesPerFrame), 1, Movie.BytesPerFrame, Movie.File); + } + break; + + default: + break; + } +} + +void S9xMovieStop (bool8 suppress_message) +{ + if(Movie.State!=MOVIE_STATE_NONE) + { + change_state(MOVIE_STATE_NONE); + + if(!suppress_message) + S9xMessage(S9X_INFO, S9X_MOVIE_INFO, MOVIE_INFO_STOP); + } +} + +int S9xMovieGetInfo (const char* filename, struct MovieInfo* info) +{ + FILE* fd; + int result; + SMovie local_movie; + int metadata_length; + + return FILE_NOT_FOUND; +#if 0 + + memset(info, 0, sizeof(*info)); + if(!(fd=fopen(filename, "rb"))) + return FILE_NOT_FOUND; + + if((result=(read_movie_header(fd, &local_movie)))!=SUCCESS) + return result; + + info->TimeCreated=(time_t)local_movie.MovieId; + info->LengthFrames=local_movie.MaxFrame; + info->RerecordCount=local_movie.RerecordCount; + info->Opts=local_movie.Opts; + info->ControllersMask=local_movie.ControllersMask; + + if(local_movie.SaveStateOffset > SMV_HEADER_SIZE) + { + uint8 meta_buf[MOVIE_MAX_METADATA * sizeof(uint16)]; + int i; + + metadata_length=((int)local_movie.SaveStateOffset-SMV_HEADER_SIZE)/sizeof(uint16); + metadata_length=(metadata_length>=MOVIE_MAX_METADATA) ? MOVIE_MAX_METADATA-1 : metadata_length; + metadata_length=(int)fread(meta_buf, sizeof(uint16), metadata_length, fd); + + for(i=0; iMetadata[i]=(wchar_t)c; + } + info->Metadata[i]='\0'; + } + else + { + info->Metadata[0]='\0'; + } + + fclose(fd); + + if(access(filename, W_OK)) + info->ReadOnly=true; + + return SUCCESS; +#endif +} + +bool8 S9xMovieActive () +{ + return (Movie.State!=MOVIE_STATE_NONE); +} + +bool8 S9xMovieReadOnly () +{ + if(!S9xMovieActive()) + return false; + + return Movie.ReadOnly; +} + +uint32 S9xMovieGetId () +{ + if(!S9xMovieActive()) + return 0; + + return Movie.MovieId; +} + +uint32 S9xMovieGetLength () +{ + if(!S9xMovieActive()) + return 0; + + return Movie.MaxFrame; +} + +uint32 S9xMovieGetFrameCounter () +{ + if(!S9xMovieActive()) + return 0; + + return Movie.CurrentFrame; +} + +void S9xMovieToggleFrameDisplay () +{ + Movie.FrameDisplay = !Movie.FrameDisplay; + if(!Movie.FrameDisplay) + { + GFX.InfoStringTimeout = 1; + } +} + +void S9xMovieFreeze (uint8** buf, uint32* size) +{ + // sanity check + if(!S9xMovieActive()) + { + return; + } + + *buf = NULL; + *size = 0; + + // compute size needed for the buffer + uint32 size_needed = 4*3; // room for MovieId, CurrentFrame, and MaxFrame + size_needed += (uint32)(Movie.BytesPerFrame * (Movie.MaxFrame+1)); + *buf=new uint8[size_needed]; + *size=size_needed; + + uint8* ptr = *buf; + if(!ptr) + { + return; + } + + Write32(Movie.MovieId, ptr); + Write32(Movie.CurrentFrame, ptr); + Write32(Movie.MaxFrame, ptr); + + memcpy(ptr, Movie.InputBuffer, Movie.BytesPerFrame * (Movie.MaxFrame+1)); +} + +bool8 S9xMovieUnfreeze (const uint8* buf, uint32 size) +{ + // sanity check + if(!S9xMovieActive()) + { + return false; + } + + const uint8* ptr = buf; + if(size < 4*3) + { + return false; + } + + uint32 movie_id = Read32(ptr); + uint32 current_frame = Read32(ptr); + uint32 max_frame = Read32(ptr); + uint32 space_needed = (Movie.BytesPerFrame * (max_frame+1)); + + if(movie_id != Movie.MovieId || + current_frame > max_frame || + space_needed > size) + { + return false; + } + + if(!Movie.ReadOnly) + { + // here, we are going to take the input data from the savestate + // and make it the input data for the current movie, then continue + // writing new input data at the currentframe pointer + change_state(MOVIE_STATE_RECORD); + S9xMessage(S9X_INFO, S9X_MOVIE_INFO, MOVIE_INFO_RERECORD); + + Movie.CurrentFrame = current_frame; + Movie.MaxFrame = max_frame; + ++Movie.RerecordCount; + + reserve_buffer_space(space_needed); + memcpy(Movie.InputBuffer, ptr, space_needed); + flush_movie(); + fseek(Movie.File, Movie.ControllerDataOffset+(Movie.BytesPerFrame * (Movie.CurrentFrame+1)), SEEK_SET); + } + else + { + // here, we are going to keep the input data from the movie file + // and simply rewind to the currentframe pointer + // this will cause a desync if the savestate is not in sync + // with the on-disk recording data, but it's easily solved + // by loading another savestate or playing the movie from the beginning + + // and older savestate might have a currentframe pointer past + // the end of the input data, so check for that here + if(current_frame > Movie.MaxFrame) + { + return false; + } + + change_state(MOVIE_STATE_PLAY); + S9xMessage(S9X_INFO, S9X_MOVIE_INFO, MOVIE_INFO_REWIND); + + Movie.CurrentFrame = current_frame; + } + + Movie.InputBufferPtr = Movie.InputBuffer + (Movie.BytesPerFrame * Movie.CurrentFrame); + read_frame_controller_data(); + + return true; +} diff --git a/src/snes4iphone_src/movie.h b/src/snes4iphone_src/movie.h new file mode 100755 index 0000000..3c5684e --- /dev/null +++ b/src/snes4iphone_src/movie.h @@ -0,0 +1,146 @@ +/******************************************************************************* + Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and + Jerremy Koot (jkoot@snes9x.com) + + (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net) + + (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net), + funkyass (funkyass@spam.shaw.ca), + Joel Yliluoma (http://iki.fi/bisqwit/) + Kris Bleakley (codeviolation@hotmail.com), + Matthew Kendora, + Nach (n-a-c-h@users.sourceforge.net), + Peter Bortas (peter@bortas.org) and + zones (kasumitokoduck@yahoo.com) + + C4 x86 assembler and some C emulation code + (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com), + _Demo_ (_demo_@zsnes.com), and Nach + + C4 C++ code + (c) Copyright 2003 Brad Jorsch + + DSP-1 emulator code + (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson, + John Weidman, neviksti (neviksti@hotmail.com), + Kris Bleakley, Andreas Naive + + DSP-2 emulator code + (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and + Lord Nightmare (lord_nightmare@users.sourceforge.net + + OBC1 emulator code + (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and + Kris Bleakley + Ported from x86 assembler to C by sanmaiwashi + + SPC7110 and RTC C++ emulator code + (c) Copyright 2002 Matthew Kendora with research by + zsKnight, John Weidman, and Dark Force + + S-DD1 C emulator code + (c) Copyright 2003 Brad Jorsch with research by + Andreas Naive and John Weidman + + S-RTC C emulator code + (c) Copyright 2001 John Weidman + + ST010 C++ emulator code + (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora + + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + + Super FX C emulator code + (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman + + + SH assembler code partly based on x86 assembler code + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + + Input recording/playback code + (c) Copyright 2004 blip + + Specific ports contains the works of other authors. See headers in + individual files. + + Snes9x homepage: http://www.snes9x.com + + Permission to use, copy, modify and distribute Snes9x in both binary and + source form, for non-commercial purposes, is hereby granted without fee, + providing that this license information and copyright notice appear with + all copies and any derived work. + + This software is provided 'as-is', without any express or implied + warranty. In no event shall the authors be held liable for any damages + arising from the use of this software. + + Snes9x is freeware for PERSONAL USE only. Commercial users should + seek permission of the copyright holders first. Commercial use includes + charging money for Snes9x or software derived from Snes9x. + + The copyright holders request that bug fixes and improvements to the code + should be forwarded to them so everyone can benefit from the modifications + in future versions. + + Super NES and Super Nintendo Entertainment System are trademarks of + Nintendo Co., Limited and its subsidiary companies. +*******************************************************************************/ +#ifndef _MOVIE_H_ +#define _MOVIE_H_ + +#include +#include +#include "snes9x.h" + +#ifndef SUCCESS +# define SUCCESS 1 +# define WRONG_FORMAT (-1) +# define WRONG_VERSION (-2) +# define FILE_NOT_FOUND (-3) +#endif + +#define MOVIE_OPT_FROM_SNAPSHOT 0 +#define MOVIE_OPT_FROM_RESET (1<<0) +#define MOVIE_OPT_PAL (1<<1) +#define MOVIE_MAX_METADATA 512 + +START_EXTERN_C +struct MovieInfo +{ + time_t TimeCreated; + uint32 LengthFrames; + uint32 RerecordCount; + wchar_t Metadata[MOVIE_MAX_METADATA]; // really should be wchar_t + uint8 Opts; + uint8 ControllersMask; + bool8 ReadOnly; +}; + +// methods used by the user-interface code +int S9xMovieOpen (const char* filename, bool8 read_only); +int S9xMovieCreate (const char* filename, uint8 controllers_mask, uint8 opts, const wchar_t* metadata, int metadata_length); +int S9xMovieGetInfo (const char* filename, struct MovieInfo* info); +void S9xMovieStop (bool8 suppress_message); +void S9xMovieToggleFrameDisplay (); + +// methods used by the emulation +void S9xMovieInit (); +void S9xMovieUpdate (); +//bool8 S9xMovieRewind (uint32 at_frame); +void S9xMovieFreeze (uint8** buf, uint32* size); +bool8 S9xMovieUnfreeze (const uint8* buf, uint32 size); + +// accessor functions +bool8 S9xMovieActive (); +// the following accessors return 0/false if !S9xMovieActive() +bool8 S9xMovieReadOnly (); +uint32 S9xMovieGetId (); +uint32 S9xMovieGetLength (); +uint32 S9xMovieGetFrameCounter (); + +END_EXTERN_C + +#endif diff --git a/src/snes4iphone_src/netplay.h b/src/snes4iphone_src/netplay.h new file mode 100755 index 0000000..287da9c --- /dev/null +++ b/src/snes4iphone_src/netplay.h @@ -0,0 +1,282 @@ +/******************************************************************************* + Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and + Jerremy Koot (jkoot@snes9x.com) + + (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net) + + (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net), + funkyass (funkyass@spam.shaw.ca), + Joel Yliluoma (http://iki.fi/bisqwit/) + Kris Bleakley (codeviolation@hotmail.com), + Matthew Kendora, + Nach (n-a-c-h@users.sourceforge.net), + Peter Bortas (peter@bortas.org) and + zones (kasumitokoduck@yahoo.com) + + C4 x86 assembler and some C emulation code + (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com), + _Demo_ (_demo_@zsnes.com), and Nach + + C4 C++ code + (c) Copyright 2003 Brad Jorsch + + DSP-1 emulator code + (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson, + John Weidman, neviksti (neviksti@hotmail.com), + Kris Bleakley, Andreas Naive + + DSP-2 emulator code + (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and + Lord Nightmare (lord_nightmare@users.sourceforge.net + + OBC1 emulator code + (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and + Kris Bleakley + Ported from x86 assembler to C by sanmaiwashi + + SPC7110 and RTC C++ emulator code + (c) Copyright 2002 Matthew Kendora with research by + zsKnight, John Weidman, and Dark Force + + S-DD1 C emulator code + (c) Copyright 2003 Brad Jorsch with research by + Andreas Naive and John Weidman + + S-RTC C emulator code + (c) Copyright 2001 John Weidman + + ST010 C++ emulator code + (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora + + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + + Super FX C emulator code + (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman + + + SH assembler code partly based on x86 assembler code + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + + + Specific ports contains the works of other authors. See headers in + individual files. + + Snes9x homepage: http://www.snes9x.com + + Permission to use, copy, modify and distribute Snes9x in both binary and + source form, for non-commercial purposes, is hereby granted without fee, + providing that this license information and copyright notice appear with + all copies and any derived work. + + This software is provided 'as-is', without any express or implied + warranty. In no event shall the authors be held liable for any damages + arising from the use of this software. + + Snes9x is freeware for PERSONAL USE only. Commercial users should + seek permission of the copyright holders first. Commercial use includes + charging money for Snes9x or software derived from Snes9x. + + The copyright holders request that bug fixes and improvements to the code + should be forwarded to them so everyone can benefit from the modifications + in future versions. + + Super NES and Super Nintendo Entertainment System are trademarks of + Nintendo Co., Limited and its subsidiary companies. +*******************************************************************************/ + +#ifndef _NETPLAY_H_ +#define _NETPLAY_H_ + +/* + * Client to server joypad update + * + * magic 1 + * sequence_no 1 + * opcode 1 + * joypad data 4 + * + * Server to client joypad update + * magic 1 + * sequence_no 1 + * opcode 1 + num joypads (top 3 bits) + * joypad data 4 * n + */ + +//#define NP_DEBUG 1 + +#define NP_VERSION 10 +#define NP_JOYPAD_HIST_SIZE 120 +#define NP_DEFAULT_PORT 6096 + +#define NP_MAX_CLIENTS 5 + +#define NP_SERV_MAGIC 'S' +#define NP_CLNT_MAGIC 'C' + +#define NP_CLNT_HELLO 0 +#define NP_CLNT_JOYPAD 1 +#define NP_CLNT_RESET 2 +#define NP_CLNT_PAUSE 3 +#define NP_CLNT_LOAD_ROM 4 +#define NP_CLNT_ROM_IMAGE 5 +#define NP_CLNT_FREEZE_FILE 6 +#define NP_CLNT_SRAM_DATA 7 +#define NP_CLNT_READY 8 +#define NP_CLNT_LOADED_ROM 9 +#define NP_CLNT_RECEIVED_ROM_IMAGE 10 +#define NP_CLNT_WAITING_FOR_ROM_IMAGE 11 + +#define NP_SERV_HELLO 0 +#define NP_SERV_JOYPAD 1 +#define NP_SERV_RESET 2 +#define NP_SERV_PAUSE 3 +#define NP_SERV_LOAD_ROM 4 +#define NP_SERV_ROM_IMAGE 5 +#define NP_SERV_FREEZE_FILE 6 +#define NP_SERV_SRAM_DATA 7 +#define NP_SERV_READY 8 + +struct SNPClient +{ + volatile uint8 SendSequenceNum; + volatile uint8 ReceiveSequenceNum; + volatile bool8 Connected; + volatile bool8 SaidHello; + volatile bool8 Paused; + volatile bool8 Ready; + int Socket; + char *ROMName; + char *HostName; + char *Who; +}; + +enum { + NP_SERVER_SEND_ROM_IMAGE, + NP_SERVER_SYNC_ALL, + NP_SERVER_SYNC_CLIENT, + NP_SERVER_SEND_FREEZE_FILE_ALL, + NP_SERVER_SEND_ROM_LOAD_REQUEST_ALL, + NP_SERVER_RESET_ALL, + NP_SERVER_SEND_SRAM_ALL, + NP_SERVER_SEND_SRAM +}; + +#define NP_MAX_TASKS 20 + +struct NPServerTask +{ + uint32 Task; + void *Data; +}; + +struct SNPServer +{ + struct SNPClient Clients [NP_MAX_CLIENTS]; + int NumClients; + volatile struct NPServerTask TaskQueue [NP_MAX_TASKS]; + volatile uint32 TaskHead; + volatile uint32 TaskTail; + int Socket; + uint32 FrameTime; + uint32 FrameCount; + char ROMName [30]; + uint32 Joypads [5]; + bool8 ClientPaused; + uint32 Paused; + bool8 SendROMImageOnConnect; + bool8 SyncByReset; +}; + +#define NP_MAX_ACTION_LEN 200 + +struct SNetPlay +{ + volatile uint8 MySequenceNum; + volatile uint8 ServerSequenceNum; + volatile bool8 Connected; + volatile bool8 Abort; + volatile uint8 Player; + volatile bool8 ClientsReady [NP_MAX_CLIENTS]; + volatile bool8 ClientsPaused [NP_MAX_CLIENTS]; + volatile bool8 Paused; + volatile bool8 PendingWait4Sync; + volatile uint8 PercentageComplete; + volatile bool8 Waiting4EmulationThread; + volatile bool8 Answer; + volatile int Socket; + char *ServerHostName; + char *ROMName; + int Port; + volatile uint32 JoypadWriteInd; + volatile uint32 JoypadReadInd; + uint32 Joypads [NP_JOYPAD_HIST_SIZE][NP_MAX_CLIENTS]; + uint32 Frame [NP_JOYPAD_HIST_SIZE]; + uint32 FrameCount; + uint32 MaxFrameSkip; + uint32 MaxBehindFrameCount; + char ActionMsg [NP_MAX_ACTION_LEN]; + char ErrorMsg [NP_MAX_ACTION_LEN]; + char WarningMsg [NP_MAX_ACTION_LEN]; +}; + +extern "C" struct SNetPlay NetPlay; + +// +// NETPLAY_CLIENT_HELLO message format: +// header +// frame_time (4) +// ROMName (variable) + +#define WRITE_LONG(p, v) { \ +*((p) + 0) = (uint8) ((v) >> 24); \ +*((p) + 1) = (uint8) ((v) >> 16); \ +*((p) + 2) = (uint8) ((v) >> 8); \ +*((p) + 3) = (uint8) ((v) >> 0); \ +} + +#define READ_LONG(p) \ +((((uint8) *((p) + 0)) << 24) | \ + (((uint8) *((p) + 1)) << 16) | \ + (((uint8) *((p) + 2)) << 8) | \ + (((uint8) *((p) + 3)) << 0)) + +bool8 S9xNPConnectToServer (const char *server_name, int port, + const char *rom_name); +bool8 S9xNPWaitForHeartBeat (); +uint32 S9xNPGetJoypad (int which1); +bool8 S9xNPSendJoypadUpdate (uint32 joypad); +void S9xNPDisconnect (); +bool8 S9xNPInitialise (); +bool8 S9xNPSendData (int fd, const uint8 *data, int len); +bool8 S9xNPGetData (int fd, uint8 *data, int len); + +void S9xNPSyncClients (); +void S9xNPStepJoypadHistory (); + +void S9xNPResetJoypadReadPos (); +bool8 S9xNPSendReady (uint8 op = NP_CLNT_READY); +bool8 S9xNPSendPause (bool8 pause); +void S9xNPReset (); +void S9xNPSetAction (const char *action, bool8 force = FALSE); +void S9xNPSetError (const char *error); +void S9xNPSetWarning (const char *warning); +void S9xNPDiscardHeartbeats (); +void S9xNPServerQueueSendingFreezeFile (const char *filename); +void S9xNPServerQueueSyncAll (); +void S9xNPServerQueueSendingROMImage (); +void S9xNPServerQueueSendingLoadROMRequest (const char *filename); + +void S9xNPServerAddTask (uint32 task, void *data); + +bool8 S9xNPStartServer (int port); +void S9xNPStopServer (); +#ifdef __WIN32kk__ +#define S9xGetMilliTime timeGetTime +#else +uint32 S9xGetMilliTime (); +#endif +#endif + diff --git a/src/snes4iphone_src/newres.h b/src/snes4iphone_src/newres.h new file mode 100755 index 0000000..ecda174 --- /dev/null +++ b/src/snes4iphone_src/newres.h @@ -0,0 +1,41 @@ +#ifndef __NEWRES_H__ +#define __NEWRES_H__ + +#if !defined(UNDER_CE) +#define UNDER_CE _WIN32_WCE +#endif + +#if defined(_WIN32_WCE) + #if !defined(WCEOLE_ENABLE_DIALOGEX) + #define DIALOGEX DIALOG DISCARDABLE + #endif + #include + #define SHMENUBAR RCDATA + #if defined(WIN32_PLATFORM_PSPC) && (_WIN32_WCE >= 300) + #include + #define AFXCE_IDR_SCRATCH_SHMENU 28700 + #else + #define I_IMAGENONE (-2) + #define NOMENU 0xFFFF + #define IDS_SHNEW 1 + + #define IDM_SHAREDNEW 10 + #define IDM_SHAREDNEWDEFAULT 11 + #endif // _WIN32_WCE_PSPC + #define AFXCE_IDD_SAVEMODIFIEDDLG 28701 +#endif // _WIN32_WCE + +#ifdef RC_INVOKED +#ifndef _INC_WINDOWS +#define _INC_WINDOWS + #include "winuser.h" // extract from windows header + //#include "winver.h" +#endif +#endif + +#ifdef IDC_STATIC +#undef IDC_STATIC +#endif +#define IDC_STATIC (-1) + +#endif //__NEWRES_H__ diff --git a/src/snes4iphone_src/os9x_65c816.S b/src/snes4iphone_src/os9x_65c816.S new file mode 100755 index 0000000..8610153 --- /dev/null +++ b/src/snes4iphone_src/os9x_65c816.S @@ -0,0 +1,9409 @@ +.text +/**************************************************************** +****************************************************************/ + .align 4 + + @ notaz +#define asm_spc700 1 // 1 = use notaz's asm_spc700 core + +/**************************************************************** + defines +****************************************************************/ + +#define map_last 12 + +#define rstatus r4 // format : 0xff800000 +#define reg_d_bank r4 // format : 0x000000ll +#define reg_a r5 // format : 0xhhll0000 or 0xll000000 +#define reg_d r6 // format : 0xhhll0000 +#define reg_p_bank r6 // format : 0x000000ll +#define reg_x r7 // format : 0xhhll0000 or 0xll000000 +#define reg_s r8 // format : 0x0000hhll +#define reg_y r9 // format : 0xhhll0000 or 0xll000000 + +#define rpc r10 // 32bits address +#define reg_cycles r11 // 32bits counter +#define regpcbase r12 // 32bits address + +#define rscratch r0 // format : 0xhhll0000 if data and calculation or return of s9xreadbyte or word +#define regopcode r0 // format : 0x000000ll +#define rscratch2 r1 // format : 0xhhll for calculation and value +#define rscratch3 r2 // +#define rscratch4 r3 // ?????? + +// used for sbc opcode +#define rscratch9 r10 // ?????? + +#define reg_cpu_var r14 + + + +// not used +// r13 // pointer 32 bit on a struct. + +// r15 = pc (sic!) + + +#define status_shifter 24 +#define mask_emul (1<<(status_shifter-1)) +#define mask_shifter_carry (status_shifter+1) +#define mask_carry (1<<(status_shifter)) @ 0 +#define mask_zero (2<<(status_shifter)) @ 1 +#define mask_irq (4<<(status_shifter)) @ 2 +#define mask_decimal (8<<(status_shifter)) @ 3 +#define mask_index (16<<(status_shifter)) @ 4 @ 1 +#define mask_mem (32<<(status_shifter)) @ 5 @ 2 +#define mask_overflow (64<<(status_shifter)) @ 6 @ 4 +#define mask_neg (128<<(status_shifter))@ 7 @ 8 + +#define mask_emul_orr_mask_mem_orr_mask_index 813694976 +#define mask_carry_orr_mask_mem_orr_mask_index 822083584 +#define mask_mem_orr_mask_index 805306368 + +#define one_cycle 6 +#define two_cycle 12 +#define three_cycle 18 +#define slow_one_cycle 8 +#define slow_two_cycle 16 + +#define nmi_flag (1 << 7) +#define irq_pending_flag (1 << 11) +#define irq_pending_flag_orr_nmi_flag 2176 +#define scan_keys_flag (1 << 4) + + +#define memmap_block_size (0x1000) +#define memmap_shift 12 +#define memmap_mask (0xfff) + +/**************************************************************** + macros +****************************************************************/ + +@ #include "os9x_65c816_mac_gen.h" +/*****************************************************************/ +/* offset in scpustate structure */ +/*****************************************************************/ +#define flags_ofs 0 +#define branchskip_ofs 4 +#define nmiactive_ofs 5 +#define irqactive_ofs 6 +#define waitingforinterrupt_ofs 7 + +#define rpb_ofs 8 +#define rdb_ofs 9 +#define rp_ofs 10 +#define ra_ofs 12 +#define rah_ofs 13 +#define rd_ofs 14 +#define rx_ofs 16 +#define rs_ofs 18 +#define ry_ofs 20 +@#define rpc_ofs 22 + +#define pc_ofs 24 +#define cycles_ofs 28 +#define pcbase_ofs 32 + +#define pcatopcodestart_ofs 36 +#define waitaddress_ofs 40 +#define waitcounter_ofs 44 +#define nextevent_ofs 48 +#define v_counter_ofs 52 +#define memspeed_ofs 56 +#define memspeedx2_ofs 60 +#define fastromspeed_ofs 64 +#define autosavetimer_ofs 68 +#define nmitriggerpoint_ofs 72 +#define nmicyclecount_ofs 76 +#define irqcyclecount_ofs 80 + +#define indma_ofs 84 +#define whichevent 85 +#define srammodified_ofs 86 +#define brktriggered_ofs 87 +#define asm_optable_ofs 88 +#define triedinterleavedmode2_ofs 92 + +#define map_ofs 96 +#define writemap_ofs 100 +#define memoryspeed_ofs 104 +#define blockisram_ofs 108 +#define sram 112 +#define bwram 116 +#define srammask 120 + +#define apuexecuting_ofs 122 + +#define iphone_r9_ofs 124 +#define iphone_r9s_ofs 128 + +@ notaz +#define apu_cycles 132 + +#define jump1 136 +#define jump2 140 +#define jump3 144 +#define jump4 148 + + +/*****************************************************************/ + +/* prepare */ +.macro prepare_c_call + str r9,[reg_cpu_var,#iphone_r9_ofs] + ldr r9,[reg_cpu_var,#iphone_r9s_ofs] + stmfd r13!,{r12,r14} +.endm +.macro prepare_c_call_r0 + str r9,[reg_cpu_var,#iphone_r9_ofs] + ldr r9,[reg_cpu_var,#iphone_r9s_ofs] + stmfd r13!,{r0,r12,r14} +.endm +.macro prepare_c_call_r0r1 + str r9,[reg_cpu_var,#iphone_r9_ofs] + ldr r9,[reg_cpu_var,#iphone_r9s_ofs] + stmfd r13!,{r0,r1,r12,r14} +.endm +.macro prepare_c_call_light + str r9,[reg_cpu_var,#iphone_r9_ofs] + ldr r9,[reg_cpu_var,#iphone_r9s_ofs] + stmfd r13!,{r14} +.endm +.macro prepare_c_call_lightr12 + str r9,[reg_cpu_var,#iphone_r9_ofs] + ldr r9,[reg_cpu_var,#iphone_r9s_ofs] + stmfd r13!,{r12,r14} +.endm +/* restore */ +.macro restore_c_call + ldmfd r13!,{r12,r14} + ldr r9,[reg_cpu_var,#iphone_r9_ofs] +.endm +.macro restore_c_call_r0 + ldmfd r13!,{r0,r12,r14} + ldr r9,[reg_cpu_var,#iphone_r9_ofs] +.endm +.macro restore_c_call_r1 + ldmfd r13!,{r1,r12,r14} + ldr r9,[reg_cpu_var,#iphone_r9_ofs] +.endm +.macro restore_c_call_light + ldmfd r13!,{r14} + ldr r9,[reg_cpu_var,#iphone_r9_ofs] +.endm +.macro restore_c_call_lightr12 + ldmfd r13!,{r12,r14} + ldr r9,[reg_cpu_var,#iphone_r9_ofs] +.endm + + +@ -------------- +.macro load_regs + @ notaz + add r0,reg_cpu_var,#8 + ldmia r0,{r1,reg_a,reg_x,reg_y,rpc,reg_cycles,regpcbase} + @ rstatus (p) & reg_d_bank + mov reg_d_bank,r1,lsl #16 + mov reg_d_bank,reg_d_bank,lsr #24 + mov r0,r1,lsr #16 + orrs rstatus, rstatus, r0,lsl #status_shifter @ 24 + @ if carry set, then emulation bit was set + orrcs rstatus,rstatus,#mask_emul + @ reg_d & reg_p_bank + mov reg_d,reg_a,lsr #16 + mov reg_d,reg_d,lsl #8 + orr reg_d,reg_d,r1,lsl #24 + mov reg_d,reg_d,ror #24 @ 0xdddd00pb + @ reg_x, reg_s + mov reg_s,reg_x,lsr #16 + @ shift x,y & a according to the current mode (index, memory bits) + tst rstatus,#mask_index + movne reg_x,reg_x,lsl #24 + movne reg_y,reg_y,lsl #24 + moveq reg_x,reg_x,lsl #16 + moveq reg_y,reg_y,lsl #16 + tst rstatus,#mask_mem + movne reg_a,reg_a,lsl #24 + moveq reg_a,reg_a,lsl #16 +.endm + + +.macro save_regs + @ notaz + @ reg_p_bank, reg_d_bank and rstatus + mov r1, rstatus, lsr #16 + orr r1, r1, reg_p_bank, lsl #24 + movs r1, r1, lsr #8 + orrcs r1, r1, #0x100 @ emulation bit + orr r1, r1, reg_d_bank, lsl #24 + mov r1, r1, ror #16 + @ reg_a, reg_d + tst rstatus,#mask_mem + ldrneh r0, [reg_cpu_var,#ra_ofs] + bicne r0, r0,#0xff + orrne reg_a, r0, reg_a,lsr #24 + moveq reg_a, reg_a, lsr #16 + mov reg_d, reg_d, lsr #16 + orr reg_a, reg_a, reg_d, lsl #16 + @ shift x&y according to the current mode (index, memory bits) + tst rstatus,#mask_index + movne reg_x,reg_x,lsr #24 + movne reg_y,reg_y,lsr #24 + moveq reg_x,reg_x,lsr #16 + moveq reg_y,reg_y,lsr #16 + @ reg_x, reg_s + orr reg_x, reg_x, reg_s, lsl #16 + @ store + add r0,reg_cpu_var,#8 + stmia r0,{r1,reg_a,reg_x,reg_y,rpc,reg_cycles,regpcbase} + +/* + @ reg_d & reg_p_bank is same register + strb reg_p_bank,[reg_cpu_var,#rpb_ofs] + mov rscratch,reg_d, lsr #16 + strh rscratch,[reg_cpu_var,#rd_ofs] + @ rstatus & reg_d_bank is same register + strb reg_d_bank,[reg_cpu_var,#rdb_ofs] + movs rscratch, rstatus, lsr #status_shifter + orrcs rscratch,rscratch,#0x100 @ emulation bit + strh rscratch,[reg_cpu_var,#rp_ofs] + @ + @ shift x,y & a according to the current mode (index, memory bits) + tst rstatus,#mask_index + movne rscratch,reg_x,lsr #24 + movne rscratch2,reg_y,lsr #24 + moveq rscratch,reg_x,lsr #16 + moveq rscratch2,reg_y,lsr #16 + strh rscratch,[reg_cpu_var,#rx_ofs] + strh rscratch2,[reg_cpu_var,#ry_ofs] + tst rstatus,#mask_mem + ldrneh rscratch,[reg_cpu_var,#ra_ofs] + bicne rscratch,rscratch,#0xff + orrne rscratch,rscratch,reg_a,lsr #24 + moveq rscratch,reg_a,lsr #16 + strh rscratch,[reg_cpu_var,#ra_ofs] + + strh reg_s,[reg_cpu_var,#rs_ofs] + str regpcbase,[reg_cpu_var,#pcbase_ofs] + str rpc,[reg_cpu_var,#pc_ofs] + + str reg_cycles,[reg_cpu_var,#cycles_ofs] +*/ +.endm + +/*****************************************************************/ +.macro add1cycle + add reg_cycles,reg_cycles, #one_cycle +.endm +.macro add1cyclene + addne reg_cycles,reg_cycles, #one_cycle +.endm +.macro add1cycleeq + addeq reg_cycles,reg_cycles, #one_cycle +.endm + +.macro add2cycle + add reg_cycles,reg_cycles, #two_cycle +.endm +.macro add2cyclene + addne reg_cycles,reg_cycles, #two_cycle +.endm +.macro add2cycle2mem + ldr rscratch,[reg_cpu_var,#memspeed_ofs] + add reg_cycles,reg_cycles, #two_cycle + add reg_cycles, reg_cycles, rscratch, lsl #1 +.endm +.macro add2cycle1mem + ldr rscratch,[reg_cpu_var,#memspeed_ofs] + add reg_cycles,reg_cycles, #two_cycle + add reg_cycles, reg_cycles, rscratch +.endm + +.macro add3cycle + add reg_cycles,reg_cycles, #three_cycle +.endm + +.macro add1cycle1mem + ldr rscratch,[reg_cpu_var,#memspeed_ofs] + add reg_cycles,reg_cycles, #one_cycle + add reg_cycles, reg_cycles, rscratch +.endm + +.macro add1cycle2mem + ldr rscratch,[reg_cpu_var,#memspeed_ofs] + add reg_cycles,reg_cycles, #one_cycle + add reg_cycles, reg_cycles, rscratch, lsl #1 +.endm + +.macro add1mem + ldr rscratch,[reg_cpu_var,#memspeed_ofs] + add reg_cycles, reg_cycles, rscratch +.endm + +.macro add2mem + ldr rscratch,[reg_cpu_var,#memspeed_ofs] + add reg_cycles, reg_cycles, rscratch, lsl #1 +.endm + +.macro add3mem + ldr rscratch,[reg_cpu_var,#memspeed_ofs] + add reg_cycles, rscratch, reg_cycles + add reg_cycles, reg_cycles, rscratch, lsl #1 +.endm + +/**************/ +.macro cleardecimal + bic rstatus,rstatus,#mask_decimal +.endm +.macro setdecimal + orr rstatus,rstatus,#mask_decimal +.endm +.macro setirq + orr rstatus,rstatus,#mask_irq +.endm +.macro clearirq + bic rstatus,rstatus,#mask_irq +.endm + +.macro cpushutdown +@ if (settings.shutdown && cpu.pc == cpu.waitaddress) + ldr rscratch,[reg_cpu_var,#waitaddress_ofs] + cmp rpc,rscratch + bne 5431f +@ if (cpu.waitcounter == 0 && !(cpu.flags & (irq_pending_flag | nmi_flag))) + ldr rscratch,[reg_cpu_var,#flags_ofs] + ldr rscratch2,[reg_cpu_var,#waitcounter_ofs] + tst rscratch,#irq_pending_flag_orr_nmi_flag + bne 5432f + movs rscratch2,rscratch2 + bne 5432f +@ cpu.waitaddress = null; + mov rscratch,#0 + str rscratch,[reg_cpu_var,#waitaddress_ofs] +@ if (settings.sa1) +@ s9xsa1executeduringsleep (); : todo + +@ cpu.cycles = cpu.nextevent; + ldr reg_cycles,[reg_cpu_var,#nextevent_ofs] + ldrb r0,[reg_cpu_var,#apuexecuting_ofs] + movs r0,r0 + beq 5431f +@ if (iapu.apuexecuting) +/* { + icpu.cpuexecuting = false; + do + { + apu_execute1(); + } while (apu.cycles < cpu.nextevent); + icpu.cpuexecuting = true; + } + */ + asmapu_execute2 + b 5431f +@@.pool +5432: +/* else + if (cpu.waitcounter >= 2) + cpu.waitcounter = 1; + else + cpu.waitcounter--; +*/ + cmp rscratch2,#1 + movhi rscratch2,#1 + @ subls rscratch2,rscratch2,#1 + movls rscratch2,#0 + str rscratch2,[reg_cpu_var,#waitcounter_ofs] +5431: + +.endm +.macro branchcheck0 + /*in rsctach : opaddress + /*destroy rscratch2*/ + ldrb rscratch2,[reg_cpu_var,#branchskip_ofs] + movs rscratch2,rscratch2 + beq 1110f + mov rscratch2,#0 + strb rscratch2,[reg_cpu_var,#branchskip_ofs] + sub rscratch2,rpc,regpcbase + @ if( cpu.pc - cpu.pcbase > opaddress) return; + cmp rscratch2,rscratch + bhi 1111f +1110: +.endm +.macro branchcheck1 + /*in rsctach : opaddress + /*destroy rscratch2*/ + ldrb rscratch2,[reg_cpu_var,#branchskip_ofs] + movs rscratch2,rscratch2 + beq 1110f + mov rscratch2,#0 + strb rscratch2,[reg_cpu_var,#branchskip_ofs] + sub rscratch2,rpc,regpcbase + @ if( cpu.pc - cpu.pcbase > opaddress) return; + cmp rscratch2,rscratch + bhi 1111f +1110: +.endm +.macro branchcheck2 + /*in rsctach : opaddress + /*destroy rscratch2*/ + ldrb rscratch2,[reg_cpu_var,#branchskip_ofs] + movs rscratch2,rscratch2 + beq 1110f + mov rscratch2,#0 + strb rscratch2,[reg_cpu_var,#branchskip_ofs] + sub rscratch2,rpc,regpcbase + @ if( cpu.pc - cpu.pcbase > opaddress) return; + cmp rscratch2,rscratch + bhi 1111f +1110: +.endm + +.macro s9xsetpcbase + @ in : rscratch (0x00hhmmll) + prepare_c_call + bl _asm_S9xSetPCBase + restore_c_call + ldr rpc,[reg_cpu_var,#pc_ofs] + ldr regpcbase,[reg_cpu_var,#pcbase_ofs] +.endm + +.macro s9xfixcycles + tst rstatus, #mask_emul + ldrne rscratch, [reg_cpu_var,#jump1] + bne 991111f + @ emulation=0 + tst rstatus,#mask_mem + beq 991112f + @ memory=1 + tst rstatus,#mask_index + @ index=1 @ mode 0 : m=1,x=1 + ldrne rscratch, [reg_cpu_var,#jump1] + @ index=0 @ mode 1 : m=1,x=0 + ldreq rscratch, [reg_cpu_var,#jump2] + b 991111f +991112: @ memory=0 + tst rstatus,#mask_index + @ index=1 @ mode 3 : m=0,x=1 + ldrne rscratch, [reg_cpu_var,#jump4] + @ index=0 @ mode 2 : m=0,x=0 + ldreq rscratch, [reg_cpu_var,#jump3] +991111: + str rscratch,[reg_cpu_var,#asm_optable_ofs] +.endm + +.macro s9xdohblankprocessing + save_regs + prepare_c_call_light +@ bl asm_s9xdohblankprocessing + bl _S9xDoHBlankProcessing @ let's go straight to number one + restore_c_call_light + load_regs +.endm + +/********************************/ +.macro exec_op + ldr r1,[reg_cpu_var,#asm_optable_ofs] + str rpc,[reg_cpu_var,#pcatopcodestart_ofs] + add1mem + ldrb r0, [rpc], #1 + + ldr pc, [r1,r0, lsl #2] +.endm +.macro nextopcode + ldr rscratch,[reg_cpu_var,#nextevent_ofs] + cmp reg_cycles,rscratch + blt mainloop + s9xdohblankprocessing + b mainloop +.endm + +.macro asmapu_execute + ldrb r0,[reg_cpu_var,#apuexecuting_ofs] + cmp r0,#1 @ spc700 enabled, hack mode off + bne 43210f + ldr r0,[reg_cpu_var,#apu_cycles] + subs r0,reg_cycles,r0 + bmi 43210f +.if asm_spc700 + prepare_c_call_lightr12 + bl _spc700_execute + restore_c_call_lightr12 + sub r0,reg_cycles,r0 @ sub cycles left + str r0,[reg_cpu_var,#apu_cycles] +.else + @ save_regs + str reg_cycles,[reg_cpu_var,#cycles_ofs] + prepare_c_call_lightr12 + bl _asm_APU_EXECUTE + restore_c_call_lightr12 + ldr reg_cycles,[reg_cpu_var,#cycles_ofs] +.endif + @ load_regs + @ s9xfixcycles +43210: +.endm + +.macro asmapu_execute2 +.if asm_spc700 + ldrb r0,[reg_cpu_var,#apuexecuting_ofs] + cmp r0,#1 @ spc700 enabled, hack mode off + bne 43211f + ldr r0,[reg_cpu_var,#apu_cycles] + subs r0,reg_cycles,r0 @ reg_cycles == nextevent + ble 43211f + prepare_c_call_lightr12 + bl _spc700_execute + restore_c_call_lightr12 + sub r0,reg_cycles,r0 @ sub cycles left + str r0,[reg_cpu_var,#apu_cycles] +43211: +.else + @ save_regs + str reg_cycles,[reg_cpu_var,#cycles_ofs] + prepare_c_call_lightr12 + bl _asm_APU_EXECUTE2 + restore_c_call_lightr12 + ldr reg_cycles,[reg_cpu_var,#cycles_ofs] + @ load_regs +.endif +.endm + +@ #include "os9x_65c816_mac_mem.h" +.macro s9xgetword + @ in : rscratch (0x00hhmmll) + @ out : rscratch (0xhhll0000) + stmfd r13!,{pc} @ push return address + b _asms9xgetword + mov r0,r0 + mov r0, r0, lsl #16 +.endm +.macro s9xgetwordlow + @ in : rscratch (0x00hhmmll) + @ out : rscratch (0x0000hhll) + stmfd r13!,{pc} @ push return address + b _asms9xgetword + mov r0,r0 +.endm +.macro s9xgetwordregstatus reg + @ in : rscratch (0x00hhmmll) + @ out : reg (0xhhll0000) + @ flags have to be updated with read value + stmfd r13!,{pc} @ push return address + b _asms9xgetword + mov r0,r0 + movs $0, r0, lsl #16 +.endm +.macro s9xgetwordregns reg + @ in : rscratch (0x00hhmmll) + @ out : reg (0xhhll0000) + @ does not destroy rscratch (r0) + stmfd r13!,{r0} + stmfd r13!,{pc} @ push return address + b _asms9xgetword + mov r0,r0 + mov $0, r0, lsl #16 + ldmfd r13!,{r0} +.endm +.macro s9xgetwordlowregns reg + @ in : rscratch (0x00hhmmll) + @ out : reg (0xhhll0000) + @ does not destroy rscratch (r0) + stmfd r13!,{r0} + stmfd r13!,{pc} @ push return address + b _asms9xgetword + mov r0,r0 + mov $0, r0 + ldmfd r13!,{r0} +.endm + +.macro s9xgetbyte + @ in : rscratch (0x00hhmmll) + @ out : rscratch (0xll000000) + stmfd r13!,{pc} @ push return address + b _asms9xgetbyte + mov r0,r0 + mov r0, r0, lsl #24 +.endm +.macro s9xgetbytelow + @ in : rscratch (0x00hhmmll) + @ out : rscratch (0x000000ll) + stmfd r13!,{pc} + b _asms9xgetbyte + mov r0,r0 +.endm +.macro s9xgetbyteregstatus reg + @ in : rscratch (0x00hhmmll) + @ out : reg (0xll000000) + @ flags have to be updated with read value + stmfd r13!,{pc} @ push return address + b _asms9xgetbyte + mov r0,r0 + movs $0, r0, lsl #24 +.endm +.macro s9xgetbyteregns reg + @ in : rscratch (0x00hhmmll) + @ out : reg (0xll000000) + @ does not destroy rscratch (r0) + stmfd r13!,{r0} + stmfd r13!,{pc} @ push return address + b _asms9xgetbyte + mov r0,r0 + movs $0, r0, lsl #24 + ldmfd r13!,{r0} +.endm +.macro s9xgetbytelowregns reg + @ in : rscratch (0x00hhmmll) + @ out : reg (0x000000ll) + @ does not destroy rscratch (r0) + stmfd r13!,{r0} + stmfd r13!,{pc} @ push return address + b _asms9xgetbyte + mov r0,r0 + movs $0, r0 + ldmfd r13!,{r0} +.endm + +.macro s9xsetword regvalue + @ in : regvalue (0xhhll0000) + @ in : rscratch=address (0x00hhmmll) + mov r1,$0, lsr #16 + stmfd r13!,{pc} @ push return address + b _asms9xsetword + mov r0,r0 +.endm +.macro s9xsetwordzero + @ in : rscratch=address (0x00hhmmll) + mov r1,#0 + stmfd r13!,{pc} @ push return address + b _asms9xsetword + mov r0,r0 +.endm +.macro s9xsetwordlow regvalue + @ in : regvalue (0x0000hhll) + @ in : rscratch=address (0x00hhmmll) + mov r1,$0 + stmfd r13!,{pc} @ push return address + b _asms9xsetword + mov r0,r0 +.endm +.macro s9xsetbyte regvalue + @ in : regvalue (0xll000000) + @ in : rscratch=address (0x00hhmmll) + mov r1,$0, lsr #24 + stmfd r13!,{pc} @ push return address + b _asms9xsetbyte + mov r0,r0 +.endm +.macro s9xsetbytezero + @ in : rscratch=address (0x00hhmmll) + mov r1,#0 + stmfd r13!,{pc} @ push return address + b _asms9xsetbyte + mov r0,r0 +.endm +.macro s9xsetbytelow regvalue + @ in : regvalue (0x000000ll) + @ in : rscratch=address (0x00hhmmll) + mov r1,$0 + stmfd r13!,{pc} @ push return address + b _asms9xsetbyte + mov r0,r0 +.endm + + +@ =========================================== +@ =========================================== +@ adressing mode +@ =========================================== +@ =========================================== + + +.macro absolute + add2mem + ldrb rscratch2 , [rpc, #1] + ldrb rscratch , [rpc],#2 + orr rscratch , rscratch, rscratch2, lsl #8 + orr rscratch , rscratch, reg_d_bank, lsl #16 +.endm +.macro absoluteindexedindirectx0 + add2mem + ldrb rscratch2 , [rpc, #1] + ldrb rscratch , [rpc], #2 + orr rscratch , rscratch, rscratch2, lsl #8 + add rscratch , reg_x, rscratch, lsl #16 + mov rscratch , rscratch, lsr #16 + orr rscratch , rscratch, reg_p_bank, lsl #16 + s9xgetwordlow + +.endm +.macro absoluteindexedindirectx1 + add2mem + ldrb rscratch2 , [rpc, #1] + ldrb rscratch , [rpc], #2 + orr rscratch , rscratch, rscratch2, lsl #8 + add rscratch , rscratch, reg_x, lsr #24 + bic rscratch , rscratch, #0x00ff0000 + orr rscratch , rscratch, reg_p_bank, lsl #16 + s9xgetwordlow + +.endm +.macro absoluteindirectlong + add2mem + ldrb rscratch2 , [rpc, #1] + ldrb rscratch , [rpc], #2 + orr rscratch , rscratch, rscratch2, lsl #8 + s9xgetwordlowregns rscratch2 + add rscratch , rscratch, #2 + stmfd r13!,{rscratch2} + s9xgetbytelow + ldmfd r13!,{rscratch2} + orr rscratch , rscratch2, rscratch, lsl #16 +.endm +.macro absoluteindirect + add2mem + ldrb rscratch2 , [rpc,#1] + ldrb rscratch , [rpc], #2 + orr rscratch , rscratch, rscratch2, lsl #8 + s9xgetwordlow + orr rscratch , rscratch, reg_p_bank, lsl #16 +.endm +.macro absoluteindexedx0 + add2mem + ldrb rscratch2 , [rpc, #1] + ldrb rscratch , [rpc], #2 + orr rscratch , rscratch, rscratch2, lsl #8 + orr rscratch , rscratch, reg_d_bank, lsl #16 + add rscratch , rscratch, reg_x, lsr #16 +.endm +.macro absoluteindexedx1 + add2mem + ldrb rscratch2 , [rpc, #1] + ldrb rscratch , [rpc], #2 + orr rscratch , rscratch, rscratch2, lsl #8 + orr rscratch , rscratch, reg_d_bank, lsl #16 + add rscratch , rscratch, reg_x, lsr #24 +.endm + + +.macro absoluteindexedy0 + add2mem + ldrb rscratch2 , [rpc, #1] + ldrb rscratch , [rpc], #2 + orr rscratch , rscratch, rscratch2, lsl #8 + orr rscratch , rscratch, reg_d_bank, lsl #16 + add rscratch , rscratch, reg_y, lsr #16 +.endm +.macro absoluteindexedy1 + add2mem + ldrb rscratch2 , [rpc, #1] + ldrb rscratch , [rpc], #2 + orr rscratch , rscratch, rscratch2, lsl #8 + orr rscratch , rscratch, reg_d_bank, lsl #16 + add rscratch , rscratch, reg_y, lsr #24 +.endm +.macro absolutelong + add3mem + ldrb rscratch2 , [rpc, #1] + ldrb rscratch , [rpc], #2 + orr rscratch , rscratch, rscratch2, lsl #8 + ldrb rscratch2 , [rpc], #1 + orr rscratch , rscratch, rscratch2, lsl #16 +.endm + + +.macro absolutelongindexedx0 + add3mem + ldrb rscratch2 , [rpc, #1] + ldrb rscratch , [rpc], #2 + orr rscratch , rscratch, rscratch2, lsl #8 + ldrb rscratch2 , [rpc], #1 + orr rscratch , rscratch, rscratch2, lsl #16 + add rscratch , rscratch, reg_x, lsr #16 + bic rscratch, rscratch, #0xff000000 +.endm +.macro absolutelongindexedx1 + add3mem + ldrb rscratch2 , [rpc, #1] + ldrb rscratch , [rpc], #2 + orr rscratch , rscratch, rscratch2, lsl #8 + ldrb rscratch2 , [rpc], #1 + orr rscratch , rscratch, rscratch2, lsl #16 + add rscratch , rscratch, reg_x, lsr #24 + bic rscratch, rscratch, #0xff000000 +.endm +.macro direct + add1mem + ldrb rscratch , [rpc], #1 + add rscratch , reg_d, rscratch, lsl #16 + mov rscratch, rscratch, lsr #16 +.endm +.macro directindirect + add1mem + ldrb rscratch , [rpc], #1 + add rscratch , reg_d, rscratch, lsl #16 + mov rscratch, rscratch, lsr #16 + s9xgetwordlow + orr rscratch , rscratch, reg_d_bank, lsl #16 +.endm +.macro directindirectlong + add1mem + ldrb rscratch , [rpc], #1 + add rscratch , reg_d, rscratch, lsl #16 + mov rscratch, rscratch, lsr #16 + s9xgetwordlowregns rscratch2 + add rscratch , rscratch,#2 + stmfd r13!,{rscratch2} + s9xgetbytelow + ldmfd r13!,{rscratch2} + orr rscratch , rscratch2, rscratch, lsl #16 +.endm +.macro directindirectindexed0 + add1mem + ldrb rscratch , [rpc], #1 + add rscratch , reg_d, rscratch, lsl #16 + mov rscratch, rscratch, lsr #16 + s9xgetwordlow + orr rscratch, rscratch,reg_d_bank, lsl #16 + add rscratch, rscratch,reg_y, lsr #16 +.endm +.macro directindirectindexed1 + add1mem + ldrb rscratch , [rpc], #1 + add rscratch , reg_d, rscratch, lsl #16 + mov rscratch, rscratch, lsr #16 + s9xgetwordlow + orr rscratch, rscratch,reg_d_bank, lsl #16 + add rscratch, rscratch,reg_y, lsr #24 +.endm +.macro directindirectindexedlong0 + add1mem + ldrb rscratch , [rpc], #1 + add rscratch , reg_d, rscratch, lsl #16 + mov rscratch, rscratch, lsr #16 + s9xgetwordlowregns rscratch2 + add rscratch , rscratch,#2 + stmfd r13!,{rscratch2} + s9xgetbytelow + ldmfd r13!,{rscratch2} + orr rscratch , rscratch2, rscratch, lsl #16 + add rscratch, rscratch,reg_y, lsr #16 +.endm +.macro directindirectindexedlong1 + add1mem + ldrb rscratch , [rpc], #1 + add rscratch , reg_d, rscratch, lsl #16 + mov rscratch, rscratch, lsr #16 + s9xgetwordlowregns rscratch2 + add rscratch , rscratch,#2 + stmfd r13!,{rscratch2} + s9xgetbytelow + ldmfd r13!,{rscratch2} + orr rscratch , rscratch2, rscratch, lsl #16 + add rscratch, rscratch,reg_y, lsr #24 +.endm +.macro directindexedindirect0 + add1cycle1mem + ldrb rscratch , [rpc], #1 + add rscratch2 , reg_d , reg_x + add rscratch , rscratch2 , rscratch, lsl #16 + mov rscratch, rscratch, lsr #16 + s9xgetwordlow + orr rscratch , rscratch , reg_d_bank, lsl #16 +.endm +.macro directindexedindirect1 + add1cycle1mem + ldrb rscratch , [rpc], #1 + add rscratch2 , reg_d , reg_x, lsr #8 + add rscratch , rscratch2 , rscratch, lsl #16 + mov rscratch, rscratch, lsr #16 + s9xgetwordlow + orr rscratch , rscratch , reg_d_bank, lsl #16 +.endm +.macro directindexedx0 + add1cycle1mem + ldrb rscratch , [rpc], #1 + add rscratch2 , reg_d , reg_x + add rscratch , rscratch2 , rscratch, lsl #16 + mov rscratch, rscratch, lsr #16 +.endm +.macro directindexedx1 + add1cycle1mem + ldrb rscratch , [rpc], #1 + add rscratch2 , reg_d , reg_x, lsr #8 + add rscratch , rscratch2 , rscratch, lsl #16 + mov rscratch, rscratch, lsr #16 +.endm +.macro directindexedy0 + add1cycle1mem + ldrb rscratch , [rpc], #1 + add rscratch2 , reg_d , reg_y + add rscratch , rscratch2 , rscratch, lsl #16 + mov rscratch, rscratch, lsr #16 +.endm +.macro directindexedy1 + add1cycle1mem + ldrb rscratch , [rpc], #1 + add rscratch2 , reg_d , reg_y, lsr #8 + add rscratch , rscratch2 , rscratch, lsl #16 + mov rscratch, rscratch, lsr #16 +.endm +.macro immediate8 + add rscratch, rpc, reg_p_bank, lsl #16 + sub rscratch, rscratch, regpcbase + add rpc, rpc, #1 +.endm +.macro immediate16 + add rscratch, rpc, reg_p_bank, lsl #16 + sub rscratch, rscratch, regpcbase + add rpc, rpc, #2 +.endm +.macro asmrelative + add1mem + ldrsb rscratch , [rpc],#1 + add rscratch , rscratch , rpc + sub rscratch , rscratch, regpcbase + bic rscratch,rscratch,#0x00ff0000 + bic rscratch,rscratch,#0xff000000 +.endm +.macro asmrelativelong + add1cycle2mem + ldrb rscratch2 , [rpc, #1] + ldrb rscratch , [rpc], #2 + orr rscratch , rscratch, rscratch2, lsl #8 + sub rscratch2 , rpc, regpcbase + add rscratch , rscratch2, rscratch + bic rscratch,rscratch,#0x00ff0000 +.endm + + +.macro stackasmrelative + add1cycle1mem + ldrb rscratch , [rpc], #1 + add rscratch , rscratch, reg_s + bic rscratch,rscratch,#0x00ff0000 +.endm +.macro stackasmrelativeindirectindexed0 + add2cycle1mem + ldrb rscratch , [rpc], #1 + add rscratch , rscratch, reg_s + bic rscratch,rscratch,#0x00ff0000 + s9xgetwordlow + orr rscratch , rscratch, reg_d_bank, lsl #16 + add rscratch , rscratch, reg_y, lsr #16 + bic rscratch, rscratch, #0xff000000 +.endm +.macro stackasmrelativeindirectindexed1 + add2cycle1mem + ldrb rscratch , [rpc], #1 + add rscratch , rscratch, reg_s + bic rscratch,rscratch,#0x00ff0000 + s9xgetwordlow + orr rscratch , rscratch, reg_d_bank, lsl #16 + add rscratch , rscratch, reg_y, lsr #24 + bic rscratch, rscratch, #0xff000000 +.endm + + +/****************************************/ +.macro pushb reg + mov rscratch,reg_s + s9xsetbyte $0 + sub reg_s,reg_s,#1 +.endm +.macro pushblow reg + mov rscratch,reg_s + s9xsetbytelow $0 + sub reg_s,reg_s,#1 +.endm +.macro pushwlow reg + sub rscratch,reg_s,#1 + s9xsetwordlow $0 + sub reg_s,reg_s,#2 +.endm +.macro pushwrlow + mov rscratch2,rscratch + sub rscratch,reg_s,#1 + s9xsetwordlow rscratch2 + sub reg_s,reg_s,#2 +.endm +.macro pushw reg + sub rscratch,reg_s,#1 + s9xsetword $0 + sub reg_s,reg_s,#2 +.endm + +/********/ + +.macro pullb reg + add rscratch,reg_s,#1 + s9xgetbytelow + add reg_s,reg_s,#1 + mov $0,rscratch,lsl #24 +.endm +.macro pullbr + add rscratch,reg_s,#1 + s9xgetbyte + add reg_s,reg_s,#1 +.endm +.macro pullblow reg + add rscratch,reg_s,#1 + s9xgetbytelow + add reg_s,reg_s,#1 + mov $0,rscratch +.endm +.macro pullbrlow + add rscratch,reg_s,#1 + s9xgetbytelow + add reg_s,reg_s,#1 +.endm +.macro pullw reg + add rscratch,reg_s,#1 + s9xgetwordlow + add reg_s,reg_s,#2 + mov $0,rscratch,lsl #16 +.endm + +.macro pullwlow reg + add rscratch,reg_s,#1 + s9xgetwordlow + add reg_s,reg_s,#2 + mov $0,rscratch +.endm + + +/*****************/ +.macro pullbs reg + add rscratch,reg_s,#1 + s9xgetbytelow + add reg_s,reg_s,#1 + movs $0,rscratch,lsl #24 +.endm +.macro pullbrs + add rscratch,reg_s,#1 + s9xgetbytelow + add reg_s,reg_s,#1 + movs rscratch,rscratch,lsl #24 +.endm +.macro pullblows reg + add rscratch,reg_s,#1 + s9xgetbytelow + add reg_s,reg_s,#1 + movs $0,rscratch +.endm +.macro pullbrlows + add rscratch,reg_s,#1 + s9xgetbytelow + add reg_s,reg_s,#1 + movs rscratch,rscratch +.endm +.macro pullws reg + add rscratch,reg_s,#1 + s9xgetwordlow + add reg_s,reg_s,#2 + movs $0,rscratch, lsl #16 +.endm +.macro pullwrs + add rscratch,reg_s,#1 + s9xgetwordlow + add reg_s,reg_s,#2 + movs rscratch,rscratch, lsl #16 +.endm +.macro pullwlows reg + add rscratch,reg_s,#1 + s9xgetwordlow + add reg_s,reg_s,#2 + movs $0,rscratch +.endm +.macro pullwrlows + add rscratch,reg_s,#1 + s9xgetwordlow + add reg_s,reg_s,#2 + movs rscratch,rscratch +.endm + + +.globl _asms9xgetbyte +.globl _asms9xgetword +.globl _asms9xsetbyte +.globl _asms9xsetword + +@ uint8 aas9xgetbyte(uint32 address); +_asms9xgetbyte: + @ in : r0 = 0x00hhmmll + @ out : r0 = 0x000000ll + @ destroyed : r1,r2,r3 + @ update : reg_cycles + @ r1 <= block + mov r1,r0,lsr #memmap_shift + @ memmap_shift is 12, address is 0xffffffff at max, so + @ r1 is maxed by 0x000fffff, memmap_mask is 0x1000-1=0xfff + @ so and memmap_mask is bic 0xff000 + bic r1,r1,#0xff000 + @ r2 <= map[block] (getaddress) + ldr r2,[reg_cpu_var,#map_ofs] + ldr r2,[r2,r1,lsl #2] + cmp r2,#map_last + blo gbspecial @ special + @ direct rom/ram acess + @ r2 <= getaddress + address & 0xffff + @ r3 <= memoryspeed[block] + ldr r3,[reg_cpu_var,#memoryspeed_ofs] + mov r0,r0,lsl #16 + ldrb r3,[r3,r1] + add r2,r2,r0,lsr #16 + @ update cpu.cycles + add reg_cycles,reg_cycles,r3 + @ r3 = blockisram[block] + ldr r3,[reg_cpu_var,#blockisram_ofs] + @ get value to return + ldrb r0,[r2] + ldrb r3,[r3,r1] + movs r3,r3 + @ if blockisram => update for cpushutdown + ldrne r1,[reg_cpu_var,#pcatopcodestart_ofs] + strne r1,[reg_cpu_var,#waitaddress_ofs] + + ldmfd r13!,{pc} @ return +gbspecial: + + ldr pc,[pc,r2,lsl #2] + mov r0,r0 @ nop, for align + .long gbppu + .long gbcpu + .long gbdsp + .long gblsram + .long gbhsram + .long gbnone + .long gbdebug + .long gbc4 + .long gbbwram + .long gbnone + .long gbnone + .long gbnone + /*.long gb7rom + .long gb7ram + .long gb7srm*/ +gbppu: + @ indma ? + ldrb r1,[reg_cpu_var,#indma_ofs] + movs r1,r1 + addeq reg_cycles,reg_cycles,#one_cycle @ no -> update cycles + mov r0,r0,lsl #16 @ s9xgetppu(address&0xffff); + str reg_cycles,[reg_cpu_var,#cycles_ofs] @ save cycles + mov r0,r0,lsr #16 + prepare_c_call + bl _S9xGetPPU + restore_c_call + ldr reg_cycles,[reg_cpu_var,#cycles_ofs] @ load cycles + ldmfd r13!,{pc} @ return +gbcpu: + add reg_cycles,reg_cycles,#one_cycle @ update cycles + mov r0,r0,lsl #16 @ s9xgetcpu(address&0xffff); + str reg_cycles,[reg_cpu_var,#cycles_ofs] @ save cycles + mov r0,r0,lsr #16 + prepare_c_call + bl _S9xGetCPU + restore_c_call + ldr reg_cycles,[reg_cpu_var,#cycles_ofs] @ load cycles + ldmfd r13!,{pc} @ return +gbdsp: + add reg_cycles,reg_cycles,#slow_one_cycle @ update cycles + mov r0,r0,lsl #16 @ s9xgetcpu(address&0xffff); + str reg_cycles,[reg_cpu_var,#cycles_ofs] @ save cycles + mov r0,r0,lsr #16 + prepare_c_call + bl _S9xGetDSP + restore_c_call + ldr reg_cycles,[reg_cpu_var,#cycles_ofs] @ load cycles + ldmfd r13!,{pc} @ return +gblsram: + add reg_cycles,reg_cycles,#slow_one_cycle @ update cycles + ldrh r2,[reg_cpu_var,#srammask] + ldr r1,[reg_cpu_var,#sram] + and r0,r2,r0 @ address&srammask + ldrb r0,[r1,r0] @ *memory.sram + address&srammask + ldmfd r13!,{pc} +gb7srm: +gbhsram: + add reg_cycles,reg_cycles,#slow_one_cycle @ update cycles + + mov r1,r0,lsl #17 + and r2,r0,#0xf0000 + mov r1,r1,lsr #17 @ address&0x7fff + mov r2,r2,lsr #3 @ (address&0xf0000 >> 3) + add r0,r2,r1 + ldrh r2,[reg_cpu_var,#srammask] + sub r0,r0,#0x6000 @ ((address & 0x7fff) - 0x6000 + ((address & 0xf0000) >> 3)) + ldr r1,[reg_cpu_var,#sram] + and r0,r2,r0 @ address&srammask + ldrb r0,[r1,r0] @ *memory.sram + address&srammask + ldmfd r13!,{pc} @ return +gb7rom: +gb7ram: +gbnone: + mov r0,r0,lsr #8 + add reg_cycles,reg_cycles,#slow_one_cycle @ update cycles + and r0,r0,#0xff + ldmfd r13!,{pc} +@ gbdebug: + /*add reg_cycles,reg_cycles,#slow_one_cycle @ update cycles + mov r0,#0 + ldmfd r13!,{pc}*/ +gbc4: + add reg_cycles,reg_cycles,#slow_one_cycle @ update cycles + mov r0,r0,lsl #16 @ s9xgetc4(address&0xffff); + str reg_cycles,[reg_cpu_var,#cycles_ofs] @ save cycles + mov r0,r0,lsr #16 + prepare_c_call + bl _S9xGetC4 + restore_c_call + ldr reg_cycles,[reg_cpu_var,#cycles_ofs] @ load cycles + ldmfd r13!,{pc} @ return +gbdebug: +gbbwram: + mov r0,r0,lsl #17 + add reg_cycles,reg_cycles,#slow_one_cycle @ update cycles + mov r0,r0,lsr #17 @ address&0x7fff + ldr r1,[reg_cpu_var,#bwram] + sub r0,r0,#0x6000 @ ((address & 0x7fff) - 0x6000) + ldrb r0,[r0,r1] @ *memory.bwram + ((address & 0x7fff) - 0x6000) + ldmfd r13!,{pc} + + +@ uint16 aas9xgetword(uint32 address); +_asms9xgetword: + @ in : r0 = 0x00hhmmll + @ out : r0 = 0x000000ll + @ destroyed : r1,r2,r3 + @ update : reg_cycles + + + mov r1,r0,lsl #19 + adds r1,r1,#0x80000 + @ if = 0x1fff => 0 + bne gw_notboundary + + stmfd r13!,{r0} + stmfd r13!,{pc} + b _asms9xgetbyte + mov r0,r0 + ldmfd r13!,{r1} + stmfd r13!,{r0} + add r0,r1,#1 + stmfd r13!,{pc} + b _asms9xgetbyte + mov r0,r0 + ldmfd r13!,{r1} + orr r0,r1,r0,lsl #8 + ldmfd r13!,{pc} + +gw_notboundary: + + @ r1 <= block + mov r1,r0,lsr #memmap_shift + @ memmap_shift is 12, address is 0xffffffff at max, so + @ r1 is maxed by 0x000fffff, memmap_mask is 0x1000-1=0xfff + @ so and memmap_mask is bic 0xff000 + bic r1,r1,#0xff000 + @ r2 <= map[block] (getaddress) + ldr r2,[reg_cpu_var,#map_ofs] + ldr r2,[r2,r1,lsl #2] + cmp r2,#map_last + blo gwspecial @ special + @ direct rom/ram acess + + tst r0,#1 + bne gw_not_aligned1 + @ r2 <= getaddress + address & 0xffff + @ r3 <= memoryspeed[block] + ldr r3,[reg_cpu_var,#memoryspeed_ofs] + mov r0,r0,lsl #16 + ldrb r3,[r3,r1] + mov r0,r0,lsr #16 + @ update cpu.cycles + add reg_cycles,reg_cycles,r3, lsl #1 + @ r3 = blockisram[block] + ldr r3,[reg_cpu_var,#blockisram_ofs] + @ get value to return + ldrh r0,[r2,r0] + ldrb r3,[r3,r1] + movs r3,r3 + @ if blockisram => update for cpushutdown + ldrne r1,[reg_cpu_var,#pcatopcodestart_ofs] + strne r1,[reg_cpu_var,#waitaddress_ofs] + + ldmfd r13!,{pc} @ return +gw_not_aligned1: + + mov r0,r0,lsl #16 + add r3,r0,#0x10000 + ldrb r3,[r2,r3,lsr #16] @ getaddress+ (address+1)&0xffff + ldrb r0,[r2,r0,lsr #16] @ getaddress+ address&0xffff + orr r0,r0,r3,lsl #8 + + @ if blockisram => update for cpushutdown + ldr r3,[reg_cpu_var,#blockisram_ofs] + ldr r2,[reg_cpu_var,#memoryspeed_ofs] + ldrb r3,[r3,r1] @ r3 = blockisram[block] + ldrb r2,[r2,r1] @ r2 <= memoryspeed[block] + movs r3,r3 @ isram ? cpushutdown stuff + ldrne r1,[reg_cpu_var,#pcatopcodestart_ofs] + strne r1,[reg_cpu_var,#waitaddress_ofs] + add reg_cycles,reg_cycles,r2, lsl #1 @ update cpu.cycles + ldmfd r13!,{pc} @ return +gwspecial: + ldr pc,[pc,r2,lsl #2] + mov r0,r0 @ nop, for align + .long gwppu + .long gwcpu + .long gwdsp + .long gwlsram + .long gwhsram + .long gwnone + .long gwdebug + .long gwc4 + .long gwbwram + .long gwnone + .long gwnone + .long gwnone + /*.long gw7rom + .long gw7ram + .long gw7srm*/ +/* map_ppu, map_cpu, map_dsp, map_lorom_sram, map_hirom_sram, + map_none, map_debug, map_c4, map_bwram, map_bwram_bitmap, + map_bwram_bitmap2, map_sa1ram, map_last*/ + +gwppu: + @ indma ? + ldrb r1,[reg_cpu_var,#indma_ofs] + movs r1,r1 + addeq reg_cycles,reg_cycles,#two_cycle @ no -> update cycles + mov r0,r0,lsl #16 @ s9xgetppu(address&0xffff); + str reg_cycles,[reg_cpu_var,#cycles_ofs] @ save cycles + mov r0,r0,lsr #16 + prepare_c_call_r0 + bl _S9xGetPPU + ldmfd r13!,{r1} + stmfd r13!,{r0} + add r0,r1,#1 + @ bic r0,r0,#0x10000 + bl _S9xGetPPU + restore_c_call_r1 + orr r0,r1,r0,lsl #8 + ldr reg_cycles,[reg_cpu_var,#cycles_ofs] @ load cycles + ldmfd r13!,{pc} @ return +gwcpu: + add reg_cycles,reg_cycles,#two_cycle @ update cycles + mov r0,r0,lsl #16 @ s9xgetcpu(address&0xffff); + str reg_cycles,[reg_cpu_var,#cycles_ofs] @ save cycles + mov r0,r0,lsr #16 + prepare_c_call_r0 + bl _S9xGetCPU + ldmfd r13!,{r1} + stmfd r13!,{r0} + add r0,r1,#1 + @ bic r0,r0,#0x10000 + bl _S9xGetCPU + restore_c_call_r1 + orr r0,r1,r0,lsl #8 + ldr reg_cycles,[reg_cpu_var,#cycles_ofs] @ load cycles + ldmfd r13!,{pc} @ return +gwdsp: + add reg_cycles,reg_cycles,#slow_two_cycle @ update cycles + mov r0,r0,lsl #16 @ s9xgetcpu(address&0xffff); + str reg_cycles,[reg_cpu_var,#cycles_ofs] @ save cycles + mov r0,r0,lsr #16 + prepare_c_call_r0 + bl _S9xGetDSP + ldmfd r13!,{r1} + stmfd r13!,{r0} + add r0,r1,#1 + @ bic r0,r0,#0x10000 + bl _S9xGetDSP + restore_c_call_r1 + orr r0,r1,r0,lsl #8 + ldr reg_cycles,[reg_cpu_var,#cycles_ofs] @ load cycles + ldmfd r13!,{pc} @ return +gwlsram: + add reg_cycles,reg_cycles,#slow_two_cycle @ update cycles + + tst r0,#1 + bne gw_not_aligned2 + ldrh r2,[reg_cpu_var,#srammask] + ldr r1,[reg_cpu_var,#sram] + and r3,r2,r0 @ address&srammask + ldrh r0,[r3,r1] @ *memory.sram + address&srammask + ldmfd r13!,{pc} @ return +gw_not_aligned2: + ldrh r2,[reg_cpu_var,#srammask] + ldr r1,[reg_cpu_var,#sram] + and r3,r2,r0 @ address&srammask + add r0,r0,#1 + and r2,r0,r2 @ address&srammask + ldrb r3,[r1,r3] @ *memory.sram + address&srammask + ldrb r2,[r1,r2] @ *memory.sram + address&srammask + orr r0,r3,r2,lsl #8 + ldmfd r13!,{pc} @ return +gw7srm: +gwhsram: + add reg_cycles,reg_cycles,#slow_two_cycle @ update cycles + + tst r0,#1 + bne gw_not_aligned3 + + mov r1,r0,lsl #17 + and r2,r0,#0xf0000 + mov r1,r1,lsr #17 @ address&0x7fff + mov r2,r2,lsr #3 @ (address&0xf0000 >> 3) + add r0,r2,r1 + ldrh r2,[reg_cpu_var,#srammask] + sub r0,r0,#0x6000 @ ((address & 0x7fff) - 0x6000 + ((address & 0xf0000) >> 3)) + ldr r1,[reg_cpu_var,#sram] + and r0,r2,r0 @ address&srammask + ldrh r0,[r1,r0] @ *memory.sram + address&srammask + ldmfd r13!,{pc} @ return + +gw_not_aligned3: + mov r3,r0,lsl #17 + and r2,r0,#0xf0000 + mov r3,r3,lsr #17 @ address&0x7fff + mov r2,r2,lsr #3 @ (address&0xf0000 >> 3) + add r2,r2,r3 + add r0,r0,#1 + sub r2,r2,#0x6000 @ ((address & 0x7fff) - 0x6000 + ((address & 0xf0000) >> 3)) + mov r3,r0,lsl #17 + and r0,r0,#0xf0000 + mov r3,r3,lsr #17 @ (address+1)&0x7fff + mov r0,r0,lsr #3 @ ((address+1)&0xf0000 >> 3) + add r0,r0,r3 + ldrh r3,[reg_cpu_var,#srammask] @ reload mask + sub r0,r0,#0x6000 @ (((address+1) & 0x7fff) - 0x6000 + (((address+1) & 0xf0000) >> 3)) + and r2,r3,r2 @ address...&srammask + and r0,r3,r0 @ (address+1...)&srammask + + ldr r3,[reg_cpu_var,#sram] + ldrb r0,[r0,r3] @ *memory.sram + (address...)&srammask + ldrb r2,[r2,r3] @ *memory.sram + (address+1...)&srammask + orr r0,r2,r0,lsl #8 + + ldmfd r13!,{pc} @ return +gw7rom: +gw7ram: +gwnone: + mov r0,r0,lsl #16 + add reg_cycles,reg_cycles,#slow_two_cycle @ update cycles + mov r0,r0,lsr #24 + orr r0,r0,r0,lsl #8 + ldmfd r13!,{pc} +gwdebug: + add reg_cycles,reg_cycles,#slow_two_cycle @ update cycles + mov r0,#0 + ldmfd r13!,{pc} +gwc4: + add reg_cycles,reg_cycles,#slow_two_cycle @ update cycles + mov r0,r0,lsl #16 @ s9xgetc4(address&0xffff); + str reg_cycles,[reg_cpu_var,#cycles_ofs] @ save cycles + mov r0,r0,lsr #16 + prepare_c_call_r0 + bl _S9xGetC4 + ldmfd r13!,{r1} + stmfd r13!,{r0} + add r0,r1,#1 + @ bic r0,r0,#0x10000 + bl _S9xGetC4 + restore_c_call_r1 + orr r0,r1,r0,lsl #8 + ldr reg_cycles,[reg_cpu_var,#cycles_ofs] @ load cycles + ldmfd r13!,{pc} @ return +gwbwram: + tst r0,#1 + bne gw_not_aligned4 + mov r0,r0,lsl #17 + add reg_cycles,reg_cycles,#slow_two_cycle @ update cycles + mov r0,r0,lsr #17 @ address&0x7fff + ldr r1,[reg_cpu_var,#bwram] + sub r0,r0,#0x6000 @ ((address & 0x7fff) - 0x6000) + ldrh r0,[r1,r0] @ *memory.bwram + ((address & 0x7fff) - 0x6000) + ldmfd r13!,{pc} @ return +gw_not_aligned4: + mov r0,r0,lsl #17 + add reg_cycles,reg_cycles,#slow_two_cycle @ update cycles + add r3,r0,#0x20000 + mov r0,r0,lsr #17 @ address&0x7fff + mov r3,r3,lsr #17 @ (address+1)&0x7fff + ldr r1,[reg_cpu_var,#bwram] + sub r0,r0,#0x6000 @ ((address & 0x7fff) - 0x6000) + sub r3,r3,#0x6000 @ (((address+1) & 0x7fff) - 0x6000) + ldrb r0,[r1,r0] @ *memory.bwram + ((address & 0x7fff) - 0x6000) + ldrb r3,[r1,r3] @ *memory.bwram + (((address+1) & 0x7fff) - 0x6000) + orr r0,r0,r3,lsl #8 + ldmfd r13!,{pc} @ return + + + + +@ void aas9xsetbyte(uint32 address,uint8 val); +_asms9xsetbyte: + @ in : r0=0x00hhmmll r1=0x000000ll + @ destroyed : r0,r1,r2,r3 + @ update : reg_cycles + @ cpu shutdown + mov r2,#0 + str r2,[reg_cpu_var,#waitaddress_ofs] + @ + + @ r3 <= block + mov r3,r0,lsr #memmap_shift + @ memmap_shift is 12, address is 0xffffffff at max, so + @ r0 is maxed by 0x000fffff, memmap_mask is 0x1000-1=0xfff + @ so and memmap_mask is bic 0xff000 + bic r3,r3,#0xff000 + @ r2 <= map[block] (setaddress) + ldr r2,[reg_cpu_var,#writemap_ofs] + ldr r2,[r2,r3,lsl #2] + cmp r2,#map_last + blo sbspecial @ special + @ direct rom/ram acess + + @ r2 <= setaddress + address & 0xffff + mov r0,r0,lsl #16 + add r2,r2,r0,lsr #16 + ldr r0,[reg_cpu_var,#memoryspeed_ofs] + @ set byte + strb r1,[r2] + @ r0 <= memoryspeed[block] + ldrb r0,[r0,r3] + @ update cpu.cycles + add reg_cycles,reg_cycles,r0 + @ cpushutdown + @ only sa1 here : todo + @ return + ldmfd r13!,{pc} +sbspecial: + ldr pc,[pc,r2,lsl #2] + mov r0,r0 @ nop, for align + .long sbppu + .long sbcpu + .long sbdsp + .long sblsram + .long sbhsram + .long sbnone + .long sbdebug + .long sbc4 + .long sbbwram + .long sbnone + .long sbnone + .long sbnone + /*.long sb7rom + .long sb7ram + .long sb7srm*/ +sbppu: + @ indma ? + ldrb r2,[reg_cpu_var,#indma_ofs] + movs r2,r2 + addeq reg_cycles,reg_cycles,#one_cycle @ no -> update cycles + mov r0,r0,lsl #16 + str reg_cycles,[reg_cpu_var,#cycles_ofs] @ save cycles + mov r0,r0,lsr #16 + prepare_c_call + mov r12,r0 + mov r0,r1 + mov r1,r12 + bl _S9xSetPPU + restore_c_call + ldr reg_cycles,[reg_cpu_var,#cycles_ofs] @ load cycles + ldmfd r13!,{pc} @ return +sbcpu: + add reg_cycles,reg_cycles,#one_cycle @ update cycles + mov r0,r0,lsl #16 + str reg_cycles,[reg_cpu_var,#cycles_ofs] @ save cycles + mov r0,r0,lsr #16 @ address&0xffff + prepare_c_call + mov r12,r0 + mov r0,r1 + mov r1,r12 + bl _S9xSetCPU + restore_c_call + ldr reg_cycles,[reg_cpu_var,#cycles_ofs] @ load cycles + ldmfd r13!,{pc} @ return +sbdsp: + add reg_cycles,reg_cycles,#slow_one_cycle @ update cycles + mov r0,r0,lsl #16 + str reg_cycles,[reg_cpu_var,#cycles_ofs] @ save cycles + mov r0,r0,lsr #16 @ address&0xffff + prepare_c_call + mov r12,r0 + mov r0,r1 + mov r1,r12 + bl _S9xSetDSP + restore_c_call + ldr reg_cycles,[reg_cpu_var,#cycles_ofs] @ load cycles + ldmfd r13!,{pc} @ return +sblsram: + add reg_cycles,reg_cycles,#slow_one_cycle @ update cycles + ldrh r2,[reg_cpu_var,#srammask] + movs r2,r2 + ldmeqfd r13!,{pc} @ return if srammask=0 + ldr r3,[reg_cpu_var,#sram] + and r0,r2,r0 @ address&srammask + strb r1,[r0,r3] @ *memory.sram + address&srammask + + mov r0,#1 + strb r0,[reg_cpu_var,#srammodified_ofs] + ldmfd r13!,{pc} @ return +sb7srm: +sbhsram: + add reg_cycles,reg_cycles,#slow_one_cycle @ update cycles + + mov r3,r0,lsl #17 + and r2,r0,#0xf0000 + mov r3,r3,lsr #17 @ address&0x7fff + mov r2,r2,lsr #3 @ (address&0xf0000 >> 3) + add r0,r2,r3 + + ldrh r2,[reg_cpu_var,#srammask] + movs r2,r2 + ldmeqfd r13!,{pc} @ return if srammask=0 + + sub r0,r0,#0x6000 @ ((address & 0x7fff) - 0x6000 + ((address & 0xf0000) >> 3)) + ldr r3,[reg_cpu_var,#sram] + and r0,r2,r0 @ address&srammask + strb r1,[r0,r3] @ *memory.sram + address&srammask + + mov r0,#1 + strb r0,[reg_cpu_var,#srammodified_ofs] + ldmfd r13!,{pc} @ return +sb7rom: +sb7ram: +sbnone: +sbdebug: + add reg_cycles,reg_cycles,#slow_one_cycle @ update cycles + ldmfd r13!,{pc} +sbc4: + add reg_cycles,reg_cycles,#slow_one_cycle @ update cycles + mov r0,r0,lsl #16 + str reg_cycles,[reg_cpu_var,#cycles_ofs] @ save cycles + mov r0,r0,lsr #16 @ address&0xffff + prepare_c_call + mov r12,r0 + mov r0,r1 + mov r1,r12 + bl _S9xSetC4 + restore_c_call + ldr reg_cycles,[reg_cpu_var,#cycles_ofs] @ load cycles + ldmfd r13!,{pc} @ return +sbbwram: + mov r0,r0,lsl #17 + add reg_cycles,reg_cycles,#slow_one_cycle @ update cycles + mov r0,r0,lsr #17 @ address&0x7fff + ldr r2,[reg_cpu_var,#bwram] + sub r0,r0,#0x6000 @ ((address & 0x7fff) - 0x6000) + strb r1,[r0,r2] @ *memory.bwram + ((address & 0x7fff) - 0x6000) + + mov r0,#1 + strb r0,[reg_cpu_var,#srammodified_ofs] + + ldmfd r13!,{pc} + + + +@ void aas9xsetword(uint32 address,uint16 val); +_asms9xsetword: + @ in : r0 = 0x00hhmmll r1=0x0000hhll + @ destroyed : r0,r1,r2,r3 + @ update : reg_cycles + @ r1 <= block + + mov r2,r0,lsl #19 + adds r2,r2,#0x80000 + @ if = 0x1fff => 0 + bne sw_notboundary + + stmfd r13!,{r0,r1} + stmfd r13!,{pc} + b _asms9xsetbyte + mov r0,r0 + ldmfd r13!,{r0,r1} + add r0,r0,#1 + mov r1,r1,lsr #8 + stmfd r13!,{pc} + b _asms9xsetbyte + mov r0,r0 + + ldmfd r13!,{pc} + +sw_notboundary: + + mov r2,#0 + str r2,[reg_cpu_var,#waitaddress_ofs] + @ + @ r3 <= block + mov r3,r0,lsr #memmap_shift + @ memmap_shift is 12, address is 0xffffffff at max, so + @ r1 is maxed by 0x000fffff, memmap_mask is 0x1000-1=0xfff + @ so and memmap_mask is bic 0xff000 + bic r3,r3,#0xff000 + @ r2 <= map[block] (setaddress) + ldr r2,[reg_cpu_var,#writemap_ofs] + ldr r2,[r2,r3,lsl #2] + cmp r2,#map_last + blo swspecial @ special + @ direct rom/ram acess + + + @ check if address is 16bits aligned or not + tst r0,#1 + bne sw_not_aligned1 + @ aligned + mov r0,r0,lsl #16 + add r2,r2,r0,lsr #16 @ address & 0xffff + setaddress + ldr r0,[reg_cpu_var,#memoryspeed_ofs] + @ set word + strh r1,[r2] + @ r1 <= memoryspeed[block] + ldrb r0,[r0,r3] + @ update cpu.cycles + add reg_cycles,reg_cycles,r0, lsl #1 + @ cpushutdown + @ only sa1 here : todo + @ return + ldmfd r13!,{pc} + +sw_not_aligned1: + @ r1 = (address&0xffff)<<16 + mov r0,r0,lsl #16 + @ first write @address + strb r1,[r2,r0,lsr #16] + add r0,r0,#0x10000 + mov r1,r1,lsr #8 + @ second write @address+1 + strb r1,[r2,r0,lsr #16] + @ r1 <= memoryspeed[block] + ldr r0,[reg_cpu_var,#memoryspeed_ofs] + ldrb r0,[r0,r3] + @ update cpu.cycles + add reg_cycles,reg_cycles,r0,lsl #1 + @ cpushutdown + @ only sa1 here : todo + @ return + ldmfd r13!,{pc} +swspecial: + ldr pc,[pc,r2,lsl #2] + mov r0,r0 @ nop, for align + .long swppu + .long swcpu + .long swdsp + .long swlsram + .long swhsram + .long swnone + .long swdebug + .long swc4 + .long swbwram + .long swnone + .long swnone + .long swnone + /*.long sw7rom + .long sw7ram + .long sw7srm*/ +swppu: + @ indma ? + ldrb r2,[reg_cpu_var,#indma_ofs] + movs r2,r2 + addeq reg_cycles,reg_cycles,#two_cycle @ no -> update cycles + mov r0,r0,lsl #16 + str reg_cycles,[reg_cpu_var,#cycles_ofs] @ save cycles + mov r0,r0,lsr #16 + mov r2,r1 + mov r1,r0 + mov r0,r2 + prepare_c_call_r0r1 + bl _S9xSetPPU + ldmfd r13!,{r0,r1} + add r1,r1,#1 + mov r0,r0,lsr #8 + bic r1,r1,#0x10000 + bl _S9xSetPPU + restore_c_call + ldr reg_cycles,[reg_cpu_var,#cycles_ofs] @ load cycles + ldmfd r13!,{pc} @ return +swcpu: + add reg_cycles,reg_cycles,#two_cycle @ update cycles + mov r0,r0,lsl #16 + str reg_cycles,[reg_cpu_var,#cycles_ofs] @ save cycles + mov r0,r0,lsr #16 @ address&0xffff + mov r2,r1 + mov r1,r0 + mov r0,r2 + prepare_c_call_r0r1 + bl _S9xSetCPU + ldmfd r13!,{r0,r1} + add r1,r1,#1 + mov r0,r0,lsr #8 + bic r1,r1,#0x10000 + bl _S9xSetCPU + restore_c_call + ldr reg_cycles,[reg_cpu_var,#cycles_ofs] @ load cycles + ldmfd r13!,{pc} @ return +swdsp: + add reg_cycles,reg_cycles,#slow_one_cycle @ update cycles + mov r0,r0,lsl #16 + str reg_cycles,[reg_cpu_var,#cycles_ofs] @ save cycles + mov r0,r0,lsr #16 @ address&0xffff + mov r2,r1 + mov r1,r0 + mov r0,r2 + prepare_c_call_r0r1 + bl _S9xSetDSP + ldmfd r13!,{r0,r1} + add r1,r1,#1 + mov r0,r0,lsr #8 + bic r1,r1,#0x10000 + bl _S9xSetDSP + restore_c_call + ldr reg_cycles,[reg_cpu_var,#cycles_ofs] @ load cycles + ldmfd r13!,{pc} @ return +swlsram: + add reg_cycles,reg_cycles,#slow_two_cycle @ update cycles + ldrh r2,[reg_cpu_var,#srammask] + movs r2,r2 + ldmeqfd r13!,{pc} @ return if srammask=0 + + and r3,r2,r0 @ address&srammask + tst r0,#1 + bne sw_not_aligned2 + @ aligned + ldr r0,[reg_cpu_var,#sram] + strh r1,[r0,r3] @ *memory.sram + address&srammask + mov r0,#1 + strb r0,[reg_cpu_var,#srammodified_ofs] + ldmfd r13!,{pc} @ return +sw_not_aligned2: + + add r0,r0,#1 + and r2,r2,r0 @ (address+1)&srammask + ldr r0,[reg_cpu_var,#sram] + strb r1,[r0,r3] @ *memory.sram + address&srammask + mov r1,r1,lsr #8 + strb r1,[r0,r2] @ *memory.sram + (address+1)&srammask + mov r0,#1 + strb r0,[reg_cpu_var,#srammodified_ofs] + ldmfd r13!,{pc} @ return +sw7srm: +swhsram: + add reg_cycles,reg_cycles,#slow_two_cycle @ update cycles + + ldrh r2,[reg_cpu_var,#srammask] + movs r2,r2 + ldmeqfd r13!,{pc} @ return if srammask=0 + + tst r0,#1 + bne sw_not_aligned3 + @ aligned + mov r3,r0,lsl #17 + and r2,r0,#0xf0000 + mov r3,r3,lsr #17 @ address&0x7fff + mov r2,r2,lsr #3 @ (address&0xf0000 >> 3) + add r0,r2,r3 + sub r0,r0,#0x6000 @ ((address & 0x7fff) - 0x6000 + ((address & 0xf0000) >> 3)) + ldrh r2,[reg_cpu_var,#srammask] + ldr r3,[reg_cpu_var,#sram] + and r0,r2,r0 @ address&srammask + strh r1,[r0,r3] @ *memory.sram + address&srammask + mov r0,#1 + strb r0,[reg_cpu_var,#srammodified_ofs] + ldmfd r13!,{pc} @ return +sw_not_aligned3: + mov r3,r0,lsl #17 + and r2,r0,#0xf0000 + mov r3,r3,lsr #17 @ address&0x7fff + mov r2,r2,lsr #3 @ (address&0xf0000 >> 3) + add r2,r2,r3 + sub r2,r2,#0x6000 @ ((address & 0x7fff) - 0x6000 + ((address & 0xf0000) >> 3)) + + add r0,r0,#1 + mov r3,r0,lsl #17 + and r0,r0,#0xf0000 + mov r3,r3,lsr #17 @ (address+1)&0x7fff + mov r0,r0,lsr #3 @ ((address+1)&0xf0000 >> 3) + add r0,r0,r3 + ldrh r3,[reg_cpu_var,#srammask] @ reload mask + sub r0,r0,#0x6000 @ (((address+1) & 0x7fff) - 0x6000 + (((address+1) & 0xf0000) >> 3)) + and r2,r3,r2 @ address...&srammask + and r0,r3,r0 @ (address+1...)&srammask + + ldr r3,[reg_cpu_var,#sram] + strb r1,[r2,r3] @ *memory.sram + (address...)&srammask + mov r1,r1,lsr #8 + strb r1,[r0,r3] @ *memory.sram + (address+1...)&srammask + + mov r0,#1 + strb r0,[reg_cpu_var,#srammodified_ofs] + ldmfd r13!,{pc} @ return +sw7rom: +sw7ram: +swnone: +swdebug: + add reg_cycles,reg_cycles,#slow_two_cycle @ update cycles + ldmfd r13!,{pc} @ return +swc4: + add reg_cycles,reg_cycles,#slow_two_cycle @ update cycles + mov r0,r0,lsl #16 + str reg_cycles,[reg_cpu_var,#cycles_ofs] @ save cycles + mov r0,r0,lsr #16 @ address&0xffff + mov r2,r1 + mov r1,r0 + mov r0,r2 + prepare_c_call_r0r1 + bl _S9xSetC4 + ldmfd r13!,{r0,r1} + add r1,r1,#1 + mov r0,r0,lsr #8 + bic r1,r1,#0x10000 + bl _S9xSetC4 + restore_c_call + ldr reg_cycles,[reg_cpu_var,#cycles_ofs] @ load cycles + ldmfd r13!,{pc} @ return +swbwram: + add reg_cycles,reg_cycles,#slow_two_cycle @ update cycles + tst r0,#1 + bne sw_not_aligned4 + @ aligned + mov r0,r0,lsl #17 + ldr r2,[reg_cpu_var,#bwram] + mov r0,r0,lsr #17 @ address&0x7fff + sub r0,r0,#0x6000 @ ((address & 0x7fff) - 0x6000) + mov r3,#1 + strh r1,[r0,r2] @ *memory.bwram + ((address & 0x7fff) - 0x6000) + strb r3,[reg_cpu_var,#srammodified_ofs] + ldmfd r13!,{pc} @ return +sw_not_aligned4: + mov r0,r0,lsl #17 + add r3,r0,#0x20000 + mov r0,r0,lsr #17 @ address&0x7fff + mov r3,r3,lsr #17 @ (address+1)&0x7fff + ldr r2,[reg_cpu_var,#bwram] + sub r0,r0,#0x6000 @ ((address & 0x7fff) - 0x6000) + sub r3,r3,#0x6000 @ (((address+1) & 0x7fff) - 0x6000) + strb r1,[r2,r0] @ *memory.bwram + ((address & 0x7fff) - 0x6000) + mov r1,r1,lsr #8 + strb r1,[r2,r3] @ *memory.bwram + (((address+1) & 0x7fff) - 0x6000) + mov r0,#1 + strb r0,[reg_cpu_var,#srammodified_ofs] + ldmfd r13!,{pc} @ return + + + + + +/***************************************************************** + flags +*****************************************************************/ + +.macro update_c + @ cc : arm carry clear + biccc rstatus, rstatus, #mask_carry @ 0 : and mask 11111011111 : set c to zero + @ cs : arm carry set + orrcs rstatus, rstatus, #mask_carry @ 1 : or mask 00000100000 : set c to one +.endm +.macro update_z + @ ne : arm zero clear + bicne rstatus, rstatus, #mask_zero @ 0 : and mask 11111011111 : set z to zero + @ eq : arm zero set + orreq rstatus, rstatus, #mask_zero @ 1 : or mask 00000100000 : set z to one +.endm +.macro update_zn + @ ne : arm zero clear + bicne rstatus, rstatus, #mask_zero @ 0 : and mask 11111011111 : set z to zero + @ eq : arm zero set + orreq rstatus, rstatus, #mask_zero @ 1 : or mask 00000100000 : set z to one + @ pl : arm neg clear + bicpl rstatus, rstatus, #mask_neg @ 0 : and mask 11111011111 : set n to zero + @ mi : arm neg set + orrmi rstatus, rstatus, #mask_neg @ 1 : or mask 00000100000 : set n to one +.endm + +/***************************************************************** + opcodes_mac +*****************************************************************/ + + + + +.macro adc8 + tst rstatus, #mask_decimal + beq 1111f + s9xgetbyte + + + stmfd r13!,{rscratch} + mov rscratch4,#0x0f000000 + @ rscratch2=xxw1xxxxxxxxxxxx + and rscratch2, rscratch, rscratch4 + @ rscratch=xxw2xxxxxxxxxxxx + and rscratch, rscratch4, rscratch, lsr #4 + @ rscratch3=xxa2xxxxxxxxxxxx + and rscratch3, rscratch4, reg_a, lsr #4 + @ rscratch4=xxa1xxxxxxxxxxxx + and rscratch4,reg_a,rscratch4 + @ r1=a1+w1+carry + tst rstatus, #mask_carry + addne rscratch2, rscratch2, #0x01000000 + add rscratch2,rscratch2,rscratch4 + @ if r1 > 9 + cmp rscratch2, #0x09000000 + @ then r1 -= 10 + subgt rscratch2, rscratch2, #0x0a000000 + @ then a2++ + addgt rscratch3, rscratch3, #0x01000000 + @ r2 = a2+w2 + add rscratch3, rscratch3, rscratch + @ if r2 > 9 + cmp rscratch3, #0x09000000 + @ then r2 -= 10@ + subgt rscratch3, rscratch3, #0x0a000000 + @ then setcarry() + orrgt rstatus, rstatus, #mask_carry @ 1 : or mask 00000100000 : set c to one + @ else clearcarry() + bicle rstatus, rstatus, #mask_carry @ 0 : and mask 11111011111 : set c to zero + @ gather rscratch3 and rscratch2 into ans8 + @ rscratch3 : 0r2000000 + @ rscratch2 : 0r1000000 + @ -> 0xr2r1000000 + orr rscratch2, rscratch2, rscratch3, lsl #4 + ldmfd r13!,{rscratch} + @ only last bit + and rscratch,rscratch,#0x80000000 + @ (register.al ^ work8) + eors rscratch3, reg_a, rscratch + bicne rstatus, rstatus, #mask_overflow @ 0 : and mask 11111011111 : set v to zero + bne 1112f + @ (work8 ^ ans8) + eors rscratch3, rscratch2, rscratch + @ & 0x80 + tstne rscratch3,#0x80000000 + biceq rstatus, rstatus, #mask_overflow @ 0 : and mask 11111011111 : set v to zero + orrne rstatus, rstatus, #mask_overflow @ 1 : or mask 00000100000 : set v to one +1112: + movs reg_a, rscratch2 + update_zn + b 1113f +1111: + s9xgetbytelow + movs rscratch2, rstatus, lsr #mask_shifter_carry + subcs rscratch, rscratch, #0x100 + adcs reg_a, reg_a, rscratch, ror #8 + @ overflow + orrvs rstatus, rstatus, #mask_overflow + bicvc rstatus, rstatus, #mask_overflow + @ carry + update_c + @ clear lower part + ands reg_a, reg_a, #0xff000000 + @ update flag + update_zn +1113: +.endm +/* to test */ +.macro adc16 + tst rstatus, #mask_decimal + beq 1111f + s9xgetword + + @ rscratch = w3w2w1w0........ + @ PATCH ldr rscratch4, = 0x0f0f0000 + mov rscratch4, #0x0f0000 + orr rscratch4, rscratch4, #0x0f000000 + @ rscratch2 = xxw2xxw0xxxxxx + @ rscratch3 = xxw3xxw1xxxxxx + and rscratch2, rscratch4, rscratch + and rscratch3, rscratch4, rscratch, lsr #4 + @ rscratch2 = xxw3xxw1xxw2xxw0 + orr rscratch2, rscratch3, rscratch2, lsr #16 + @ rscratch3 = xxa2xxa0xxxxxx + @ rscratch4 = xxa3xxa1xxxxxx + @ rscratch2 = xxa3xxa1xxa2xxa0 + and rscratch3, rscratch4, reg_a + and rscratch4, rscratch4, reg_a, lsr #4 + orr rscratch3, rscratch4, rscratch3, lsr #16 + add rscratch2, rscratch3, rscratch2 + @ PATCH ldr rscratch4, = 0x0f0f0000 + mov rscratch4, #0x0f0000 + orr rscratch4, rscratch4, #0x0f000000 + @ rscratch2 = a + w + tst rstatus, #mask_carry + addne rscratch2, rscratch2, #0x1 + @ rscratch2 = a + w + c + @ a0 + and rscratch3, rscratch2, #0x0000001f + cmp rscratch3, #0x00000009 + addhi rscratch2, rscratch2, #0x00010000 + subhi rscratch2, rscratch2, #0x0000000a + @ a1 + and rscratch3, rscratch2, #0x001f0000 + cmp rscratch3, #0x00090000 + addhi rscratch2, rscratch2, #0x00000100 + subhi rscratch2, rscratch2, #0x000a0000 + @ a2 + and rscratch3, rscratch2, #0x00001f00 + cmp rscratch3, #0x00000900 + subhi rscratch2, rscratch2, #0x00000a00 + addhi rscratch2, rscratch2, #0x01000000 + @ a3 + and rscratch3, rscratch2, #0x1f000000 + cmp rscratch3, #0x09000000 + subhi rscratch2, rscratch2, #0x0a000000 + @ setcarry + orrhi rstatus, rstatus, #mask_carry + @ clearcarry + bicls rstatus, rstatus, #mask_carry + @ rscratch2 = xxr3xxr1xxr2xxr0 + @ pack result + @ rscratch3 = xxr3xxr1xxxxxxxx + and rscratch3, rscratch4, rscratch2 + @ rscratch2 = xxr2xxr0xxxxxxxx + and rscratch2, rscratch4, rscratch2,lsl #16 + @ rscratch2 = r3r2r1r0xxxxxxxx + orr rscratch2, rscratch2,rscratch3,lsl #4 +@ only last bit + and rscratch,rscratch,#0x80000000 + @ (register.al ^ work8) + eors rscratch3, reg_a, rscratch + bicne rstatus, rstatus, #mask_overflow @ 0 : and mask 11111011111 : set v to zero + bne 1112f + @ (work8 ^ ans8) + eors rscratch3, rscratch2, rscratch + tstne rscratch3,#0x80000000 + biceq rstatus, rstatus, #mask_overflow @ 0 : and mask 11111011111 : set v to zero + orrne rstatus, rstatus, #mask_overflow @ 1 : or mask 00000100000 : set v to one +1112: + movs reg_a, rscratch2 + update_zn + b 1113f +1111: + s9xgetwordlow + movs rscratch2, rstatus, lsr #mask_shifter_carry + subcs rscratch, rscratch, #0x10000 + adcs reg_a, reg_a,rscratch, ror #16 + @ overflow + orrvs rstatus, rstatus, #mask_overflow + bicvc rstatus, rstatus, #mask_overflow + mov reg_a, reg_a, lsr #16 + @ carry + update_c + @ clear lower parts + movs reg_a, reg_a, lsl #16 + @ update flag + update_zn +1113: +.endm + + +.macro and16 + s9xgetword + ands reg_a, reg_a, rscratch + update_zn +.endm +.macro and8 + s9xgetbyte + ands reg_a, reg_a, rscratch + update_zn +.endm +.macro a_asl8 + @ 7 instr + movs reg_a, reg_a, lsl #1 + update_c + update_zn + add1cycle +.endm +.macro a_asl16 + @ 7 instr + movs reg_a, reg_a, lsl #1 + update_c + update_zn + add1cycle +.endm +.macro asl16 + s9xgetwordregns rscratch2 @ do not destroy opadress in rscratch + movs rscratch2, rscratch2, lsl #1 + update_c + update_zn + s9xsetword rscratch2 + add1cycle +.endm +.macro asl8 + s9xgetbyteregns rscratch2 @ do not destroy opadress in rscratch + movs rscratch2, rscratch2, lsl #1 + update_c + update_zn + s9xsetbyte rscratch2 + add1cycle +.endm +.macro bit8 + s9xgetbyte + movs rscratch2, rscratch, lsl #1 + @ trick in asm : shift one more bit : arm c = snes n + @ arm n = snes v + @ if carry set, then set neg in snes + biccc rstatus, rstatus, #mask_neg @ 0 : and mask 11111011111 : set c to zero + orrcs rstatus, rstatus, #mask_neg @ 1 : or mask 00000100000 : set c to one + @ if neg set, then set overflow in snes + bicpl rstatus, rstatus, #mask_overflow @ 0 : and mask 11111011111 : set n to zero + orrmi rstatus, rstatus, #mask_overflow @ 1 : or mask 00000100000 : set n to one + + @ now do a real and with a register + @ set zero flag, bit test + ands rscratch2, reg_a, rscratch + bicne rstatus, rstatus, #mask_zero @ 0 : and mask 11111011111 : set z to zero + orreq rstatus, rstatus, #mask_zero @ 1 : or mask 00000100000 : set z to one +.endm + +.macro bit16 + s9xgetword + movs rscratch2, rscratch, lsl #1 + @ trick in asm : shift one more bit : arm c = snes n + @ arm n = snes v + @ if carry set, then set neg in snes + biccc rstatus, rstatus, #mask_neg @ 0 : and mask 11111011111 : set n to zero + orrcs rstatus, rstatus, #mask_neg @ 1 : or mask 00000100000 : set n to one + @ if neg set, then set overflow in snes + bicpl rstatus, rstatus, #mask_overflow @ 0 : and mask 11111011111 : set v to zero + orrmi rstatus, rstatus, #mask_overflow @ 1 : or mask 00000100000 : set v to one + @ now do a real and with a register + @ set zero flag, bit test + ands rscratch2, reg_a, rscratch + @ bit set ->z=0->xxxne clear flag + bicne rstatus, rstatus, #mask_zero @ 0 : and mask 11111011111 : set z to zero + @ bit clear->z=1->xxxeq set flag + orreq rstatus, rstatus, #mask_zero @ 1 : or mask 00000100000 : set z to one +.endm +.macro cmp8 + s9xgetbyte + subs rscratch2,reg_a,rscratch + biccc rstatus, rstatus, #mask_carry + orrcs rstatus, rstatus, #mask_carry + update_zn + +.endm +.macro cmp16 + s9xgetword + subs rscratch2,reg_a,rscratch + biccc rstatus, rstatus, #mask_carry + orrcs rstatus, rstatus, #mask_carry + update_zn + +.endm +.macro cmx16 + s9xgetword + subs rscratch2,reg_x,rscratch + biccc rstatus, rstatus, #mask_carry + orrcs rstatus, rstatus, #mask_carry + update_zn +.endm +.macro cmx8 + s9xgetbyte + subs rscratch2,reg_x,rscratch + biccc rstatus, rstatus, #mask_carry + orrcs rstatus, rstatus, #mask_carry + update_zn +.endm +.macro cmy16 + s9xgetword + subs rscratch2,reg_y,rscratch + biccc rstatus, rstatus, #mask_carry + orrcs rstatus, rstatus, #mask_carry + update_zn +.endm +.macro cmy8 + s9xgetbyte + subs rscratch2,reg_y,rscratch + biccc rstatus, rstatus, #mask_carry + orrcs rstatus, rstatus, #mask_carry + update_zn +.endm +.macro a_dec8 + mov rscratch,#0 + subs reg_a, reg_a, #0x01000000 + str rscratch,[reg_cpu_var,#waitaddress_ofs] + update_zn + add1cycle +.endm +.macro a_dec16 + mov rscratch,#0 + subs reg_a, reg_a, #0x00010000 + str rscratch,[reg_cpu_var,#waitaddress_ofs] + update_zn + add1cycle +.endm +.macro dec16 + s9xgetwordregns rscratch2 @ do not destroy opadress in rscratch + mov rscratch3,#0 + subs rscratch2, rscratch2, #0x00010000 + str rscratch3,[reg_cpu_var,#waitaddress_ofs] + update_zn + s9xsetword rscratch2 + add1cycle +.endm +.macro dec8 + s9xgetbyteregns rscratch2 @ do not destroy opadress in rscratch + mov rscratch3,#0 + subs rscratch2, rscratch2, #0x01000000 + str rscratch3,[reg_cpu_var,#waitaddress_ofs] + update_zn + s9xsetbyte rscratch2 + add1cycle +.endm +.macro eor16 + s9xgetword + eors reg_a, reg_a, rscratch + update_zn +.endm +.macro eor8 + s9xgetbyte + eors reg_a, reg_a, rscratch + update_zn +.endm +.macro a_inc8 + mov rscratch3,#0 + adds reg_a, reg_a, #0x01000000 + str rscratch3,[reg_cpu_var,#waitaddress_ofs] + update_zn + add1cycle +.endm +.macro a_inc16 + mov rscratch3,#0 + adds reg_a, reg_a, #0x00010000 + str rscratch3,[reg_cpu_var,#waitaddress_ofs] + update_zn + add1cycle +.endm +.macro inc16 + s9xgetwordregns rscratch2 + mov rscratch3,#0 + adds rscratch2, rscratch2, #0x00010000 + str rscratch3,[reg_cpu_var,#waitaddress_ofs] + update_zn + s9xsetword rscratch2 + add1cycle +.endm +.macro inc8 + s9xgetbyteregns rscratch2 + mov rscratch3,#0 + adds rscratch2, rscratch2, #0x01000000 + str rscratch3,[reg_cpu_var,#waitaddress_ofs] + update_zn + s9xsetbyte rscratch2 + add1cycle +.endm +.macro lda16 + s9xgetwordregstatus reg_a + update_zn +.endm +.macro lda8 + s9xgetbyteregstatus reg_a + update_zn +.endm +.macro ldx16 + s9xgetwordregstatus reg_x + update_zn +.endm +.macro ldx8 + s9xgetbyteregstatus reg_x + update_zn +.endm +.macro ldy16 + s9xgetwordregstatus reg_y + update_zn +.endm +.macro ldy8 + s9xgetbyteregstatus reg_y + update_zn +.endm +.macro a_lsr16 + bic rstatus, rstatus, #mask_neg @ 0 : and mask 11111011111 : set n to zero + movs reg_a, reg_a, lsr #17 @ hhhhhhhh llllllll 00000000 00000000 -> 00000000 00000000 0hhhhhhh hlllllll + @ update zero + bicne rstatus, rstatus, #mask_zero @ 0 : and mask 11111011111 : set z to zero + mov reg_a, reg_a, lsl #16 @ -> 0lllllll 00000000 00000000 00000000 + orreq rstatus, rstatus, #mask_zero @ 1 : or mask 00000100000 : set z to one + @ note : the two mov are included between instruction, to optimize + @ the pipeline. + update_c + add1cycle +.endm +.macro a_lsr8 + bic rstatus, rstatus, #mask_neg @ 0 : and mask 11111011111 : set n to zero + movs reg_a, reg_a, lsr #25 @ llllllll 00000000 00000000 00000000 -> 00000000 00000000 00000000 0lllllll + @ update zero + bicne rstatus, rstatus, #mask_zero @ 0 : and mask 11111011111 : set z to zero + mov reg_a, reg_a, lsl #24 @ -> 00000000 00000000 00000000 0lllllll + orreq rstatus, rstatus, #mask_zero @ 1 : or mask 00000100000 : set z to one + @ note : the two mov are included between instruction, to optimize + @ the pipeline. + update_c + add1cycle +.endm +.macro lsr16 + s9xgetwordregns rscratch2 + @ n set to zero by >> 1 lsr + bic rstatus, rstatus, #mask_neg @ 0 : and mask 11111011111 : set n to zero + movs rscratch2, rscratch2, lsr #17 @ llllllll 00000000 00000000 00000000 -> 00000000 00000000 00000000 0lllllll + @ update carry + biccc rstatus, rstatus, #mask_carry @ 0 : and mask 11111011111 : set c to zero + orrcs rstatus, rstatus, #mask_carry @ 1 : or mask 00000100000 : set c to one + @ update zero + bicne rstatus, rstatus, #mask_zero @ 0 : and mask 11111011111 : set z to zero + orreq rstatus, rstatus, #mask_zero @ 1 : or mask 00000100000 : set z to one + s9xsetwordlow rscratch2 + add1cycle +.endm +.macro lsr8 + s9xgetbyteregns rscratch2 + @ n set to zero by >> 1 lsr + bic rstatus, rstatus, #mask_neg @ 0 : and mask 11111011111 : set n to zero + movs rscratch2, rscratch2, lsr #25 @ llllllll 00000000 00000000 00000000 -> 00000000 00000000 00000000 0lllllll + @ update carry + biccc rstatus, rstatus, #mask_carry @ 0 : and mask 11111011111 : set c to zero + orrcs rstatus, rstatus, #mask_carry @ 1 : or mask 00000100000 : set c to one + @ update zero + bicne rstatus, rstatus, #mask_zero @ 0 : and mask 11111011111 : set z to zero + orreq rstatus, rstatus, #mask_zero @ 1 : or mask 00000100000 : set z to one + s9xsetbytelow rscratch2 + add1cycle +.endm +.macro ora8 + s9xgetbyte + orrs reg_a, reg_a, rscratch + update_zn +.endm +.macro ora16 + s9xgetword + orrs reg_a, reg_a, rscratch + update_zn +.endm +.macro a_rol16 + tst rstatus, #mask_carry + orrne reg_a, reg_a, #0x00008000 + movs reg_a, reg_a, lsl #1 + update_zn + update_c + add1cycle +.endm +.macro a_rol8 + tst rstatus, #mask_carry + orrne reg_a, reg_a, #0x00800000 + movs reg_a, reg_a, lsl #1 + update_zn + update_c + add1cycle +.endm +.macro rol16 + s9xgetwordregns rscratch2 + tst rstatus, #mask_carry + orrne rscratch2, rscratch2, #0x00008000 + movs rscratch2, rscratch2, lsl #1 + update_zn + update_c + s9xsetword rscratch2 + add1cycle +.endm +.macro rol8 + s9xgetbyteregns rscratch2 + tst rstatus, #mask_carry + orrne rscratch2, rscratch2, #0x00800000 + movs rscratch2, rscratch2, lsl #1 + update_zn + update_c + s9xsetbyte rscratch2 + add1cycle +.endm +.macro a_ror16 + mov reg_a,reg_a, lsr #16 + tst rstatus, #mask_carry + orrne reg_a, reg_a, #0x00010000 + orrne rstatus,rstatus,#mask_neg + biceq rstatus,rstatus,#mask_neg + movs reg_a,reg_a,lsr #1 + update_c + update_z + mov reg_a,reg_a, lsl #16 + add1cycle +.endm +.macro a_ror8 + mov reg_a,reg_a, lsr #24 + tst rstatus, #mask_carry + orrne reg_a, reg_a, #0x00000100 + orrne rstatus,rstatus,#mask_neg + biceq rstatus,rstatus,#mask_neg + movs reg_a,reg_a,lsr #1 + update_c + update_z + mov reg_a,reg_a, lsl #24 + add1cycle +.endm +.macro ror16 + s9xgetwordlowregns rscratch2 + tst rstatus, #mask_carry + orrne rscratch2, rscratch2, #0x00010000 + orrne rstatus,rstatus,#mask_neg + biceq rstatus,rstatus,#mask_neg + movs rscratch2,rscratch2,lsr #1 + update_c + update_z + s9xsetwordlow rscratch2 + add1cycle + +.endm +.macro ror8 + s9xgetbytelowregns rscratch2 + tst rstatus, #mask_carry + orrne rscratch2, rscratch2, #0x00000100 + orrne rstatus,rstatus,#mask_neg + biceq rstatus,rstatus,#mask_neg + movs rscratch2,rscratch2,lsr #1 + update_c + update_z + s9xsetbytelow rscratch2 + add1cycle +.endm + +.macro sbc16 + tst rstatus, #mask_decimal + beq 1111f + @ todo + s9xgetword + + stmfd r13!,{rscratch9} + mov rscratch9,#0x000f0000 + @ rscratch2 - result + @ rscratch3 - scratch + @ rscratch4 - scratch + @ rscratch9 - pattern + + and rscratch2, rscratch, #0x000f0000 + tst rstatus, #mask_carry + addeq rscratch2, rscratch2, #0x00010000 @ w1=w1+!carry + and rscratch4, reg_a, #0x000f0000 + sub rscratch2, rscratch4,rscratch2 @ r1=a1-w1-!carry + cmp rscratch2, #0x00090000 @ if r1 > 9 + addhi rscratch2, rscratch2, #0x000a0000 @ then r1 += 10 + and rscratch2, rscratch2, #0x000f0000 + + and rscratch3, rscratch9, rscratch, lsr #4 + addhi rscratch3, rscratch3, #0x00010000 @ then (w2++) + + and rscratch4, rscratch9, reg_a, lsr #4 + sub rscratch3, rscratch4, rscratch3 @ r2=a2-w2 + cmp rscratch3, #0x00090000 @ if r2 > 9 + addhi rscratch3, rscratch3, #0x000a0000 @ then r2 += 10 + and rscratch3, rscratch3, #0x000f0000 + orr rscratch2, rscratch2, rscratch3,lsl #4 + + and rscratch3, rscratch9, rscratch, lsr #8 + addhi rscratch3, rscratch3, #0x00010000 @ then (w3++) + + and rscratch4, rscratch9, reg_a, lsr #8 + sub rscratch3, rscratch4, rscratch3 @ r3=a3-w3 + cmp rscratch3, #0x00090000 @ if r3 > 9 + addhi rscratch3, rscratch3, #0x000a0000 @ then r3 += 10 + and rscratch3, rscratch3, #0x000f0000 + orr rscratch2, rscratch2, rscratch3,lsl #8 + + and rscratch3, rscratch9, rscratch, lsr #12 + addhi rscratch3, rscratch3, #0x00010000 @ then (w3++) + + and rscratch4, rscratch9, reg_a, lsr #12 + sub rscratch3, rscratch4, rscratch3 @ r4=a4-w4 + cmp rscratch3, #0x00090000 @ if r4 > 9 + addhi rscratch3, rscratch3, #0x000a0000 @ then r4 += 10 + bichi rstatus, rstatus, #mask_carry @ then clearcarry + orrls rstatus, rstatus, #mask_carry @ else setcarry + + and rscratch3,rscratch3,#0x000f0000 + orr rscratch2,rscratch2,rscratch3,lsl #12 + + ldmfd r13!,{rscratch9} + @ only last bit + and reg_a,reg_a,#0x80000000 + @ (register.a.w ^ work8) + eors rscratch3, reg_a, rscratch + biceq rstatus, rstatus, #mask_overflow @ 0 : and mask 11111011111 : set v to zero + beq 1112f + @ (register.a.w ^ ans8) + eors rscratch3, reg_a, rscratch2 + @ & 0x80 + tstne rscratch3,#0x80000000 + biceq rstatus, rstatus, #mask_overflow @ 0 : and mask 11111011111 : set v to zero + orrne rstatus, rstatus, #mask_overflow @ 1 : or mask 00000100000 : set v to one +1112: + movs reg_a, rscratch2 + update_zn + b 1113f +1111: + s9xgetwordlow + movs rscratch2,rstatus,lsr #mask_shifter_carry + sbcs reg_a, reg_a, rscratch, lsl #16 + @ overflow + orrvs rstatus, rstatus, #mask_overflow + bicvc rstatus, rstatus, #mask_overflow + mov reg_a, reg_a, lsr #16 + @ carry + update_c + movs reg_a, reg_a, lsl #16 + @ update flag + update_zn +1113: +.endm + +.macro sbc8 + tst rstatus, #mask_decimal + beq 1111f + s9xgetbyte + stmfd r13!,{rscratch} + mov rscratch4,#0x0f000000 + @ rscratch2=xxw1xxxxxxxxxxxx + and rscratch2, rscratch, rscratch4 + @ rscratch=xxw2xxxxxxxxxxxx + and rscratch, rscratch4, rscratch, lsr #4 + @ rscratch3=xxa2xxxxxxxxxxxx + and rscratch3, rscratch4, reg_a, lsr #4 + @ rscratch4=xxa1xxxxxxxxxxxx + and rscratch4,reg_a,rscratch4 + @ r1=a1-w1-!carry + tst rstatus, #mask_carry + addeq rscratch2, rscratch2, #0x01000000 + sub rscratch2,rscratch4,rscratch2 + @ if r1 > 9 + cmp rscratch2, #0x09000000 + @ then r1 += 10 + addhi rscratch2, rscratch2, #0x0a000000 + @ then a2-- (w2++) + addhi rscratch, rscratch, #0x01000000 + @ r2=a2-w2 + sub rscratch3, rscratch3, rscratch + @ if r2 > 9 + cmp rscratch3, #0x09000000 + @ then r2 -= 10@ + addhi rscratch3, rscratch3, #0x0a000000 + @ then setcarry() + bichi rstatus, rstatus, #mask_carry @ 1 : or mask 00000100000 : set c to one + @ else clearcarry() + orrls rstatus, rstatus, #mask_carry @ 0 : and mask 11111011111 : set c to zero + @ gather rscratch3 and rscratch2 into ans8 + and rscratch3,rscratch3,#0x0f000000 + and rscratch2,rscratch2,#0x0f000000 + @ rscratch3 : 0r2000000 + @ rscratch2 : 0r1000000 + @ -> 0xr2r1000000 + orr rscratch2, rscratch2, rscratch3, lsl #4 + ldmfd r13!,{rscratch} + @ only last bit + and reg_a,reg_a,#0x80000000 + @ (register.al ^ work8) + eors rscratch3, reg_a, rscratch + biceq rstatus, rstatus, #mask_overflow @ 0 : and mask 11111011111 : set v to zero + beq 1112f + @ (register.al ^ ans8) + eors rscratch3, reg_a, rscratch2 + @ & 0x80 + tstne rscratch3,#0x80000000 + biceq rstatus, rstatus, #mask_overflow @ 0 : and mask 11111011111 : set v to zero + orrne rstatus, rstatus, #mask_overflow @ 1 : or mask 00000100000 : set v to one +1112: + movs reg_a, rscratch2 + update_zn + b 1113f +1111: + s9xgetbytelow + movs rscratch2,rstatus,lsr #mask_shifter_carry + sbcs reg_a, reg_a, rscratch, lsl #24 + @ overflow + orrvs rstatus, rstatus, #mask_overflow + bicvc rstatus, rstatus, #mask_overflow + @ carry + update_c + @ update flag + ands reg_a, reg_a, #0xff000000 + update_zn +1113: +.endm + +.macro sta16 + s9xsetword reg_a +.endm +.macro sta8 + s9xsetbyte reg_a +.endm +.macro stx16 + s9xsetword reg_x +.endm +.macro stx8 + s9xsetbyte reg_x +.endm +.macro sty16 + s9xsetword reg_y +.endm +.macro sty8 + s9xsetbyte reg_y +.endm +.macro stz16 + s9xsetwordzero +.endm +.macro stz8 + s9xsetbytezero +.endm +.macro tsb16 + s9xgetwordregns rscratch2 + tst reg_a, rscratch2 + bicne rstatus, rstatus, #mask_zero @ 0 : and mask 11111011111 : set z to zero + orreq rstatus, rstatus, #mask_zero @ 1 : or mask 00000100000 : set z to one + orr rscratch2, reg_a, rscratch2 + s9xsetword rscratch2 + add1cycle +.endm +.macro tsb8 + s9xgetbyteregns rscratch2 + tst reg_a, rscratch2 + bicne rstatus, rstatus, #mask_zero @ 0 : and mask 11111011111 : set z to zero + orreq rstatus, rstatus, #mask_zero @ 1 : or mask 00000100000 : set z to one + orr rscratch2, reg_a, rscratch2 + s9xsetbyte rscratch2 + add1cycle +.endm +.macro trb16 + s9xgetwordregns rscratch2 + tst reg_a, rscratch2 + bicne rstatus, rstatus, #mask_zero @ 0 : and mask 11111011111 : set z to zero + orreq rstatus, rstatus, #mask_zero @ 1 : or mask 00000100000 : set z to one + mvn rscratch3, reg_a + and rscratch2, rscratch3, rscratch2 + s9xsetword rscratch2 + add1cycle +.endm +.macro trb8 + s9xgetbyteregns rscratch2 + tst reg_a, rscratch2 + bicne rstatus, rstatus, #mask_zero @ 0 : and mask 11111011111 : set z to zero + orreq rstatus, rstatus, #mask_zero @ 1 : or mask 00000100000 : set z to one + mvn rscratch3, reg_a + and rscratch2, rscratch3, rscratch2 + s9xsetbyte rscratch2 + add1cycle +.endm +/**************************************************************************/ + + +/**************************************************************************/ + +.macro op09m0 /*ora*/ + ldrb rscratch2, [rpc,#1] + ldrb rscratch, [rpc], #2 + orr rscratch2,rscratch,rscratch2,lsl #8 + orrs reg_a,reg_a,rscratch2,lsl #16 + update_zn + add2mem +.endm +.macro op09m1 /*ora*/ + ldrb rscratch, [rpc], #1 + orrs reg_a,reg_a,rscratch,lsl #24 + update_zn + add1mem +.endm +/***********************************************************************/ +.macro op90 /*bcc*/ + asmrelative + branchcheck0 + tst rstatus, #mask_carry + bne 1111f + add rpc, rscratch, regpcbase @ rpc = opaddress +pcbase + add1cycle + cpushutdown +1111: +.endm +.macro opb0 /*bcs*/ + asmrelative + branchcheck0 + tst rstatus, #mask_carry + beq 1111f + add rpc, rscratch, regpcbase @ rpc = opaddress +pcbase + add1cycle + cpushutdown +1111: +.endm +.macro opf0 /*beq*/ + asmrelative + branchcheck2 + tst rstatus, #mask_zero + beq 1111f + add rpc, rscratch, regpcbase @ rpc = opaddress +pcbase + add1cycle + cpushutdown +1111: +.endm +.macro opd0 /*bne*/ + asmrelative + branchcheck1 + tst rstatus, #mask_zero + bne 1111f + add rpc, rscratch, regpcbase @ rpc = opaddress +pcbase + add1cycle + cpushutdown +1111: +.endm +.macro op30 /*bmi*/ + asmrelative + branchcheck0 + tst rstatus, #mask_neg + beq 1111f + add rpc, rscratch, regpcbase @ rpc = opaddress +pcbase + add1cycle + cpushutdown +1111: +.endm +.macro op10 /*bpl*/ + asmrelative + branchcheck1 + tst rstatus, #mask_neg @ neg, z!=0, ne + bne 1111f + add rpc, rscratch, regpcbase @ rpc = opaddress + pcbase + add1cycle + cpushutdown +1111: +.endm +.macro op50 /*bvc*/ + asmrelative + branchcheck0 + tst rstatus, #mask_overflow @ neg, z!=0, ne + bne 1111f + add rpc, rscratch, regpcbase @ rpc = opaddress + pcbase + add1cycle + cpushutdown +1111: +.endm +.macro op70 /*bvs*/ + asmrelative + branchcheck0 + tst rstatus, #mask_overflow @ neg, z!=0, ne + beq 1111f + add rpc, rscratch, regpcbase @ rpc = opaddress + pcbase + add1cycle + cpushutdown +1111: +.endm +.macro op80 /*bra*/ + asmrelative + add rpc, rscratch, regpcbase @ rpc = opaddress + pcbase + add1cycle + cpushutdown +1111: +.endm +/*******************************************************************************************/ +/************************************************************/ +/* setflag instructions ********************************************************************** */ +.macro op38 /*sec*/ + orr rstatus, rstatus, #mask_carry @ 1 : or mask 00000100000 : set c to one + add1cycle +.endm +.macro opf8 /*sed*/ + setdecimal + add1cycle +.endm +.macro op78 /*sei*/ + setirq + add1cycle +.endm + + +/****************************************************************************************/ +/* clearflag instructions ******************************************************************** */ +.macro op18 /*clc*/ + bic rstatus, rstatus, #mask_carry + add1cycle +.endm +.macro opd8 /*cld*/ + cleardecimal + add1cycle +.endm +.macro op58 /*cli*/ + clearirq + add1cycle + @ check_for_irq +.endm +.macro opb8 /*clv*/ + bic rstatus, rstatus, #mask_overflow + add1cycle +.endm + +/******************************************************************************************/ +/* dex/dey *********************************************************************************** */ + +.macro opcax1 /*dex*/ + mov rscratch3,#0 + subs reg_x, reg_x, #0x01000000 + str rscratch3,[reg_cpu_var,#waitaddress_ofs] + update_zn + add1cycle +.endm +.macro opcax0 /*dex*/ + mov rscratch3,#0 + subs reg_x, reg_x, #0x00010000 + str rscratch3,[reg_cpu_var,#waitaddress_ofs] + update_zn + add1cycle +.endm +.macro op88x1 /*dey*/ + mov rscratch3,#0 + subs reg_y, reg_y, #0x01000000 + str rscratch3,[reg_cpu_var,#waitaddress_ofs] + update_zn + add1cycle +.endm +.macro op88x0 /*dey*/ + mov rscratch3,#0 + subs reg_y, reg_y, #0x00010000 + str rscratch3,[reg_cpu_var,#waitaddress_ofs] + update_zn + add1cycle +.endm + +/******************************************************************************************/ +/* inx/iny *********************************************************************************** */ +.macro ope8x1 + mov rscratch3,#0 + adds reg_x, reg_x, #0x01000000 + str rscratch3,[reg_cpu_var,#waitaddress_ofs] + update_zn + add1cycle +.endm +.macro ope8x0 + mov rscratch3,#0 + adds reg_x, reg_x, #0x00010000 + str rscratch3,[reg_cpu_var,#waitaddress_ofs] + update_zn + add1cycle +.endm +.macro opc8x1 + mov rscratch3,#0 + adds reg_y, reg_y, #0x01000000 + str rscratch3,[reg_cpu_var,#waitaddress_ofs] + update_zn + add1cycle +.endm +.macro opc8x0 + mov rscratch3,#0 + adds reg_y, reg_y, #0x00010000 + str rscratch3,[reg_cpu_var,#waitaddress_ofs] + update_zn + add1cycle +.endm + +/**********************************************************************************************/ + +/* nop *************************************************************************************** */ +.macro opea + add1cycle +.endm + +/**************************************************************************/ +/* push instructions **************************************************** */ +.macro opf4 + absolute + pushwrlow +.endm +.macro opd4 + directindirect + pushwrlow +.endm +.macro op62 + asmrelativelong + pushwrlow +.endm +.macro op48m0 + pushw reg_a + add1cycle +.endm +.macro op48m1 + pushb reg_a + add1cycle +.endm +.macro op8b + and rscratch2, reg_d_bank, #0xff + pushblow rscratch2 + add1cycle +.endm +.macro op0b + pushw reg_d + add1cycle +.endm +.macro op4b + pushblow reg_p_bank + add1cycle +.endm +.macro op08 + pushb rstatus + add1cycle +.endm +.macro opdax1 + pushb reg_x + add1cycle +.endm +.macro opdax0 + pushw reg_x + add1cycle +.endm +.macro op5ax1 + pushb reg_y + add1cycle +.endm +.macro op5ax0 + pushw reg_y + add1cycle +.endm +/**************************************************************************/ +/* pull instructions **************************************************** */ +.macro op68m1 + pullbs reg_a + update_zn + add2cycle +.endm +.macro op68m0 + pullws reg_a + update_zn + add2cycle +.endm +.macro opab + bic reg_d_bank,reg_d_bank, #0xff + pullbrs + orr reg_d_bank,reg_d_bank,rscratch, lsr #24 + update_zn + add2cycle +.endm +.macro op2b + bic reg_d,reg_d, #0xff000000 + bic reg_d,reg_d, #0x00ff0000 + pullwrs + orr reg_d,rscratch,reg_d + update_zn + add2cycle +.endm +.macro op28x1m1 /*plp*/ + @ index set, memory set + bic rstatus,rstatus,#0xff000000 + pullbr + orr rstatus,rscratch,rstatus + tst rstatus, #mask_index + @ index clear & was set : 8->16 + moveq reg_x,reg_x,lsr #8 + moveq reg_y,reg_y,lsr #8 + tst rstatus, #mask_mem + @ memory cleared & was set : 8->16 + ldreqb rscratch,[reg_cpu_var,#rah_ofs] + moveq reg_a,reg_a,lsr #8 + orreq reg_a,reg_a,rscratch, lsl #24 + s9xfixcycles + add2cycle +.endm +.macro op28x0m1 /*plp*/ + @ index cleared, memory set + bic rstatus,rstatus,#0xff000000 + pullbr + orr rstatus,rscratch,rstatus + tst rstatus, #mask_index + @ index set & was cleared : 16->8 + movne reg_x,reg_x,lsl #8 + movne reg_y,reg_y,lsl #8 + tst rstatus, #mask_mem + @ memory cleared & was set : 8->16 + ldreqb rscratch,[reg_cpu_var,#rah_ofs] + moveq reg_a,reg_a,lsr #8 + orreq reg_a,reg_a,rscratch, lsl #24 + s9xfixcycles + add2cycle +.endm +.macro op28x1m0 /*plp*/ + @ index set, memory set + bic rstatus,rstatus,#0xff000000 + pullbr + orr rstatus,rscratch,rstatus + tst rstatus, #mask_index + @ index clear & was set : 8->16 + moveq reg_x,reg_x,lsr #8 + moveq reg_y,reg_y,lsr #8 + tst rstatus, #mask_mem + @ memory set & was cleared : 16->8 + movne rscratch,reg_a,lsr #24 + movne reg_a,reg_a,lsl #8 + strneb rscratch,[reg_cpu_var,#rah_ofs] + s9xfixcycles + add2cycle +.endm +.macro op28x0m0 /*plp*/ + @ index set, memory set + bic rstatus,rstatus,#0xff000000 + pullbr + orr rstatus,rscratch,rstatus + tst rstatus, #mask_index + @ index set & was cleared : 16->8 + movne reg_x,reg_x,lsl #8 + movne reg_y,reg_y,lsl #8 + tst rstatus, #mask_mem + @ memory set & was cleared : 16->8 + movne rscratch,reg_a,lsr #24 + movne reg_a,reg_a,lsl #8 + strneb rscratch,[reg_cpu_var,#rah_ofs] + s9xfixcycles + add2cycle +.endm +.macro opfax1 + pullbs reg_x + update_zn + add2cycle +.endm +.macro opfax0 + pullws reg_x + update_zn + add2cycle +.endm +.macro op7ax1 + pullbs reg_y + update_zn + add2cycle +.endm +.macro op7ax0 + pullws reg_y + update_zn + add2cycle +.endm + +/**********************************************************************************************/ +/* transfer instructions ********************************************************************* */ +.macro opaax1m1 /*tax8*/ + movs reg_x, reg_a + update_zn + add1cycle +.endm +.macro opaax0m1 /*tax16*/ + ldrb reg_x, [reg_cpu_var,#rah_ofs] + mov reg_x, reg_x,lsl #24 + orrs reg_x, reg_x,reg_a, lsr #8 + update_zn + add1cycle +.endm +.macro opaax1m0 /*tax8*/ + movs reg_x, reg_a, lsl #8 + update_zn + add1cycle +.endm +.macro opaax0m0 /*tax16*/ + movs reg_x, reg_a + update_zn + add1cycle +.endm +.macro opa8x1m1 /*tay8*/ + movs reg_y, reg_a + update_zn + add1cycle +.endm +.macro opa8x0m1 /*tay16*/ + ldrb reg_y, [reg_cpu_var,#rah_ofs] + mov reg_y, reg_y,lsl #24 + orrs reg_y, reg_y,reg_a, lsr #8 + update_zn + add1cycle +.endm +.macro opa8x1m0 /*tay8*/ + movs reg_y, reg_a, lsl #8 + update_zn + add1cycle +.endm +.macro opa8x0m0 /*tay16*/ + movs reg_y, reg_a + update_zn + add1cycle +.endm +.macro op5bm1 + ldrb rscratch, [reg_cpu_var,#rah_ofs] + mov reg_d,reg_d,lsl #16 + mov rscratch,rscratch,lsl #24 + orrs rscratch,rscratch,reg_a, lsr #8 + update_zn + orr reg_d,rscratch,reg_d,lsr #16 + add1cycle +.endm +.macro op5bm0 + mov reg_d,reg_d,lsl #16 + movs reg_a,reg_a + update_zn + orr reg_d,reg_a,reg_d,lsr #16 + add1cycle +.endm +.macro op1bm1 + tst rstatus, #mask_emul + movne reg_s, reg_a, lsr #24 + orrne reg_s, reg_s, #0x100 + ldreqb reg_s, [reg_cpu_var,#rah_ofs] + orreq reg_s, reg_s, reg_a + moveq reg_s, reg_s, ror #24 + add1cycle +.endm +.macro op1bm0 + mov reg_s, reg_a, lsr #16 + add1cycle +.endm +.macro op7bm1 + movs reg_a, reg_d, asr #16 + update_zn + mov rscratch,reg_a,lsr #8 + mov reg_a,reg_a, lsl #24 + strb rscratch, [reg_cpu_var,#rah_ofs] + add1cycle +.endm +.macro op7bm0 + movs reg_a, reg_d, asr #16 + update_zn + mov reg_a,reg_a, lsl #16 + add1cycle +.endm +.macro op3bm1 + mov rscratch,reg_s, lsr #8 + movs reg_a, reg_s, lsl #16 + strb rscratch, [reg_cpu_var,#rah_ofs] + update_zn + mov reg_a,reg_a, lsl #8 + add1cycle +.endm +.macro op3bm0 + movs reg_a, reg_s, lsl #16 + update_zn + add1cycle +.endm +.macro opbax1 + movs reg_x, reg_s, lsl #24 + update_zn + add1cycle +.endm +.macro opbax0 + movs reg_x, reg_s, lsl #16 + update_zn + add1cycle +.endm +.macro op8am1x1 + movs reg_a, reg_x + update_zn + add1cycle +.endm +.macro op8am1x0 + movs reg_a, reg_x, lsl #8 + update_zn + add1cycle +.endm +.macro op8am0x1 + movs reg_a, reg_x, lsr #8 + update_zn + add1cycle +.endm +.macro op8am0x0 + movs reg_a, reg_x + update_zn + add1cycle +.endm +.macro op9ax1 + mov reg_s, reg_x, lsr #24 + tst rstatus, #mask_emul + orrne reg_s, reg_s, #0x100 + add1cycle +.endm +.macro op9ax0 + mov reg_s, reg_x, lsr #16 + add1cycle +.endm +.macro op9bx1 + movs reg_y, reg_x + update_zn + add1cycle +.endm +.macro op9bx0 + movs reg_y, reg_x + update_zn + add1cycle +.endm +.macro op98m1x1 + movs reg_a, reg_y + update_zn + add1cycle +.endm +.macro op98m1x0 + movs reg_a, reg_y, lsl #8 + update_zn + add1cycle +.endm +.macro op98m0x1 + movs reg_a, reg_y, lsr #8 + update_zn + add1cycle +.endm +.macro op98m0x0 + movs reg_a, reg_y + update_zn + add1cycle +.endm +.macro opbbx1 + movs reg_x, reg_y + update_zn + add1cycle +.endm +.macro opbbx0 + movs reg_x, reg_y + update_zn + add1cycle +.endm + +/**********************************************************************************************/ +/* xce *************************************************************************************** */ + +.macro opfb + tst rstatus,#mask_carry + beq 1111f + @ carry is set + tst rstatus,#mask_emul + bne 1112f + @ emul is cleared + bic rstatus,rstatus,#mask_carry + tst rstatus,#mask_index + @ x & y were 16bits before + moveq reg_x,reg_x,lsl #8 + moveq reg_y,reg_y,lsl #8 + tst rstatus,#mask_mem + @ a was 16bits before + @ save ah + moveq rscratch,reg_a,lsr #24 + streqb rscratch,[reg_cpu_var,#rah_ofs] + moveq reg_a,reg_a,lsl #8 + orr rstatus,rstatus,#mask_emul_orr_mask_mem_orr_mask_index + and reg_s,reg_s,#0xff + orr reg_s,reg_s,#0x100 + b 1113f +1112: + @ emul is set + tst rstatus,#mask_index + @ x & y were 16bits before + moveq reg_x,reg_x,lsl #8 + moveq reg_y,reg_y,lsl #8 + tst rstatus,#mask_mem + @ a was 16bits before + @ save ah + moveq rscratch,reg_a,lsr #24 + streqb rscratch,[reg_cpu_var,#rah_ofs] + moveq reg_a,reg_a,lsl #8 + orr rstatus,rstatus,#mask_carry_orr_mask_mem_orr_mask_index + and reg_s,reg_s,#0xff + orr reg_s,reg_s,#0x100 + b 1113f +1111: + @ carry is cleared + tst rstatus,#mask_emul + beq 1115f + @ emul was set : x,y & a were 8bits + @ now have to check memory & index for potential conversions to 16bits + tst rstatus,#mask_index + @ x & y are now 16bits + moveq reg_x,reg_x,lsr #8 + moveq reg_y,reg_y,lsr #8 + tst rstatus,#mask_mem + @ a is now 16bits + moveq reg_a,reg_a,lsr #8 + @ restore ah + ldreqb rscratch,[reg_cpu_var,#rah_ofs] + orreq reg_a,reg_a,rscratch,lsl #24 +1115: + bic rstatus,rstatus,#mask_emul + orr rstatus,rstatus,#mask_carry +1113: + add1cycle + s9xfixcycles +.endm + +/*******************************************************************************/ +/* brk *************************************************************************/ +.macro op00 /*brk*/ + mov rscratch,#1 + strb rscratch,[reg_cpu_var,#brktriggered_ofs] + + tst rstatus, #mask_emul + @ eq is flag to zero (!checkemu) + bne 2001f@ elseop00 + pushblow reg_p_bank + sub rscratch, rpc, regpcbase + add rscratch2, rscratch, #1 + pushwlow rscratch2 + @ packstatus + pushb rstatus + cleardecimal + setirq + bic reg_p_bank, reg_p_bank, #0xff + mov rscratch, #0xe6 + orr rscratch, rscratch, #0xff00 + s9xgetwordlow + s9xsetpcbase + add2cycle + b 2002f@ endop00 +2001:@ elseop00 + sub rscratch2, rpc, regpcbase + pushwlow rscratch2 + @ packstatus + pushb rstatus + cleardecimal + setirq + bic reg_p_bank,reg_p_bank, #0xff + mov rscratch, #0xfe + orr rscratch, rscratch, #0xff00 + s9xgetwordlow + s9xsetpcbase + add1cycle +2002:@ endop00 +.endm + + +/**********************************************************************************************/ +/* brl ************************************************************************************** */ +.macro op82 /*brl*/ + asmrelativelong + orr rscratch, rscratch, reg_p_bank, lsl #16 + s9xsetpcbase +.endm +/**********************************************************************************************/ +/* irq *************************************************************************************** */ +@ void s9xopcode_irq (void) +.macro s9xopcode_irq @ irq + tst rstatus, #mask_emul + @ eq is flag to zero (!checkemu) + bne 2121f@ elseop02 + pushblow reg_p_bank + sub rscratch2, rpc, regpcbase + pushwlow rscratch2 + @ packstatus + pushb rstatus + cleardecimal + setirq + bic reg_p_bank, reg_p_bank,#0xff + mov rscratch, #0xee + orr rscratch, rscratch, #0xff00 + s9xgetwordlow + s9xsetpcbase + add2cycle + b 2122f +2121:@ else + sub rscratch2, rpc, regpcbase + pushwlow rscratch2 + @ packstatus + pushb rstatus + cleardecimal + setirq + bic reg_p_bank,reg_p_bank, #0xff + mov rscratch, #0xfe + orr rscratch, rscratch, #0xff00 + s9xgetwordlow + s9xsetpcbase + add1cycle +2122: +.endm + +/* +void asm_s9xopcode_irq(void) +{ + if (!checkemulation()) + { + pushb (registers.pb); + pushw (cpu.pc - cpu.pcbase); + pushb (registers.pl); + cleardecimal (); + setirq (); + + registers.pb = 0; + s9xsetpcbase (s9xgetword (0xffee)); + cpu.cycles += two_cycles; + } + else + { + pushw (cpu.pc - cpu.pcbase); + pushb (registers.pl); + cleardecimal (); + setirq (); + + registers.pb = 0; + s9xsetpcbase (s9xgetword (0xfffe)); + cpu.cycles += one_cycle; + } +} +*/ + +/**********************************************************************************************/ +/* nmi *************************************************************************************** */ +@ void s9xopcode_nmi (void) +.macro s9xopcode_nmi @ nmi + tst rstatus, #mask_emul + @ eq is flag to zero (!checkemu) + bne 2123f@ elseop02 + pushblow reg_p_bank + sub rscratch2, rpc, regpcbase + pushwlow rscratch2 + @ packstatus + pushb rstatus + cleardecimal + setirq + bic reg_p_bank, reg_p_bank,#0xff + mov rscratch, #0xea + orr rscratch, rscratch, #0xff00 + s9xgetwordlow + s9xsetpcbase + add2cycle + b 2124f +2123:@ else + sub rscratch2, rpc, regpcbase + pushwlow rscratch2 + @ packstatus + pushb rstatus + cleardecimal + setirq + bic reg_p_bank,reg_p_bank, #0xff + mov rscratch, #0xfa + orr rscratch, rscratch, #0xff00 + s9xgetwordlow + s9xsetpcbase + add1cycle +2124: +.endm +/* +void asm_s9xopcode_nmi(void) +{ + if (!checkemulation()) + { + pushb (registers.pb); + pushw (cpu.pc - cpu.pcbase); + pushb (registers.pl); + cleardecimal (); + setirq (); + + registers.pb = 0; + s9xsetpcbase (s9xgetword (0xffea)); + cpu.cycles += two_cycles; + } + else + { + pushw (cpu.pc - cpu.pcbase); + pushb (registers.pl); + cleardecimal (); + setirq (); + + registers.pb = 0; + s9xsetpcbase (s9xgetword (0xfffa)); + cpu.cycles += one_cycle; + } +} +*/ + +/**********************************************************************************************/ +/* cop *************************************************************************************** */ +.macro op02 /*cop*/ + tst rstatus, #mask_emul + @ eq is flag to zero (!checkemu) + bne 2021f@ elseop02 + pushblow reg_p_bank + sub rscratch, rpc, regpcbase + add rscratch2, rscratch, #1 + pushwlow rscratch2 + @ packstatus + pushb rstatus + cleardecimal + setirq + bic reg_p_bank, reg_p_bank,#0xff + mov rscratch, #0xe4 + orr rscratch, rscratch, #0xff00 + s9xgetwordlow + s9xsetpcbase + add2cycle + b 2022f@ endop02 +2021:@ elseop02 + sub rscratch2, rpc, regpcbase + pushwlow rscratch2 + @ packstatus + pushb rstatus + cleardecimal + setirq + bic reg_p_bank,reg_p_bank, #0xff + mov rscratch, #0xf4 + orr rscratch, rscratch, #0xff00 + s9xgetwordlow + s9xsetpcbase + add1cycle +2022:@ endop02 +.endm + +/**********************************************************************************************/ +/* jml *************************************************************************************** */ +.macro opdc + absoluteindirectlong + bic reg_p_bank,reg_p_bank,#0xff + orr reg_p_bank,reg_p_bank, rscratch, lsr #16 + s9xsetpcbase + add2cycle +.endm +.macro op5c + absolutelong + bic reg_p_bank,reg_p_bank,#0xff + orr reg_p_bank,reg_p_bank, rscratch, lsr #16 + s9xsetpcbase +.endm + +/**********************************************************************************************/ +/* jmp *************************************************************************************** */ +.macro op4c + absolute + bic rscratch, rscratch, #0xff0000 + orr rscratch, rscratch, reg_p_bank, lsl #16 + s9xsetpcbase + cpushutdown +.endm +.macro op6c + absoluteindirect + bic rscratch, rscratch, #0xff0000 + orr rscratch, rscratch, reg_p_bank, lsl #16 + s9xsetpcbase +.endm +.macro op7c + add rscratch, rscratch, reg_p_bank, lsl #16 + s9xsetpcbase + add1cycle +.endm + +/**********************************************************************************************/ +/* jsl/rtl *********************************************************************************** */ +.macro op22 + pushblow reg_p_bank + sub rscratch, rpc, regpcbase + @ sub rscratch2, rscratch2, #1 + add rscratch2, rscratch, #2 + pushwlow rscratch2 + absolutelong + bic reg_p_bank,reg_p_bank,#0xff + orr reg_p_bank, reg_p_bank, rscratch, lsr #16 + s9xsetpcbase +.endm +.macro op6b + pullwlow rpc + bic reg_p_bank,reg_p_bank,#0xff + pullbrlow + orr reg_p_bank, reg_p_bank, rscratch + add rscratch, rpc, #1 + bic rscratch, rscratch,#0xff0000 + orr rscratch, rscratch, reg_p_bank, lsl #16 + s9xsetpcbase + add2cycle +.endm +/**********************************************************************************************/ +/* jsr/rts *********************************************************************************** */ +.macro op20 + sub rscratch, rpc, regpcbase + @ sub rscratch2, rscratch2, #1 + add rscratch2, rscratch, #1 + pushwlow rscratch2 + absolute + bic rscratch, rscratch, #0xff0000 + orr rscratch, rscratch, reg_p_bank, lsl #16 + s9xsetpcbase + add1cycle +.endm +.macro opfcx0 + sub rscratch, rpc, regpcbase + @ sub rscratch2, rscratch2, #1 + add rscratch2, rscratch, #1 + pushwlow rscratch2 + absoluteindexedindirectx0 + orr rscratch, rscratch, reg_p_bank, lsl #16 + s9xsetpcbase + add1cycle +.endm +.macro opfcx1 + sub rscratch, rpc, regpcbase + @ sub rscratch2, rscratch2, #1 + add rscratch2, rscratch, #1 + pushwlow rscratch2 + absoluteindexedindirectx1 + orr rscratch, rscratch, reg_p_bank, lsl #16 + s9xsetpcbase + add1cycle +.endm +.macro op60 + pullwlow rpc + add rscratch, rpc, #1 + bic rscratch, rscratch,#0x10000 + orr rscratch, rscratch, reg_p_bank, lsl #16 + s9xsetpcbase + add3cycle +.endm + +/**********************************************************************************************/ +/* mvn/mvp *********************************************************************************** */ +.macro op54x1m1 + @ save regstatus = reg_d_bank >> 24 + mov rscratch, reg_d_bank, lsr #16 + ldrb reg_d_bank , [rpc], #1 + ldrb rscratch2 , [rpc], #1 + @ restore regstatus = reg_d_bank >> 24 + orr reg_d_bank, reg_d_bank, rscratch, lsl #16 + mov rscratch , reg_x, lsr #24 + orr rscratch , rscratch, rscratch2, lsl #16 + s9xgetbytelow + mov rscratch2, rscratch + mov rscratch , reg_y, lsr #24 + orr rscratch , rscratch, reg_d_bank, lsl #16 + s9xsetbytelow rscratch2 + @ load 16bits a + ldrb rscratch,[reg_cpu_var,#rah_ofs] + mov reg_a,reg_a,lsr #8 + orr reg_a,reg_a,rscratch, lsl #24 + add reg_x, reg_x, #0x01000000 + sub reg_a, reg_a, #0x00010000 + add reg_y, reg_y, #0x01000000 + cmp reg_a, #0xffff0000 + subne rpc, rpc, #3 + @ update ah + mov rscratch, reg_a, lsr #24 + mov reg_a,reg_a,lsl #8 + strb rscratch,[reg_cpu_var,#rah_ofs] + add2cycle2mem +.endm +.macro op54x1m0 + @ save regstatus = reg_d_bank >> 24 + mov rscratch, reg_d_bank, lsr #16 + ldrb reg_d_bank , [rpc], #1 + ldrb rscratch2 , [rpc], #1 + @ restore regstatus = reg_d_bank >> 24 + orr reg_d_bank, reg_d_bank, rscratch, lsl #16 + mov rscratch , reg_x, lsr #24 + orr rscratch , rscratch, rscratch2, lsl #16 + s9xgetbytelow + mov rscratch2, rscratch + mov rscratch , reg_y, lsr #24 + orr rscratch , rscratch, reg_d_bank, lsl #16 + s9xsetbytelow rscratch2 + add reg_x, reg_x, #0x01000000 + sub reg_a, reg_a, #0x00010000 + add reg_y, reg_y, #0x01000000 + cmp reg_a, #0xffff0000 + subne rpc, rpc, #3 + add2cycle2mem +.endm +.macro op54x0m1 + @ save regstatus = reg_d_bank >> 24 + mov rscratch, reg_d_bank, lsr #16 + ldrb reg_d_bank , [rpc], #1 + ldrb rscratch2 , [rpc], #1 + @ restore regstatus = reg_d_bank >> 24 + orr reg_d_bank, reg_d_bank, rscratch, lsl #16 + mov rscratch , reg_x, lsr #16 + orr rscratch , rscratch, rscratch2, lsl #16 + s9xgetbytelow + mov rscratch2, rscratch + mov rscratch , reg_y, lsr #16 + orr rscratch , rscratch, reg_d_bank, lsl #16 + s9xsetbytelow rscratch2 + @ load 16bits a + ldrb rscratch,[reg_cpu_var,#rah_ofs] + mov reg_a,reg_a,lsr #8 + orr reg_a,reg_a,rscratch, lsl #24 + add reg_x, reg_x, #0x00010000 + sub reg_a, reg_a, #0x00010000 + add reg_y, reg_y, #0x00010000 + cmp reg_a, #0xffff0000 + subne rpc, rpc, #3 + @ update ah + mov rscratch, reg_a, lsr #24 + mov reg_a,reg_a,lsl #8 + strb rscratch,[reg_cpu_var,#rah_ofs] + add2cycle2mem +.endm +.macro op54x0m0 + @ save regstatus = reg_d_bank >> 24 + mov rscratch, reg_d_bank, lsr #16 + ldrb reg_d_bank , [rpc], #1 + ldrb rscratch2 , [rpc], #1 + @ restore regstatus = reg_d_bank >> 24 + orr reg_d_bank, reg_d_bank, rscratch, lsl #16 + mov rscratch , reg_x, lsr #16 + orr rscratch , rscratch, rscratch2, lsl #16 + s9xgetbytelow + mov rscratch2, rscratch + mov rscratch , reg_y, lsr #16 + orr rscratch , rscratch, reg_d_bank, lsl #16 + s9xsetbytelow rscratch2 + add reg_x, reg_x, #0x00010000 + sub reg_a, reg_a, #0x00010000 + add reg_y, reg_y, #0x00010000 + cmp reg_a, #0xffff0000 + subne rpc, rpc, #3 + add2cycle2mem +.endm + +.macro op44x1m1 + @ save regstatus = reg_d_bank >> 24 + mov rscratch, reg_d_bank, lsr #16 + ldrb reg_d_bank , [rpc], #1 + ldrb rscratch2 , [rpc], #1 + @ restore regstatus = reg_d_bank >> 24 + orr reg_d_bank, reg_d_bank, rscratch, lsl #16 + mov rscratch , reg_x, lsr #24 + orr rscratch , rscratch, rscratch2, lsl #16 + s9xgetbytelow + mov rscratch2, rscratch + mov rscratch , reg_y, lsr #24 + orr rscratch , rscratch, reg_d_bank, lsl #16 + s9xsetbytelow rscratch2 + @ load 16bits a + ldrb rscratch,[reg_cpu_var,#rah_ofs] + mov reg_a,reg_a,lsr #8 + orr reg_a,reg_a,rscratch, lsl #24 + sub reg_x, reg_x, #0x01000000 + sub reg_a, reg_a, #0x00010000 + sub reg_y, reg_y, #0x01000000 + cmp reg_a, #0xffff0000 + subne rpc, rpc, #3 + @ update ah + mov rscratch, reg_a, lsr #24 + mov reg_a,reg_a,lsl #8 + strb rscratch,[reg_cpu_var,#rah_ofs] + add2cycle2mem +.endm +.macro op44x1m0 + @ save regstatus = reg_d_bank >> 24 + mov rscratch, reg_d_bank, lsr #16 + ldrb reg_d_bank , [rpc], #1 + ldrb rscratch2 , [rpc], #1 + @ restore regstatus = reg_d_bank >> 24 + orr reg_d_bank, reg_d_bank, rscratch, lsl #16 + mov rscratch , reg_x, lsr #24 + orr rscratch , rscratch, rscratch2, lsl #16 + s9xgetbytelow + mov rscratch2, rscratch + mov rscratch , reg_y, lsr #24 + orr rscratch , rscratch, reg_d_bank, lsl #16 + s9xsetbytelow rscratch2 + sub reg_x, reg_x, #0x01000000 + sub reg_a, reg_a, #0x00010000 + sub reg_y, reg_y, #0x01000000 + cmp reg_a, #0xffff0000 + subne rpc, rpc, #3 + add2cycle2mem +.endm +.macro op44x0m1 + @ save regstatus = reg_d_bank >> 24 + mov rscratch, reg_d_bank, lsr #16 + ldrb reg_d_bank , [rpc], #1 + ldrb rscratch2 , [rpc], #1 + @ restore regstatus = reg_d_bank >> 24 + orr reg_d_bank, reg_d_bank, rscratch, lsl #16 + mov rscratch , reg_x, lsr #16 + orr rscratch , rscratch, rscratch2, lsl #16 + s9xgetbytelow + mov rscratch2, rscratch + mov rscratch , reg_y, lsr #16 + orr rscratch , rscratch, reg_d_bank, lsl #16 + s9xsetbytelow rscratch2 + @ load 16bits a + ldrb rscratch,[reg_cpu_var,#rah_ofs] + mov reg_a,reg_a,lsr #8 + orr reg_a,reg_a,rscratch, lsl #24 + sub reg_x, reg_x, #0x00010000 + sub reg_a, reg_a, #0x00010000 + sub reg_y, reg_y, #0x00010000 + cmp reg_a, #0xffff0000 + subne rpc, rpc, #3 + @ update ah + mov rscratch, reg_a, lsr #24 + mov reg_a,reg_a,lsl #8 + strb rscratch,[reg_cpu_var,#rah_ofs] + add2cycle2mem +.endm +.macro op44x0m0 + @ save regstatus = reg_d_bank >> 24 + mov rscratch, reg_d_bank, lsr #16 + ldrb reg_d_bank , [rpc], #1 + ldrb rscratch2 , [rpc], #1 + @ restore regstatus = reg_d_bank >> 24 + orr reg_d_bank, reg_d_bank, rscratch, lsl #16 + mov rscratch , reg_x, lsr #16 + orr rscratch , rscratch, rscratch2, lsl #16 + s9xgetbytelow + mov rscratch2, rscratch + mov rscratch , reg_y, lsr #16 + orr rscratch , rscratch, reg_d_bank, lsl #16 + s9xsetbytelow rscratch2 + sub reg_x, reg_x, #0x00010000 + sub reg_a, reg_a, #0x00010000 + sub reg_y, reg_y, #0x00010000 + cmp reg_a, #0xffff0000 + subne rpc, rpc, #3 + add2cycle2mem +.endm + +/**********************************************************************************************/ +/* rep/sep *********************************************************************************** */ +.macro opc2 + @ status&=~(*rpc++); + @ so possible changes are : + @ index = 1 -> 0 : x,y 8bits -> 16bits + @ mem = 1 -> 0 : a 8bits -> 16bits + @ save old status for mask_index & mask_mem comparison + mov rscratch3, rstatus + ldrb rscratch, [rpc], #1 + mvn rscratch, rscratch + and rstatus,rstatus,rscratch, ror #8 @ 32 - status_shifter + tst rstatus,#mask_emul + beq 1111f + @ emulation mode on : no changes since it was on before opcode + @ just be sure to reset mem & index accordingly + orr rstatus,rstatus,#mask_mem_orr_mask_index + b 1112f +1111: + @ not in emulation mode, check index & memory bits + @ now check index + tst rscratch3,#mask_index + beq 1113f + @ x & y were 8bit before + tst rstatus,#mask_index + bne 1113f + @ x & y are now 16bits + mov reg_x,reg_x,lsr #8 + mov reg_y,reg_y,lsr #8 +1113: @ x & y still in 16bits + @ now check memory + tst rscratch3,#mask_mem + beq 1112f + @ a was 8bit before + tst rstatus,#mask_mem + bne 1112f + @ a is now 16bits + mov reg_a,reg_a,lsr #8 + @ restore ah + ldreqb rscratch,[reg_cpu_var,#rah_ofs] + orreq reg_a,reg_a,rscratch,lsl #24 +1112: + s9xfixcycles + add1cycle1mem +.endm +.macro ope2 + @ status|=*rpc++; + @ so possible changes are : + @ index = 0 -> 1 : x,y 16bits -> 8bits + @ mem = 0 -> 1 : a 16bits -> 8bits + @ save old status for mask_index & mask_mem comparison + mov rscratch3, rstatus + ldrb rscratch, [rpc], #1 + orr rstatus,rstatus,rscratch, lsl #status_shifter + tst rstatus,#mask_emul + beq 10111f + @ emulation mode on : no changes sinc eit was on before opcode + @ just be sure to have mem & index set accordingly + orr rstatus,rstatus,#mask_mem_orr_mask_index + b 10112f +10111: + @ not in emulation mode, check index & memory bits + @ now check index + tst rscratch3,#mask_index + bne 10113f + @ x & y were 16bit before + tst rstatus,#mask_index + beq 10113f + @ x & y are now 8bits + mov reg_x,reg_x,lsl #8 + mov reg_y,reg_y,lsl #8 +10113: @ x & y still in 16bits + @ now check memory + tst rscratch3,#mask_mem + bne 10112f + @ a was 16bit before + tst rstatus,#mask_mem + beq 10112f + @ a is now 8bits + @ save ah + mov rscratch,reg_a,lsr #24 + mov reg_a,reg_a,lsl #8 + strb rscratch,[reg_cpu_var,#rah_ofs] +10112: + s9xfixcycles + add1cycle1mem +.endm + +/**********************************************************************************************/ +/* xba *************************************************************************************** */ +.macro opebm1 + @ a is 8bits + add rscratch,reg_cpu_var,#rah_ofs + mov reg_a,reg_a, lsr #24 + swpb reg_a,reg_a,[rscratch] + movs reg_a,reg_a, lsl #24 + update_zn + add2cycle +.endm +.macro opebm0 + @ a is 16bits + mov rscratch, reg_a, ror #24 @ ll0000hh + orr rscratch, rscratch, reg_a, lsr #8@ ll0000hh + 00hhll00 -> llhhllhh + mov reg_a, rscratch, lsl #16@ llhhllhh -> llhh0000 + movs rscratch,rscratch,lsl #24 @ to set z & n flags with al + update_zn + add2cycle +.endm + + +/**********************************************************************************************/ +/* rti *************************************************************************************** */ +.macro op40x1m1 + @ index set, memory set + bic rstatus,rstatus,#0xff000000 + pullbr + orr rstatus,rscratch,rstatus + pullwlow rpc + tst rstatus, #mask_emul + orrne rstatus, rstatus, #mask_mem_orr_mask_index + bne 2401f + pullbrlow + bic reg_p_bank,reg_p_bank,#0xff + orr reg_p_bank,reg_p_bank,rscratch +2401: + add rscratch, rpc, reg_p_bank, lsl #16 + s9xsetpcbase + tst rstatus, #mask_index + @ index cleared & was set : 8->16 + moveq reg_x,reg_x,lsr #8 + moveq reg_y,reg_y,lsr #8 + tst rstatus, #mask_mem + @ memory cleared & was set : 8->16 + ldreqb rscratch,[reg_cpu_var,#rah_ofs] + moveq reg_a,reg_a,lsr #8 + orreq reg_a,reg_a,rscratch, lsl #24 + add2cycle + s9xfixcycles +.endm +.macro op40x0m1 + @ index cleared, memory set + bic rstatus,rstatus,#0xff000000 + pullbr + orr rstatus,rscratch,rstatus + pullwlow rpc + tst rstatus, #mask_emul + orrne rstatus, rstatus, #mask_mem_orr_mask_index + bne 2401f + pullbrlow + bic reg_p_bank,reg_p_bank,#0xff + orr reg_p_bank,reg_p_bank,rscratch +2401: + add rscratch, rpc, reg_p_bank, lsl #16 + s9xsetpcbase + tst rstatus, #mask_index + @ index set & was cleared : 16->8 + movne reg_x,reg_x,lsl #8 + movne reg_y,reg_y,lsl #8 + tst rstatus, #mask_mem + @ memory cleared & was set : 8->16 + ldreqb rscratch,[reg_cpu_var,#rah_ofs] + moveq reg_a,reg_a,lsr #8 + orreq reg_a,reg_a,rscratch, lsl #24 + add2cycle + s9xfixcycles +.endm +.macro op40x1m0 + @ index set, memory cleared + bic rstatus,rstatus,#0xff000000 + pullbr + orr rstatus,rscratch,rstatus + pullwlow rpc + tst rstatus, #mask_emul + orrne rstatus, rstatus, #mask_mem_orr_mask_index + bne 2401f + pullbrlow + bic reg_p_bank,reg_p_bank,#0xff + orr reg_p_bank,reg_p_bank,rscratch +2401: + add rscratch, rpc, reg_p_bank, lsl #16 + s9xsetpcbase + tst rstatus, #mask_index + @ index cleared & was set : 8->16 + moveq reg_x,reg_x,lsr #8 + moveq reg_y,reg_y,lsr #8 + tst rstatus, #mask_mem + @ memory set & was cleared : 16->8 + movne rscratch,reg_a,lsr #24 + movne reg_a,reg_a,lsl #8 + strneb rscratch,[reg_cpu_var,#rah_ofs] + add2cycle + s9xfixcycles +.endm +.macro op40x0m0 + @ index cleared, memory cleared + bic rstatus,rstatus,#0xff000000 + pullbr + orr rstatus,rscratch,rstatus + pullwlow rpc + tst rstatus, #mask_emul + orrne rstatus, rstatus, #mask_mem_orr_mask_index + bne 2401f + pullbrlow + bic reg_p_bank,reg_p_bank,#0xff + orr reg_p_bank,reg_p_bank,rscratch +2401: + add rscratch, rpc, reg_p_bank, lsl #16 + s9xsetpcbase + tst rstatus, #mask_index + @ index set & was cleared : 16->8 + movne reg_x,reg_x,lsl #8 + movne reg_y,reg_y,lsl #8 + tst rstatus, #mask_mem + @ memory set & was cleared : 16->8 + @ memory set & was cleared : 16->8 + movne rscratch,reg_a,lsr #24 + movne reg_a,reg_a,lsl #8 + strneb rscratch,[reg_cpu_var,#rah_ofs] + add2cycle + s9xfixcycles +.endm + + +/**********************************************************************************************/ +/* stp/wai/db ******************************************************************************** */ +@ wai +.macro opcb /*wai*/ + ldrb rscratch,[reg_cpu_var,#irqactive_ofs] + movs rscratch,rscratch + @ (cpu.irqactive) + add2cyclene + bne 1234f +/* + cpu.waitingforinterrupt = true; + cpu.pc--;*/ + mov rscratch,#1 + sub rpc,rpc,#1 +/* + cpu.cycles = cpu.nextevent; +*/ + strb rscratch,[reg_cpu_var,#waitingforinterrupt_ofs] + ldr reg_cycles,[reg_cpu_var,#nextevent_ofs] +/* + if (iapu.apuexecuting) + { + icpu.cpuexecuting = false; + do + { + apu_execute1 (); + } while (apu.cycles < cpu.nextevent); + icpu.cpuexecuting = true; + } +*/ + ldrb rscratch,[reg_cpu_var,#apuexecuting_ofs] + movs rscratch,rscratch + beq 1234f + asmapu_execute2 + +1234: +.endm +.macro opdb /*stp*/ + sub rpc,rpc,#1 + @ cpu.flags |= debug_mode_flag; +.endm +.macro op42 /*reserved snes9x*/ +.endm + +/**********************************************************************************************/ +/* and ******************************************************************************** */ +.macro op29m1 + ldrb rscratch , [rpc], #1 + ands reg_a , reg_a, rscratch, lsl #24 + update_zn + add1mem +.endm +.macro op29m0 + ldrb rscratch2 , [rpc,#1] + ldrb rscratch , [rpc], #2 + orr rscratch, rscratch, rscratch2, lsl #8 + ands reg_a , reg_a, rscratch, lsl #16 + update_zn + add2mem +.endm + + + + + + + + + + + + + + + +/**********************************************************************************************/ +/* eor ******************************************************************************** */ +.macro op49m0 + ldrb rscratch2 , [rpc, #1] + ldrb rscratch , [rpc], #2 + orr rscratch, rscratch, rscratch2,lsl #8 + eors reg_a, reg_a, rscratch,lsl #16 + update_zn + add2mem +.endm + + +.macro op49m1 + ldrb rscratch , [rpc], #1 + eors reg_a, reg_a, rscratch,lsl #24 + update_zn + add1mem +.endm + + +/**********************************************************************************************/ +/* sta *************************************************************************************** */ +.macro op81m1 + sta8 + @ tst rstatus, #mask_index + @ add1cyclene +.endm +.macro op81m0 + sta16 + @ tst rstatus, #mask_index + @ add1cyclene +.endm + + +/**********************************************************************************************/ +/* bit *************************************************************************************** */ +.macro op89m1 + ldrb rscratch , [rpc], #1 + tst reg_a, rscratch, lsl #24 + update_z + add1mem +.endm +.macro op89m0 + ldrb rscratch2 , [rpc, #1] + ldrb rscratch , [rpc], #2 + orr rscratch, rscratch, rscratch2, lsl #8 + tst reg_a, rscratch, lsl #16 + update_z + add2mem +.endm + + + + + + +/**********************************************************************************************/ +/* ldy *************************************************************************************** */ +.macro opa0x1 + ldrb rscratch , [rpc], #1 + movs reg_y, rscratch, lsl #24 + update_zn + add1mem +.endm +.macro opa0x0 + ldrb rscratch2 , [rpc, #1] + ldrb rscratch , [rpc], #2 + orr rscratch, rscratch, rscratch2, lsl #8 + movs reg_y, rscratch, lsl #16 + update_zn + add2mem +.endm + +/**********************************************************************************************/ +/* ldx *************************************************************************************** */ +.macro opa2x1 + ldrb rscratch , [rpc], #1 + movs reg_x, rscratch, lsl #24 + update_zn + add1mem +.endm +.macro opa2x0 + ldrb rscratch2 , [rpc, #1] + ldrb rscratch , [rpc], #2 + orr rscratch, rscratch, rscratch2, lsl #8 + movs reg_x, rscratch, lsl #16 + update_zn + add2mem +.endm + +/**********************************************************************************************/ +/* lda *************************************************************************************** */ +.macro opa9m1 + ldrb rscratch , [rpc], #1 + movs reg_a, rscratch, lsl #24 + update_zn + add1mem +.endm +.macro opa9m0 + ldrb rscratch2 , [rpc, #1] + ldrb rscratch , [rpc], #2 + orr rscratch, rscratch, rscratch2, lsl #8 + movs reg_a, rscratch, lsl #16 + update_zn + add2mem +.endm + +/**********************************************************************************************/ +/* cmy *************************************************************************************** */ +.macro opc0x1 + ldrb rscratch , [rpc], #1 + subs rscratch2 , reg_y , rscratch, lsl #24 + biccc rstatus, rstatus, #mask_carry + orrcs rstatus, rstatus, #mask_carry + update_zn + add1mem +.endm +.macro opc0x0 + ldrb rscratch2 , [rpc, #1] + ldrb rscratch , [rpc], #2 + orr rscratch, rscratch, rscratch2, lsl #8 + subs rscratch2 , reg_y, rscratch, lsl #16 + biccc rstatus, rstatus, #mask_carry + orrcs rstatus, rstatus, #mask_carry + update_zn + add2mem +.endm + + + + + +/**********************************************************************************************/ +/* cmp *************************************************************************************** */ +.macro opc9m1 + ldrb rscratch , [rpc], #1 + subs rscratch2 , reg_a , rscratch, lsl #24 + biccc rstatus, rstatus, #mask_carry + orrcs rstatus, rstatus, #mask_carry + update_zn + add1mem +.endm +.macro opc9m0 + ldrb rscratch2 , [rpc,#1] + ldrb rscratch , [rpc], #2 + orr rscratch, rscratch, rscratch2, lsl #8 + subs rscratch2 , reg_a, rscratch, lsl #16 + biccc rstatus, rstatus, #mask_carry + orrcs rstatus, rstatus, #mask_carry + update_zn + add2mem +.endm + +/**********************************************************************************************/ +/* cmx *************************************************************************************** */ +.macro ope0x1 + ldrb rscratch , [rpc], #1 + subs rscratch2 , reg_x , rscratch, lsl #24 + biccc rstatus, rstatus, #mask_carry + orrcs rstatus, rstatus, #mask_carry + update_zn + add1mem +.endm +.macro ope0x0 + ldrb rscratch2 , [rpc,#1] + ldrb rscratch , [rpc], #2 + orr rscratch, rscratch, rscratch2, lsl #8 + subs rscratch2 , reg_x, rscratch, lsl #16 + biccc rstatus, rstatus, #mask_carry + orrcs rstatus, rstatus, #mask_carry + update_zn + add2mem +.endm + +/* + + +cli_ope_rec_nos_layer0 + nos.nos_ope_treasury_date = convert(datetime, @treasurydate, 103) + nos.nos_ope_accounting_date = convert(datetime, @accountingdate, 103) + +cli_ope_nos_ope_layer0 + n.nos_ope_treasury_date = convert(datetime, @lard, 103) + n.nos_ope_accounting_date = convert(datetime, @lard, 103) + +cli_ope_nos_layer0 + nos.nos_ope_treasury_date = convert(datetime, @lard, 103) + nos.nos_ope_accounting_date = convert(datetime, @lard, 103) + +ecrans: +------ + + +[gnv] : utilisation de la lard (laccdate) pour afficher les openings. + +nécessité d'avoir des valeurs dans l'opening pour date tréso=date compta=laccdate + +[accounting rec] : si laccdate pas bonne (pas = bd-1) -> message warning et pas de donnée +sinon : + +données nécessaires : opening date tréso=date compta=laccdate=bd-1 + +données nécessaires : opening date tréso=date compta=laccdate-1 + +données nécessaires : opening date tréso=laccdate-1 et date compta=laccdate + */ + + + +/**************************************************************** + global +****************************************************************/ + .globl _test_opcode + .globl _asmMainLoop + +1: + .long jumptable1 +2: + .long jumptable2 +3: + .long jumptable3 +4: + .long jumptable4 + +@ void asmmainloop(asm_cpu_var_t *asmcpuptr); +_asmMainLoop: + @ save registers + stmfd r13!,{r4-r11,lr} + @ init pointer to cpuvar structure + mov reg_cpu_var,r0 + ldr r1, 1b + str r1, [reg_cpu_var,#jump1] + ldr r1, 2b + str r1, [reg_cpu_var,#jump2] + ldr r1, 3b + str r1, [reg_cpu_var,#jump3] + ldr r1, 4b + str r1, [reg_cpu_var,#jump4] + str r9,[reg_cpu_var,#iphone_r9s_ofs] + @ init registers + load_regs + @ get cpu mode from flag and init jump table + s9xfixcycles + +mainloop: + @ apu execute + asmapu_execute + + @ test flags + ldr rscratch,[reg_cpu_var,#flags_ofs] + movs rscratch,rscratch + bne cpuflags_set @ if flags => check for irq/nmi/scan_keys... + + exec_op @ execute next opcode + +cpuflags_set: @ check flags (!=0) + tst rscratch,#nmi_flag @ check nmi + beq cpuflagsnmi_flag_cleared + ldr rscratch2,[reg_cpu_var,#nmicyclecount_ofs] + subs rscratch2,rscratch2,#1 + str rscratch2,[reg_cpu_var,#nmicyclecount_ofs] + bne cpuflagsnmi_flag_cleared + bic rscratch,rscratch,#nmi_flag + str rscratch,[reg_cpu_var,#flags_ofs] + ldrb rscratch2,[reg_cpu_var,#waitingforinterrupt_ofs] + movs rscratch2,rscratch2 + beq notcpuaitingforinterruptnmi + mov rscratch2,#0 + add rpc,rpc,#1 + strb rscratch2,[reg_cpu_var,#waitingforinterrupt_ofs] +notcpuaitingforinterruptnmi: + s9xopcode_nmi + ldr rscratch,[reg_cpu_var,#flags_ofs] +cpuflagsnmi_flag_cleared: + tst rscratch,#irq_pending_flag @ check irq_pending_flag + beq cpuflagsirq_pending_flag_cleared + ldr rscratch2,[reg_cpu_var,#irqcyclecount_ofs] + movs rscratch2,rscratch2 + bne cpuirqcyclecount_notzero + ldrb rscratch2,[reg_cpu_var,#waitingforinterrupt_ofs] + movs rscratch2,rscratch2 + beq notcpuaitingforinterruptirq + mov rscratch2,#0 + add rpc,rpc,#1 + strb rscratch2,[reg_cpu_var,#waitingforinterrupt_ofs] +notcpuaitingforinterruptirq: + ldrb rscratch2,[reg_cpu_var,#irqactive_ofs] + movs rscratch2,rscratch2 + beq cpuirqactive_cleared + tst rstatus,#mask_irq + bne cpuflagsirq_pending_flag_cleared + s9xopcode_irq + ldr rscratch,[reg_cpu_var,#flags_ofs] + b cpuflagsirq_pending_flag_cleared +cpuirqactive_cleared: + bic rscratch,rscratch,#irq_pending_flag + str rscratch,[reg_cpu_var,#flags_ofs] + b cpuflagsirq_pending_flag_cleared +cpuirqcyclecount_notzero: + sub rscratch2,rscratch2,#1 + str rscratch2,[reg_cpu_var,#irqcyclecount_ofs] +cpuflagsirq_pending_flag_cleared: + + tst rscratch,#scan_keys_flag @ check scan_keys_flag + bne endmainloop + + exec_op @ execute next opcode + +endmainloop: + + /*registers.pc = cpu.pc - cpu.pcbase; + s9xpackstatus (); + apuregisters.pc = iapu.pc - iapu.ram; + s9xapupackstatus (); + + if (cpu.flags & scan_keys_flag) + { + s9xsyncspeed (); + cpu.flags &= ~scan_keys_flag; + } */ +/********end*/ + save_regs + ldmfd r13!,{r4-r11,lr} + mov pc,lr +@@.pool + +@ void test_opcode(struct asm_cpu_var *asm_var); +_test_opcode: + @ save registers + stmfd r13!,{r4-r11,lr} + @ init pointer to cpuvar structure + mov reg_cpu_var,r0 + @ init registers + load_regs + @ get cpu mode from flag and init jump table + s9xfixcycles + + exec_op +@@.pool + +/***************************************************************** + asm code +*****************************************************************/ + + +jumptable1: .long op00mod1 + .long op01m1mod1 + .long op02mod1 + .long op03m1mod1 + .long op04m1mod1 + .long op05m1mod1 + .long op06m1mod1 + .long op07m1mod1 + .long op08mod1 + .long op09m1mod1 + .long op0am1mod1 + .long op0bmod1 + .long op0cm1mod1 + .long op0dm1mod1 + .long op0em1mod1 + .long op0fm1mod1 + .long op10mod1 + .long op11m1mod1 + .long op12m1mod1 + .long op13m1mod1 + .long op14m1mod1 + .long op15m1mod1 + .long op16m1mod1 + .long op17m1mod1 + .long op18mod1 + .long op19m1mod1 + .long op1am1mod1 + .long op1bmod1 + .long op1cm1mod1 + .long op1dm1mod1 + .long op1em1mod1 + .long op1fm1mod1 + .long op20mod1 + .long op21m1mod1 + .long op22mod1 + .long op23m1mod1 + .long op24m1mod1 + .long op25m1mod1 + .long op26m1mod1 + .long op27m1mod1 + .long op28mod1 + .long op29m1mod1 + .long op2am1mod1 + .long op2bmod1 + .long op2cm1mod1 + .long op2dm1mod1 + .long op2em1mod1 + .long op2fm1mod1 + .long op30mod1 + .long op31m1mod1 + .long op32m1mod1 + .long op33m1mod1 + .long op34m1mod1 + .long op35m1mod1 + .long op36m1mod1 + .long op37m1mod1 + .long op38mod1 + .long op39m1mod1 + .long op3am1mod1 + .long op3bmod1 + .long op3cm1mod1 + .long op3dm1mod1 + .long op3em1mod1 + .long op3fm1mod1 + .long op40mod1 + .long op41m1mod1 + .long op42mod1 + .long op43m1mod1 + .long op44x1mod1 + .long op45m1mod1 + .long op46m1mod1 + .long op47m1mod1 + .long op48m1mod1 + .long op49m1mod1 + .long op4am1mod1 + .long op4bmod1 + .long op4cmod1 + .long op4dm1mod1 + .long op4em1mod1 + .long op4fm1mod1 + .long op50mod1 + .long op51m1mod1 + .long op52m1mod1 + .long op53m1mod1 + .long op54x1mod1 + .long op55m1mod1 + .long op56m1mod1 + .long op57m1mod1 + .long op58mod1 + .long op59m1mod1 + .long op5ax1mod1 + .long op5bmod1 + .long op5cmod1 + .long op5dm1mod1 + .long op5em1mod1 + .long op5fm1mod1 + .long op60mod1 + .long op61m1mod1 + .long op62mod1 + .long op63m1mod1 + .long op64m1mod1 + .long op65m1mod1 + .long op66m1mod1 + .long op67m1mod1 + .long op68m1mod1 + .long op69m1mod1 + .long op6am1mod1 + .long op6bmod1 + .long op6cmod1 + .long op6dm1mod1 + .long op6em1mod1 + .long op6fm1mod1 + .long op70mod1 + .long op71m1mod1 + .long op72m1mod1 + .long op73m1mod1 + .long op74m1mod1 + .long op75m1mod1 + .long op76m1mod1 + .long op77m1mod1 + .long op78mod1 + .long op79m1mod1 + .long op7ax1mod1 + .long op7bmod1 + .long op7cmod1 + .long op7dm1mod1 + .long op7em1mod1 + .long op7fm1mod1 + .long op80mod1 + .long op81m1mod1 + .long op82mod1 + .long op83m1mod1 + .long op84x1mod1 + .long op85m1mod1 + .long op86x1mod1 + .long op87m1mod1 + .long op88x1mod1 + .long op89m1mod1 + .long op8am1mod1 + .long op8bmod1 + .long op8cx1mod1 + .long op8dm1mod1 + .long op8ex1mod1 + .long op8fm1mod1 + .long op90mod1 + .long op91m1mod1 + .long op92m1mod1 + .long op93m1mod1 + .long op94x1mod1 + .long op95m1mod1 + .long op96x1mod1 + .long op97m1mod1 + .long op98m1mod1 + .long op99m1mod1 + .long op9amod1 + .long op9bx1mod1 + .long op9cm1mod1 + .long op9dm1mod1 + .long op9em1mod1 + .long op9fm1mod1 + .long opa0x1mod1 + .long opa1m1mod1 + .long opa2x1mod1 + .long opa3m1mod1 + .long opa4x1mod1 + .long opa5m1mod1 + .long opa6x1mod1 + .long opa7m1mod1 + .long opa8x1mod1 + .long opa9m1mod1 + .long opaax1mod1 + .long opabmod1 + .long opacx1mod1 + .long opadm1mod1 + .long opaex1mod1 + .long opafm1mod1 + .long opb0mod1 + .long opb1m1mod1 + .long opb2m1mod1 + .long opb3m1mod1 + .long opb4x1mod1 + .long opb5m1mod1 + .long opb6x1mod1 + .long opb7m1mod1 + .long opb8mod1 + .long opb9m1mod1 + .long opbax1mod1 + .long opbbx1mod1 + .long opbcx1mod1 + .long opbdm1mod1 + .long opbex1mod1 + .long opbfm1mod1 + .long opc0x1mod1 + .long opc1m1mod1 + .long opc2mod1 + .long opc3m1mod1 + .long opc4x1mod1 + .long opc5m1mod1 + .long opc6m1mod1 + .long opc7m1mod1 + .long opc8x1mod1 + .long opc9m1mod1 + .long opcax1mod1 + .long opcbmod1 + .long opccx1mod1 + .long opcdm1mod1 + .long opcem1mod1 + .long opcfm1mod1 + .long opd0mod1 + .long opd1m1mod1 + .long opd2m1mod1 + .long opd3m1mod1 + .long opd4mod1 + .long opd5m1mod1 + .long opd6m1mod1 + .long opd7m1mod1 + .long opd8mod1 + .long opd9m1mod1 + .long opdax1mod1 + .long opdbmod1 + .long opdcmod1 + .long opddm1mod1 + .long opdem1mod1 + .long opdfm1mod1 + .long ope0x1mod1 + .long ope1m1mod1 + .long ope2mod1 + .long ope3m1mod1 + .long ope4x1mod1 + .long ope5m1mod1 + .long ope6m1mod1 + .long ope7m1mod1 + .long ope8x1mod1 + .long ope9m1mod1 + .long opeamod1 + .long opebmod1 + .long opecx1mod1 + .long opedm1mod1 + .long opeem1mod1 + .long opefm1mod1 + .long opf0mod1 + .long opf1m1mod1 + .long opf2m1mod1 + .long opf3m1mod1 + .long opf4mod1 + .long opf5m1mod1 + .long opf6m1mod1 + .long opf7m1mod1 + .long opf8mod1 + .long opf9m1mod1 + .long opfax1mod1 + .long opfbmod1 + .long opfcmod1 + .long opfdm1mod1 + .long opfem1mod1 + .long opffm1mod1 + +op00mod1: +lbl00mod1: op00 + nextopcode +op01m1mod1: +lbl01mod1a: directindexedindirect1 +lbl01mod1b: ora8 + nextopcode +op02mod1: +lbl02mod1: op02 + nextopcode +op03m1mod1: +lbl03mod1a: stackasmrelative +lbl03mod1b: ora8 + nextopcode +op04m1mod1: +lbl04mod1a: direct +lbl04mod1b: tsb8 + nextopcode +op05m1mod1: +lbl05mod1a: direct +lbl05mod1b: ora8 + nextopcode +op06m1mod1: +lbl06mod1a: direct +lbl06mod1b: asl8 + nextopcode +op07m1mod1: +lbl07mod1a: directindirectlong +lbl07mod1b: ora8 + nextopcode +op08mod1: +lbl08mod1: op08 + nextopcode +op09m1mod1: +lbl09mod1: op09m1 + nextopcode +op0am1mod1: +lbl0amod1a: a_asl8 + nextopcode +op0bmod1: +lbl0bmod1: op0b + nextopcode +op0cm1mod1: +lbl0cmod1a: absolute +lbl0cmod1b: tsb8 + nextopcode +op0dm1mod1: +lbl0dmod1a: absolute +lbl0dmod1b: ora8 + nextopcode +op0em1mod1: +lbl0emod1a: absolute +lbl0emod1b: asl8 + nextopcode +op0fm1mod1: +lbl0fmod1a: absolutelong +lbl0fmod1b: ora8 + nextopcode +op10mod1: +lbl10mod1: op10 + nextopcode +op11m1mod1: +lbl11mod1a: directindirectindexed1 +lbl11mod1b: ora8 + nextopcode +op12m1mod1: +lbl12mod1a: directindirect +lbl12mod1b: ora8 + nextopcode +op13m1mod1: +lbl13mod1a: stackasmrelativeindirectindexed1 +lbl13mod1b: ora8 + nextopcode +op14m1mod1: +lbl14mod1a: direct +lbl14mod1b: trb8 + nextopcode +op15m1mod1: +lbl15mod1a: directindexedx1 +lbl15mod1b: ora8 + nextopcode +op16m1mod1: +lbl16mod1a: directindexedx1 +lbl16mod1b: asl8 + nextopcode +op17m1mod1: +lbl17mod1a: directindirectindexedlong1 +lbl17mod1b: ora8 + nextopcode +op18mod1: +lbl18mod1: op18 + nextopcode +op19m1mod1: +lbl19mod1a: absoluteindexedy1 +lbl19mod1b: ora8 + nextopcode +op1am1mod1: +lbl1amod1a: a_inc8 + nextopcode +op1bmod1: +lbl1bmod1: op1bm1 + nextopcode +op1cm1mod1: +lbl1cmod1a: absolute +lbl1cmod1b: trb8 + nextopcode +op1dm1mod1: +lbl1dmod1a: absoluteindexedx1 +lbl1dmod1b: ora8 + nextopcode +op1em1mod1: +lbl1emod1a: absoluteindexedx1 +lbl1emod1b: asl8 + nextopcode +op1fm1mod1: +lbl1fmod1a: absolutelongindexedx1 +lbl1fmod1b: ora8 + nextopcode +op20mod1: +lbl20mod1: op20 + nextopcode +op21m1mod1: +lbl21mod1a: directindexedindirect1 +lbl21mod1b: and8 + nextopcode +op22mod1: +lbl22mod1: op22 + nextopcode +op23m1mod1: +lbl23mod1a: stackasmrelative +lbl23mod1b: and8 + nextopcode +op24m1mod1: +lbl24mod1a: direct +lbl24mod1b: bit8 + nextopcode +op25m1mod1: +lbl25mod1a: direct +lbl25mod1b: and8 + nextopcode +op26m1mod1: +lbl26mod1a: direct +lbl26mod1b: rol8 + nextopcode +op27m1mod1: +lbl27mod1a: directindirectlong +lbl27mod1b: and8 + nextopcode +op28mod1: +lbl28mod1: op28x1m1 + nextopcode +@@.pool +op29m1mod1: +lbl29mod1: op29m1 + nextopcode +op2am1mod1: +lbl2amod1a: a_rol8 + nextopcode +op2bmod1: +lbl2bmod1: op2b + nextopcode +op2cm1mod1: +lbl2cmod1a: absolute +lbl2cmod1b: bit8 + nextopcode +op2dm1mod1: +lbl2dmod1a: absolute +lbl2dmod1b: and8 + nextopcode +op2em1mod1: +lbl2emod1a: absolute +lbl2emod1b: rol8 + nextopcode +op2fm1mod1: +lbl2fmod1a: absolutelong +lbl2fmod1b: and8 + nextopcode +op30mod1: +lbl30mod1: op30 + nextopcode +op31m1mod1: +lbl31mod1a: directindirectindexed1 +lbl31mod1b: and8 + nextopcode +op32m1mod1: +lbl32mod1a: directindirect +lbl32mod1b: and8 + nextopcode +op33m1mod1: +lbl33mod1a: stackasmrelativeindirectindexed1 +lbl33mod1b: and8 + nextopcode +op34m1mod1: +lbl34mod1a: directindexedx1 +lbl34mod1b: bit8 + nextopcode +op35m1mod1: +lbl35mod1a: directindexedx1 +lbl35mod1b: and8 + nextopcode +op36m1mod1: +lbl36mod1a: directindexedx1 +lbl36mod1b: rol8 + nextopcode +op37m1mod1: +lbl37mod1a: directindirectindexedlong1 +lbl37mod1b: and8 + nextopcode +op38mod1: +lbl38mod1: op38 + nextopcode +op39m1mod1: +lbl39mod1a: absoluteindexedy1 +lbl39mod1b: and8 + nextopcode +op3am1mod1: +lbl3amod1a: a_dec8 + nextopcode +op3bmod1: +lbl3bmod1: op3bm1 + nextopcode +op3cm1mod1: +lbl3cmod1a: absoluteindexedx1 +lbl3cmod1b: bit8 + nextopcode +op3dm1mod1: +lbl3dmod1a: absoluteindexedx1 +lbl3dmod1b: and8 + nextopcode +op3em1mod1: +lbl3emod1a: absoluteindexedx1 +lbl3emod1b: rol8 + nextopcode +op3fm1mod1: +lbl3fmod1a: absolutelongindexedx1 +lbl3fmod1b: and8 + nextopcode +op40mod1: +lbl40mod1: op40x1m1 + nextopcode +@@.pool +op41m1mod1: +lbl41mod1a: directindexedindirect1 +lbl41mod1b: eor8 + nextopcode +op42mod1: +lbl42mod1: op42 + nextopcode +op43m1mod1: +lbl43mod1a: stackasmrelative +lbl43mod1b: eor8 + nextopcode +op44x1mod1: +lbl44mod1: op44x1m1 + nextopcode +op45m1mod1: +lbl45mod1a: direct +lbl45mod1b: eor8 + nextopcode +op46m1mod1: +lbl46mod1a: direct +lbl46mod1b: lsr8 + nextopcode +op47m1mod1: +lbl47mod1a: directindirectlong +lbl47mod1b: eor8 + nextopcode +op48m1mod1: +lbl48mod1: op48m1 + nextopcode +op49m1mod1: +lbl49mod1: op49m1 + nextopcode +op4am1mod1: +lbl4amod1a: a_lsr8 + nextopcode +op4bmod1: +lbl4bmod1: op4b + nextopcode +op4cmod1: +lbl4cmod1: op4c + nextopcode +op4dm1mod1: +lbl4dmod1a: absolute +lbl4dmod1b: eor8 + nextopcode +op4em1mod1: +lbl4emod1a: absolute +lbl4emod1b: lsr8 + nextopcode +op4fm1mod1: +lbl4fmod1a: absolutelong +lbl4fmod1b: eor8 + nextopcode +op50mod1: +lbl50mod1: op50 + nextopcode +op51m1mod1: +lbl51mod1a: directindirectindexed1 +lbl51mod1b: eor8 + nextopcode +op52m1mod1: +lbl52mod1a: directindirect +lbl52mod1b: eor8 + nextopcode +op53m1mod1: +lbl53mod1a: stackasmrelativeindirectindexed1 +lbl53mod1b: eor8 + nextopcode +op54x1mod1: +lbl54mod1: op54x1m1 + nextopcode +op55m1mod1: +lbl55mod1a: directindexedx1 +lbl55mod1b: eor8 + nextopcode +op56m1mod1: +lbl56mod1a: directindexedx1 +lbl56mod1b: lsr8 + nextopcode +op57m1mod1: +lbl57mod1a: directindirectindexedlong1 +lbl57mod1b: eor8 + nextopcode +op58mod1: +lbl58mod1: op58 + nextopcode +op59m1mod1: +lbl59mod1a: absoluteindexedy1 +lbl59mod1b: eor8 + nextopcode +op5ax1mod1: +lbl5amod1: op5ax1 + nextopcode +op5bmod1: +lbl5bmod1: op5bm1 + nextopcode +op5cmod1: +lbl5cmod1: op5c + nextopcode +op5dm1mod1: +lbl5dmod1a: absoluteindexedx1 +lbl5dmod1b: eor8 + nextopcode +op5em1mod1: +lbl5emod1a: absoluteindexedx1 +lbl5emod1b: lsr8 + nextopcode +op5fm1mod1: +lbl5fmod1a: absolutelongindexedx1 +lbl5fmod1b: eor8 + nextopcode +op60mod1: +lbl60mod1: op60 + nextopcode +op61m1mod1: +lbl61mod1a: directindexedindirect1 +lbl61mod1b: adc8 + nextopcode +op62mod1: +lbl62mod1: op62 + nextopcode +op63m1mod1: +lbl63mod1a: stackasmrelative +lbl63mod1b: adc8 + nextopcode +op64m1mod1: +lbl64mod1a: direct +lbl64mod1b: stz8 + nextopcode +op65m1mod1: +lbl65mod1a: direct +lbl65mod1b: adc8 + nextopcode +op66m1mod1: +lbl66mod1a: direct +lbl66mod1b: ror8 + nextopcode +op67m1mod1: +lbl67mod1a: directindirectlong +lbl67mod1b: adc8 + nextopcode +op68m1mod1: +lbl68mod1: op68m1 + nextopcode +op69m1mod1: +lbl69mod1a: immediate8 +lbl69mod1b: adc8 + nextopcode +op6am1mod1: +lbl6amod1a: a_ror8 + nextopcode +op6bmod1: +lbl6bmod1: op6b + nextopcode +op6cmod1: +lbl6cmod1: op6c + nextopcode +op6dm1mod1: +lbl6dmod1a: absolute +lbl6dmod1b: adc8 + nextopcode +op6em1mod1: +lbl6emod1a: absolute +lbl6emod1b: ror8 + nextopcode +op6fm1mod1: +lbl6fmod1a: absolutelong +lbl6fmod1b: adc8 + nextopcode +op70mod1: +lbl70mod1: op70 + nextopcode +op71m1mod1: +lbl71mod1a: directindirectindexed1 +lbl71mod1b: adc8 + nextopcode +op72m1mod1: +lbl72mod1a: directindirect +lbl72mod1b: adc8 + nextopcode +op73m1mod1: +lbl73mod1a: stackasmrelativeindirectindexed1 +lbl73mod1b: adc8 + nextopcode + +op74m1mod1: +lbl74mod1a: directindexedx1 +lbl74mod1b: stz8 + nextopcode +op75m1mod1: +lbl75mod1a: directindexedx1 +lbl75mod1b: adc8 + nextopcode +op76m1mod1: +lbl76mod1a: directindexedx1 +lbl76mod1b: ror8 + nextopcode +op77m1mod1: +lbl77mod1a: directindirectindexedlong1 +lbl77mod1b: adc8 + nextopcode +op78mod1: +lbl78mod1: op78 + nextopcode +op79m1mod1: +lbl79mod1a: absoluteindexedy1 +lbl79mod1b: adc8 + nextopcode +op7ax1mod1: +lbl7amod1: op7ax1 + nextopcode +op7bmod1: +lbl7bmod1: op7bm1 + nextopcode +op7cmod1: +lbl7cmod1: absoluteindexedindirectx1 + op7c + nextopcode +op7dm1mod1: +lbl7dmod1a: absoluteindexedx1 +lbl7dmod1b: adc8 + nextopcode +op7em1mod1: +lbl7emod1a: absoluteindexedx1 +lbl7emod1b: ror8 + nextopcode +op7fm1mod1: +lbl7fmod1a: absolutelongindexedx1 +lbl7fmod1b: adc8 + nextopcode + + +op80mod1: +lbl80mod1: op80 + nextopcode +op81m1mod1: +lbl81mod1a: directindexedindirect1 +lbl81mod1b: op81m1 + nextopcode +op82mod1: +lbl82mod1: op82 + nextopcode +op83m1mod1: +lbl83mod1a: stackasmrelative +lbl83mod1b: sta8 + nextopcode +op84x1mod1: +lbl84mod1a: direct +lbl84mod1b: sty8 + nextopcode +op85m1mod1: +lbl85mod1a: direct +lbl85mod1b: sta8 + nextopcode +op86x1mod1: +lbl86mod1a: direct +lbl86mod1b: stx8 + nextopcode +op87m1mod1: +lbl87mod1a: directindirectlong +lbl87mod1b: sta8 + nextopcode +op88x1mod1: +lbl88mod1: op88x1 + nextopcode +op89m1mod1: +lbl89mod1: op89m1 + nextopcode +op8am1mod1: +lbl8amod1: op8am1x1 + nextopcode +op8bmod1: +lbl8bmod1: op8b + nextopcode +op8cx1mod1: +lbl8cmod1a: absolute +lbl8cmod1b: sty8 + nextopcode +op8dm1mod1: +lbl8dmod1a: absolute +lbl8dmod1b: sta8 + nextopcode +op8ex1mod1: +lbl8emod1a: absolute +lbl8emod1b: stx8 + nextopcode +op8fm1mod1: +lbl8fmod1a: absolutelong +lbl8fmod1b: sta8 + nextopcode +op90mod1: +lbl90mod1: op90 + nextopcode +op91m1mod1: +lbl91mod1a: directindirectindexed1 +lbl91mod1b: sta8 + nextopcode +op92m1mod1: +lbl92mod1a: directindirect +lbl92mod1b: sta8 + nextopcode +op93m1mod1: +lbl93mod1a: stackasmrelativeindirectindexed1 +lbl93mod1b: sta8 + nextopcode +op94x1mod1: +lbl94mod1a: directindexedx1 +lbl94mod1b: sty8 + nextopcode +op95m1mod1: +lbl95mod1a: directindexedx1 +lbl95mod1b: sta8 + nextopcode +op96x1mod1: +lbl96mod1a: directindexedy1 +lbl96mod1b: stx8 + nextopcode +op97m1mod1: +lbl97mod1a: directindirectindexedlong1 +lbl97mod1b: sta8 + nextopcode +op98m1mod1: +lbl98mod1: op98m1x1 + nextopcode +op99m1mod1: +lbl99mod1a: absoluteindexedy1 +lbl99mod1b: sta8 + nextopcode +op9amod1: +lbl9amod1: op9ax1 + nextopcode +op9bx1mod1: +lbl9bmod1: op9bx1 + nextopcode +op9cm1mod1: +lbl9cmod1a: absolute +lbl9cmod1b: stz8 + nextopcode +op9dm1mod1: +lbl9dmod1a: absoluteindexedx1 +lbl9dmod1b: sta8 + nextopcode +op9em1mod1: +lbl9emod1: absoluteindexedx1 + stz8 + nextopcode +op9fm1mod1: +lbl9fmod1a: absolutelongindexedx1 +lbl9fmod1b: sta8 + nextopcode +opa0x1mod1: +lbla0mod1: opa0x1 + nextopcode +opa1m1mod1: +lbla1mod1a: directindexedindirect1 +lbla1mod1b: lda8 + nextopcode +opa2x1mod1: +lbla2mod1: opa2x1 + nextopcode +opa3m1mod1: +lbla3mod1a: stackasmrelative +lbla3mod1b: lda8 + nextopcode +opa4x1mod1: +lbla4mod1a: direct +lbla4mod1b: ldy8 + nextopcode +opa5m1mod1: +lbla5mod1a: direct +lbla5mod1b: lda8 + nextopcode +opa6x1mod1: +lbla6mod1a: direct +lbla6mod1b: ldx8 + nextopcode +opa7m1mod1: +lbla7mod1a: directindirectlong +lbla7mod1b: lda8 + nextopcode +opa8x1mod1: +lbla8mod1: opa8x1m1 + nextopcode +opa9m1mod1: +lbla9mod1: opa9m1 + nextopcode +opaax1mod1: +lblaamod1: opaax1m1 + nextopcode +opabmod1: +lblabmod1: opab + nextopcode +opacx1mod1: +lblacmod1a: absolute +lblacmod1b: ldy8 + nextopcode +opadm1mod1: +lbladmod1a: absolute +lbladmod1b: lda8 + nextopcode +opaex1mod1: +lblaemod1a: absolute +lblaemod1b: ldx8 + nextopcode +opafm1mod1: +lblafmod1a: absolutelong +lblafmod1b: lda8 + nextopcode +opb0mod1: +lblb0mod1: opb0 + nextopcode +opb1m1mod1: +lblb1mod1a: directindirectindexed1 +lblb1mod1b: lda8 + nextopcode +opb2m1mod1: +lblb2mod1a: directindirect +lblb2mod1b: lda8 + nextopcode +opb3m1mod1: +lblb3mod1a: stackasmrelativeindirectindexed1 +lblb3mod1b: lda8 + nextopcode +opb4x1mod1: +lblb4mod1a: directindexedx1 +lblb4mod1b: ldy8 + nextopcode +opb5m1mod1: +lblb5mod1a: directindexedx1 +lblb5mod1b: lda8 + nextopcode +opb6x1mod1: +lblb6mod1a: directindexedy1 +lblb6mod1b: ldx8 + nextopcode +opb7m1mod1: +lblb7mod1a: directindirectindexedlong1 +lblb7mod1b: lda8 + nextopcode +opb8mod1: +lblb8mod1: opb8 + nextopcode +opb9m1mod1: +lblb9mod1a: absoluteindexedy1 +lblb9mod1b: lda8 + nextopcode +opbax1mod1: +lblbamod1: opbax1 + nextopcode +opbbx1mod1: +lblbbmod1: opbbx1 + nextopcode +opbcx1mod1: +lblbcmod1a: absoluteindexedx1 +lblbcmod1b: ldy8 + nextopcode +opbdm1mod1: +lblbdmod1a: absoluteindexedx1 +lblbdmod1b: lda8 + nextopcode +opbex1mod1: +lblbemod1a: absoluteindexedy1 +lblbemod1b: ldx8 + nextopcode +opbfm1mod1: +lblbfmod1a: absolutelongindexedx1 +lblbfmod1b: lda8 + nextopcode +opc0x1mod1: +lblc0mod1: opc0x1 + nextopcode +opc1m1mod1: +lblc1mod1a: directindexedindirect1 +lblc1mod1b: cmp8 + nextopcode +opc2mod1: +lblc2mod1: opc2 + nextopcode +@@.pool +opc3m1mod1: +lblc3mod1a: stackasmrelative +lblc3mod1b: cmp8 + nextopcode +opc4x1mod1: +lblc4mod1a: direct +lblc4mod1b: cmy8 + nextopcode +opc5m1mod1: +lblc5mod1a: direct +lblc5mod1b: cmp8 + nextopcode +opc6m1mod1: +lblc6mod1a: direct +lblc6mod1b: dec8 + nextopcode +opc7m1mod1: +lblc7mod1a: directindirectlong +lblc7mod1b: cmp8 + nextopcode +opc8x1mod1: +lblc8mod1: opc8x1 + nextopcode +opc9m1mod1: +lblc9mod1: opc9m1 + nextopcode +opcax1mod1: +lblcamod1: opcax1 + nextopcode +opcbmod1: +lblcbmod1: opcb + nextopcode +opccx1mod1: +lblccmod1a: absolute +lblccmod1b: cmy8 + nextopcode +opcdm1mod1: +lblcdmod1a: absolute +lblcdmod1b: cmp8 + nextopcode +opcem1mod1: +lblcemod1a: absolute +lblcemod1b: dec8 + nextopcode +opcfm1mod1: +lblcfmod1a: absolutelong +lblcfmod1b: cmp8 + nextopcode +opd0mod1: +lbld0mod1: opd0 + nextopcode +opd1m1mod1: +lbld1mod1a: directindirectindexed1 +lbld1mod1b: cmp8 + nextopcode +opd2m1mod1: +lbld2mod1a: directindirect +lbld2mod1b: cmp8 + nextopcode +opd3m1mod1: +lbld3mod1a: stackasmrelativeindirectindexed1 +lbld3mod1b: cmp8 + nextopcode +opd4mod1: +lbld4mod1: opd4 + nextopcode +opd5m1mod1: +lbld5mod1a: directindexedx1 +lbld5mod1b: cmp8 + nextopcode +opd6m1mod1: +lbld6mod1a: directindexedx1 +lbld6mod1b: dec8 + nextopcode +opd7m1mod1: +lbld7mod1a: directindirectindexedlong1 +lbld7mod1b: cmp8 + nextopcode +opd8mod1: +lbld8mod1: opd8 + nextopcode +opd9m1mod1: +lbld9mod1a: absoluteindexedy1 +lbld9mod1b: cmp8 + nextopcode +opdax1mod1: +lbldamod1: opdax1 + nextopcode +opdbmod1: +lbldbmod1: opdb + nextopcode +opdcmod1: +lbldcmod1: opdc + nextopcode +opddm1mod1: +lblddmod1a: absoluteindexedx1 +lblddmod1b: cmp8 + nextopcode +opdem1mod1: +lbldemod1a: absoluteindexedx1 +lbldemod1b: dec8 + nextopcode +opdfm1mod1: +lbldfmod1a: absolutelongindexedx1 +lbldfmod1b: cmp8 + nextopcode +ope0x1mod1: +lble0mod1: ope0x1 + nextopcode +ope1m1mod1: +lble1mod1a: directindexedindirect1 +lble1mod1b: sbc8 + nextopcode +ope2mod1: +lble2mod1: ope2 + nextopcode +@@.pool +ope3m1mod1: +lble3mod1a: stackasmrelative +lble3mod1b: sbc8 + nextopcode +ope4x1mod1: +lble4mod1a: direct +lble4mod1b: cmx8 + nextopcode +ope5m1mod1: +lble5mod1a: direct +lble5mod1b: sbc8 + nextopcode +ope6m1mod1: +lble6mod1a: direct +lble6mod1b: inc8 + nextopcode +ope7m1mod1: +lble7mod1a: directindirectlong +lble7mod1b: sbc8 + nextopcode +ope8x1mod1: +lble8mod1: ope8x1 + nextopcode +ope9m1mod1: +lble9mod1a: immediate8 +lble9mod1b: sbc8 + nextopcode +opeamod1: +lbleamod1: opea + nextopcode +opebmod1: +lblebmod1: opebm1 + nextopcode +opecx1mod1: +lblecmod1a: absolute +lblecmod1b: cmx8 + nextopcode +opedm1mod1: +lbledmod1a: absolute +lbledmod1b: sbc8 + nextopcode +opeem1mod1: +lbleemod1a: absolute +lbleemod1b: inc8 + nextopcode +opefm1mod1: +lblefmod1a: absolutelong +lblefmod1b: sbc8 + nextopcode +opf0mod1: +lblf0mod1: opf0 + nextopcode +opf1m1mod1: +lblf1mod1a: directindirectindexed1 +lblf1mod1b: sbc8 + nextopcode +opf2m1mod1: +lblf2mod1a: directindirect +lblf2mod1b: sbc8 + nextopcode +opf3m1mod1: +lblf3mod1a: stackasmrelativeindirectindexed1 +lblf3mod1b: sbc8 + nextopcode +opf4mod1: +lblf4mod1: opf4 + nextopcode +opf5m1mod1: +lblf5mod1a: directindexedx1 +lblf5mod1b: sbc8 + nextopcode +opf6m1mod1: +lblf6mod1a: directindexedx1 +lblf6mod1b: inc8 + nextopcode +opf7m1mod1: +lblf7mod1a: directindirectindexedlong1 +lblf7mod1b: sbc8 + nextopcode +opf8mod1: +lblf8mod1: opf8 + nextopcode +opf9m1mod1: +lblf9mod1a: absoluteindexedy1 +lblf9mod1b: sbc8 + nextopcode +opfax1mod1: +lblfamod1: opfax1 + nextopcode +opfbmod1: +lblfbmod1: opfb + nextopcode +opfcmod1: +lblfcmod1: opfcx1 + nextopcode +opfdm1mod1: +lblfdmod1a: absoluteindexedx1 +lblfdmod1b: sbc8 + nextopcode +opfem1mod1: +lblfemod1a: absoluteindexedx1 +lblfemod1b: inc8 + nextopcode +opffm1mod1: +lblffmod1a: absolutelongindexedx1 +lblffmod1b: sbc8 + nextopcode +@@.pool + + +jumptable2: .long op00mod2 + .long op01m1mod2 + .long op02mod2 + .long op03m1mod2 + .long op04m1mod2 + .long op05m1mod2 + .long op06m1mod2 + .long op07m1mod2 + .long op08mod2 + .long op09m1mod2 + .long op0am1mod2 + .long op0bmod2 + .long op0cm1mod2 + .long op0dm1mod2 + .long op0em1mod2 + .long op0fm1mod2 + .long op10mod2 + .long op11m1mod2 + .long op12m1mod2 + .long op13m1mod2 + .long op14m1mod2 + .long op15m1mod2 + .long op16m1mod2 + .long op17m1mod2 + .long op18mod2 + .long op19m1mod2 + .long op1am1mod2 + .long op1bmod2 + .long op1cm1mod2 + .long op1dm1mod2 + .long op1em1mod2 + .long op1fm1mod2 + .long op20mod2 + .long op21m1mod2 + .long op22mod2 + .long op23m1mod2 + .long op24m1mod2 + .long op25m1mod2 + .long op26m1mod2 + .long op27m1mod2 + .long op28mod2 + .long op29m1mod2 + .long op2am1mod2 + .long op2bmod2 + .long op2cm1mod2 + .long op2dm1mod2 + .long op2em1mod2 + .long op2fm1mod2 + .long op30mod2 + .long op31m1mod2 + .long op32m1mod2 + .long op33m1mod2 + .long op34m1mod2 + .long op35m1mod2 + .long op36m1mod2 + .long op37m1mod2 + .long op38mod2 + .long op39m1mod2 + .long op3am1mod2 + .long op3bmod2 + .long op3cm1mod2 + .long op3dm1mod2 + .long op3em1mod2 + .long op3fm1mod2 + .long op40mod2 + .long op41m1mod2 + .long op42mod2 + .long op43m1mod2 + .long op44x0mod2 + .long op45m1mod2 + .long op46m1mod2 + .long op47m1mod2 + .long op48m1mod2 + .long op49m1mod2 + .long op4am1mod2 + .long op4bmod2 + .long op4cmod2 + .long op4dm1mod2 + .long op4em1mod2 + .long op4fm1mod2 + .long op50mod2 + .long op51m1mod2 + .long op52m1mod2 + .long op53m1mod2 + .long op54x0mod2 + .long op55m1mod2 + .long op56m1mod2 + .long op57m1mod2 + .long op58mod2 + .long op59m1mod2 + .long op5ax0mod2 + .long op5bmod2 + .long op5cmod2 + .long op5dm1mod2 + .long op5em1mod2 + .long op5fm1mod2 + .long op60mod2 + .long op61m1mod2 + .long op62mod2 + .long op63m1mod2 + .long op64m1mod2 + .long op65m1mod2 + .long op66m1mod2 + .long op67m1mod2 + .long op68m1mod2 + .long op69m1mod2 + .long op6am1mod2 + .long op6bmod2 + .long op6cmod2 + .long op6dm1mod2 + .long op6em1mod2 + .long op6fm1mod2 + .long op70mod2 + .long op71m1mod2 + .long op72m1mod2 + .long op73m1mod2 + .long op74m1mod2 + .long op75m1mod2 + .long op76m1mod2 + .long op77m1mod2 + .long op78mod2 + .long op79m1mod2 + .long op7ax0mod2 + .long op7bmod2 + .long op7cmod2 + .long op7dm1mod2 + .long op7em1mod2 + .long op7fm1mod2 + .long op80mod2 + .long op81m1mod2 + .long op82mod2 + .long op83m1mod2 + .long op84x0mod2 + .long op85m1mod2 + .long op86x0mod2 + .long op87m1mod2 + .long op88x0mod2 + .long op89m1mod2 + .long op8am1mod2 + .long op8bmod2 + .long op8cx0mod2 + .long op8dm1mod2 + .long op8ex0mod2 + .long op8fm1mod2 + .long op90mod2 + .long op91m1mod2 + .long op92m1mod2 + .long op93m1mod2 + .long op94x0mod2 + .long op95m1mod2 + .long op96x0mod2 + .long op97m1mod2 + .long op98m1mod2 + .long op99m1mod2 + .long op9amod2 + .long op9bx0mod2 + .long op9cm1mod2 + .long op9dm1mod2 + .long op9em1mod2 + .long op9fm1mod2 + .long opa0x0mod2 + .long opa1m1mod2 + .long opa2x0mod2 + .long opa3m1mod2 + .long opa4x0mod2 + .long opa5m1mod2 + .long opa6x0mod2 + .long opa7m1mod2 + .long opa8x0mod2 + .long opa9m1mod2 + .long opaax0mod2 + .long opabmod2 + .long opacx0mod2 + .long opadm1mod2 + .long opaex0mod2 + .long opafm1mod2 + .long opb0mod2 + .long opb1m1mod2 + .long opb2m1mod2 + .long opb3m1mod2 + .long opb4x0mod2 + .long opb5m1mod2 + .long opb6x0mod2 + .long opb7m1mod2 + .long opb8mod2 + .long opb9m1mod2 + .long opbax0mod2 + .long opbbx0mod2 + .long opbcx0mod2 + .long opbdm1mod2 + .long opbex0mod2 + .long opbfm1mod2 + .long opc0x0mod2 + .long opc1m1mod2 + .long opc2mod2 + .long opc3m1mod2 + .long opc4x0mod2 + .long opc5m1mod2 + .long opc6m1mod2 + .long opc7m1mod2 + .long opc8x0mod2 + .long opc9m1mod2 + .long opcax0mod2 + .long opcbmod2 + .long opccx0mod2 + .long opcdm1mod2 + .long opcem1mod2 + .long opcfm1mod2 + .long opd0mod2 + .long opd1m1mod2 + .long opd2m1mod2 + .long opd3m1mod2 + .long opd4mod2 + .long opd5m1mod2 + .long opd6m1mod2 + .long opd7m1mod2 + .long opd8mod2 + .long opd9m1mod2 + .long opdax0mod2 + .long opdbmod2 + .long opdcmod2 + .long opddm1mod2 + .long opdem1mod2 + .long opdfm1mod2 + .long ope0x0mod2 + .long ope1m1mod2 + .long ope2mod2 + .long ope3m1mod2 + .long ope4x0mod2 + .long ope5m1mod2 + .long ope6m1mod2 + .long ope7m1mod2 + .long ope8x0mod2 + .long ope9m1mod2 + .long opeamod2 + .long opebmod2 + .long opecx0mod2 + .long opedm1mod2 + .long opeem1mod2 + .long opefm1mod2 + .long opf0mod2 + .long opf1m1mod2 + .long opf2m1mod2 + .long opf3m1mod2 + .long opf4mod2 + .long opf5m1mod2 + .long opf6m1mod2 + .long opf7m1mod2 + .long opf8mod2 + .long opf9m1mod2 + .long opfax0mod2 + .long opfbmod2 + .long opfcmod2 + .long opfdm1mod2 + .long opfem1mod2 + .long opffm1mod2 +op00mod2: +lbl00mod2: op00 + nextopcode +op01m1mod2: +lbl01mod2a: directindexedindirect0 +lbl01mod2b: ora8 + nextopcode +op02mod2: +lbl02mod2: op02 + nextopcode +op03m1mod2: +lbl03mod2a: stackasmrelative +lbl03mod2b: ora8 + nextopcode +op04m1mod2: +lbl04mod2a: direct +lbl04mod2b: tsb8 + nextopcode +op05m1mod2: +lbl05mod2a: direct +lbl05mod2b: ora8 + nextopcode +op06m1mod2: +lbl06mod2a: direct +lbl06mod2b: asl8 + nextopcode +op07m1mod2: +lbl07mod2a: directindirectlong +lbl07mod2b: ora8 + nextopcode +op08mod2: +lbl08mod2: op08 + nextopcode +op09m1mod2: +lbl09mod2: op09m1 + nextopcode +op0am1mod2: +lbl0amod2a: a_asl8 + nextopcode +op0bmod2: +lbl0bmod2: op0b + nextopcode +op0cm1mod2: +lbl0cmod2a: absolute +lbl0cmod2b: tsb8 + nextopcode +op0dm1mod2: +lbl0dmod2a: absolute +lbl0dmod2b: ora8 + nextopcode +op0em1mod2: +lbl0emod2a: absolute +lbl0emod2b: asl8 + nextopcode +op0fm1mod2: +lbl0fmod2a: absolutelong +lbl0fmod2b: ora8 + nextopcode +op10mod2: +lbl10mod2: op10 + nextopcode +op11m1mod2: +lbl11mod2a: directindirectindexed0 +lbl11mod2b: ora8 + nextopcode +op12m1mod2: +lbl12mod2a: directindirect +lbl12mod2b: ora8 + nextopcode +op13m1mod2: +lbl13mod2a: stackasmrelativeindirectindexed0 +lbl13mod2b: ora8 + nextopcode +op14m1mod2: +lbl14mod2a: direct +lbl14mod2b: trb8 + nextopcode +op15m1mod2: +lbl15mod2a: directindexedx0 +lbl15mod2b: ora8 + nextopcode +op16m1mod2: +lbl16mod2a: directindexedx0 +lbl16mod2b: asl8 + nextopcode +op17m1mod2: +lbl17mod2a: directindirectindexedlong0 +lbl17mod2b: ora8 + nextopcode +op18mod2: +lbl18mod2: op18 + nextopcode +op19m1mod2: +lbl19mod2a: absoluteindexedy0 +lbl19mod2b: ora8 + nextopcode +op1am1mod2: +lbl1amod2a: a_inc8 + nextopcode +op1bmod2: +lbl1bmod2: op1bm1 + nextopcode +op1cm1mod2: +lbl1cmod2a: absolute +lbl1cmod2b: trb8 + nextopcode +op1dm1mod2: +lbl1dmod2a: absoluteindexedx0 +lbl1dmod2b: ora8 + nextopcode +op1em1mod2: +lbl1emod2a: absoluteindexedx0 +lbl1emod2b: asl8 + nextopcode +op1fm1mod2: +lbl1fmod2a: absolutelongindexedx0 +lbl1fmod2b: ora8 + nextopcode +op20mod2: +lbl20mod2: op20 + nextopcode +op21m1mod2: +lbl21mod2a: directindexedindirect0 +lbl21mod2b: and8 + nextopcode +op22mod2: +lbl22mod2: op22 + nextopcode +op23m1mod2: +lbl23mod2a: stackasmrelative +lbl23mod2b: and8 + nextopcode +op24m1mod2: +lbl24mod2a: direct +lbl24mod2b: bit8 + nextopcode +op25m1mod2: +lbl25mod2a: direct +lbl25mod2b: and8 + nextopcode +op26m1mod2: +lbl26mod2a: direct +lbl26mod2b: rol8 + nextopcode +op27m1mod2: +lbl27mod2a: directindirectlong +lbl27mod2b: and8 + nextopcode +op28mod2: +lbl28mod2: op28x0m1 + nextopcode +@@.pool +op29m1mod2: +lbl29mod2: op29m1 + nextopcode +op2am1mod2: +lbl2amod2a: a_rol8 + nextopcode +op2bmod2: +lbl2bmod2: op2b + nextopcode +op2cm1mod2: +lbl2cmod2a: absolute +lbl2cmod2b: bit8 + nextopcode +op2dm1mod2: +lbl2dmod2a: absolute +lbl2dmod2b: and8 + nextopcode +op2em1mod2: +lbl2emod2a: absolute +lbl2emod2b: rol8 + nextopcode +op2fm1mod2: +lbl2fmod2a: absolutelong +lbl2fmod2b: and8 + nextopcode +op30mod2: +lbl30mod2: op30 + nextopcode +op31m1mod2: +lbl31mod2a: directindirectindexed0 +lbl31mod2b: and8 + nextopcode +op32m1mod2: +lbl32mod2a: directindirect +lbl32mod2b: and8 + nextopcode +op33m1mod2: +lbl33mod2a: stackasmrelativeindirectindexed0 +lbl33mod2b: and8 + nextopcode +op34m1mod2: +lbl34mod2a: directindexedx0 +lbl34mod2b: bit8 + nextopcode +op35m1mod2: +lbl35mod2a: directindexedx0 +lbl35mod2b: and8 + nextopcode +op36m1mod2: +lbl36mod2a: directindexedx0 +lbl36mod2b: rol8 + nextopcode +op37m1mod2: +lbl37mod2a: directindirectindexedlong0 +lbl37mod2b: and8 + nextopcode +op38mod2: +lbl38mod2: op38 + nextopcode +op39m1mod2: +lbl39mod2a: absoluteindexedy0 +lbl39mod2b: and8 + nextopcode +op3am1mod2: +lbl3amod2a: a_dec8 + nextopcode +op3bmod2: +lbl3bmod2: op3bm1 + nextopcode +op3cm1mod2: +lbl3cmod2a: absoluteindexedx0 +lbl3cmod2b: bit8 + nextopcode +op3dm1mod2: +lbl3dmod2a: absoluteindexedx0 +lbl3dmod2b: and8 + nextopcode +op3em1mod2: +lbl3emod2a: absoluteindexedx0 +lbl3emod2b: rol8 + nextopcode +op3fm1mod2: +lbl3fmod2a: absolutelongindexedx0 +lbl3fmod2b: and8 + nextopcode +op40mod2: +lbl40mod2: op40x0m1 + nextopcode +@@.pool +op41m1mod2: +lbl41mod2a: directindexedindirect0 +lbl41mod2b: eor8 + nextopcode +op42mod2: +lbl42mod2: op42 + nextopcode +op43m1mod2: +lbl43mod2a: stackasmrelative +lbl43mod2b: eor8 + nextopcode +op44x0mod2: +lbl44mod2: op44x0m1 + nextopcode +op45m1mod2: +lbl45mod2a: direct +lbl45mod2b: eor8 + nextopcode +op46m1mod2: +lbl46mod2a: direct +lbl46mod2b: lsr8 + nextopcode +op47m1mod2: +lbl47mod2a: directindirectlong +lbl47mod2b: eor8 + nextopcode +op48m1mod2: +lbl48mod2: op48m1 + nextopcode +op49m1mod2: +lbl49mod2: op49m1 + nextopcode +op4am1mod2: +lbl4amod2a: a_lsr8 + nextopcode +op4bmod2: +lbl4bmod2: op4b + nextopcode +op4cmod2: +lbl4cmod2: op4c + nextopcode +op4dm1mod2: +lbl4dmod2a: absolute +lbl4dmod2b: eor8 + nextopcode +op4em1mod2: +lbl4emod2a: absolute +lbl4emod2b: lsr8 + nextopcode +op4fm1mod2: +lbl4fmod2a: absolutelong +lbl4fmod2b: eor8 + nextopcode +op50mod2: +lbl50mod2: op50 + nextopcode +op51m1mod2: +lbl51mod2a: directindirectindexed0 +lbl51mod2b: eor8 + nextopcode +op52m1mod2: +lbl52mod2a: directindirect +lbl52mod2b: eor8 + nextopcode +op53m1mod2: +lbl53mod2a: stackasmrelativeindirectindexed0 +lbl53mod2b: eor8 + nextopcode +op54x0mod2: +lbl54mod2: op54x0m1 + nextopcode +op55m1mod2: +lbl55mod2a: directindexedx0 +lbl55mod2b: eor8 + nextopcode +op56m1mod2: +lbl56mod2a: directindexedx0 +lbl56mod2b: lsr8 + nextopcode +op57m1mod2: +lbl57mod2a: directindirectindexedlong0 +lbl57mod2b: eor8 + nextopcode +op58mod2: +lbl58mod2: op58 + nextopcode +op59m1mod2: +lbl59mod2a: absoluteindexedy0 +lbl59mod2b: eor8 + nextopcode +op5ax0mod2: +lbl5amod2: op5ax0 + nextopcode +op5bmod2: +lbl5bmod2: op5bm1 + nextopcode +op5cmod2: +lbl5cmod2: op5c + nextopcode +op5dm1mod2: +lbl5dmod2a: absoluteindexedx0 +lbl5dmod2b: eor8 + nextopcode +op5em1mod2: +lbl5emod2a: absoluteindexedx0 +lbl5emod2b: lsr8 + nextopcode +op5fm1mod2: +lbl5fmod2a: absolutelongindexedx0 +lbl5fmod2b: eor8 + nextopcode +op60mod2: +lbl60mod2: op60 + nextopcode +op61m1mod2: +lbl61mod2a: directindexedindirect0 +lbl61mod2b: adc8 + nextopcode +op62mod2: +lbl62mod2: op62 + nextopcode +op63m1mod2: +lbl63mod2a: stackasmrelative +lbl63mod2b: adc8 + nextopcode +op64m1mod2: +lbl64mod2a: direct +lbl64mod2b: stz8 + nextopcode +op65m1mod2: +lbl65mod2a: direct +lbl65mod2b: adc8 + nextopcode +op66m1mod2: +lbl66mod2a: direct +lbl66mod2b: ror8 + nextopcode +op67m1mod2: +lbl67mod2a: directindirectlong +lbl67mod2b: adc8 + nextopcode +op68m1mod2: +lbl68mod2: op68m1 + nextopcode +op69m1mod2: +lbl69mod2a: immediate8 +lbl69mod2b: adc8 + nextopcode +op6am1mod2: +lbl6amod2a: a_ror8 + nextopcode +op6bmod2: +lbl6bmod2: op6b + nextopcode +op6cmod2: +lbl6cmod2: op6c + nextopcode +op6dm1mod2: +lbl6dmod2a: absolute +lbl6dmod2b: adc8 + nextopcode +op6em1mod2: +lbl6emod2a: absolute +lbl6emod2b: ror8 + nextopcode +op6fm1mod2: +lbl6fmod2a: absolutelong +lbl6fmod2b: adc8 + nextopcode +op70mod2: +lbl70mod2: op70 + nextopcode +op71m1mod2: +lbl71mod2a: directindirectindexed0 +lbl71mod2b: adc8 + nextopcode +op72m1mod2: +lbl72mod2a: directindirect +lbl72mod2b: adc8 + nextopcode +op73m1mod2: +lbl73mod2a: stackasmrelativeindirectindexed0 +lbl73mod2b: adc8 + nextopcode +op74m1mod2: +lbl74mod2a: directindexedx0 +lbl74mod2b: stz8 + nextopcode +op75m1mod2: +lbl75mod2a: directindexedx0 +lbl75mod2b: adc8 + nextopcode +op76m1mod2: +lbl76mod2a: directindexedx0 +lbl76mod2b: ror8 + nextopcode +op77m1mod2: +lbl77mod2a: directindirectindexedlong0 +lbl77mod2b: adc8 + nextopcode +op78mod2: +lbl78mod2: op78 + nextopcode +op79m1mod2: +lbl79mod2a: absoluteindexedy0 +lbl79mod2b: adc8 + nextopcode +op7ax0mod2: +lbl7amod2: op7ax0 + nextopcode +op7bmod2: +lbl7bmod2: op7bm1 + nextopcode +op7cmod2: +lbl7cmod2: absoluteindexedindirectx0 + op7c + nextopcode +op7dm1mod2: +lbl7dmod2a: absoluteindexedx0 +lbl7dmod2b: adc8 + nextopcode +op7em1mod2: +lbl7emod2a: absoluteindexedx0 +lbl7emod2b: ror8 + nextopcode +op7fm1mod2: +lbl7fmod2a: absolutelongindexedx0 +lbl7fmod2b: adc8 + nextopcode + + +op80mod2: +lbl80mod2: op80 + nextopcode +op81m1mod2: +lbl81mod2a: directindexedindirect0 +lbl81mod2b: op81m1 + nextopcode +op82mod2: +lbl82mod2: op82 + nextopcode +op83m1mod2: +lbl83mod2a: stackasmrelative +lbl83mod2b: sta8 + nextopcode +op84x0mod2: +lbl84mod2a: direct +lbl84mod2b: sty16 + nextopcode +op85m1mod2: +lbl85mod2a: direct +lbl85mod2b: sta8 + nextopcode +op86x0mod2: +lbl86mod2a: direct +lbl86mod2b: stx16 + nextopcode +op87m1mod2: +lbl87mod2a: directindirectlong +lbl87mod2b: sta8 + nextopcode +op88x0mod2: +lbl88mod2: op88x0 + nextopcode +op89m1mod2: +lbl89mod2: op89m1 + nextopcode +op8am1mod2: +lbl8amod2: op8am1x0 + nextopcode +op8bmod2: +lbl8bmod2: op8b + nextopcode +op8cx0mod2: +lbl8cmod2a: absolute +lbl8cmod2b: sty16 + nextopcode +op8dm1mod2: +lbl8dmod2a: absolute +lbl8dmod2b: sta8 + nextopcode +op8ex0mod2: +lbl8emod2a: absolute +lbl8emod2b: stx16 + nextopcode +op8fm1mod2: +lbl8fmod2a: absolutelong +lbl8fmod2b: sta8 + nextopcode +op90mod2: +lbl90mod2: op90 + nextopcode +op91m1mod2: +lbl91mod2a: directindirectindexed0 +lbl91mod2b: sta8 + nextopcode +op92m1mod2: +lbl92mod2a: directindirect +lbl92mod2b: sta8 + nextopcode +op93m1mod2: +lbl93mod2a: stackasmrelativeindirectindexed0 +lbl93mod2b: sta8 + nextopcode +op94x0mod2: +lbl94mod2a: directindexedx0 +lbl94mod2b: sty16 + nextopcode +op95m1mod2: +lbl95mod2a: directindexedx0 +lbl95mod2b: sta8 + nextopcode +op96x0mod2: +lbl96mod2a: directindexedy0 +lbl96mod2b: stx16 + nextopcode +op97m1mod2: +lbl97mod2a: directindirectindexedlong0 +lbl97mod2b: sta8 + nextopcode +op98m1mod2: +lbl98mod2: op98m1x0 + nextopcode +op99m1mod2: +lbl99mod2a: absoluteindexedy0 +lbl99mod2b: sta8 + nextopcode +op9amod2: +lbl9amod2: op9ax0 + nextopcode +op9bx0mod2: +lbl9bmod2: op9bx0 + nextopcode +op9cm1mod2: +lbl9cmod2a: absolute +lbl9cmod2b: stz8 + nextopcode +op9dm1mod2: +lbl9dmod2a: absoluteindexedx0 +lbl9dmod2b: sta8 + nextopcode +op9em1mod2: +lbl9emod2: absoluteindexedx0 + stz8 + nextopcode +op9fm1mod2: +lbl9fmod2a: absolutelongindexedx0 +lbl9fmod2b: sta8 + nextopcode +opa0x0mod2: +lbla0mod2: opa0x0 + nextopcode +opa1m1mod2: +lbla1mod2a: directindexedindirect0 +lbla1mod2b: lda8 + nextopcode +opa2x0mod2: +lbla2mod2: opa2x0 + nextopcode +opa3m1mod2: +lbla3mod2a: stackasmrelative +lbla3mod2b: lda8 + nextopcode +opa4x0mod2: +lbla4mod2a: direct +lbla4mod2b: ldy16 + nextopcode +opa5m1mod2: +lbla5mod2a: direct +lbla5mod2b: lda8 + nextopcode +opa6x0mod2: +lbla6mod2a: direct +lbla6mod2b: ldx16 + nextopcode +opa7m1mod2: +lbla7mod2a: directindirectlong +lbla7mod2b: lda8 + nextopcode +opa8x0mod2: +lbla8mod2: opa8x0m1 + nextopcode +opa9m1mod2: +lbla9mod2: opa9m1 + nextopcode +opaax0mod2: +lblaamod2: opaax0m1 + nextopcode +opabmod2: +lblabmod2: opab + nextopcode +opacx0mod2: +lblacmod2a: absolute +lblacmod2b: ldy16 + nextopcode +opadm1mod2: +lbladmod2a: absolute +lbladmod2b: lda8 + nextopcode +opaex0mod2: +lblaemod2a: absolute +lblaemod2b: ldx16 + nextopcode +opafm1mod2: +lblafmod2a: absolutelong +lblafmod2b: lda8 + nextopcode +opb0mod2: +lblb0mod2: opb0 + nextopcode +opb1m1mod2: +lblb1mod2a: directindirectindexed0 +lblb1mod2b: lda8 + nextopcode +opb2m1mod2: +lblb2mod2a: directindirect +lblb2mod2b: lda8 + nextopcode +opb3m1mod2: +lblb3mod2a: stackasmrelativeindirectindexed0 +lblb3mod2b: lda8 + nextopcode +opb4x0mod2: +lblb4mod2a: directindexedx0 +lblb4mod2b: ldy16 + nextopcode +opb5m1mod2: +lblb5mod2a: directindexedx0 +lblb5mod2b: lda8 + nextopcode +opb6x0mod2: +lblb6mod2a: directindexedy0 +lblb6mod2b: ldx16 + nextopcode +opb7m1mod2: +lblb7mod2a: directindirectindexedlong0 +lblb7mod2b: lda8 + nextopcode +opb8mod2: +lblb8mod2: opb8 + nextopcode +opb9m1mod2: +lblb9mod2a: absoluteindexedy0 +lblb9mod2b: lda8 + nextopcode +opbax0mod2: +lblbamod2: opbax0 + nextopcode +opbbx0mod2: +lblbbmod2: opbbx0 + nextopcode +opbcx0mod2: +lblbcmod2a: absoluteindexedx0 +lblbcmod2b: ldy16 + nextopcode +opbdm1mod2: +lblbdmod2a: absoluteindexedx0 +lblbdmod2b: lda8 + nextopcode +opbex0mod2: +lblbemod2a: absoluteindexedy0 +lblbemod2b: ldx16 + nextopcode +opbfm1mod2: +lblbfmod2a: absolutelongindexedx0 +lblbfmod2b: lda8 + nextopcode +opc0x0mod2: +lblc0mod2: opc0x0 + nextopcode +opc1m1mod2: +lblc1mod2a: directindexedindirect0 +lblc1mod2b: cmp8 + nextopcode +opc2mod2: +lblc2mod2: opc2 + nextopcode +@@.pool +opc3m1mod2: +lblc3mod2a: stackasmrelative +lblc3mod2b: cmp8 + nextopcode +opc4x0mod2: +lblc4mod2a: direct +lblc4mod2b: cmy16 + nextopcode +opc5m1mod2: +lblc5mod2a: direct +lblc5mod2b: cmp8 + nextopcode +opc6m1mod2: +lblc6mod2a: direct +lblc6mod2b: dec8 + nextopcode +opc7m1mod2: +lblc7mod2a: directindirectlong +lblc7mod2b: cmp8 + nextopcode +opc8x0mod2: +lblc8mod2: opc8x0 + nextopcode +opc9m1mod2: +lblc9mod2: opc9m1 + nextopcode +opcax0mod2: +lblcamod2: opcax0 + nextopcode +opcbmod2: +lblcbmod2: opcb + nextopcode +opccx0mod2: +lblccmod2a: absolute +lblccmod2b: cmy16 + nextopcode +opcdm1mod2: +lblcdmod2a: absolute +lblcdmod2b: cmp8 + nextopcode +opcem1mod2: +lblcemod2a: absolute +lblcemod2b: dec8 + nextopcode +opcfm1mod2: +lblcfmod2a: absolutelong +lblcfmod2b: cmp8 + nextopcode +opd0mod2: +lbld0mod2: opd0 + nextopcode +opd1m1mod2: +lbld1mod2a: directindirectindexed0 +lbld1mod2b: cmp8 + nextopcode +opd2m1mod2: +lbld2mod2a: directindirect +lbld2mod2b: cmp8 + nextopcode +opd3m1mod2: +lbld3mod2a: stackasmrelativeindirectindexed0 +lbld3mod2b: cmp8 + nextopcode +opd4mod2: +lbld4mod2: opd4 + nextopcode +opd5m1mod2: +lbld5mod2a: directindexedx0 +lbld5mod2b: cmp8 + nextopcode +opd6m1mod2: +lbld6mod2a: directindexedx0 +lbld6mod2b: dec8 + nextopcode +opd7m1mod2: +lbld7mod2a: directindirectindexedlong0 +lbld7mod2b: cmp8 + nextopcode +opd8mod2: +lbld8mod2: opd8 + nextopcode +opd9m1mod2: +lbld9mod2a: absoluteindexedy0 +lbld9mod2b: cmp8 + nextopcode +opdax0mod2: +lbldamod2: opdax0 + nextopcode +opdbmod2: +lbldbmod2: opdb + nextopcode +opdcmod2: +lbldcmod2: opdc + nextopcode +opddm1mod2: +lblddmod2a: absoluteindexedx0 +lblddmod2b: cmp8 + nextopcode +opdem1mod2: +lbldemod2a: absoluteindexedx0 +lbldemod2b: dec8 + nextopcode +opdfm1mod2: +lbldfmod2a: absolutelongindexedx0 +lbldfmod2b: cmp8 + nextopcode +ope0x0mod2: +lble0mod2: ope0x0 + nextopcode +ope1m1mod2: +lble1mod2a: directindexedindirect0 +lble1mod2b: sbc8 + nextopcode +ope2mod2: +lble2mod2: ope2 + nextopcode +@@.pool +ope3m1mod2: +lble3mod2a: stackasmrelative +lble3mod2b: sbc8 + nextopcode +ope4x0mod2: +lble4mod2a: direct +lble4mod2b: cmx16 + nextopcode +ope5m1mod2: +lble5mod2a: direct +lble5mod2b: sbc8 + nextopcode +ope6m1mod2: +lble6mod2a: direct +lble6mod2b: inc8 + nextopcode +ope7m1mod2: +lble7mod2a: directindirectlong +lble7mod2b: sbc8 + nextopcode +ope8x0mod2: +lble8mod2: ope8x0 + nextopcode +ope9m1mod2: +lble9mod2a: immediate8 +lble9mod2b: sbc8 + nextopcode +opeamod2: +lbleamod2: opea + nextopcode +opebmod2: +lblebmod2: opebm1 + nextopcode +opecx0mod2: +lblecmod2a: absolute +lblecmod2b: cmx16 + nextopcode +opedm1mod2: +lbledmod2a: absolute +lbledmod2b: sbc8 + nextopcode +opeem1mod2: +lbleemod2a: absolute +lbleemod2b: inc8 + nextopcode +opefm1mod2: +lblefmod2a: absolutelong +lblefmod2b: sbc8 + nextopcode +opf0mod2: +lblf0mod2: opf0 + nextopcode +opf1m1mod2: +lblf1mod2a: directindirectindexed0 +lblf1mod2b: sbc8 + nextopcode +opf2m1mod2: +lblf2mod2a: directindirect +lblf2mod2b: sbc8 + nextopcode +opf3m1mod2: +lblf3mod2a: stackasmrelativeindirectindexed0 +lblf3mod2b: sbc8 + nextopcode +opf4mod2: +lblf4mod2: opf4 + nextopcode +opf5m1mod2: +lblf5mod2a: directindexedx0 +lblf5mod2b: sbc8 + nextopcode +opf6m1mod2: +lblf6mod2a: directindexedx0 +lblf6mod2b: inc8 + nextopcode +opf7m1mod2: +lblf7mod2a: directindirectindexedlong0 +lblf7mod2b: sbc8 + nextopcode +opf8mod2: +lblf8mod2: opf8 + nextopcode +opf9m1mod2: +lblf9mod2a: absoluteindexedy0 +lblf9mod2b: sbc8 + nextopcode +opfax0mod2: +lblfamod2: opfax0 + nextopcode +opfbmod2: +lblfbmod2: opfb + nextopcode +opfcmod2: +lblfcmod2: opfcx0 + nextopcode +opfdm1mod2: +lblfdmod2a: absoluteindexedx0 +lblfdmod2b: sbc8 + nextopcode +opfem1mod2: +lblfemod2a: absoluteindexedx0 +lblfemod2b: inc8 + nextopcode +opffm1mod2: +lblffmod2a: absolutelongindexedx0 +lblffmod2b: sbc8 + nextopcode + +@@.pool + + +jumptable3: .long op00mod3 + .long op01m0mod3 + .long op02mod3 + .long op03m0mod3 + .long op04m0mod3 + .long op05m0mod3 + .long op06m0mod3 + .long op07m0mod3 + .long op08mod3 + .long op09m0mod3 + .long op0am0mod3 + .long op0bmod3 + .long op0cm0mod3 + .long op0dm0mod3 + .long op0em0mod3 + .long op0fm0mod3 + .long op10mod3 + .long op11m0mod3 + .long op12m0mod3 + .long op13m0mod3 + .long op14m0mod3 + .long op15m0mod3 + .long op16m0mod3 + .long op17m0mod3 + .long op18mod3 + .long op19m0mod3 + .long op1am0mod3 + .long op1bmod3 + .long op1cm0mod3 + .long op1dm0mod3 + .long op1em0mod3 + .long op1fm0mod3 + .long op20mod3 + .long op21m0mod3 + .long op22mod3 + .long op23m0mod3 + .long op24m0mod3 + .long op25m0mod3 + .long op26m0mod3 + .long op27m0mod3 + .long op28mod3 + .long op29m0mod3 + .long op2am0mod3 + .long op2bmod3 + .long op2cm0mod3 + .long op2dm0mod3 + .long op2em0mod3 + .long op2fm0mod3 + .long op30mod3 + .long op31m0mod3 + .long op32m0mod3 + .long op33m0mod3 + .long op34m0mod3 + .long op35m0mod3 + .long op36m0mod3 + .long op37m0mod3 + .long op38mod3 + .long op39m0mod3 + .long op3am0mod3 + .long op3bmod3 + .long op3cm0mod3 + .long op3dm0mod3 + .long op3em0mod3 + .long op3fm0mod3 + .long op40mod3 + .long op41m0mod3 + .long op42mod3 + .long op43m0mod3 + .long op44x0mod3 + .long op45m0mod3 + .long op46m0mod3 + .long op47m0mod3 + .long op48m0mod3 + .long op49m0mod3 + .long op4am0mod3 + .long op4bmod3 + .long op4cmod3 + .long op4dm0mod3 + .long op4em0mod3 + .long op4fm0mod3 + .long op50mod3 + .long op51m0mod3 + .long op52m0mod3 + .long op53m0mod3 + .long op54x0mod3 + .long op55m0mod3 + .long op56m0mod3 + .long op57m0mod3 + .long op58mod3 + .long op59m0mod3 + .long op5ax0mod3 + .long op5bmod3 + .long op5cmod3 + .long op5dm0mod3 + .long op5em0mod3 + .long op5fm0mod3 + .long op60mod3 + .long op61m0mod3 + .long op62mod3 + .long op63m0mod3 + .long op64m0mod3 + .long op65m0mod3 + .long op66m0mod3 + .long op67m0mod3 + .long op68m0mod3 + .long op69m0mod3 + .long op6am0mod3 + .long op6bmod3 + .long op6cmod3 + .long op6dm0mod3 + .long op6em0mod3 + .long op6fm0mod3 + .long op70mod3 + .long op71m0mod3 + .long op72m0mod3 + .long op73m0mod3 + .long op74m0mod3 + .long op75m0mod3 + .long op76m0mod3 + .long op77m0mod3 + .long op78mod3 + .long op79m0mod3 + .long op7ax0mod3 + .long op7bmod3 + .long op7cmod3 + .long op7dm0mod3 + .long op7em0mod3 + .long op7fm0mod3 + .long op80mod3 + .long op81m0mod3 + .long op82mod3 + .long op83m0mod3 + .long op84x0mod3 + .long op85m0mod3 + .long op86x0mod3 + .long op87m0mod3 + .long op88x0mod3 + .long op89m0mod3 + .long op8am0mod3 + .long op8bmod3 + .long op8cx0mod3 + .long op8dm0mod3 + .long op8ex0mod3 + .long op8fm0mod3 + .long op90mod3 + .long op91m0mod3 + .long op92m0mod3 + .long op93m0mod3 + .long op94x0mod3 + .long op95m0mod3 + .long op96x0mod3 + .long op97m0mod3 + .long op98m0mod3 + .long op99m0mod3 + .long op9amod3 + .long op9bx0mod3 + .long op9cm0mod3 + .long op9dm0mod3 + .long op9em0mod3 + .long op9fm0mod3 + .long opa0x0mod3 + .long opa1m0mod3 + .long opa2x0mod3 + .long opa3m0mod3 + .long opa4x0mod3 + .long opa5m0mod3 + .long opa6x0mod3 + .long opa7m0mod3 + .long opa8x0mod3 + .long opa9m0mod3 + .long opaax0mod3 + .long opabmod3 + .long opacx0mod3 + .long opadm0mod3 + .long opaex0mod3 + .long opafm0mod3 + .long opb0mod3 + .long opb1m0mod3 + .long opb2m0mod3 + .long opb3m0mod3 + .long opb4x0mod3 + .long opb5m0mod3 + .long opb6x0mod3 + .long opb7m0mod3 + .long opb8mod3 + .long opb9m0mod3 + .long opbax0mod3 + .long opbbx0mod3 + .long opbcx0mod3 + .long opbdm0mod3 + .long opbex0mod3 + .long opbfm0mod3 + .long opc0x0mod3 + .long opc1m0mod3 + .long opc2mod3 + .long opc3m0mod3 + .long opc4x0mod3 + .long opc5m0mod3 + .long opc6m0mod3 + .long opc7m0mod3 + .long opc8x0mod3 + .long opc9m0mod3 + .long opcax0mod3 + .long opcbmod3 + .long opccx0mod3 + .long opcdm0mod3 + .long opcem0mod3 + .long opcfm0mod3 + .long opd0mod3 + .long opd1m0mod3 + .long opd2m0mod3 + .long opd3m0mod3 + .long opd4mod3 + .long opd5m0mod3 + .long opd6m0mod3 + .long opd7m0mod3 + .long opd8mod3 + .long opd9m0mod3 + .long opdax0mod3 + .long opdbmod3 + .long opdcmod3 + .long opddm0mod3 + .long opdem0mod3 + .long opdfm0mod3 + .long ope0x0mod3 + .long ope1m0mod3 + .long ope2mod3 + .long ope3m0mod3 + .long ope4x0mod3 + .long ope5m0mod3 + .long ope6m0mod3 + .long ope7m0mod3 + .long ope8x0mod3 + .long ope9m0mod3 + .long opeamod3 + .long opebmod3 + .long opecx0mod3 + .long opedm0mod3 + .long opeem0mod3 + .long opefm0mod3 + .long opf0mod3 + .long opf1m0mod3 + .long opf2m0mod3 + .long opf3m0mod3 + .long opf4mod3 + .long opf5m0mod3 + .long opf6m0mod3 + .long opf7m0mod3 + .long opf8mod3 + .long opf9m0mod3 + .long opfax0mod3 + .long opfbmod3 + .long opfcmod3 + .long opfdm0mod3 + .long opfem0mod3 + .long opffm0mod3 +op00mod3: +lbl00mod3: op00 + nextopcode +op01m0mod3: +lbl01mod3a: directindexedindirect0 +lbl01mod3b: ora16 + nextopcode +op02mod3: +lbl02mod3: op02 + nextopcode +op03m0mod3: +lbl03mod3a: stackasmrelative +lbl03mod3b: ora16 + nextopcode +op04m0mod3: +lbl04mod3a: direct +lbl04mod3b: tsb16 + nextopcode +op05m0mod3: +lbl05mod3a: direct +lbl05mod3b: ora16 + nextopcode +op06m0mod3: +lbl06mod3a: direct +lbl06mod3b: asl16 + nextopcode +op07m0mod3: +lbl07mod3a: directindirectlong +lbl07mod3b: ora16 + nextopcode +op08mod3: +lbl08mod3: op08 + nextopcode +op09m0mod3: +lbl09mod3: op09m0 + nextopcode +op0am0mod3: +lbl0amod3a: a_asl16 + nextopcode +op0bmod3: +lbl0bmod3: op0b + nextopcode +op0cm0mod3: +lbl0cmod3a: absolute +lbl0cmod3b: tsb16 + nextopcode +op0dm0mod3: +lbl0dmod3a: absolute +lbl0dmod3b: ora16 + nextopcode +op0em0mod3: +lbl0emod3a: absolute +lbl0emod3b: asl16 + nextopcode +op0fm0mod3: +lbl0fmod3a: absolutelong +lbl0fmod3b: ora16 + nextopcode +op10mod3: +lbl10mod3: op10 + nextopcode +op11m0mod3: +lbl11mod3a: directindirectindexed0 +lbl11mod3b: ora16 + nextopcode +op12m0mod3: +lbl12mod3a: directindirect +lbl12mod3b: ora16 + nextopcode +op13m0mod3: +lbl13mod3a: stackasmrelativeindirectindexed0 +lbl13mod3b: ora16 + nextopcode +op14m0mod3: +lbl14mod3a: direct +lbl14mod3b: trb16 + nextopcode +op15m0mod3: +lbl15mod3a: directindexedx0 +lbl15mod3b: ora16 + nextopcode +op16m0mod3: +lbl16mod3a: directindexedx0 +lbl16mod3b: asl16 + nextopcode +op17m0mod3: +lbl17mod3a: directindirectindexedlong0 +lbl17mod3b: ora16 + nextopcode +op18mod3: +lbl18mod3: op18 + nextopcode +op19m0mod3: +lbl19mod3a: absoluteindexedy0 +lbl19mod3b: ora16 + nextopcode +op1am0mod3: +lbl1amod3a: a_inc16 + nextopcode +op1bmod3: +lbl1bmod3: op1bm0 + nextopcode +op1cm0mod3: +lbl1cmod3a: absolute +lbl1cmod3b: trb16 + nextopcode +op1dm0mod3: +lbl1dmod3a: absoluteindexedx0 +lbl1dmod3b: ora16 + nextopcode +op1em0mod3: +lbl1emod3a: absoluteindexedx0 +lbl1emod3b: asl16 + nextopcode +op1fm0mod3: +lbl1fmod3a: absolutelongindexedx0 +lbl1fmod3b: ora16 + nextopcode +op20mod3: +lbl20mod3: op20 + nextopcode +op21m0mod3: +lbl21mod3a: directindexedindirect0 +lbl21mod3b: and16 + nextopcode +op22mod3: +lbl22mod3: op22 + nextopcode +op23m0mod3: +lbl23mod3a: stackasmrelative +lbl23mod3b: and16 + nextopcode +op24m0mod3: +lbl24mod3a: direct +lbl24mod3b: bit16 + nextopcode +op25m0mod3: +lbl25mod3a: direct +lbl25mod3b: and16 + nextopcode +op26m0mod3: +lbl26mod3a: direct +lbl26mod3b: rol16 + nextopcode +op27m0mod3: +lbl27mod3a: directindirectlong +lbl27mod3b: and16 + nextopcode +op28mod3: +lbl28mod3: op28x0m0 + nextopcode +@@.pool +op29m0mod3: +lbl29mod3: op29m0 + nextopcode +op2am0mod3: +lbl2amod3a: a_rol16 + nextopcode +op2bmod3: +lbl2bmod3: op2b + nextopcode +op2cm0mod3: +lbl2cmod3a: absolute +lbl2cmod3b: bit16 + nextopcode +op2dm0mod3: +lbl2dmod3a: absolute +lbl2dmod3b: and16 + nextopcode +op2em0mod3: +lbl2emod3a: absolute +lbl2emod3b: rol16 + nextopcode +op2fm0mod3: +lbl2fmod3a: absolutelong +lbl2fmod3b: and16 + nextopcode +op30mod3: +lbl30mod3: op30 + nextopcode +op31m0mod3: +lbl31mod3a: directindirectindexed0 +lbl31mod3b: and16 + nextopcode +op32m0mod3: +lbl32mod3a: directindirect +lbl32mod3b: and16 + nextopcode +op33m0mod3: +lbl33mod3a: stackasmrelativeindirectindexed0 +lbl33mod3b: and16 + nextopcode +op34m0mod3: +lbl34mod3a: directindexedx0 +lbl34mod3b: bit16 + nextopcode +op35m0mod3: +lbl35mod3a: directindexedx0 +lbl35mod3b: and16 + nextopcode +op36m0mod3: +lbl36mod3a: directindexedx0 +lbl36mod3b: rol16 + nextopcode +op37m0mod3: +lbl37mod3a: directindirectindexedlong0 +lbl37mod3b: and16 + nextopcode +op38mod3: +lbl38mod3: op38 + nextopcode +op39m0mod3: +lbl39mod3a: absoluteindexedy0 +lbl39mod3b: and16 + nextopcode +op3am0mod3: +lbl3amod3a: a_dec16 + nextopcode +op3bmod3: +lbl3bmod3: op3bm0 + nextopcode +op3cm0mod3: +lbl3cmod3a: absoluteindexedx0 +lbl3cmod3b: bit16 + nextopcode +op3dm0mod3: +lbl3dmod3a: absoluteindexedx0 +lbl3dmod3b: and16 + nextopcode +op3em0mod3: +lbl3emod3a: absoluteindexedx0 +lbl3emod3b: rol16 + nextopcode +op3fm0mod3: +lbl3fmod3a: absolutelongindexedx0 +lbl3fmod3b: and16 + nextopcode +op40mod3: +lbl40mod3: op40x0m0 + nextopcode +@@.pool +op41m0mod3: +lbl41mod3a: directindexedindirect0 +lbl41mod3b: eor16 + nextopcode +op42mod3: +lbl42mod3: op42 + nextopcode +op43m0mod3: +lbl43mod3a: stackasmrelative +lbl43mod3b: eor16 + nextopcode +op44x0mod3: +lbl44mod3: op44x0m0 + nextopcode +op45m0mod3: +lbl45mod3a: direct +lbl45mod3b: eor16 + nextopcode +op46m0mod3: +lbl46mod3a: direct +lbl46mod3b: lsr16 + nextopcode +op47m0mod3: +lbl47mod3a: directindirectlong +lbl47mod3b: eor16 + nextopcode +op48m0mod3: +lbl48mod3: op48m0 + nextopcode +op49m0mod3: +lbl49mod3: op49m0 + nextopcode +op4am0mod3: +lbl4amod3a: a_lsr16 + nextopcode +op4bmod3: +lbl4bmod3: op4b + nextopcode +op4cmod3: +lbl4cmod3: op4c + nextopcode +op4dm0mod3: +lbl4dmod3a: absolute +lbl4dmod3b: eor16 + nextopcode +op4em0mod3: +lbl4emod3a: absolute +lbl4emod3b: lsr16 + nextopcode +op4fm0mod3: +lbl4fmod3a: absolutelong +lbl4fmod3b: eor16 + nextopcode +op50mod3: +lbl50mod3: op50 + nextopcode +op51m0mod3: +lbl51mod3a: directindirectindexed0 +lbl51mod3b: eor16 + nextopcode +op52m0mod3: +lbl52mod3a: directindirect +lbl52mod3b: eor16 + nextopcode +op53m0mod3: +lbl53mod3a: stackasmrelativeindirectindexed0 +lbl53mod3b: eor16 + nextopcode +op54x0mod3: +lbl54mod3: op54x0m0 + nextopcode +op55m0mod3: +lbl55mod3a: directindexedx0 +lbl55mod3b: eor16 + nextopcode +op56m0mod3: +lbl56mod3a: directindexedx0 +lbl56mod3b: lsr16 + nextopcode +op57m0mod3: +lbl57mod3a: directindirectindexedlong0 +lbl57mod3b: eor16 + nextopcode +op58mod3: +lbl58mod3: op58 + nextopcode +op59m0mod3: +lbl59mod3a: absoluteindexedy0 +lbl59mod3b: eor16 + nextopcode +op5ax0mod3: +lbl5amod3: op5ax0 + nextopcode +op5bmod3: +lbl5bmod3: op5bm0 + nextopcode +op5cmod3: +lbl5cmod3: op5c + nextopcode +op5dm0mod3: +lbl5dmod3a: absoluteindexedx0 +lbl5dmod3b: eor16 + nextopcode +op5em0mod3: +lbl5emod3a: absoluteindexedx0 +lbl5emod3b: lsr16 + nextopcode +op5fm0mod3: +lbl5fmod3a: absolutelongindexedx0 +lbl5fmod3b: eor16 + nextopcode +op60mod3: +lbl60mod3: op60 + nextopcode +op61m0mod3: +lbl61mod3a: directindexedindirect0 +lbl61mod3b: adc16 + nextopcode +op62mod3: +lbl62mod3: op62 + nextopcode +op63m0mod3: +lbl63mod3a: stackasmrelative +lbl63mod3b: adc16 + nextopcode +@@.pool +op64m0mod3: +lbl64mod3a: direct +lbl64mod3b: stz16 + nextopcode +op65m0mod3: +lbl65mod3a: direct +lbl65mod3b: adc16 + nextopcode +@@.pool +op66m0mod3: +lbl66mod3a: direct +lbl66mod3b: ror16 + nextopcode +op67m0mod3: +lbl67mod3a: directindirectlong +lbl67mod3b: adc16 + nextopcode +@@.pool +op68m0mod3: +lbl68mod3: op68m0 + nextopcode +op69m0mod3: +lbl69mod3a: immediate16 +lbl69mod3b: adc16 + nextopcode +@.pool +op6am0mod3: +lbl6amod3a: a_ror16 + nextopcode +op6bmod3: +lbl6bmod3: op6b + nextopcode +op6cmod3: +lbl6cmod3: op6c + nextopcode +op6dm0mod3: +lbl6dmod3a: absolute +lbl6dmod3b: adc16 + nextopcode +op6em0mod3: +lbl6emod3a: absolute +lbl6emod3b: ror16 + nextopcode +op6fm0mod3: +lbl6fmod3a: absolutelong +lbl6fmod3b: adc16 + nextopcode +op70mod3: +lbl70mod3: op70 + nextopcode +op71m0mod3: +lbl71mod3a: directindirectindexed0 +lbl71mod3b: adc16 + nextopcode +op72m0mod3: +lbl72mod3a: directindirect +lbl72mod3b: adc16 + nextopcode +op73m0mod3: +lbl73mod3a: stackasmrelativeindirectindexed0 +lbl73mod3b: adc16 + nextopcode +@.pool +op74m0mod3: +lbl74mod3a: directindexedx0 +lbl74mod3b: stz16 + nextopcode +op75m0mod3: +lbl75mod3a: directindexedx0 +lbl75mod3b: adc16 + nextopcode +@.pool +op76m0mod3: +lbl76mod3a: directindexedx0 +lbl76mod3b: ror16 + nextopcode +op77m0mod3: +lbl77mod3a: directindirectindexedlong0 +lbl77mod3b: adc16 + nextopcode +op78mod3: +lbl78mod3: op78 + nextopcode +op79m0mod3: +lbl79mod3a: absoluteindexedy0 +lbl79mod3b: adc16 + nextopcode +op7ax0mod3: +lbl7amod3: op7ax0 + nextopcode +op7bmod3: +lbl7bmod3: op7bm0 + nextopcode +op7cmod3: +lbl7cmod3: absoluteindexedindirectx0 + op7c + nextopcode +op7dm0mod3: +lbl7dmod3a: absoluteindexedx0 +lbl7dmod3b: adc16 + nextopcode +op7em0mod3: +lbl7emod3a: absoluteindexedx0 +lbl7emod3b: ror16 + nextopcode +op7fm0mod3: +lbl7fmod3a: absolutelongindexedx0 +lbl7fmod3b: adc16 + nextopcode +@.pool +op80mod3: +lbl80mod3: op80 + nextopcode +op81m0mod3: +lbl81mod3a: directindexedindirect0 +lbl81mod3b: op81m0 + nextopcode +op82mod3: +lbl82mod3: op82 + nextopcode +op83m0mod3: +lbl83mod3a: stackasmrelative +lbl83mod3b: sta16 + nextopcode +op84x0mod3: +lbl84mod3a: direct +lbl84mod3b: sty16 + nextopcode +op85m0mod3: +lbl85mod3a: direct +lbl85mod3b: sta16 + nextopcode +op86x0mod3: +lbl86mod3a: direct +lbl86mod3b: stx16 + nextopcode +op87m0mod3: +lbl87mod3a: directindirectlong +lbl87mod3b: sta16 + nextopcode +op88x0mod3: +lbl88mod3: op88x0 + nextopcode +op89m0mod3: +lbl89mod3: op89m0 + nextopcode +op8am0mod3: +lbl8amod3: op8am0x0 + nextopcode +op8bmod3: +lbl8bmod3: op8b + nextopcode +op8cx0mod3: +lbl8cmod3a: absolute +lbl8cmod3b: sty16 + nextopcode +op8dm0mod3: +lbl8dmod3a: absolute +lbl8dmod3b: sta16 + nextopcode +op8ex0mod3: +lbl8emod3a: absolute +lbl8emod3b: stx16 + nextopcode +op8fm0mod3: +lbl8fmod3a: absolutelong +lbl8fmod3b: sta16 + nextopcode +op90mod3: +lbl90mod3: op90 + nextopcode +op91m0mod3: +lbl91mod3a: directindirectindexed0 +lbl91mod3b: sta16 + nextopcode +op92m0mod3: +lbl92mod3a: directindirect +lbl92mod3b: sta16 + nextopcode +op93m0mod3: +lbl93mod3a: stackasmrelativeindirectindexed0 +lbl93mod3b: sta16 + nextopcode +op94x0mod3: +lbl94mod3a: directindexedx0 +lbl94mod3b: sty16 + nextopcode +op95m0mod3: +lbl95mod3a: directindexedx0 +lbl95mod3b: sta16 + nextopcode +op96x0mod3: +lbl96mod3a: directindexedy0 +lbl96mod3b: stx16 + nextopcode +op97m0mod3: +lbl97mod3a: directindirectindexedlong0 +lbl97mod3b: sta16 + nextopcode +op98m0mod3: +lbl98mod3: op98m0x0 + nextopcode +op99m0mod3: +lbl99mod3a: absoluteindexedy0 +lbl99mod3b: sta16 + nextopcode +op9amod3: +lbl9amod3: op9ax0 + nextopcode +op9bx0mod3: +lbl9bmod3: op9bx0 + nextopcode +op9cm0mod3: +lbl9cmod3a: absolute +lbl9cmod3b: stz16 + nextopcode +op9dm0mod3: +lbl9dmod3a: absoluteindexedx0 +lbl9dmod3b: sta16 + nextopcode +op9em0mod3: +lbl9emod3: absoluteindexedx0 + stz16 + nextopcode +op9fm0mod3: +lbl9fmod3a: absolutelongindexedx0 +lbl9fmod3b: sta16 + nextopcode +opa0x0mod3: +lbla0mod3: opa0x0 + nextopcode +opa1m0mod3: +lbla1mod3a: directindexedindirect0 +lbla1mod3b: lda16 + nextopcode +opa2x0mod3: +lbla2mod3: opa2x0 + nextopcode +opa3m0mod3: +lbla3mod3a: stackasmrelative +lbla3mod3b: lda16 + nextopcode +opa4x0mod3: +lbla4mod3a: direct +lbla4mod3b: ldy16 + nextopcode +opa5m0mod3: +lbla5mod3a: direct +lbla5mod3b: lda16 + nextopcode +opa6x0mod3: +lbla6mod3a: direct +lbla6mod3b: ldx16 + nextopcode +opa7m0mod3: +lbla7mod3a: directindirectlong +lbla7mod3b: lda16 + nextopcode +opa8x0mod3: +lbla8mod3: opa8x0m0 + nextopcode +opa9m0mod3: +lbla9mod3: opa9m0 + nextopcode +opaax0mod3: +lblaamod3: opaax0m0 + nextopcode +opabmod3: +lblabmod3: opab + nextopcode +opacx0mod3: +lblacmod3a: absolute +lblacmod3b: ldy16 + nextopcode +opadm0mod3: +lbladmod3a: absolute +lbladmod3b: lda16 + nextopcode +opaex0mod3: +lblaemod3a: absolute +lblaemod3b: ldx16 + nextopcode +opafm0mod3: +lblafmod3a: absolutelong +lblafmod3b: lda16 + nextopcode +opb0mod3: +lblb0mod3: opb0 + nextopcode +opb1m0mod3: +lblb1mod3a: directindirectindexed0 +lblb1mod3b: lda16 + nextopcode +opb2m0mod3: +lblb2mod3a: directindirect +lblb2mod3b: lda16 + nextopcode +opb3m0mod3: +lblb3mod3a: stackasmrelativeindirectindexed0 +lblb3mod3b: lda16 + nextopcode +opb4x0mod3: +lblb4mod3a: directindexedx0 +lblb4mod3b: ldy16 + nextopcode +opb5m0mod3: +lblb5mod3a: directindexedx0 +lblb5mod3b: lda16 + nextopcode +opb6x0mod3: +lblb6mod3a: directindexedy0 +lblb6mod3b: ldx16 + nextopcode +opb7m0mod3: +lblb7mod3a: directindirectindexedlong0 +lblb7mod3b: lda16 + nextopcode +opb8mod3: +lblb8mod3: opb8 + nextopcode +opb9m0mod3: +lblb9mod3a: absoluteindexedy0 +lblb9mod3b: lda16 + nextopcode +opbax0mod3: +lblbamod3: opbax0 + nextopcode +opbbx0mod3: +lblbbmod3: opbbx0 + nextopcode +opbcx0mod3: +lblbcmod3a: absoluteindexedx0 +lblbcmod3b: ldy16 + nextopcode +opbdm0mod3: +lblbdmod3a: absoluteindexedx0 +lblbdmod3b: lda16 + nextopcode +opbex0mod3: +lblbemod3a: absoluteindexedy0 +lblbemod3b: ldx16 + nextopcode +opbfm0mod3: +lblbfmod3a: absolutelongindexedx0 +lblbfmod3b: lda16 + nextopcode +opc0x0mod3: +lblc0mod3: opc0x0 + nextopcode +opc1m0mod3: +lblc1mod3a: directindexedindirect0 +lblc1mod3b: cmp16 + nextopcode +opc2mod3: +lblc2mod3: opc2 + nextopcode +@.pool +opc3m0mod3: +lblc3mod3a: stackasmrelative +lblc3mod3b: cmp16 + nextopcode +opc4x0mod3: +lblc4mod3a: direct +lblc4mod3b: cmy16 + nextopcode +opc5m0mod3: +lblc5mod3a: direct +lblc5mod3b: cmp16 + nextopcode +opc6m0mod3: +lblc6mod3a: direct +lblc6mod3b: dec16 + nextopcode +opc7m0mod3: +lblc7mod3a: directindirectlong +lblc7mod3b: cmp16 + nextopcode +opc8x0mod3: +lblc8mod3: opc8x0 + nextopcode +opc9m0mod3: +lblc9mod3: opc9m0 + nextopcode +opcax0mod3: +lblcamod3: opcax0 + nextopcode +opcbmod3: +lblcbmod3: opcb + nextopcode +opccx0mod3: +lblccmod3a: absolute +lblccmod3b: cmy16 + nextopcode +opcdm0mod3: +lblcdmod3a: absolute +lblcdmod3b: cmp16 + nextopcode +opcem0mod3: +lblcemod3a: absolute +lblcemod3b: dec16 + nextopcode +opcfm0mod3: +lblcfmod3a: absolutelong +lblcfmod3b: cmp16 + nextopcode +opd0mod3: +lbld0mod3: opd0 + nextopcode +opd1m0mod3: +lbld1mod3a: directindirectindexed0 +lbld1mod3b: cmp16 + nextopcode +opd2m0mod3: +lbld2mod3a: directindirect +lbld2mod3b: cmp16 + nextopcode +opd3m0mod3: +lbld3mod3a: stackasmrelativeindirectindexed0 +lbld3mod3b: cmp16 + nextopcode +opd4mod3: +lbld4mod3: opd4 + nextopcode +opd5m0mod3: +lbld5mod3a: directindexedx0 +lbld5mod3b: cmp16 + nextopcode +opd6m0mod3: +lbld6mod3a: directindexedx0 +lbld6mod3b: dec16 + nextopcode +opd7m0mod3: +lbld7mod3a: directindirectindexedlong0 +lbld7mod3b: cmp16 + nextopcode +opd8mod3: +lbld8mod3: opd8 + nextopcode +opd9m0mod3: +lbld9mod3a: absoluteindexedy0 +lbld9mod3b: cmp16 + nextopcode +opdax0mod3: +lbldamod3: opdax0 + nextopcode +opdbmod3: +lbldbmod3: opdb + nextopcode +opdcmod3: +lbldcmod3: opdc + nextopcode +opddm0mod3: +lblddmod3a: absoluteindexedx0 +lblddmod3b: cmp16 + nextopcode +opdem0mod3: +lbldemod3a: absoluteindexedx0 +lbldemod3b: dec16 + nextopcode +opdfm0mod3: +lbldfmod3a: absolutelongindexedx0 +lbldfmod3b: cmp16 + nextopcode +ope0x0mod3: +lble0mod3: ope0x0 + nextopcode +ope1m0mod3: +lble1mod3a: directindexedindirect0 +lble1mod3b: sbc16 + nextopcode +ope2mod3: +lble2mod3: ope2 + nextopcode +@.pool +ope3m0mod3: +lble3mod3a: stackasmrelative +lble3mod3b: sbc16 + nextopcode +ope4x0mod3: +lble4mod3a: direct +lble4mod3b: cmx16 + nextopcode +ope5m0mod3: +lble5mod3a: direct +lble5mod3b: sbc16 + nextopcode +ope6m0mod3: +lble6mod3a: direct +lble6mod3b: inc16 + nextopcode +ope7m0mod3: +lble7mod3a: directindirectlong +lble7mod3b: sbc16 + nextopcode +ope8x0mod3: +lble8mod3: ope8x0 + nextopcode +ope9m0mod3: +lble9mod3a: immediate16 +lble9mod3b: sbc16 + nextopcode +opeamod3: +lbleamod3: opea + nextopcode +opebmod3: +lblebmod3: opebm0 + nextopcode +opecx0mod3: +lblecmod3a: absolute +lblecmod3b: cmx16 + nextopcode +opedm0mod3: +lbledmod3a: absolute +lbledmod3b: sbc16 + nextopcode +opeem0mod3: +lbleemod3a: absolute +lbleemod3b: inc16 + nextopcode +opefm0mod3: +lblefmod3a: absolutelong +lblefmod3b: sbc16 + nextopcode +opf0mod3: +lblf0mod3: opf0 + nextopcode +opf1m0mod3: +lblf1mod3a: directindirectindexed0 +lblf1mod3b: sbc16 + nextopcode +opf2m0mod3: +lblf2mod3a: directindirect +lblf2mod3b: sbc16 + nextopcode +opf3m0mod3: +lblf3mod3a: stackasmrelativeindirectindexed0 +lblf3mod3b: sbc16 + nextopcode +opf4mod3: +lblf4mod3: opf4 + nextopcode +opf5m0mod3: +lblf5mod3a: directindexedx0 +lblf5mod3b: sbc16 + nextopcode +opf6m0mod3: +lblf6mod3a: directindexedx0 +lblf6mod3b: inc16 + nextopcode +opf7m0mod3: +lblf7mod3a: directindirectindexedlong0 +lblf7mod3b: sbc16 + nextopcode +opf8mod3: +lblf8mod3: opf8 + nextopcode +opf9m0mod3: +lblf9mod3a: absoluteindexedy0 +lblf9mod3b: sbc16 + nextopcode +opfax0mod3: +lblfamod3: opfax0 + nextopcode +opfbmod3: +lblfbmod3: opfb + nextopcode +opfcmod3: +lblfcmod3: opfcx0 + nextopcode +opfdm0mod3: +lblfdmod3a: absoluteindexedx0 +lblfdmod3b: sbc16 + nextopcode +opfem0mod3: +lblfemod3a: absoluteindexedx0 +lblfemod3b: inc16 + nextopcode +opffm0mod3: +lblffmod3a: absolutelongindexedx0 +lblffmod3b: sbc16 + nextopcode +@.pool + +jumptable4: .long op00mod4 + .long op01m0mod4 + .long op02mod4 + .long op03m0mod4 + .long op04m0mod4 + .long op05m0mod4 + .long op06m0mod4 + .long op07m0mod4 + .long op08mod4 + .long op09m0mod4 + .long op0am0mod4 + .long op0bmod4 + .long op0cm0mod4 + .long op0dm0mod4 + .long op0em0mod4 + .long op0fm0mod4 + .long op10mod4 + .long op11m0mod4 + .long op12m0mod4 + .long op13m0mod4 + .long op14m0mod4 + .long op15m0mod4 + .long op16m0mod4 + .long op17m0mod4 + .long op18mod4 + .long op19m0mod4 + .long op1am0mod4 + .long op1bmod4 + .long op1cm0mod4 + .long op1dm0mod4 + .long op1em0mod4 + .long op1fm0mod4 + .long op20mod4 + .long op21m0mod4 + .long op22mod4 + .long op23m0mod4 + .long op24m0mod4 + .long op25m0mod4 + .long op26m0mod4 + .long op27m0mod4 + .long op28mod4 + .long op29m0mod4 + .long op2am0mod4 + .long op2bmod4 + .long op2cm0mod4 + .long op2dm0mod4 + .long op2em0mod4 + .long op2fm0mod4 + .long op30mod4 + .long op31m0mod4 + .long op32m0mod4 + .long op33m0mod4 + .long op34m0mod4 + .long op35m0mod4 + .long op36m0mod4 + .long op37m0mod4 + .long op38mod4 + .long op39m0mod4 + .long op3am0mod4 + .long op3bmod4 + .long op3cm0mod4 + .long op3dm0mod4 + .long op3em0mod4 + .long op3fm0mod4 + .long op40mod4 + .long op41m0mod4 + .long op42mod4 + .long op43m0mod4 + .long op44x1mod4 + .long op45m0mod4 + .long op46m0mod4 + .long op47m0mod4 + .long op48m0mod4 + .long op49m0mod4 + .long op4am0mod4 + .long op4bmod4 + .long op4cmod4 + .long op4dm0mod4 + .long op4em0mod4 + .long op4fm0mod4 + .long op50mod4 + .long op51m0mod4 + .long op52m0mod4 + .long op53m0mod4 + .long op54x1mod4 + .long op55m0mod4 + .long op56m0mod4 + .long op57m0mod4 + .long op58mod4 + .long op59m0mod4 + .long op5ax1mod4 + .long op5bmod4 + .long op5cmod4 + .long op5dm0mod4 + .long op5em0mod4 + .long op5fm0mod4 + .long op60mod4 + .long op61m0mod4 + .long op62mod4 + .long op63m0mod4 + .long op64m0mod4 + .long op65m0mod4 + .long op66m0mod4 + .long op67m0mod4 + .long op68m0mod4 + .long op69m0mod4 + .long op6am0mod4 + .long op6bmod4 + .long op6cmod4 + .long op6dm0mod4 + .long op6em0mod4 + .long op6fm0mod4 + .long op70mod4 + .long op71m0mod4 + .long op72m0mod4 + .long op73m0mod4 + .long op74m0mod4 + .long op75m0mod4 + .long op76m0mod4 + .long op77m0mod4 + .long op78mod4 + .long op79m0mod4 + .long op7ax1mod4 + .long op7bmod4 + .long op7cmod4 + .long op7dm0mod4 + .long op7em0mod4 + .long op7fm0mod4 + .long op80mod4 + .long op81m0mod4 + .long op82mod4 + .long op83m0mod4 + .long op84x1mod4 + .long op85m0mod4 + .long op86x1mod4 + .long op87m0mod4 + .long op88x1mod4 + .long op89m0mod4 + .long op8am0mod4 + .long op8bmod4 + .long op8cx1mod4 + .long op8dm0mod4 + .long op8ex1mod4 + .long op8fm0mod4 + .long op90mod4 + .long op91m0mod4 + .long op92m0mod4 + .long op93m0mod4 + .long op94x1mod4 + .long op95m0mod4 + .long op96x1mod4 + .long op97m0mod4 + .long op98m0mod4 + .long op99m0mod4 + .long op9amod4 + .long op9bx1mod4 + .long op9cm0mod4 + .long op9dm0mod4 + .long op9em0mod4 + .long op9fm0mod4 + .long opa0x1mod4 + .long opa1m0mod4 + .long opa2x1mod4 + .long opa3m0mod4 + .long opa4x1mod4 + .long opa5m0mod4 + .long opa6x1mod4 + .long opa7m0mod4 + .long opa8x1mod4 + .long opa9m0mod4 + .long opaax1mod4 + .long opabmod4 + .long opacx1mod4 + .long opadm0mod4 + .long opaex1mod4 + .long opafm0mod4 + .long opb0mod4 + .long opb1m0mod4 + .long opb2m0mod4 + .long opb3m0mod4 + .long opb4x1mod4 + .long opb5m0mod4 + .long opb6x1mod4 + .long opb7m0mod4 + .long opb8mod4 + .long opb9m0mod4 + .long opbax1mod4 + .long opbbx1mod4 + .long opbcx1mod4 + .long opbdm0mod4 + .long opbex1mod4 + .long opbfm0mod4 + .long opc0x1mod4 + .long opc1m0mod4 + .long opc2mod4 + .long opc3m0mod4 + .long opc4x1mod4 + .long opc5m0mod4 + .long opc6m0mod4 + .long opc7m0mod4 + .long opc8x1mod4 + .long opc9m0mod4 + .long opcax1mod4 + .long opcbmod4 + .long opccx1mod4 + .long opcdm0mod4 + .long opcem0mod4 + .long opcfm0mod4 + .long opd0mod4 + .long opd1m0mod4 + .long opd2m0mod4 + .long opd3m0mod4 + .long opd4mod4 + .long opd5m0mod4 + .long opd6m0mod4 + .long opd7m0mod4 + .long opd8mod4 + .long opd9m0mod4 + .long opdax1mod4 + .long opdbmod4 + .long opdcmod4 + .long opddm0mod4 + .long opdem0mod4 + .long opdfm0mod4 + .long ope0x1mod4 + .long ope1m0mod4 + .long ope2mod4 + .long ope3m0mod4 + .long ope4x1mod4 + .long ope5m0mod4 + .long ope6m0mod4 + .long ope7m0mod4 + .long ope8x1mod4 + .long ope9m0mod4 + .long opeamod4 + .long opebmod4 + .long opecx1mod4 + .long opedm0mod4 + .long opeem0mod4 + .long opefm0mod4 + .long opf0mod4 + .long opf1m0mod4 + .long opf2m0mod4 + .long opf3m0mod4 + .long opf4mod4 + .long opf5m0mod4 + .long opf6m0mod4 + .long opf7m0mod4 + .long opf8mod4 + .long opf9m0mod4 + .long opfax1mod4 + .long opfbmod4 + .long opfcmod4 + .long opfdm0mod4 + .long opfem0mod4 + .long opffm0mod4 +op00mod4: +lbl00mod4: op00 + nextopcode +op01m0mod4: +lbl01mod4a: directindexedindirect1 +lbl01mod4b: ora16 + nextopcode +op02mod4: +lbl02mod4: op02 + nextopcode +op03m0mod4: +lbl03mod4a: stackasmrelative +lbl03mod4b: ora16 + nextopcode +op04m0mod4: +lbl04mod4a: direct +lbl04mod4b: tsb16 + nextopcode +op05m0mod4: +lbl05mod4a: direct +lbl05mod4b: ora16 + nextopcode +op06m0mod4: +lbl06mod4a: direct +lbl06mod4b: asl16 + nextopcode +op07m0mod4: +lbl07mod4a: directindirectlong +lbl07mod4b: ora16 + nextopcode +op08mod4: +lbl08mod4: op08 + nextopcode +op09m0mod4: +lbl09mod4: op09m0 + nextopcode +op0am0mod4: +lbl0amod4a: a_asl16 + nextopcode +op0bmod4: +lbl0bmod4: op0b + nextopcode +op0cm0mod4: +lbl0cmod4a: absolute +lbl0cmod4b: tsb16 + nextopcode +op0dm0mod4: +lbl0dmod4a: absolute +lbl0dmod4b: ora16 + nextopcode +op0em0mod4: +lbl0emod4a: absolute +lbl0emod4b: asl16 + nextopcode +op0fm0mod4: +lbl0fmod4a: absolutelong +lbl0fmod4b: ora16 + nextopcode +op10mod4: +lbl10mod4: op10 + nextopcode +op11m0mod4: +lbl11mod4a: directindirectindexed1 +lbl11mod4b: ora16 + nextopcode +op12m0mod4: +lbl12mod4a: directindirect +lbl12mod4b: ora16 + nextopcode +op13m0mod4: +lbl13mod4a: stackasmrelativeindirectindexed1 +lbl13mod4b: ora16 + nextopcode +op14m0mod4: +lbl14mod4a: direct +lbl14mod4b: trb16 + nextopcode +op15m0mod4: +lbl15mod4a: directindexedx1 +lbl15mod4b: ora16 + nextopcode +op16m0mod4: +lbl16mod4a: directindexedx1 +lbl16mod4b: asl16 + nextopcode +op17m0mod4: +lbl17mod4a: directindirectindexedlong1 +lbl17mod4b: ora16 + nextopcode +op18mod4: +lbl18mod4: op18 + nextopcode +op19m0mod4: +lbl19mod4a: absoluteindexedy1 +lbl19mod4b: ora16 + nextopcode +op1am0mod4: +lbl1amod4a: a_inc16 + nextopcode +op1bmod4: +lbl1bmod4: op1bm0 + nextopcode +op1cm0mod4: +lbl1cmod4a: absolute +lbl1cmod4b: trb16 + nextopcode +op1dm0mod4: +lbl1dmod4a: absoluteindexedx1 +lbl1dmod4b: ora16 + nextopcode +op1em0mod4: +lbl1emod4a: absoluteindexedx1 +lbl1emod4b: asl16 + nextopcode +op1fm0mod4: +lbl1fmod4a: absolutelongindexedx1 +lbl1fmod4b: ora16 + nextopcode +op20mod4: +lbl20mod4: op20 + nextopcode +op21m0mod4: +lbl21mod4a: directindexedindirect1 +lbl21mod4b: and16 + nextopcode +op22mod4: +lbl22mod4: op22 + nextopcode +op23m0mod4: +lbl23mod4a: stackasmrelative +lbl23mod4b: and16 + nextopcode +op24m0mod4: +lbl24mod4a: direct +lbl24mod4b: bit16 + nextopcode +op25m0mod4: +lbl25mod4a: direct +lbl25mod4b: and16 + nextopcode +op26m0mod4: +lbl26mod4a: direct +lbl26mod4b: rol16 + nextopcode +op27m0mod4: +lbl27mod4a: directindirectlong +lbl27mod4b: and16 + nextopcode +op28mod4: +lbl28mod4: op28x1m0 + nextopcode +@.pool +op29m0mod4: +lbl29mod4: op29m0 + nextopcode +op2am0mod4: +lbl2amod4a: a_rol16 + nextopcode +op2bmod4: +lbl2bmod4: op2b + nextopcode +op2cm0mod4: +lbl2cmod4a: absolute +lbl2cmod4b: bit16 + nextopcode +op2dm0mod4: +lbl2dmod4a: absolute +lbl2dmod4b: and16 + nextopcode +op2em0mod4: +lbl2emod4a: absolute +lbl2emod4b: rol16 + nextopcode +op2fm0mod4: +lbl2fmod4a: absolutelong +lbl2fmod4b: and16 + nextopcode +op30mod4: +lbl30mod4: op30 + nextopcode +op31m0mod4: +lbl31mod4a: directindirectindexed1 +lbl31mod4b: and16 + nextopcode +op32m0mod4: +lbl32mod4a: directindirect +lbl32mod4b: and16 + nextopcode +op33m0mod4: +lbl33mod4a: stackasmrelativeindirectindexed1 +lbl33mod4b: and16 + nextopcode +op34m0mod4: +lbl34mod4a: directindexedx1 +lbl34mod4b: bit16 + nextopcode +op35m0mod4: +lbl35mod4a: directindexedx1 +lbl35mod4b: and16 + nextopcode +op36m0mod4: +lbl36mod4a: directindexedx1 +lbl36mod4b: rol16 + nextopcode +op37m0mod4: +lbl37mod4a: directindirectindexedlong1 +lbl37mod4b: and16 + nextopcode +op38mod4: +lbl38mod4: op38 + nextopcode +op39m0mod4: +lbl39mod4a: absoluteindexedy1 +lbl39mod4b: and16 + nextopcode +op3am0mod4: +lbl3amod4a: a_dec16 + nextopcode +op3bmod4: +lbl3bmod4: op3bm0 + nextopcode +op3cm0mod4: +lbl3cmod4a: absoluteindexedx1 +lbl3cmod4b: bit16 + nextopcode +op3dm0mod4: +lbl3dmod4a: absoluteindexedx1 +lbl3dmod4b: and16 + nextopcode +op3em0mod4: +lbl3emod4a: absoluteindexedx1 +lbl3emod4b: rol16 + nextopcode +op3fm0mod4: +lbl3fmod4a: absolutelongindexedx1 +lbl3fmod4b: and16 + nextopcode +op40mod4: +lbl40mod4: op40x1m0 + nextopcode +@.pool +op41m0mod4: +lbl41mod4a: directindexedindirect1 +lbl41mod4b: eor16 + nextopcode +op42mod4: +lbl42mod4: op42 + nextopcode +op43m0mod4: +lbl43mod4a: stackasmrelative +lbl43mod4b: eor16 + nextopcode +op44x1mod4: +lbl44mod4: op44x1m0 + nextopcode +op45m0mod4: +lbl45mod4a: direct +lbl45mod4b: eor16 + nextopcode +op46m0mod4: +lbl46mod4a: direct +lbl46mod4b: lsr16 + nextopcode +op47m0mod4: +lbl47mod4a: directindirectlong +lbl47mod4b: eor16 + nextopcode +op48m0mod4: +lbl48mod4: op48m0 + nextopcode +op49m0mod4: +lbl49mod4: op49m0 + nextopcode +op4am0mod4: +lbl4amod4a: a_lsr16 + nextopcode +op4bmod4: +lbl4bmod4: op4b + nextopcode +op4cmod4: +lbl4cmod4: op4c + nextopcode +op4dm0mod4: +lbl4dmod4a: absolute +lbl4dmod4b: eor16 + nextopcode +op4em0mod4: +lbl4emod4a: absolute +lbl4emod4b: lsr16 + nextopcode +op4fm0mod4: +lbl4fmod4a: absolutelong +lbl4fmod4b: eor16 + nextopcode +op50mod4: +lbl50mod4: op50 + nextopcode +op51m0mod4: +lbl51mod4a: directindirectindexed1 +lbl51mod4b: eor16 + nextopcode +op52m0mod4: +lbl52mod4a: directindirect +lbl52mod4b: eor16 + nextopcode +op53m0mod4: +lbl53mod4a: stackasmrelativeindirectindexed1 +lbl53mod4b: eor16 + nextopcode +op54x1mod4: +lbl54mod4: op54x1m0 + nextopcode +op55m0mod4: +lbl55mod4a: directindexedx1 +lbl55mod4b: eor16 + nextopcode +op56m0mod4: +lbl56mod4a: directindexedx1 +lbl56mod4b: lsr16 + nextopcode +op57m0mod4: +lbl57mod4a: directindirectindexedlong1 +lbl57mod4b: eor16 + nextopcode +op58mod4: +lbl58mod4: op58 + nextopcode +op59m0mod4: +lbl59mod4a: absoluteindexedy1 +lbl59mod4b: eor16 + nextopcode +op5ax1mod4: +lbl5amod4: op5ax1 + nextopcode +op5bmod4: +lbl5bmod4: op5bm0 + nextopcode +op5cmod4: +lbl5cmod4: op5c + nextopcode +op5dm0mod4: +lbl5dmod4a: absoluteindexedx1 +lbl5dmod4b: eor16 + nextopcode +op5em0mod4: +lbl5emod4a: absoluteindexedx1 +lbl5emod4b: lsr16 + nextopcode +op5fm0mod4: +lbl5fmod4a: absolutelongindexedx1 +lbl5fmod4b: eor16 + nextopcode +op60mod4: +lbl60mod4: op60 + nextopcode +op61m0mod4: +lbl61mod4a: directindexedindirect1 +lbl61mod4b: adc16 + nextopcode +op62mod4: +lbl62mod4: op62 + nextopcode +op63m0mod4: +lbl63mod4a: stackasmrelative +lbl63mod4b: adc16 + nextopcode +@.pool +op64m0mod4: +lbl64mod4a: direct +lbl64mod4b: stz16 + nextopcode +op65m0mod4: +lbl65mod4a: direct +lbl65mod4b: adc16 + nextopcode +@.pool +op66m0mod4: +lbl66mod4a: direct +lbl66mod4b: ror16 + nextopcode +op67m0mod4: +lbl67mod4a: directindirectlong +lbl67mod4b: adc16 + nextopcode +@.pool +op68m0mod4: +lbl68mod4: op68m0 + nextopcode +op69m0mod4: +lbl69mod4a: immediate16 +lbl69mod4b: adc16 + nextopcode +@.pool +op6am0mod4: +lbl6amod4a: a_ror16 + nextopcode +op6bmod4: +lbl6bmod4: op6b + nextopcode +op6cmod4: +lbl6cmod4: op6c + nextopcode +op6dm0mod4: +lbl6dmod4a: absolute +lbl6dmod4b: adc16 + nextopcode +op6em0mod4: +lbl6emod4a: absolute +lbl6emod4b: ror16 + nextopcode +op6fm0mod4: +lbl6fmod4a: absolutelong +lbl6fmod4b: adc16 + nextopcode +op70mod4: +lbl70mod4: op70 + nextopcode +op71m0mod4: +lbl71mod4a: directindirectindexed1 +lbl71mod4b: adc16 + nextopcode +op72m0mod4: +lbl72mod4a: directindirect +lbl72mod4b: adc16 + nextopcode +op73m0mod4: +lbl73mod4a: stackasmrelativeindirectindexed1 +lbl73mod4b: adc16 + nextopcode +@.pool +op74m0mod4: +lbl74mod4a: directindexedx1 +lbl74mod4b: stz16 + nextopcode +op75m0mod4: +lbl75mod4a: directindexedx1 +lbl75mod4b: adc16 + nextopcode +@.pool +op76m0mod4: +lbl76mod4a: directindexedx1 +lbl76mod4b: ror16 + nextopcode +op77m0mod4: +lbl77mod4a: directindirectindexedlong1 +lbl77mod4b: adc16 + nextopcode +op78mod4: +lbl78mod4: op78 + nextopcode +op79m0mod4: +lbl79mod4a: absoluteindexedy1 +lbl79mod4b: adc16 + nextopcode +op7ax1mod4: +lbl7amod4: op7ax1 + nextopcode +op7bmod4: +lbl7bmod4: op7bm0 + nextopcode +op7cmod4: +lbl7cmod4: absoluteindexedindirectx1 + op7c + nextopcode +op7dm0mod4: +lbl7dmod4a: absoluteindexedx1 +lbl7dmod4b: adc16 + nextopcode +op7em0mod4: +lbl7emod4a: absoluteindexedx1 +lbl7emod4b: ror16 + nextopcode +op7fm0mod4: +lbl7fmod4a: absolutelongindexedx1 +lbl7fmod4b: adc16 + nextopcode +@.pool +op80mod4: +lbl80mod4: op80 + nextopcode +op81m0mod4: +lbl81mod4a: directindexedindirect1 +lbl81mod4b: op81m0 + nextopcode +op82mod4: +lbl82mod4: op82 + nextopcode +op83m0mod4: +lbl83mod4a: stackasmrelative +lbl83mod4b: sta16 + nextopcode +op84x1mod4: +lbl84mod4a: direct +lbl84mod4b: sty8 + nextopcode +op85m0mod4: +lbl85mod4a: direct +lbl85mod4b: sta16 + nextopcode +op86x1mod4: +lbl86mod4a: direct +lbl86mod4b: stx8 + nextopcode +op87m0mod4: +lbl87mod4a: directindirectlong +lbl87mod4b: sta16 + nextopcode +op88x1mod4: +lbl88mod4: op88x1 + nextopcode +op89m0mod4: +lbl89mod4: op89m0 + nextopcode +op8am0mod4: +lbl8amod4: op8am0x1 + nextopcode +op8bmod4: +lbl8bmod4: op8b + nextopcode +op8cx1mod4: +lbl8cmod4a: absolute +lbl8cmod4b: sty8 + nextopcode +op8dm0mod4: +lbl8dmod4a: absolute +lbl8dmod4b: sta16 + nextopcode +op8ex1mod4: +lbl8emod4a: absolute +lbl8emod4b: stx8 + nextopcode +op8fm0mod4: +lbl8fmod4a: absolutelong +lbl8fmod4b: sta16 + nextopcode +op90mod4: +lbl90mod4: op90 + nextopcode +op91m0mod4: +lbl91mod4a: directindirectindexed1 +lbl91mod4b: sta16 + nextopcode +op92m0mod4: +lbl92mod4a: directindirect +lbl92mod4b: sta16 + nextopcode +op93m0mod4: +lbl93mod4a: stackasmrelativeindirectindexed1 +lbl93mod4b: sta16 + nextopcode +op94x1mod4: +lbl94mod4a: directindexedx1 +lbl94mod4b: sty8 + nextopcode +op95m0mod4: +lbl95mod4a: directindexedx1 +lbl95mod4b: sta16 + nextopcode +op96x1mod4: +lbl96mod4a: directindexedy1 +lbl96mod4b: stx8 + nextopcode +op97m0mod4: +lbl97mod4a: directindirectindexedlong1 +lbl97mod4b: sta16 + nextopcode +op98m0mod4: +lbl98mod4: op98m0x1 + nextopcode +op99m0mod4: +lbl99mod4a: absoluteindexedy1 +lbl99mod4b: sta16 + nextopcode +op9amod4: +lbl9amod4: op9ax1 + nextopcode +op9bx1mod4: +lbl9bmod4: op9bx1 + nextopcode +op9cm0mod4: +lbl9cmod4a: absolute +lbl9cmod4b: stz16 + nextopcode +op9dm0mod4: +lbl9dmod4a: absoluteindexedx1 +lbl9dmod4b: sta16 + nextopcode +op9em0mod4: +lbl9emod4: absoluteindexedx1 + stz16 + nextopcode +op9fm0mod4: +lbl9fmod4a: absolutelongindexedx1 +lbl9fmod4b: sta16 + nextopcode +opa0x1mod4: +lbla0mod4: opa0x1 + nextopcode +opa1m0mod4: +lbla1mod4a: directindexedindirect1 +lbla1mod4b: lda16 + nextopcode +opa2x1mod4: +lbla2mod4: opa2x1 + nextopcode +opa3m0mod4: +lbla3mod4a: stackasmrelative +lbla3mod4b: lda16 + nextopcode +opa4x1mod4: +lbla4mod4a: direct +lbla4mod4b: ldy8 + nextopcode +opa5m0mod4: +lbla5mod4a: direct +lbla5mod4b: lda16 + nextopcode +opa6x1mod4: +lbla6mod4a: direct +lbla6mod4b: ldx8 + nextopcode +opa7m0mod4: +lbla7mod4a: directindirectlong +lbla7mod4b: lda16 + nextopcode +opa8x1mod4: +lbla8mod4: opa8x1m0 + nextopcode +opa9m0mod4: +lbla9mod4: opa9m0 + nextopcode +opaax1mod4: +lblaamod4: opaax1m0 + nextopcode +opabmod4: +lblabmod4: opab + nextopcode +opacx1mod4: +lblacmod4a: absolute +lblacmod4b: ldy8 + nextopcode +opadm0mod4: +lbladmod4a: absolute +lbladmod4b: lda16 + nextopcode +opaex1mod4: +lblaemod4a: absolute +lblaemod4b: ldx8 + nextopcode +opafm0mod4: +lblafmod4a: absolutelong +lblafmod4b: lda16 + nextopcode +opb0mod4: +lblb0mod4: opb0 + nextopcode +opb1m0mod4: +lblb1mod4a: directindirectindexed1 +lblb1mod4b: lda16 + nextopcode +opb2m0mod4: +lblb2mod4a: directindirect +lblb2mod4b: lda16 + nextopcode +opb3m0mod4: +lblb3mod4a: stackasmrelativeindirectindexed1 +lblb3mod4b: lda16 + nextopcode +opb4x1mod4: +lblb4mod4a: directindexedx1 +lblb4mod4b: ldy8 + nextopcode +opb5m0mod4: +lblb5mod4a: directindexedx1 +lblb5mod4b: lda16 + nextopcode +opb6x1mod4: +lblb6mod4a: directindexedy1 +lblb6mod4b: ldx8 + nextopcode +opb7m0mod4: +lblb7mod4a: directindirectindexedlong1 +lblb7mod4b: lda16 + nextopcode +opb8mod4: +lblb8mod4: opb8 + nextopcode +opb9m0mod4: +lblb9mod4a: absoluteindexedy1 +lblb9mod4b: lda16 + nextopcode +opbax1mod4: +lblbamod4: opbax1 + nextopcode +opbbx1mod4: +lblbbmod4: opbbx1 + nextopcode +opbcx1mod4: +lblbcmod4a: absoluteindexedx1 +lblbcmod4b: ldy8 + nextopcode +opbdm0mod4: +lblbdmod4a: absoluteindexedx1 +lblbdmod4b: lda16 + nextopcode +opbex1mod4: +lblbemod4a: absoluteindexedy1 +lblbemod4b: ldx8 + nextopcode +opbfm0mod4: +lblbfmod4a: absolutelongindexedx1 +lblbfmod4b: lda16 + nextopcode +opc0x1mod4: +lblc0mod4: opc0x1 + nextopcode +opc1m0mod4: +lblc1mod4a: directindexedindirect1 +lblc1mod4b: cmp16 + nextopcode +opc2mod4: +lblc2mod4: opc2 + nextopcode +@.pool +opc3m0mod4: +lblc3mod4a: stackasmrelative +lblc3mod4b: cmp16 + nextopcode +opc4x1mod4: +lblc4mod4a: direct +lblc4mod4b: cmy8 + nextopcode +opc5m0mod4: +lblc5mod4a: direct +lblc5mod4b: cmp16 + nextopcode +opc6m0mod4: +lblc6mod4a: direct +lblc6mod4b: dec16 + nextopcode +opc7m0mod4: +lblc7mod4a: directindirectlong +lblc7mod4b: cmp16 + nextopcode +opc8x1mod4: +lblc8mod4: opc8x1 + nextopcode +opc9m0mod4: +lblc9mod4: opc9m0 + nextopcode +opcax1mod4: +lblcamod4: opcax1 + nextopcode +opcbmod4: +lblcbmod4: opcb + nextopcode +opccx1mod4: +lblccmod4a: absolute +lblccmod4b: cmy8 + nextopcode +opcdm0mod4: +lblcdmod4a: absolute +lblcdmod4b: cmp16 + nextopcode +opcem0mod4: +lblcemod4a: absolute +lblcemod4b: dec16 + nextopcode +opcfm0mod4: +lblcfmod4a: absolutelong +lblcfmod4b: cmp16 + nextopcode +opd0mod4: +lbld0mod4: opd0 + nextopcode +opd1m0mod4: +lbld1mod4a: directindirectindexed1 +lbld1mod4b: cmp16 + nextopcode +opd2m0mod4: +lbld2mod4a: directindirect +lbld2mod4b: cmp16 + nextopcode +opd3m0mod4: +lbld3mod4a: stackasmrelativeindirectindexed1 +lbld3mod4b: cmp16 + nextopcode +opd4mod4: +lbld4mod4: opd4 + nextopcode +opd5m0mod4: +lbld5mod4a: directindexedx1 +lbld5mod4b: cmp16 + nextopcode +opd6m0mod4: +lbld6mod4a: directindexedx1 +lbld6mod4b: dec16 + nextopcode +opd7m0mod4: +lbld7mod4a: directindirectindexedlong1 +lbld7mod4b: cmp16 + nextopcode +opd8mod4: +lbld8mod4: opd8 + nextopcode +opd9m0mod4: +lbld9mod4a: absoluteindexedy1 +lbld9mod4b: cmp16 + nextopcode +opdax1mod4: +lbldamod4: opdax1 + nextopcode +opdbmod4: +lbldbmod4: opdb + nextopcode +opdcmod4: +lbldcmod4: opdc + nextopcode +opddm0mod4: +lblddmod4a: absoluteindexedx1 +lblddmod4b: cmp16 + nextopcode +opdem0mod4: +lbldemod4a: absoluteindexedx1 +lbldemod4b: dec16 + nextopcode +opdfm0mod4: +lbldfmod4a: absolutelongindexedx1 +lbldfmod4b: cmp16 + nextopcode +ope0x1mod4: +lble0mod4: ope0x1 + nextopcode +ope1m0mod4: +lble1mod4a: directindexedindirect1 +lble1mod4b: sbc16 + nextopcode +ope2mod4: +lble2mod4: ope2 + nextopcode +@.pool +ope3m0mod4: +lble3mod4a: stackasmrelative +lble3mod4b: sbc16 + nextopcode +ope4x1mod4: +lble4mod4a: direct +lble4mod4b: cmx8 + nextopcode +ope5m0mod4: +lble5mod4a: direct +lble5mod4b: sbc16 + nextopcode +ope6m0mod4: +lble6mod4a: direct +lble6mod4b: inc16 + nextopcode +ope7m0mod4: +lble7mod4a: directindirectlong +lble7mod4b: sbc16 + nextopcode +ope8x1mod4: +lble8mod4: ope8x1 + nextopcode +ope9m0mod4: +lble9mod4a: immediate16 +lble9mod4b: sbc16 + nextopcode +opeamod4: +lbleamod4: opea + nextopcode +opebmod4: +lblebmod4: opebm0 + nextopcode +opecx1mod4: +lblecmod4a: absolute +lblecmod4b: cmx8 + nextopcode +opedm0mod4: +lbledmod4a: absolute +lbledmod4b: sbc16 + nextopcode +opeem0mod4: +lbleemod4a: absolute +lbleemod4b: inc16 + nextopcode +opefm0mod4: +lblefmod4a: absolutelong +lblefmod4b: sbc16 + nextopcode +opf0mod4: +lblf0mod4: opf0 + nextopcode +opf1m0mod4: +lblf1mod4a: directindirectindexed1 +lblf1mod4b: sbc16 + nextopcode +opf2m0mod4: +lblf2mod4a: directindirect +lblf2mod4b: sbc16 + nextopcode +opf3m0mod4: +lblf3mod4a: stackasmrelativeindirectindexed1 +lblf3mod4b: sbc16 + nextopcode +opf4mod4: +lblf4mod4: opf4 + nextopcode +opf5m0mod4: +lblf5mod4a: directindexedx1 +lblf5mod4b: sbc16 + nextopcode +opf6m0mod4: +lblf6mod4a: directindexedx1 +lblf6mod4b: inc16 + nextopcode +opf7m0mod4: +lblf7mod4a: directindirectindexedlong1 +lblf7mod4b: sbc16 + nextopcode +opf8mod4: +lblf8mod4: opf8 + nextopcode +opf9m0mod4: +lblf9mod4a: absoluteindexedy1 +lblf9mod4b: sbc16 + nextopcode +opfax1mod4: +lblfamod4: opfax1 + nextopcode +opfbmod4: +lblfbmod4: opfb + nextopcode +opfcmod4: +lblfcmod4: opfcx1 + nextopcode +opfdm0mod4: +lblfdmod4a: absoluteindexedx1 +lblfdmod4b: sbc16 + nextopcode +opfem0mod4: +lblfemod4a: absoluteindexedx1 +lblfemod4b: inc16 + nextopcode +opffm0mod4: +lblffmod4a: absolutelongindexedx1 +lblffmod4b: sbc16 + nextopcode + + + @.pool + diff --git a/src/snes4iphone_src/os9x_65c816.o.txt b/src/snes4iphone_src/os9x_65c816.o.txt new file mode 100755 index 0000000..48464fe --- /dev/null +++ b/src/snes4iphone_src/os9x_65c816.o.txt @@ -0,0 +1,10203 @@ +# 1 "os9x_65c816.S" +# 1 "" +# 1 "" +# 1 "os9x_65c816.S" +.text + + + .align 4 + + @ notaz +# 83 "os9x_65c816.S" +@ #include "os9x_65c816_mac_gen.h" +# 102 "os9x_65c816.S" +@#define rpc_ofs 22 +# 141 "os9x_65c816.S" +@ notaz +# 153 "os9x_65c816.S" +.macro prepare_c_call + str r9,[r14,#124] + ldr r9,[r14,#128] + stmfd r13!,{r12,r14} +.endm +.macro prepare_c_call_r0 + str r9,[r14,#124] + ldr r9,[r14,#128] + stmfd r13!,{r0,r12,r14} +.endm +.macro prepare_c_call_r0r1 + str r9,[r14,#124] + ldr r9,[r14,#128] + stmfd r13!,{r0,r1,r12,r14} +.endm +.macro prepare_c_call_light + str r9,[r14,#124] + ldr r9,[r14,#128] + stmfd r13!,{r14} +.endm +.macro prepare_c_call_lightr12 + str r9,[r14,#124] + ldr r9,[r14,#128] + stmfd r13!,{r12,r14} +.endm + +.macro restore_c_call + ldmfd r13!,{r12,r14} + ldr r9,[r14,#124] +.endm +.macro restore_c_call_r0 + ldmfd r13!,{r0,r12,r14} + ldr r9,[r14,#124] +.endm +.macro restore_c_call_r1 + ldmfd r13!,{r1,r12,r14} + ldr r9,[r14,#124] +.endm +.macro restore_c_call_r0r1 + ldmfd r13!,{r0,r1,r12,r14} + ldr r9,[r14,#124] +.endm +.macro restore_c_call_light + ldmfd r13!,{r14} + ldr r9,[r14,#124] +.endm +.macro restore_c_call_lightr12 + ldmfd r13!,{r12,r14} + ldr r9,[r14,#124] +.endm + + +@ -------------- +.macro load_regs + @ notaz + add r0,r14,#8 + ldmia r0,{r1,r5,r7,r9,r10,r11,r12} + @ r4 (p) & r4 + mov r4,r1,lsl #16 + mov r4,r4,lsr #24 + mov r0,r1,lsr #16 + orrs r4, r4, r0,lsl #24 @ 24 + @ if carry set, then emulation bit was set + orrcs r4,r4,#(1<<(24 -1)) + @ r6 & r6 + mov r6,r5,lsr #16 + mov r6,r6,lsl #8 + orr r6,r6,r1,lsl #24 + mov r6,r6,ror #24 @ 0xdddd00pb + @ r7, r8 + mov r8,r7,lsr #16 + @ shift x,y & a according to the current mode (index, memory bits) + tst r4,#(16<<(24)) @ 4 @ 1 + movne r7,r7,lsl #24 + movne r9,r9,lsl #24 + moveq r7,r7,lsl #16 + moveq r9,r9,lsl #16 + tst r4,#(32<<(24)) @ 5 @ 2 + movne r5,r5,lsl #24 + moveq r5,r5,lsl #16 +.endm + + +.macro save_regs + @ notaz + @ r6, r4 and r4 + mov r1, r4, lsr #16 + orr r1, r1, r6, lsl #24 + movs r1, r1, lsr #8 + orrcs r1, r1, #0x100 @ emulation bit + orr r1, r1, r4, lsl #24 + mov r1, r1, ror #16 + @ r5, r6 + tst r4,#(32<<(24)) @ 5 @ 2 + ldrneh r0, [r14,#12] + bicne r0, r0,#0xff + orrne r5, r0, r5,lsr #24 + moveq r5, r5, lsr #16 + mov r6, r6, lsr #16 + orr r5, r5, r6, lsl #16 + @ shift x&y according to the current mode (index, memory bits) + tst r4,#(16<<(24)) @ 4 @ 1 + movne r7,r7,lsr #24 + movne r9,r9,lsr #24 + moveq r7,r7,lsr #16 + moveq r9,r9,lsr #16 + @ r7, r8 + orr r7, r7, r8, lsl #16 + @ store + add r0,r14,#8 + stmia r0,{r1,r5,r7,r9,r10,r11,r12} +# 297 "os9x_65c816.S" +.endm + + +.macro add1cycle + add r11,r11, #6 +.endm +.macro add1cyclene + addne r11,r11, #6 +.endm +.macro add1cycleeq + addeq r11,r11, #6 +.endm + +.macro add2cycle + add r11,r11, #12 +.endm +.macro add2cyclene + addne r11,r11, #12 +.endm +.macro add2cycle2mem + ldr r0,[r14,#56] + add r11,r11, #12 + add r11, r11, r0, lsl #1 +.endm +.macro add2cycle1mem + ldr r0,[r14,#56] + add r11,r11, #12 + add r11, r11, r0 +.endm + +.macro add3cycle + add r11,r11, #18 +.endm + +.macro add1cycle1mem + ldr r0,[r14,#56] + add r11,r11, #6 + add r11, r11, r0 +.endm + +.macro add1cycle2mem + ldr r0,[r14,#56] + add r11,r11, #6 + add r11, r11, r0, lsl #1 +.endm + +.macro add1mem + ldr r0,[r14,#56] + add r11, r11, r0 +.endm + +.macro add2mem + ldr r0,[r14,#56] + add r11, r11, r0, lsl #1 +.endm + +.macro add3mem + ldr r0,[r14,#56] + add r11, r0, r11 + add r11, r11, r0, lsl #1 +.endm + + +.macro cleardecimal + bic r4,r4,#(8<<(24)) @ 3 +.endm +.macro setdecimal + orr r4,r4,#(8<<(24)) @ 3 +.endm +.macro setirq + orr r4,r4,#(4<<(24)) @ 2 +.endm +.macro clearirq + bic r4,r4,#(4<<(24)) @ 2 +.endm + +.macro cpushutdown +@ if (settings.shutdown && cpu.pc == cpu.waitaddress) + ldr r0,[r14,#40] + cmp r10,r0 + bne 5431f +@ if (cpu.waitcounter == 0 && !(cpu.flags & ((1 << 11) | (1 << 7)))) + ldr r0,[r14,#0] + ldr r1,[r14,#44] + tst r0,#2176 + bne 5432f + movs r1,r1 + bne 5432f +@ cpu.waitaddress = null; + mov r0,#0 + str r0,[r14,#40] +@ if (settings.sa1) +@ s9xsa1executeduringsleep (); : todo + +@ cpu.cycles = cpu.nextevent; + ldr r11,[r14,#48] + ldrb r0,[r14,#122] + movs r0,r0 + beq 5431f +@ if (iapu.apuexecuting) +# 406 "os9x_65c816.S" + asmapu_execute2 + b 5431f +@@.pool +5432: + + + + + + + cmp r1,#1 + movhi r1,#1 + @ subls r1,r1,#1 + movls r1,#0 + str r1,[r14,#44] +5431: + +.endm +.macro branchcheck0 + + + ldrb r1,[r14,#4] + movs r1,r1 + beq 1110f + mov r1,#0 + strb r1,[r14,#4] + sub r1,r10,r12 + @ if( cpu.pc - cpu.pcbase > opaddress) return; + cmp r1,r0 + bhi 1111f +1110: +.endm +.macro branchcheck1 + + + ldrb r1,[r14,#4] + movs r1,r1 + beq 1110f + mov r1,#0 + strb r1,[r14,#4] + sub r1,r10,r12 + @ if( cpu.pc - cpu.pcbase > opaddress) return; + cmp r1,r0 + bhi 1111f +1110: +.endm +.macro branchcheck2 + + + ldrb r1,[r14,#4] + movs r1,r1 + beq 1110f + mov r1,#0 + strb r1,[r14,#4] + sub r1,r10,r12 + @ if( cpu.pc - cpu.pcbase > opaddress) return; + cmp r1,r0 + bhi 1111f +1110: +.endm + +.macro s9xsetpcbase + @ in : r0 (0x00hhmmll) + prepare_c_call + bl _asm_S9xSetPCBase + restore_c_call + ldr r10,[r14,#24] + ldr r12,[r14,#32] +.endm + +.macro s9xfixcycles + tst r4, #(1<<(24 -1)) + ldrne r0, [r14,#136] + bne 991111f + @ emulation=0 + tst r4,#(32<<(24)) @ 5 @ 2 + beq 991112f + @ memory=1 + tst r4,#(16<<(24)) @ 4 @ 1 + @ index=1 @ mode 0 : m=1,x=1 + ldrne r0, [r14,#136] + @ index=0 @ mode 1 : m=1,x=0 + ldreq r0, [r14,#140] + b 991111f +991112: @ memory=0 + tst r4,#(16<<(24)) @ 4 @ 1 + @ index=1 @ mode 3 : m=0,x=1 + ldrne r0, [r14,#148] + @ index=0 @ mode 2 : m=0,x=0 + ldreq r0, [r14,#144] +991111: + str r0,[r14,#88] +.endm + +.macro s9xdohblankprocessing + save_regs + prepare_c_call_light +@ bl asm_s9xdohblankprocessing + bl _S9xDoHBlankProcessing @ let's go straight to number one + restore_c_call_light + load_regs +.endm + +.macro testmod +save_regs +prepare_c_call +mov r0, pc +bl _test_print +restore_c_call +load_regs +.endm + +.macro testmod1 num +save_regs +prepare_c_call +mov r0, #$0 +bl _test_print +restore_c_call +load_regs +.endm + + +.macro exec_op + ldr r1,[r14,#88] + str r10,[r14,#36] + add1mem + ldrb r0, [r10], #1 + ldr pc, [r1,r0, lsl #2] +.endm +.macro nextopcode + ldr r0,[r14,#48] + cmp r11,r0 + blt mainloop + s9xdohblankprocessing + b mainloop +.endm + +.macro asmapu_execute + ldrb r0,[r14,#122] + cmp r0,#1 @ spc700 enabled, hack mode off + bne 43210f + ldr r0,[r14,#132] + subs r0,r11,r0 + bmi 43210f +.if 0 + prepare_c_call_lightr12 + bl _spc700_execute + restore_c_call_lightr12 + sub r0,r11,r0 @ sub cycles left + str r0,[r14,#132] +.else + @ save_regs + str r11,[r14,#28] + prepare_c_call_lightr12 + bl _asm_APU_EXECUTE + restore_c_call_lightr12 + ldr r11,[r14,#28] +.endif + @ load_regs + @ s9xfixcycles +43210: +.endm + +.macro asmapu_execute2 +.if 0 + ldrb r0,[r14,#122] + cmp r0,#1 @ spc700 enabled, hack mode off + bne 43211f + ldr r0,[r14,#132] + subs r0,r11,r0 @ r11 == nextevent + ble 43211f + prepare_c_call_lightr12 + bl _spc700_execute + restore_c_call_lightr12 + sub r0,r11,r0 @ sub cycles left + str r0,[r14,#132] +43211: +.else + @ save_regs + str r11,[r14,#28] + prepare_c_call_lightr12 + bl _asm_APU_EXECUTE2 + restore_c_call_lightr12 + ldr r11,[r14,#28] + @ load_regs +.endif +.endm + +@ #include "os9x_65c816_mac_mem.h" +.macro s9xgetword + @ in : r0 (0x00hhmmll) + @ out : r0 (0xhhll0000) + stmfd r13!,{pc} @ push return address + b _asms9xgetword + mov r0,r0 + mov r0, r0, lsl #16 +.endm +.macro s9xgetwordlow + @ in : r0 (0x00hhmmll) + @ out : r0 (0x0000hhll) + stmfd r13!,{pc} @ push return address + b _asms9xgetword + mov r0,r0 +.endm +.macro s9xgetwordregstatus reg + @ in : r0 (0x00hhmmll) + @ out : reg (0xhhll0000) + @ flags have to be updated with read value + stmfd r13!,{pc} @ push return address + b _asms9xgetword + mov r0,r0 + movs $0, r0, lsl #16 +.endm +.macro s9xgetwordregns reg + @ in : r0 (0x00hhmmll) + @ out : reg (0xhhll0000) + @ does not destroy r0 (r0) + stmfd r13!,{r0} + stmfd r13!,{pc} @ push return address + b _asms9xgetword + mov r0,r0 + mov $0, r0, lsl #16 + ldmfd r13!,{r0} +.endm +.macro s9xgetwordlowregns reg + @ in : r0 (0x00hhmmll) + @ out : reg (0xhhll0000) + @ does not destroy r0 (r0) + stmfd r13!,{r0} + stmfd r13!,{pc} @ push return address + b _asms9xgetword + mov r0,r0 + mov $0, r0 + ldmfd r13!,{r0} +.endm + +.macro s9xgetbyte + @ in : r0 (0x00hhmmll) + @ out : r0 (0xll000000) + stmfd r13!,{pc} @ push return address + b _asms9xgetbyte + mov r0,r0 + mov r0, r0, lsl #24 +.endm +.macro s9xgetbytelow + @ in : r0 (0x00hhmmll) + @ out : r0 (0x000000ll) + stmfd r13!,{pc} + b _asms9xgetbyte + mov r0,r0 +.endm +.macro s9xgetbyteregstatus reg + @ in : r0 (0x00hhmmll) + @ out : reg (0xll000000) + @ flags have to be updated with read value + stmfd r13!,{pc} @ push return address + b _asms9xgetbyte + mov r0,r0 + movs $0, r0, lsl #24 +.endm +.macro s9xgetbyteregns reg + @ in : r0 (0x00hhmmll) + @ out : reg (0xll000000) + @ does not destroy r0 (r0) + stmfd r13!,{r0} + stmfd r13!,{pc} @ push return address + b _asms9xgetbyte + mov r0,r0 + movs $0, r0, lsl #24 + ldmfd r13!,{r0} +.endm +.macro s9xgetbytelowregns reg + @ in : r0 (0x00hhmmll) + @ out : reg (0x000000ll) + @ does not destroy r0 (r0) + stmfd r13!,{r0} + stmfd r13!,{pc} @ push return address + b _asms9xgetbyte + mov r0,r0 + movs $0, r0 + ldmfd r13!,{r0} +.endm + +.macro s9xsetword regvalue + @ in : regvalue (0xhhll0000) + @ in : r0=address (0x00hhmmll) + stmfd r13!,{pc} @ push return address + mov r1,$0, lsr #16 + b _asms9xsetword + mov r0,r0 +.endm +.macro s9xsetwordzero + @ in : r0=address (0x00hhmmll) + stmfd r13!,{pc} @ push return address + mov r1,#0 + b _asms9xsetword + mov r0,r0 +.endm +.macro s9xsetwordlow regvalue + @ in : regvalue (0x0000hhll) + @ in : r0=address (0x00hhmmll) + stmfd r13!,{pc} @ push return address + mov r1,$0 + b _asms9xsetword + mov r0,r0 +.endm +.macro s9xsetbyte regvalue + @ in : regvalue (0xll000000) + @ in : r0=address (0x00hhmmll) + stmfd r13!,{pc} @ push return address + mov r1,$0, lsr #24 + b _asms9xsetbyte + mov r0,r0 +.endm +.macro s9xsetbytezero + @ in : r0=address (0x00hhmmll) + stmfd r13!,{pc} @ push return address + mov r1,#0 + b _asms9xsetbyte + mov r0,r0 +.endm +.macro s9xsetbytelow regvalue + @ in : regvalue (0x000000ll) + @ in : r0=address (0x00hhmmll) + stmfd r13!,{pc} @ push return address + mov r1,$0 + b _asms9xsetbyte + mov r0,r0 +.endm + + +@ =========================================== +@ =========================================== +@ adressing mode +@ =========================================== +@ =========================================== + + +.macro absolute + add2mem + ldrb r1 , [r10, #1] + ldrb r0 , [r10],#2 + orr r0 , r0, r1, lsl #8 + orr r0 , r0, r4, lsl #16 +.endm +.macro absoluteindexedindirectx0 + add2mem + ldrb r1 , [r10, #1] + ldrb r0 , [r10], #2 + orr r0 , r0, r1, lsl #8 + add r0 , r7, r0, lsl #16 + mov r0 , r0, lsr #16 + orr r0 , r0, r6, lsl #16 + s9xgetwordlow + +.endm +.macro absoluteindexedindirectx1 + add2mem + ldrb r1 , [r10, #1] + ldrb r0 , [r10], #2 + orr r0 , r0, r1, lsl #8 + add r0 , r0, r7, lsr #24 + bic r0 , r0, #0x00ff0000 + orr r0 , r0, r6, lsl #16 + s9xgetwordlow + +.endm +.macro absoluteindirectlong + add2mem + ldrb r1 , [r10, #1] + ldrb r0 , [r10], #2 + orr r0 , r0, r1, lsl #8 + s9xgetwordlowregns r1 + add r0 , r0, #2 + stmfd r13!,{r1} + s9xgetbytelow + ldmfd r13!,{r1} + orr r0 , r1, r0, lsl #16 +.endm +.macro absoluteindirect + add2mem + ldrb r1 , [r10,#1] + ldrb r0 , [r10], #2 + orr r0 , r0, r1, lsl #8 + s9xgetwordlow + orr r0 , r0, r6, lsl #16 +.endm +.macro absoluteindexedx0 + add2mem + ldrb r1 , [r10, #1] + ldrb r0 , [r10], #2 + orr r0 , r0, r1, lsl #8 + orr r0 , r0, r4, lsl #16 + add r0 , r0, r7, lsr #16 +.endm +.macro absoluteindexedx1 + add2mem + ldrb r1 , [r10, #1] + ldrb r0 , [r10], #2 + orr r0 , r0, r1, lsl #8 + orr r0 , r0, r4, lsl #16 + add r0 , r0, r7, lsr #24 +.endm + + +.macro absoluteindexedy0 + add2mem + ldrb r1 , [r10, #1] + ldrb r0 , [r10], #2 + orr r0 , r0, r1, lsl #8 + orr r0 , r0, r4, lsl #16 + add r0 , r0, r9, lsr #16 +.endm +.macro absoluteindexedy1 + add2mem + ldrb r1 , [r10, #1] + ldrb r0 , [r10], #2 + orr r0 , r0, r1, lsl #8 + orr r0 , r0, r4, lsl #16 + add r0 , r0, r9, lsr #24 +.endm +.macro absolutelong + add3mem + ldrb r1 , [r10, #1] + ldrb r0 , [r10], #2 + orr r0 , r0, r1, lsl #8 + ldrb r1 , [r10], #1 + orr r0 , r0, r1, lsl #16 +.endm + + +.macro absolutelongindexedx0 + add3mem + ldrb r1 , [r10, #1] + ldrb r0 , [r10], #2 + orr r0 , r0, r1, lsl #8 + ldrb r1 , [r10], #1 + orr r0 , r0, r1, lsl #16 + add r0 , r0, r7, lsr #16 + bic r0, r0, #0xff000000 +.endm +.macro absolutelongindexedx1 + add3mem + ldrb r1 , [r10, #1] + ldrb r0 , [r10], #2 + orr r0 , r0, r1, lsl #8 + ldrb r1 , [r10], #1 + orr r0 , r0, r1, lsl #16 + add r0 , r0, r7, lsr #24 + bic r0, r0, #0xff000000 +.endm +.macro direct + add1mem + ldrb r0 , [r10], #1 + add r0 , r6, r0, lsl #16 + mov r0, r0, lsr #16 +.endm +.macro directindirect + add1mem + ldrb r0 , [r10], #1 + add r0 , r6, r0, lsl #16 + mov r0, r0, lsr #16 + s9xgetwordlow + orr r0 , r0, r4, lsl #16 +.endm +.macro directindirectlong + add1mem + ldrb r0 , [r10], #1 + add r0 , r6, r0, lsl #16 + mov r0, r0, lsr #16 + s9xgetwordlowregns r1 + add r0 , r0,#2 + stmfd r13!,{r1} + s9xgetbytelow + ldmfd r13!,{r1} + orr r0 , r1, r0, lsl #16 +.endm +.macro directindirectindexed0 + add1mem + ldrb r0 , [r10], #1 + add r0 , r6, r0, lsl #16 + mov r0, r0, lsr #16 + s9xgetwordlow + orr r0, r0,r4, lsl #16 + add r0, r0,r9, lsr #16 +.endm +.macro directindirectindexed1 + add1mem + ldrb r0 , [r10], #1 + add r0 , r6, r0, lsl #16 + mov r0, r0, lsr #16 + s9xgetwordlow + orr r0, r0,r4, lsl #16 + add r0, r0,r9, lsr #24 +.endm +.macro directindirectindexedlong0 + add1mem + ldrb r0 , [r10], #1 + add r0 , r6, r0, lsl #16 + mov r0, r0, lsr #16 + s9xgetwordlowregns r1 + add r0 , r0,#2 + stmfd r13!,{r1} + s9xgetbytelow + ldmfd r13!,{r1} + orr r0 , r1, r0, lsl #16 + add r0, r0,r9, lsr #16 +.endm +.macro directindirectindexedlong1 + add1mem + ldrb r0 , [r10], #1 + add r0 , r6, r0, lsl #16 + mov r0, r0, lsr #16 + s9xgetwordlowregns r1 + add r0 , r0,#2 + stmfd r13!,{r1} + s9xgetbytelow + ldmfd r13!,{r1} + orr r0 , r1, r0, lsl #16 + add r0, r0,r9, lsr #24 +.endm +.macro directindexedindirect0 + add1cycle1mem + ldrb r0 , [r10], #1 + add r1 , r6 , r7 + add r0 , r1 , r0, lsl #16 + mov r0, r0, lsr #16 + s9xgetwordlow + orr r0 , r0 , r4, lsl #16 +.endm +.macro directindexedindirect1 + add1cycle1mem + ldrb r0 , [r10], #1 + add r1 , r6 , r7, lsr #8 + add r0 , r1 , r0, lsl #16 + mov r0, r0, lsr #16 + s9xgetwordlow + orr r0 , r0 , r4, lsl #16 +.endm +.macro directindexedx0 + add1cycle1mem + ldrb r0 , [r10], #1 + add r1 , r6 , r7 + add r0 , r1 , r0, lsl #16 + mov r0, r0, lsr #16 +.endm +.macro directindexedx1 + add1cycle1mem + ldrb r0 , [r10], #1 + add r1 , r6 , r7, lsr #8 + add r0 , r1 , r0, lsl #16 + mov r0, r0, lsr #16 +.endm +.macro directindexedy0 + add1cycle1mem + ldrb r0 , [r10], #1 + add r1 , r6 , r9 + add r0 , r1 , r0, lsl #16 + mov r0, r0, lsr #16 +.endm +.macro directindexedy1 + add1cycle1mem + ldrb r0 , [r10], #1 + add r1 , r6 , r9, lsr #8 + add r0 , r1 , r0, lsl #16 + mov r0, r0, lsr #16 +.endm +.macro immediate8 + add r0, r10, r6, lsl #16 + sub r0, r0, r12 + add r10, r10, #1 +.endm +.macro immediate16 + add r0, r10, r6, lsl #16 + sub r0, r0, r12 + add r10, r10, #2 +.endm +.macro asmrelative + add1mem + ldrsb r0 , [r10],#1 + add r0 , r0 , r10 + sub r0 , r0, r12 + bic r0,r0,#0x00ff0000 + bic r0,r0,#0xff000000 +.endm +.macro asmrelativelong + add1cycle2mem + ldrb r1 , [r10, #1] + ldrb r0 , [r10], #2 + orr r0 , r0, r1, lsl #8 + sub r1 , r10, r12 + add r0 , r1, r0 + bic r0,r0,#0x00ff0000 +.endm + + +.macro stackasmrelative + add1cycle1mem + ldrb r0 , [r10], #1 + add r0 , r0, r8 + bic r0,r0,#0x00ff0000 +.endm +.macro stackasmrelativeindirectindexed0 + add2cycle1mem + ldrb r0 , [r10], #1 + add r0 , r0, r8 + bic r0,r0,#0x00ff0000 + s9xgetwordlow + orr r0 , r0, r4, lsl #16 + add r0 , r0, r9, lsr #16 + bic r0, r0, #0xff000000 +.endm +.macro stackasmrelativeindirectindexed1 + add2cycle1mem + ldrb r0 , [r10], #1 + add r0 , r0, r8 + bic r0,r0,#0x00ff0000 + s9xgetwordlow + orr r0 , r0, r4, lsl #16 + add r0 , r0, r9, lsr #24 + bic r0, r0, #0xff000000 +.endm + + + +.macro pushb reg + mov r0,r8 + s9xsetbyte $0 + sub r8,r8,#1 +.endm +.macro pushblow reg + mov r0,r8 + s9xsetbytelow $0 + sub r8,r8,#1 +.endm +.macro pushwlow reg + sub r0,r8,#1 + s9xsetwordlow $0 + sub r8,r8,#2 +.endm +.macro pushwrlow + mov r1,r0 + sub r0,r8,#1 + s9xsetwordlow r1 + sub r8,r8,#2 +.endm +.macro pushw reg + sub r0,r8,#1 + s9xsetword $0 + sub r8,r8,#2 +.endm + + + +.macro pullb reg + add r0,r8,#1 + s9xgetbytelow + add r8,r8,#1 + mov $0,r0,lsl #24 +.endm +.macro pullbr + add r0,r8,#1 + s9xgetbyte + add r8,r8,#1 +.endm +.macro pullblow reg + add r0,r8,#1 + s9xgetbytelow + add r8,r8,#1 + mov $0,r0 +.endm +.macro pullbrlow + add r0,r8,#1 + s9xgetbytelow + add r8,r8,#1 +.endm +.macro pullw reg + add r0,r8,#1 + s9xgetwordlow + add r8,r8,#2 + mov $0,r0,lsl #16 +.endm + +.macro pullwlow reg + add r0,r8,#1 + s9xgetwordlow + add r8,r8,#2 + mov $0,r0 +.endm + + + +.macro pullbs reg + add r0,r8,#1 + s9xgetbytelow + add r8,r8,#1 + movs $0,r0,lsl #24 +.endm +.macro pullbrs + add r0,r8,#1 + s9xgetbytelow + add r8,r8,#1 + movs r0,r0,lsl #24 +.endm +.macro pullblows reg + add r0,r8,#1 + s9xgetbytelow + add r8,r8,#1 + movs $0,r0 +.endm +.macro pullbrlows + add r0,r8,#1 + s9xgetbytelow + add r8,r8,#1 + movs r0,r0 +.endm +.macro pullws reg + add r0,r8,#1 + s9xgetwordlow + add r8,r8,#2 + movs $0,r0, lsl #16 +.endm +.macro pullwrs + add r0,r8,#1 + s9xgetwordlow + add r8,r8,#2 + movs r0,r0, lsl #16 +.endm +.macro pullwlows reg + add r0,r8,#1 + s9xgetwordlow + add r8,r8,#2 + movs $0,r0 +.endm +.macro pullwrlows + add r0,r8,#1 + s9xgetwordlow + add r8,r8,#2 + movs r0,r0 +.endm + + +.globl _asms9xgetbyte +.globl _asms9xgetword +.globl _asms9xsetbyte +.globl _asms9xsetword + +@ uint8 aas9xgetbyte(uint32 address); +_asms9xgetbyte: + @ in : r0 = 0x00hhmmll + @ out : r0 = 0x000000ll + @ destroyed : r1,r2,r3 + @ update : r11 + @ r1 <= block + mov r1,r0,lsr #12 + @ 12 is 12, address is 0xffffffff at max, so + @ r1 is maxed by 0x000fffff, (0xfff) is 0x1000-1=0xfff + @ so and (0xfff) is bic 0xff000 + bic r1,r1,#0xff000 + @ r2 <= map[block] (getaddress) + ldr r2,[r14,#96] + ldr r2,[r2,r1,lsl #2] + cmp r2,#12 + blo gbspecial @ special + @ direct rom/ram acess + @ r2 <= getaddress + address & 0xffff + @ r3 <= memoryspeed[block] + ldr r3,[r14,#104] + mov r0,r0,lsl #16 + ldrb r3,[r3,r1] + add r2,r2,r0,lsr #16 + @ update cpu.cycles + add r11,r11,r3 + @ r3 = blockisram[block] + ldr r3,[r14,#108] + @ get value to return + ldrb r0,[r2] + ldrb r3,[r3,r1] + movs r3,r3 + @ if blockisram => update for cpushutdown + ldrne r1,[r14,#36] + strne r1,[r14,#40] + + ldmfd r13!,{pc} @ return +gbspecial: + + ldr pc,[pc,r2,lsl #2] + mov r0,r0 @ nop, for align + .long gbppu + .long gbcpu + .long gbdsp + .long gblsram + .long gbhsram + .long gbnone + .long gbdebug + .long gbc4 + .long gbbwram + .long gbnone + .long gbnone + .long gbnone + + + +gbppu: + @ indma ? + ldrb r1,[r14,#84] + movs r1,r1 + addeq r11,r11,#6 @ no -> update cycles + mov r0,r0,lsl #16 @ s9xgetppu(address&0xffff); + str r11,[r14,#28] @ save cycles + mov r0,r0,lsr #16 + prepare_c_call + bl _S9xGetPPU + restore_c_call + ldr r11,[r14,#28] @ load cycles + ldmfd r13!,{pc} @ return +gbcpu: + add r11,r11,#6 @ update cycles + mov r0,r0,lsl #16 @ s9xgetcpu(address&0xffff); + str r11,[r14,#28] @ save cycles + mov r0,r0,lsr #16 + prepare_c_call + bl _S9xGetCPU + restore_c_call + ldr r11,[r14,#28] @ load cycles + ldmfd r13!,{pc} @ return +gbdsp: + add r11,r11,#8 @ update cycles + mov r0,r0,lsl #16 @ s9xgetcpu(address&0xffff); + str r11,[r14,#28] @ save cycles + mov r0,r0,lsr #16 + prepare_c_call + bl _S9xGetDSP + restore_c_call + ldr r11,[r14,#28] @ load cycles + ldmfd r13!,{pc} @ return +gblsram: + add r11,r11,#8 @ update cycles + ldrh r2,[r14,#120] + ldr r1,[r14,#112] + and r0,r2,r0 @ address&120 + ldrb r0,[r1,r0] @ *memory. 112 + address&120 + ldmfd r13!,{pc} +gb7srm: +gbhsram: + add r11,r11,#8 @ update cycles + + mov r1,r0,lsl #17 + and r2,r0,#0xf0000 + mov r1,r1,lsr #17 @ address&0x7fff + mov r2,r2,lsr #3 @ (address&0xf0000 >> 3) + add r0,r2,r1 + ldrh r2,[r14,#120] + sub r0,r0,#0x6000 @ ((address & 0x7fff) - 0x6000 + ((address & 0xf0000) >> 3)) + ldr r1,[r14,#112] + and r0,r2,r0 @ address&120 + ldrb r0,[r1,r0] @ *memory. 112 + address&120 + ldmfd r13!,{pc} @ return +gb7rom: +gb7ram: +gbnone: + mov r0,r0,lsr #8 + add r11,r11,#8 @ update cycles + and r0,r0,#0xff + ldmfd r13!,{pc} +@ gbdebug: + + + +gbc4: + add r11,r11,#8 @ update cycles + mov r0,r0,lsl #16 @ s9xgetc4(address&0xffff); + str r11,[r14,#28] @ save cycles + mov r0,r0,lsr #16 + prepare_c_call + bl _S9xGetC4 + restore_c_call + ldr r11,[r14,#28] @ load cycles + ldmfd r13!,{pc} @ return +gbdebug: +gbbwram: + mov r0,r0,lsl #17 + add r11,r11,#8 @ update cycles + mov r0,r0,lsr #17 @ address&0x7fff + ldr r1,[r14,#116] + sub r0,r0,#0x6000 @ ((address & 0x7fff) - 0x6000) + ldrb r0,[r0,r1] @ *memory. 116 + ((address & 0x7fff) - 0x6000) + ldmfd r13!,{pc} + + +@ uint16 aas9xgetword(uint32 address); +_asms9xgetword: + @ in : r0 = 0x00hhmmll + @ out : r0 = 0x000000ll + @ destroyed : r1,r2,r3 + @ update : r11 + + + mov r1,r0,lsl #19 + adds r1,r1,#0x80000 + @ if = 0x1fff => 0 + bne gw_notboundary + + stmfd r13!,{r0} + stmfd r13!,{pc} + b _asms9xgetbyte + mov r0,r0 + ldmfd r13!,{r1} + stmfd r13!,{r0} + add r0,r1,#1 + stmfd r13!,{pc} + b _asms9xgetbyte + mov r0,r0 + ldmfd r13!,{r1} + orr r0,r1,r0,lsl #8 + ldmfd r13!,{pc} + +gw_notboundary: + + @ r1 <= block + mov r1,r0,lsr #12 + @ 12 is 12, address is 0xffffffff at max, so + @ r1 is maxed by 0x000fffff, (0xfff) is 0x1000-1=0xfff + @ so and (0xfff) is bic 0xff000 + bic r1,r1,#0xff000 + @ r2 <= map[block] (getaddress) + ldr r2,[r14,#96] + ldr r2,[r2,r1,lsl #2] + cmp r2,#12 + blo gwspecial @ special + @ direct rom/ram acess + + tst r0,#1 + bne gw_not_aligned1 + @ r2 <= getaddress + address & 0xffff + @ r3 <= memoryspeed[block] + ldr r3,[r14,#104] + mov r0,r0,lsl #16 + ldrb r3,[r3,r1] + mov r0,r0,lsr #16 + @ update cpu.cycles + add r11,r11,r3, lsl #1 + @ r3 = blockisram[block] + ldr r3,[r14,#108] + @ get value to return + ldrh r0,[r2,r0] + ldrb r3,[r3,r1] + movs r3,r3 + @ if blockisram => update for cpushutdown + ldrne r1,[r14,#36] + strne r1,[r14,#40] + + ldmfd r13!,{pc} @ return +gw_not_aligned1: + + mov r0,r0,lsl #16 + add r3,r0,#0x10000 + ldrb r3,[r2,r3,lsr #16] @ getaddress+ (address+1)&0xffff + ldrb r0,[r2,r0,lsr #16] @ getaddress+ address&0xffff + orr r0,r0,r3,lsl #8 + + @ if blockisram => update for cpushutdown + ldr r3,[r14,#108] + ldr r2,[r14,#104] + ldrb r3,[r3,r1] @ r3 = blockisram[block] + ldrb r2,[r2,r1] @ r2 <= memoryspeed[block] + movs r3,r3 @ isram ? cpushutdown stuff + ldrne r1,[r14,#36] + strne r1,[r14,#40] + add r11,r11,r2, lsl #1 @ update cpu.cycles + ldmfd r13!,{pc} @ return +gwspecial: + ldr pc,[pc,r2,lsl #2] + mov r0,r0 @ nop, for align + .long gwppu + .long gwcpu + .long gwdsp + .long gwlsram + .long gwhsram + .long gwnone + .long gwdebug + .long gwc4 + .long gwbwram + .long gwnone + .long gwnone + .long gwnone + + + + + + + +gwppu: + @ indma ? + ldrb r1,[r14,#84] + movs r1,r1 + addeq r11,r11,#12 @ no -> update cycles + mov r0,r0,lsl #16 @ s9xgetppu(address&0xffff); + str r11,[r14,#28] @ save cycles + mov r0,r0,lsr #16 + prepare_c_call_r0 + bl _S9xGetPPU + ldmfd r13!,{r1} + stmfd r13!,{r0} + add r0,r1,#1 + @ bic r0,r0,#0x10000 + bl _S9xGetPPU + restore_c_call_r1 + orr r0,r1,r0,lsl #8 + ldr r11,[r14,#28] @ load cycles + ldmfd r13!,{pc} @ return +gwcpu: + add r11,r11,#12 @ update cycles + mov r0,r0,lsl #16 @ s9xgetcpu(address&0xffff); + str r11,[r14,#28] @ save cycles + mov r0,r0,lsr #16 + prepare_c_call_r0 + bl _S9xGetCPU + ldmfd r13!,{r1} + stmfd r13!,{r0} + add r0,r1,#1 + @ bic r0,r0,#0x10000 + bl _S9xGetCPU + restore_c_call_r1 + orr r0,r1,r0,lsl #8 + ldr r11,[r14,#28] @ load cycles + ldmfd r13!,{pc} @ return +gwdsp: + add r11,r11,#16 @ update cycles + mov r0,r0,lsl #16 @ s9xgetcpu(address&0xffff); + str r11,[r14,#28] @ save cycles + mov r0,r0,lsr #16 + prepare_c_call_r0 + bl _S9xGetDSP + ldmfd r13!,{r1} + stmfd r13!,{r0} + add r0,r1,#1 + @ bic r0,r0,#0x10000 + bl _S9xGetDSP + restore_c_call_r1 + orr r0,r1,r0,lsl #8 + ldr r11,[r14,#28] @ load cycles + ldmfd r13!,{pc} @ return +gwlsram: + add r11,r11,#16 @ update cycles + + tst r0,#1 + bne gw_not_aligned2 + ldrh r2,[r14,#120] + ldr r1,[r14,#112] + and r3,r2,r0 @ address&120 + ldrh r0,[r3,r1] @ *memory. 112 + address&120 + ldmfd r13!,{pc} @ return +gw_not_aligned2: + ldrh r2,[r14,#120] + ldr r1,[r14,#112] + and r3,r2,r0 @ address&120 + add r0,r0,#1 + and r2,r0,r2 @ address&120 + ldrb r3,[r1,r3] @ *memory. 112 + address&120 + ldrb r2,[r1,r2] @ *memory. 112 + address&120 + orr r0,r3,r2,lsl #8 + ldmfd r13!,{pc} @ return +gw7srm: +gwhsram: + add r11,r11,#16 @ update cycles + + tst r0,#1 + bne gw_not_aligned3 + + mov r1,r0,lsl #17 + and r2,r0,#0xf0000 + mov r1,r1,lsr #17 @ address&0x7fff + mov r2,r2,lsr #3 @ (address&0xf0000 >> 3) + add r0,r2,r1 + ldrh r2,[r14,#120] + sub r0,r0,#0x6000 @ ((address & 0x7fff) - 0x6000 + ((address & 0xf0000) >> 3)) + ldr r1,[r14,#112] + and r0,r2,r0 @ address&120 + ldrh r0,[r1,r0] @ *memory. 112 + address&120 + ldmfd r13!,{pc} @ return + +gw_not_aligned3: + mov r3,r0,lsl #17 + and r2,r0,#0xf0000 + mov r3,r3,lsr #17 @ address&0x7fff + mov r2,r2,lsr #3 @ (address&0xf0000 >> 3) + add r2,r2,r3 + add r0,r0,#1 + sub r2,r2,#0x6000 @ ((address & 0x7fff) - 0x6000 + ((address & 0xf0000) >> 3)) + mov r3,r0,lsl #17 + and r0,r0,#0xf0000 + mov r3,r3,lsr #17 @ (address+1)&0x7fff + mov r0,r0,lsr #3 @ ((address+1)&0xf0000 >> 3) + add r0,r0,r3 + ldrh r3,[r14,#120] @ reload mask + sub r0,r0,#0x6000 @ (((address+1) & 0x7fff) - 0x6000 + (((address+1) & 0xf0000) >> 3)) + and r2,r3,r2 @ address...&120 + and r0,r3,r0 @ (address+1...)&120 + + ldr r3,[r14,#112] + ldrb r0,[r0,r3] @ *memory. 112 + (address...)&120 + ldrb r2,[r2,r3] @ *memory. 112 + (address+1...)&120 + orr r0,r2,r0,lsl #8 + + ldmfd r13!,{pc} @ return +gw7rom: +gw7ram: +gwnone: + mov r0,r0,lsl #16 + add r11,r11,#16 @ update cycles + mov r0,r0,lsr #24 + orr r0,r0,r0,lsl #8 + ldmfd r13!,{pc} +gwdebug: + add r11,r11,#16 @ update cycles + mov r0,#0 + ldmfd r13!,{pc} +gwc4: + add r11,r11,#16 @ update cycles + mov r0,r0,lsl #16 @ s9xgetc4(address&0xffff); + str r11,[r14,#28] @ save cycles + mov r0,r0,lsr #16 + prepare_c_call_r0 + bl _S9xGetC4 + ldmfd r13!,{r1} + stmfd r13!,{r0} + add r0,r1,#1 + @ bic r0,r0,#0x10000 + bl _S9xGetC4 + restore_c_call_r1 + orr r0,r1,r0,lsl #8 + ldr r11,[r14,#28] @ load cycles + ldmfd r13!,{pc} @ return +gwbwram: + tst r0,#1 + bne gw_not_aligned4 + mov r0,r0,lsl #17 + add r11,r11,#16 @ update cycles + mov r0,r0,lsr #17 @ address&0x7fff + ldr r1,[r14,#116] + sub r0,r0,#0x6000 @ ((address & 0x7fff) - 0x6000) + ldrh r0,[r1,r0] @ *memory. 116 + ((address & 0x7fff) - 0x6000) + ldmfd r13!,{pc} @ return +gw_not_aligned4: + mov r0,r0,lsl #17 + add r11,r11,#16 @ update cycles + add r3,r0,#0x20000 + mov r0,r0,lsr #17 @ address&0x7fff + mov r3,r3,lsr #17 @ (address+1)&0x7fff + ldr r1,[r14,#116] + sub r0,r0,#0x6000 @ ((address & 0x7fff) - 0x6000) + sub r3,r3,#0x6000 @ (((address+1) & 0x7fff) - 0x6000) + ldrb r0,[r1,r0] @ *memory. 116 + ((address & 0x7fff) - 0x6000) + ldrb r3,[r1,r3] @ *memory. 116 + (((address+1) & 0x7fff) - 0x6000) + orr r0,r0,r3,lsl #8 + ldmfd r13!,{pc} @ return + + + + +@ void aas9xsetbyte(uint32 address,uint8 val); +_asms9xsetbyte: + @ in : r0=0x00hhmmll r1=0x000000ll + @ destroyed : r0,r1,r2,r3 + @ update : r11 + @ cpu shutdown + mov r2,#0 + str r2,[r14,#40] + @ + + @ r3 <= block + mov r3,r0,lsr #12 + @ 12 is 12, address is 0xffffffff at max, so + @ r0 is maxed by 0x000fffff, (0xfff) is 0x1000-1=0xfff + @ so and (0xfff) is bic 0xff000 + bic r3,r3,#0xff000 + @ r2 <= map[block] (setaddress) + ldr r2,[r14,#100] + ldr r2,[r2,r3,lsl #2] + cmp r2,#12 + blo sbspecial @ special + @ direct rom/ram acess + + @ r2 <= setaddress + address & 0xffff + mov r0,r0,lsl #16 + add r2,r2,r0,lsr #16 + ldr r0,[r14,#104] + @ set byte + strb r1,[r2] + @ r0 <= memoryspeed[block] + ldrb r0,[r0,r3] + @ update cpu.cycles + add r11,r11,r0 + @ cpushutdown + @ only sa1 here : todo + @ return + ldmfd r13!,{pc} +sbspecial: + ldr pc,[pc,r2,lsl #2] + mov r0,r0 @ nop, for align + .long sbppu + .long sbcpu + .long sbdsp + .long sblsram + .long sbhsram + .long sbnone + .long sbdebug + .long sbc4 + .long sbbwram + .long sbnone + .long sbnone + .long sbnone + + + +sbppu: + @ indma ? + ldrb r2,[r14,#84] + movs r2,r2 + addeq r11,r11,#6 @ no -> update cycles + mov r0,r0,lsl #16 + str r11,[r14,#28] @ save cycles + mov r0,r0,lsr #16 + prepare_c_call + mov r12,r0 + mov r0,r1 + mov r1,r12 + bl _S9xSetPPU + restore_c_call + ldr r11,[r14,#28] @ load cycles + ldmfd r13!,{pc} @ return +sbcpu: + add r11,r11,#6 @ update cycles + mov r0,r0,lsl #16 + str r11,[r14,#28] @ save cycles + mov r0,r0,lsr #16 @ address&0xffff + prepare_c_call + mov r12,r0 + mov r0,r1 + mov r1,r12 + bl _S9xSetCPU + restore_c_call + ldr r11,[r14,#28] @ load cycles + ldmfd r13!,{pc} @ return +sbdsp: + add r11,r11,#8 @ update cycles + mov r0,r0,lsl #16 + str r11,[r14,#28] @ save cycles + mov r0,r0,lsr #16 @ address&0xffff + prepare_c_call + mov r12,r0 + mov r0,r1 + mov r1,r12 + bl _S9xSetDSP + restore_c_call + ldr r11,[r14,#28] @ load cycles + ldmfd r13!,{pc} @ return +sblsram: + add r11,r11,#8 @ update cycles + ldrh r2,[r14,#120] + movs r2,r2 + ldmeqfd r13!,{pc} @ return if 120=0 + ldr r3,[r14,#112] + and r0,r2,r0 @ address&120 + strb r1,[r0,r3] @ *memory. 112 + address&120 + + mov r0,#1 + strb r0,[r14,#86] + ldmfd r13!,{pc} @ return +sb7srm: +sbhsram: + add r11,r11,#8 @ update cycles + + mov r3,r0,lsl #17 + and r2,r0,#0xf0000 + mov r3,r3,lsr #17 @ address&0x7fff + mov r2,r2,lsr #3 @ (address&0xf0000 >> 3) + add r0,r2,r3 + + ldrh r2,[r14,#120] + movs r2,r2 + ldmeqfd r13!,{pc} @ return if 120=0 + + sub r0,r0,#0x6000 @ ((address & 0x7fff) - 0x6000 + ((address & 0xf0000) >> 3)) + ldr r3,[r14,#112] + and r0,r2,r0 @ address&120 + strb r1,[r0,r3] @ *memory. 112 + address&120 + + mov r0,#1 + strb r0,[r14,#86] + ldmfd r13!,{pc} @ return +sb7rom: +sb7ram: +sbnone: +sbdebug: + add r11,r11,#8 @ update cycles + ldmfd r13!,{pc} +sbc4: + add r11,r11,#8 @ update cycles + mov r0,r0,lsl #16 + str r11,[r14,#28] @ save cycles + mov r0,r0,lsr #16 @ address&0xffff + prepare_c_call + mov r12,r0 + mov r0,r1 + mov r1,r12 + bl _S9xSetC4 + restore_c_call + ldr r11,[r14,#28] @ load cycles + ldmfd r13!,{pc} @ return +sbbwram: + mov r0,r0,lsl #17 + add r11,r11,#8 @ update cycles + mov r0,r0,lsr #17 @ address&0x7fff + ldr r2,[r14,#116] + sub r0,r0,#0x6000 @ ((address & 0x7fff) - 0x6000) + strb r1,[r0,r2] @ *memory. 116 + ((address & 0x7fff) - 0x6000) + + mov r0,#1 + strb r0,[r14,#86] + + ldmfd r13!,{pc} + + + +@ void aas9xsetword(uint32 address,uint16 val); +_asms9xsetword: + @ in : r0 = 0x00hhmmll r1=0x0000hhll + @ destroyed : r0,r1,r2,r3 + @ update : r11 + @ r1 <= block + + mov r2,r0,lsl #19 + adds r2,r2,#0x80000 + @ if = 0x1fff => 0 + bne sw_notboundary + + stmfd r13!,{r0,r1} + stmfd r13!,{pc} + b _asms9xsetbyte + mov r0,r0 + ldmfd r13!,{r0,r1} + add r0,r0,#1 + mov r1,r1,lsr #8 + stmfd r13!,{pc} + b _asms9xsetbyte + mov r0,r0 + + ldmfd r13!,{pc} + +sw_notboundary: + + mov r2,#0 + str r2,[r14,#40] + @ + @ r3 <= block + mov r3,r0,lsr #12 + @ 12 is 12, address is 0xffffffff at max, so + @ r1 is maxed by 0x000fffff, (0xfff) is 0x1000-1=0xfff + @ so and (0xfff) is bic 0xff000 + bic r3,r3,#0xff000 + @ r2 <= map[block] (setaddress) + ldr r2,[r14,#100] + ldr r2,[r2,r3,lsl #2] + cmp r2,#12 + blo swspecial @ special + @ direct rom/ram acess + + + @ check if address is 16bits aligned or not + tst r0,#1 + bne sw_not_aligned1 + @ aligned + mov r0,r0,lsl #16 + add r2,r2,r0,lsr #16 @ address & 0xffff + setaddress + ldr r0,[r14,#104] + @ set word + strh r1,[r2] + @ r1 <= memoryspeed[block] + ldrb r0,[r0,r3] + @ update cpu.cycles + add r11,r11,r0, lsl #1 + @ cpushutdown + @ only sa1 here : todo + @ return + ldmfd r13!,{pc} + +sw_not_aligned1: + @ r1 = (address&0xffff)<<16 + mov r0,r0,lsl #16 + @ first write @address + strb r1,[r2,r0,lsr #16] + add r0,r0,#0x10000 + mov r1,r1,lsr #8 + @ second write @address+1 + strb r1,[r2,r0,lsr #16] + @ r1 <= memoryspeed[block] + ldr r0,[r14,#104] + ldrb r0,[r0,r3] + @ update cpu.cycles + add r11,r11,r0,lsl #1 + @ cpushutdown + @ only sa1 here : todo + @ return + ldmfd r13!,{pc} +swspecial: + ldr pc,[pc,r2,lsl #2] + mov r0,r0 @ nop, for align + .long swppu + .long swcpu + .long swdsp + .long swlsram + .long swhsram + .long swnone + .long swdebug + .long swc4 + .long swbwram + .long swnone + .long swnone + .long swnone + + + +swppu: + @ indma ? + ldrb r2,[r14,#84] + movs r2,r2 + addeq r11,r11,#12 @ no -> update cycles + mov r0,r0,lsl #16 + str r11,[r14,#28] @ save cycles + mov r0,r0,lsr #16 + mov r2,r1 + mov r1,r0 + mov r0,r2 + prepare_c_call_r0r1 + bl _S9xSetPPU + ldmfd r13!,{r0,r1} + add r1,r1,#1 + mov r0,r0,lsr #8 + bic r1,r1,#0x10000 + bl _S9xSetPPU + restore_c_call + ldr r11,[r14,#28] @ load cycles + ldmfd r13!,{pc} @ return +swcpu: + add r11,r11,#12 @ update cycles + mov r0,r0,lsl #16 + str r11,[r14,#28] @ save cycles + mov r0,r0,lsr #16 @ address&0xffff + mov r2,r1 + mov r1,r0 + mov r0,r2 + prepare_c_call_r0r1 + bl _S9xSetCPU + ldmfd r13!,{r0,r1} + add r1,r1,#1 + mov r0,r0,lsr #8 + bic r1,r1,#0x10000 + bl _S9xSetCPU + restore_c_call + ldr r11,[r14,#28] @ load cycles + ldmfd r13!,{pc} @ return +swdsp: + add r11,r11,#8 @ update cycles + mov r0,r0,lsl #16 + str r11,[r14,#28] @ save cycles + mov r0,r0,lsr #16 @ address&0xffff + mov r2,r1 + mov r1,r0 + mov r0,r2 + prepare_c_call_r0r1 + bl _S9xSetDSP + ldmfd r13!,{r0,r1} + add r1,r1,#1 + mov r0,r0,lsr #8 + bic r1,r1,#0x10000 + bl _S9xSetDSP + restore_c_call + ldr r11,[r14,#28] @ load cycles + ldmfd r13!,{pc} @ return +swlsram: + add r11,r11,#16 @ update cycles + ldrh r2,[r14,#120] + movs r2,r2 + ldmeqfd r13!,{pc} @ return if 120=0 + + and r3,r2,r0 @ address&120 + tst r0,#1 + bne sw_not_aligned2 + @ aligned + ldr r0,[r14,#112] + strh r1,[r0,r3] @ *memory. 112 + address&120 + mov r0,#1 + strb r0,[r14,#86] + ldmfd r13!,{pc} @ return +sw_not_aligned2: + + add r0,r0,#1 + and r2,r2,r0 @ (address+1)&120 + ldr r0,[r14,#112] + strb r1,[r0,r3] @ *memory. 112 + address&120 + mov r1,r1,lsr #8 + strb r1,[r0,r2] @ *memory. 112 + (address+1)&120 + mov r0,#1 + strb r0,[r14,#86] + ldmfd r13!,{pc} @ return +sw7srm: +swhsram: + add r11,r11,#16 @ update cycles + + ldrh r2,[r14,#120] + movs r2,r2 + ldmeqfd r13!,{pc} @ return if 120=0 + + tst r0,#1 + bne sw_not_aligned3 + @ aligned + mov r3,r0,lsl #17 + and r2,r0,#0xf0000 + mov r3,r3,lsr #17 @ address&0x7fff + mov r2,r2,lsr #3 @ (address&0xf0000 >> 3) + add r0,r2,r3 + sub r0,r0,#0x6000 @ ((address & 0x7fff) - 0x6000 + ((address & 0xf0000) >> 3)) + ldrh r2,[r14,#120] + ldr r3,[r14,#112] + and r0,r2,r0 @ address&120 + strh r1,[r0,r3] @ *memory. 112 + address&120 + mov r0,#1 + strb r0,[r14,#86] + ldmfd r13!,{pc} @ return +sw_not_aligned3: + mov r3,r0,lsl #17 + and r2,r0,#0xf0000 + mov r3,r3,lsr #17 @ address&0x7fff + mov r2,r2,lsr #3 @ (address&0xf0000 >> 3) + add r2,r2,r3 + sub r2,r2,#0x6000 @ ((address & 0x7fff) - 0x6000 + ((address & 0xf0000) >> 3)) + + add r0,r0,#1 + mov r3,r0,lsl #17 + and r0,r0,#0xf0000 + mov r3,r3,lsr #17 @ (address+1)&0x7fff + mov r0,r0,lsr #3 @ ((address+1)&0xf0000 >> 3) + add r0,r0,r3 + ldrh r3,[r14,#120] @ reload mask + sub r0,r0,#0x6000 @ (((address+1) & 0x7fff) - 0x6000 + (((address+1) & 0xf0000) >> 3)) + and r2,r3,r2 @ address...&120 + and r0,r3,r0 @ (address+1...)&120 + + ldr r3,[r14,#112] + strb r1,[r2,r3] @ *memory. 112 + (address...)&120 + mov r1,r1,lsr #8 + strb r1,[r0,r3] @ *memory. 112 + (address+1...)&120 + + mov r0,#1 + strb r0,[r14,#86] + ldmfd r13!,{pc} @ return +sw7rom: +sw7ram: +swnone: +swdebug: + add r11,r11,#16 @ update cycles + ldmfd r13!,{pc} @ return +swc4: + add r11,r11,#16 @ update cycles + mov r0,r0,lsl #16 + str r11,[r14,#28] @ save cycles + mov r0,r0,lsr #16 @ address&0xffff + mov r2,r1 + mov r1,r0 + mov r0,r2 + prepare_c_call_r0r1 + bl _S9xSetC4 + ldmfd r13!,{r0,r1} + add r1,r1,#1 + mov r0,r0,lsr #8 + bic r1,r1,#0x10000 + bl _S9xSetC4 + restore_c_call + ldr r11,[r14,#28] @ load cycles + ldmfd r13!,{pc} @ return +swbwram: + add r11,r11,#16 @ update cycles + tst r0,#1 + bne sw_not_aligned4 + @ aligned + mov r0,r0,lsl #17 + ldr r2,[r14,#116] + mov r0,r0,lsr #17 @ address&0x7fff + sub r0,r0,#0x6000 @ ((address & 0x7fff) - 0x6000) + mov r3,#1 + strh r1,[r0,r2] @ *memory. 116 + ((address & 0x7fff) - 0x6000) + strb r3,[r14,#86] + ldmfd r13!,{pc} @ return +sw_not_aligned4: + mov r0,r0,lsl #17 + add r3,r0,#0x20000 + mov r0,r0,lsr #17 @ address&0x7fff + mov r3,r3,lsr #17 @ (address+1)&0x7fff + ldr r2,[r14,#116] + sub r0,r0,#0x6000 @ ((address & 0x7fff) - 0x6000) + sub r3,r3,#0x6000 @ (((address+1) & 0x7fff) - 0x6000) + strb r1,[r2,r0] @ *memory. 116 + ((address & 0x7fff) - 0x6000) + mov r1,r1,lsr #8 + strb r1,[r2,r3] @ *memory. 116 + (((address+1) & 0x7fff) - 0x6000) + mov r0,#1 + strb r0,[r14,#86] + ldmfd r13!,{pc} @ return +# 2025 "os9x_65c816.S" +.macro update_c + @ cc : arm carry clear + biccc r4, r4, #(1<<(24)) @ 0 @ 0 : and mask 11111011111 : set c to zero + @ cs : arm carry set + orrcs r4, r4, #(1<<(24)) @ 0 @ 1 : or mask 00000100000 : set c to one +.endm +.macro update_z + @ ne : arm zero clear + bicne r4, r4, #(2<<(24)) @ 1 @ 0 : and mask 11111011111 : set z to zero + @ eq : arm zero set + orreq r4, r4, #(2<<(24)) @ 1 @ 1 : or mask 00000100000 : set z to one +.endm +.macro update_zn + @ ne : arm zero clear + bicne r4, r4, #(2<<(24)) @ 1 @ 0 : and mask 11111011111 : set z to zero + @ eq : arm zero set + orreq r4, r4, #(2<<(24)) @ 1 @ 1 : or mask 00000100000 : set z to one + @ pl : arm neg clear + bicpl r4, r4, #(128<<(24))@ 7 @ 8 @ 0 : and mask 11111011111 : set n to zero + @ mi : arm neg set + orrmi r4, r4, #(128<<(24))@ 7 @ 8 @ 1 : or mask 00000100000 : set n to one +.endm +# 2055 "os9x_65c816.S" +.macro adc8 + tst r4, #(8<<(24)) @ 3 + beq 1111f + s9xgetbyte + + + stmfd r13!,{r0} + mov r3,#0x0f000000 + @ r1=xxw1xxxxxxxxxxxx + and r1, r0, r3 + @ r0=xxw2xxxxxxxxxxxx + and r0, r3, r0, lsr #4 + @ r2=xxa2xxxxxxxxxxxx + and r2, r3, r5, lsr #4 + @ r3=xxa1xxxxxxxxxxxx + and r3,r5,r3 + @ r1=a1+w1+carry + tst r4, #(1<<(24)) @ 0 + addne r1, r1, #0x01000000 + add r1,r1,r3 + @ if r1 > 9 + cmp r1, #0x09000000 + @ then r1 -= 10 + subgt r1, r1, #0x0a000000 + @ then a2++ + addgt r2, r2, #0x01000000 + @ r2 = a2+w2 + add r2, r2, r0 + @ if r2 > 9 + cmp r2, #0x09000000 + @ then r2 -= 10@ + subgt r2, r2, #0x0a000000 + @ then setcarry() + orrgt r4, r4, #(1<<(24)) @ 0 @ 1 : or mask 00000100000 : set c to one + @ else clearcarry() + bicle r4, r4, #(1<<(24)) @ 0 @ 0 : and mask 11111011111 : set c to zero + @ gather r2 and r1 into ans8 + @ r2 : 0r2000000 + @ r1 : 0r1000000 + @ -> 0xr2r1000000 + orr r1, r1, r2, lsl #4 + ldmfd r13!,{r0} + @ only last bit + and r0,r0,#0x80000000 + @ (register.al ^ work8) + eors r2, r5, r0 + bicne r4, r4, #(64<<(24)) @ 6 @ 4 @ 0 : and mask 11111011111 : set v to zero + bne 1112f + @ (work8 ^ ans8) + eors r2, r1, r0 + @ & 0x80 + tstne r2,#0x80000000 + biceq r4, r4, #(64<<(24)) @ 6 @ 4 @ 0 : and mask 11111011111 : set v to zero + orrne r4, r4, #(64<<(24)) @ 6 @ 4 @ 1 : or mask 00000100000 : set v to one +1112: + movs r5, r1 + update_zn + b 1113f +1111: + s9xgetbytelow + movs r1, r4, lsr #(24 +1) + subcs r0, r0, #0x100 + adcs r5, r5, r0, ror #8 + @ overflow + orrvs r4, r4, #(64<<(24)) @ 6 @ 4 + bicvc r4, r4, #(64<<(24)) @ 6 @ 4 + @ carry + update_c + @ clear lower part + ands r5, r5, #0xff000000 + @ update flag + update_zn +1113: +.endm + +.macro adc16 + tst r4, #(8<<(24)) @ 3 + beq 1111f + s9xgetword + + @ r0 = w3w2w1w0........ + @ PATCH ldr r3, = 0x0f0f0000 + mov r3, #0x0f0000 + orr r3, r3, #0x0f000000 + @ r1 = xxw2xxw0xxxxxx + @ r2 = xxw3xxw1xxxxxx + and r1, r3, r0 + and r2, r3, r0, lsr #4 + @ r1 = xxw3xxw1xxw2xxw0 + orr r1, r2, r1, lsr #16 + @ r2 = xxa2xxa0xxxxxx + @ r3 = xxa3xxa1xxxxxx + @ r1 = xxa3xxa1xxa2xxa0 + and r2, r3, r5 + and r3, r3, r5, lsr #4 + orr r2, r3, r2, lsr #16 + add r1, r2, r1 + @ PATCH ldr r3, = 0x0f0f0000 + mov r3, #0x0f0000 + orr r3, r3, #0x0f000000 + @ r1 = a + w + tst r4, #(1<<(24)) @ 0 + addne r1, r1, #0x1 + @ r1 = a + w + c + @ a0 + and r2, r1, #0x0000001f + cmp r2, #0x00000009 + addhi r1, r1, #0x00010000 + subhi r1, r1, #0x0000000a + @ a1 + and r2, r1, #0x001f0000 + cmp r2, #0x00090000 + addhi r1, r1, #0x00000100 + subhi r1, r1, #0x000a0000 + @ a2 + and r2, r1, #0x00001f00 + cmp r2, #0x00000900 + subhi r1, r1, #0x00000a00 + addhi r1, r1, #0x01000000 + @ a3 + and r2, r1, #0x1f000000 + cmp r2, #0x09000000 + subhi r1, r1, #0x0a000000 + @ setcarry + orrhi r4, r4, #(1<<(24)) @ 0 + @ clearcarry + bicls r4, r4, #(1<<(24)) @ 0 + @ r1 = xxr3xxr1xxr2xxr0 + @ pack result + @ r2 = xxr3xxr1xxxxxxxx + and r2, r3, r1 + @ r1 = xxr2xxr0xxxxxxxx + and r1, r3, r1,lsl #16 + @ r1 = r3r2r1r0xxxxxxxx + orr r1, r1,r2,lsl #4 +@ only last bit + and r0,r0,#0x80000000 + @ (register.al ^ work8) + eors r2, r5, r0 + bicne r4, r4, #(64<<(24)) @ 6 @ 4 @ 0 : and mask 11111011111 : set v to zero + bne 1112f + @ (work8 ^ ans8) + eors r2, r1, r0 + tstne r2,#0x80000000 + biceq r4, r4, #(64<<(24)) @ 6 @ 4 @ 0 : and mask 11111011111 : set v to zero + orrne r4, r4, #(64<<(24)) @ 6 @ 4 @ 1 : or mask 00000100000 : set v to one +1112: + movs r5, r1 + update_zn + b 1113f +1111: + s9xgetwordlow + movs r1, r4, lsr #(24 +1) + subcs r0, r0, #0x10000 + adcs r5, r5,r0, ror #16 + @ overflow + orrvs r4, r4, #(64<<(24)) @ 6 @ 4 + bicvc r4, r4, #(64<<(24)) @ 6 @ 4 + mov r5, r5, lsr #16 + @ carry + update_c + @ clear lower parts + movs r5, r5, lsl #16 + @ update flag + update_zn +1113: +.endm + + +.macro and16 + s9xgetword + ands r5, r5, r0 + update_zn +.endm +.macro and8 + s9xgetbyte + ands r5, r5, r0 + update_zn +.endm +.macro a_asl8 + @ 7 instr + movs r5, r5, lsl #1 + update_c + update_zn + add1cycle +.endm +.macro a_asl16 + @ 7 instr + movs r5, r5, lsl #1 + update_c + update_zn + add1cycle +.endm +.macro asl16 + s9xgetwordregns r1 @ do not destroy opadress in r0 + movs r1, r1, lsl #1 + update_c + update_zn + s9xsetword r1 + add1cycle +.endm +.macro asl8 + s9xgetbyteregns r1 @ do not destroy opadress in r0 + movs r1, r1, lsl #1 + update_c + update_zn + s9xsetbyte r1 + add1cycle +.endm +.macro bit8 + s9xgetbyte + movs r1, r0, lsl #1 + @ trick in asm : shift one more bit : arm c = snes n + @ arm n = snes v + @ if carry set, then set neg in snes + biccc r4, r4, #(128<<(24))@ 7 @ 8 @ 0 : and mask 11111011111 : set c to zero + orrcs r4, r4, #(128<<(24))@ 7 @ 8 @ 1 : or mask 00000100000 : set c to one + @ if neg set, then set overflow in snes + bicpl r4, r4, #(64<<(24)) @ 6 @ 4 @ 0 : and mask 11111011111 : set n to zero + orrmi r4, r4, #(64<<(24)) @ 6 @ 4 @ 1 : or mask 00000100000 : set n to one + + @ now do a real and with a register + @ set zero flag, bit test + ands r1, r5, r0 + bicne r4, r4, #(2<<(24)) @ 1 @ 0 : and mask 11111011111 : set z to zero + orreq r4, r4, #(2<<(24)) @ 1 @ 1 : or mask 00000100000 : set z to one +.endm + +.macro bit16 + s9xgetword + movs r1, r0, lsl #1 + @ trick in asm : shift one more bit : arm c = snes n + @ arm n = snes v + @ if carry set, then set neg in snes + biccc r4, r4, #(128<<(24))@ 7 @ 8 @ 0 : and mask 11111011111 : set n to zero + orrcs r4, r4, #(128<<(24))@ 7 @ 8 @ 1 : or mask 00000100000 : set n to one + @ if neg set, then set overflow in snes + bicpl r4, r4, #(64<<(24)) @ 6 @ 4 @ 0 : and mask 11111011111 : set v to zero + orrmi r4, r4, #(64<<(24)) @ 6 @ 4 @ 1 : or mask 00000100000 : set v to one + @ now do a real and with a register + @ set zero flag, bit test + ands r1, r5, r0 + @ bit set ->z=0->xxxne clear flag + bicne r4, r4, #(2<<(24)) @ 1 @ 0 : and mask 11111011111 : set z to zero + @ bit clear->z=1->xxxeq set flag + orreq r4, r4, #(2<<(24)) @ 1 @ 1 : or mask 00000100000 : set z to one +.endm +.macro cmp8 + s9xgetbyte + subs r1,r5,r0 + biccc r4, r4, #(1<<(24)) @ 0 + orrcs r4, r4, #(1<<(24)) @ 0 + update_zn + +.endm +.macro cmp16 + s9xgetword + subs r1,r5,r0 + biccc r4, r4, #(1<<(24)) @ 0 + orrcs r4, r4, #(1<<(24)) @ 0 + update_zn + +.endm +.macro cmx16 + s9xgetword + subs r1,r7,r0 + biccc r4, r4, #(1<<(24)) @ 0 + orrcs r4, r4, #(1<<(24)) @ 0 + update_zn +.endm +.macro cmx8 + s9xgetbyte + subs r1,r7,r0 + biccc r4, r4, #(1<<(24)) @ 0 + orrcs r4, r4, #(1<<(24)) @ 0 + update_zn +.endm +.macro cmy16 + s9xgetword + subs r1,r9,r0 + biccc r4, r4, #(1<<(24)) @ 0 + orrcs r4, r4, #(1<<(24)) @ 0 + update_zn +.endm +.macro cmy8 + s9xgetbyte + subs r1,r9,r0 + biccc r4, r4, #(1<<(24)) @ 0 + orrcs r4, r4, #(1<<(24)) @ 0 + update_zn +.endm +.macro a_dec8 + mov r0,#0 + subs r5, r5, #0x01000000 + str r0,[r14,#40] + update_zn + add1cycle +.endm +.macro a_dec16 + mov r0,#0 + subs r5, r5, #0x00010000 + str r0,[r14,#40] + update_zn + add1cycle +.endm +.macro dec16 + s9xgetwordregns r1 @ do not destroy opadress in r0 + mov r2,#0 + subs r1, r1, #0x00010000 + str r2,[r14,#40] + update_zn + s9xsetword r1 + add1cycle +.endm +.macro dec8 + s9xgetbyteregns r1 @ do not destroy opadress in r0 + mov r2,#0 + subs r1, r1, #0x01000000 + str r2,[r14,#40] + update_zn + s9xsetbyte r1 + add1cycle +.endm +.macro eor16 + s9xgetword + eors r5, r5, r0 + update_zn +.endm +.macro eor8 + s9xgetbyte + eors r5, r5, r0 + update_zn +.endm +.macro a_inc8 + mov r2,#0 + adds r5, r5, #0x01000000 + str r2,[r14,#40] + update_zn + add1cycle +.endm +.macro a_inc16 + mov r2,#0 + adds r5, r5, #0x00010000 + str r2,[r14,#40] + update_zn + add1cycle +.endm +.macro inc16 + s9xgetwordregns r1 + mov r2,#0 + adds r1, r1, #0x00010000 + str r2,[r14,#40] + update_zn + s9xsetword r1 + add1cycle +.endm +.macro inc8 + s9xgetbyteregns r1 + mov r2,#0 + adds r1, r1, #0x01000000 + str r2,[r14,#40] + update_zn + s9xsetbyte r1 + add1cycle +.endm +.macro lda16 + s9xgetwordregstatus r5 + update_zn +.endm +.macro lda8 + s9xgetbyteregstatus r5 + update_zn +.endm +.macro ldx16 + s9xgetwordregstatus r7 + update_zn +.endm +.macro ldx8 + s9xgetbyteregstatus r7 + update_zn +.endm +.macro ldy16 + s9xgetwordregstatus r9 + update_zn +.endm +.macro ldy8 + s9xgetbyteregstatus r9 + update_zn +.endm +.macro a_lsr16 + bic r4, r4, #(128<<(24))@ 7 @ 8 @ 0 : and mask 11111011111 : set n to zero + movs r5, r5, lsr #17 @ hhhhhhhh llllllll 00000000 00000000 -> 00000000 00000000 0hhhhhhh hlllllll + @ update zero + bicne r4, r4, #(2<<(24)) @ 1 @ 0 : and mask 11111011111 : set z to zero + mov r5, r5, lsl #16 @ -> 0lllllll 00000000 00000000 00000000 + orreq r4, r4, #(2<<(24)) @ 1 @ 1 : or mask 00000100000 : set z to one + @ note : the two mov are included between instruction, to optimize + @ the pipeline. + update_c + add1cycle +.endm +.macro a_lsr8 + bic r4, r4, #(128<<(24))@ 7 @ 8 @ 0 : and mask 11111011111 : set n to zero + movs r5, r5, lsr #25 @ llllllll 00000000 00000000 00000000 -> 00000000 00000000 00000000 0lllllll + @ update zero + bicne r4, r4, #(2<<(24)) @ 1 @ 0 : and mask 11111011111 : set z to zero + mov r5, r5, lsl #24 @ -> 00000000 00000000 00000000 0lllllll + orreq r4, r4, #(2<<(24)) @ 1 @ 1 : or mask 00000100000 : set z to one + @ note : the two mov are included between instruction, to optimize + @ the pipeline. + update_c + add1cycle +.endm +.macro lsr16 + s9xgetwordregns r1 + @ n set to zero by >> 1 lsr + bic r4, r4, #(128<<(24))@ 7 @ 8 @ 0 : and mask 11111011111 : set n to zero + movs r1, r1, lsr #17 @ llllllll 00000000 00000000 00000000 -> 00000000 00000000 00000000 0lllllll + @ update carry + biccc r4, r4, #(1<<(24)) @ 0 @ 0 : and mask 11111011111 : set c to zero + orrcs r4, r4, #(1<<(24)) @ 0 @ 1 : or mask 00000100000 : set c to one + @ update zero + bicne r4, r4, #(2<<(24)) @ 1 @ 0 : and mask 11111011111 : set z to zero + orreq r4, r4, #(2<<(24)) @ 1 @ 1 : or mask 00000100000 : set z to one + s9xsetwordlow r1 + add1cycle +.endm +.macro lsr8 + s9xgetbyteregns r1 + @ n set to zero by >> 1 lsr + bic r4, r4, #(128<<(24))@ 7 @ 8 @ 0 : and mask 11111011111 : set n to zero + movs r1, r1, lsr #25 @ llllllll 00000000 00000000 00000000 -> 00000000 00000000 00000000 0lllllll + @ update carry + biccc r4, r4, #(1<<(24)) @ 0 @ 0 : and mask 11111011111 : set c to zero + orrcs r4, r4, #(1<<(24)) @ 0 @ 1 : or mask 00000100000 : set c to one + @ update zero + bicne r4, r4, #(2<<(24)) @ 1 @ 0 : and mask 11111011111 : set z to zero + orreq r4, r4, #(2<<(24)) @ 1 @ 1 : or mask 00000100000 : set z to one + s9xsetbytelow r1 + add1cycle +.endm +.macro ora8 + s9xgetbyte + orrs r5, r5, r0 + update_zn +.endm +.macro ora16 + s9xgetword + orrs r5, r5, r0 + update_zn +.endm +.macro a_rol16 + tst r4, #(1<<(24)) @ 0 + orrne r5, r5, #0x00008000 + movs r5, r5, lsl #1 + update_zn + update_c + add1cycle +.endm +.macro a_rol8 + tst r4, #(1<<(24)) @ 0 + orrne r5, r5, #0x00800000 + movs r5, r5, lsl #1 + update_zn + update_c + add1cycle +.endm +.macro rol16 + s9xgetwordregns r1 + tst r4, #(1<<(24)) @ 0 + orrne r1, r1, #0x00008000 + movs r1, r1, lsl #1 + update_zn + update_c + s9xsetword r1 + add1cycle +.endm +.macro rol8 + s9xgetbyteregns r1 + tst r4, #(1<<(24)) @ 0 + orrne r1, r1, #0x00800000 + movs r1, r1, lsl #1 + update_zn + update_c + s9xsetbyte r1 + add1cycle +.endm +.macro a_ror16 + mov r5,r5, lsr #16 + tst r4, #(1<<(24)) @ 0 + orrne r5, r5, #0x00010000 + orrne r4,r4,#(128<<(24))@ 7 @ 8 + biceq r4,r4,#(128<<(24))@ 7 @ 8 + movs r5,r5,lsr #1 + update_c + update_z + mov r5,r5, lsl #16 + add1cycle +.endm +.macro a_ror8 + mov r5,r5, lsr #24 + tst r4, #(1<<(24)) @ 0 + orrne r5, r5, #0x00000100 + orrne r4,r4,#(128<<(24))@ 7 @ 8 + biceq r4,r4,#(128<<(24))@ 7 @ 8 + movs r5,r5,lsr #1 + update_c + update_z + mov r5,r5, lsl #24 + add1cycle +.endm +.macro ror16 + s9xgetwordlowregns r1 + tst r4, #(1<<(24)) @ 0 + orrne r1, r1, #0x00010000 + orrne r4,r4,#(128<<(24))@ 7 @ 8 + biceq r4,r4,#(128<<(24))@ 7 @ 8 + movs r1,r1,lsr #1 + update_c + update_z + s9xsetwordlow r1 + add1cycle + +.endm +.macro ror8 + s9xgetbytelowregns r1 + tst r4, #(1<<(24)) @ 0 + orrne r1, r1, #0x00000100 + orrne r4,r4,#(128<<(24))@ 7 @ 8 + biceq r4,r4,#(128<<(24))@ 7 @ 8 + movs r1,r1,lsr #1 + update_c + update_z + s9xsetbytelow r1 + add1cycle +.endm + +.macro sbc16 + tst r4, #(8<<(24)) @ 3 + beq 1111f + @ todo + s9xgetword + + stmfd r13!,{r10} + mov r10,#0x000f0000 + @ r1 - result + @ r2 - scratch + @ r3 - scratch + @ r10 - pattern + + and r1, r0, #0x000f0000 + tst r4, #(1<<(24)) @ 0 + addeq r1, r1, #0x00010000 @ w1=w1+!carry + and r3, r5, #0x000f0000 + sub r1, r3,r1 @ r1=a1-w1-!carry + cmp r1, #0x00090000 @ if r1 > 9 + addhi r1, r1, #0x000a0000 @ then r1 += 10 + and r1, r1, #0x000f0000 + + and r2, r10, r0, lsr #4 + addhi r2, r2, #0x00010000 @ then (w2++) + + and r3, r10, r5, lsr #4 + sub r2, r3, r2 @ r2=a2-w2 + cmp r2, #0x00090000 @ if r2 > 9 + addhi r2, r2, #0x000a0000 @ then r2 += 10 + and r2, r2, #0x000f0000 + orr r1, r1, r2,lsl #4 + + and r2, r10, r0, lsr #8 + addhi r2, r2, #0x00010000 @ then (w3++) + + and r3, r10, r5, lsr #8 + sub r2, r3, r2 @ r3=a3-w3 + cmp r2, #0x00090000 @ if r3 > 9 + addhi r2, r2, #0x000a0000 @ then r3 += 10 + and r2, r2, #0x000f0000 + orr r1, r1, r2,lsl #8 + + and r2, r10, r0, lsr #12 + addhi r2, r2, #0x00010000 @ then (w3++) + + and r3, r10, r5, lsr #12 + sub r2, r3, r2 @ r4=a4-w4 + cmp r2, #0x00090000 @ if r4 > 9 + addhi r2, r2, #0x000a0000 @ then r4 += 10 + bichi r4, r4, #(1<<(24)) @ 0 @ then clearcarry + orrls r4, r4, #(1<<(24)) @ 0 @ else setcarry + + and r2,r2,#0x000f0000 + orr r1,r1,r2,lsl #12 + + ldmfd r13!,{r10} + @ only last bit + and r5,r5,#0x80000000 + @ (register.a.w ^ work8) + eors r2, r5, r0 + biceq r4, r4, #(64<<(24)) @ 6 @ 4 @ 0 : and mask 11111011111 : set v to zero + beq 1112f + @ (register.a.w ^ ans8) + eors r2, r5, r1 + @ & 0x80 + tstne r2,#0x80000000 + biceq r4, r4, #(64<<(24)) @ 6 @ 4 @ 0 : and mask 11111011111 : set v to zero + orrne r4, r4, #(64<<(24)) @ 6 @ 4 @ 1 : or mask 00000100000 : set v to one +1112: + movs r5, r1 + update_zn + b 1113f +1111: + s9xgetwordlow + movs r1,r4,lsr #(24 +1) + sbcs r5, r5, r0, lsl #16 + @ overflow + orrvs r4, r4, #(64<<(24)) @ 6 @ 4 + bicvc r4, r4, #(64<<(24)) @ 6 @ 4 + mov r5, r5, lsr #16 + @ carry + update_c + movs r5, r5, lsl #16 + @ update flag + update_zn +1113: +.endm + +.macro sbc8 + tst r4, #(8<<(24)) @ 3 + beq 1111f + s9xgetbyte + stmfd r13!,{r0} + mov r3,#0x0f000000 + @ r1=xxw1xxxxxxxxxxxx + and r1, r0, r3 + @ r0=xxw2xxxxxxxxxxxx + and r0, r3, r0, lsr #4 + @ r2=xxa2xxxxxxxxxxxx + and r2, r3, r5, lsr #4 + @ r3=xxa1xxxxxxxxxxxx + and r3,r5,r3 + @ r1=a1-w1-!carry + tst r4, #(1<<(24)) @ 0 + addeq r1, r1, #0x01000000 + sub r1,r3,r1 + @ if r1 > 9 + cmp r1, #0x09000000 + @ then r1 += 10 + addhi r1, r1, #0x0a000000 + @ then a2-- (w2++) + addhi r0, r0, #0x01000000 + @ r2=a2-w2 + sub r2, r2, r0 + @ if r2 > 9 + cmp r2, #0x09000000 + @ then r2 -= 10@ + addhi r2, r2, #0x0a000000 + @ then setcarry() + bichi r4, r4, #(1<<(24)) @ 0 @ 1 : or mask 00000100000 : set c to one + @ else clearcarry() + orrls r4, r4, #(1<<(24)) @ 0 @ 0 : and mask 11111011111 : set c to zero + @ gather r2 and r1 into ans8 + and r2,r2,#0x0f000000 + and r1,r1,#0x0f000000 + @ r2 : 0r2000000 + @ r1 : 0r1000000 + @ -> 0xr2r1000000 + orr r1, r1, r2, lsl #4 + ldmfd r13!,{r0} + @ only last bit + and r5,r5,#0x80000000 + @ (register.al ^ work8) + eors r2, r5, r0 + biceq r4, r4, #(64<<(24)) @ 6 @ 4 @ 0 : and mask 11111011111 : set v to zero + beq 1112f + @ (register.al ^ ans8) + eors r2, r5, r1 + @ & 0x80 + tstne r2,#0x80000000 + biceq r4, r4, #(64<<(24)) @ 6 @ 4 @ 0 : and mask 11111011111 : set v to zero + orrne r4, r4, #(64<<(24)) @ 6 @ 4 @ 1 : or mask 00000100000 : set v to one +1112: + movs r5, r1 + update_zn + b 1113f +1111: + s9xgetbytelow + movs r1,r4,lsr #(24 +1) + sbcs r5, r5, r0, lsl #24 + @ overflow + orrvs r4, r4, #(64<<(24)) @ 6 @ 4 + bicvc r4, r4, #(64<<(24)) @ 6 @ 4 + @ carry + update_c + @ update flag + ands r5, r5, #0xff000000 + update_zn +1113: +.endm + +.macro sta16 + s9xsetword r5 +.endm +.macro sta8 + s9xsetbyte r5 +.endm +.macro stx16 + s9xsetword r7 +.endm +.macro stx8 + s9xsetbyte r7 +.endm +.macro sty16 + s9xsetword r9 +.endm +.macro sty8 + s9xsetbyte r9 +.endm +.macro stz16 + s9xsetwordzero +.endm +.macro stz8 + s9xsetbytezero +.endm +.macro tsb16 + s9xgetwordregns r1 + tst r5, r1 + bicne r4, r4, #(2<<(24)) @ 1 @ 0 : and mask 11111011111 : set z to zero + orreq r4, r4, #(2<<(24)) @ 1 @ 1 : or mask 00000100000 : set z to one + orr r1, r5, r1 + s9xsetword r1 + add1cycle +.endm +.macro tsb8 + s9xgetbyteregns r1 + tst r5, r1 + bicne r4, r4, #(2<<(24)) @ 1 @ 0 : and mask 11111011111 : set z to zero + orreq r4, r4, #(2<<(24)) @ 1 @ 1 : or mask 00000100000 : set z to one + orr r1, r5, r1 + s9xsetbyte r1 + add1cycle +.endm +.macro trb16 + s9xgetwordregns r1 + tst r5, r1 + bicne r4, r4, #(2<<(24)) @ 1 @ 0 : and mask 11111011111 : set z to zero + orreq r4, r4, #(2<<(24)) @ 1 @ 1 : or mask 00000100000 : set z to one + mvn r2, r5 + and r1, r2, r1 + s9xsetword r1 + add1cycle +.endm +.macro trb8 + s9xgetbyteregns r1 + tst r5, r1 + bicne r4, r4, #(2<<(24)) @ 1 @ 0 : and mask 11111011111 : set z to zero + orreq r4, r4, #(2<<(24)) @ 1 @ 1 : or mask 00000100000 : set z to one + mvn r2, r5 + and r1, r2, r1 + s9xsetbyte r1 + add1cycle +.endm + + + + + +.macro op09m0 + ldrb r1, [r10,#1] + ldrb r0, [r10], #2 + orr r1,r0,r1,lsl #8 + orrs r5,r5,r1,lsl #16 + update_zn + add2mem +.endm +.macro op09m1 + ldrb r0, [r10], #1 + orrs r5,r5,r0,lsl #24 + update_zn + add1mem +.endm + +.macro op90 + asmrelative + branchcheck0 + tst r4, #(1<<(24)) @ 0 + bne 1111f + add r10, r0, r12 @ r10 = opaddress +pcbase + add1cycle + cpushutdown +1111: +.endm +.macro opb0 + asmrelative + branchcheck0 + tst r4, #(1<<(24)) @ 0 + beq 1111f + add r10, r0, r12 @ r10 = opaddress +pcbase + add1cycle + cpushutdown +1111: +.endm +.macro opf0 + asmrelative + branchcheck2 + tst r4, #(2<<(24)) @ 1 + beq 1111f + add r10, r0, r12 @ r10 = opaddress +pcbase + add1cycle + cpushutdown +1111: +.endm +.macro opd0 + asmrelative + branchcheck1 + tst r4, #(2<<(24)) @ 1 + bne 1111f + add r10, r0, r12 @ r10 = opaddress +pcbase + add1cycle + cpushutdown +1111: +.endm +.macro op30 + asmrelative + branchcheck0 + tst r4, #(128<<(24))@ 7 @ 8 + beq 1111f + add r10, r0, r12 @ r10 = opaddress +pcbase + add1cycle + cpushutdown +1111: +.endm +.macro op10 + asmrelative + branchcheck1 + tst r4, #(128<<(24))@ 7 @ 8 @ neg, z!=0, ne + bne 1111f + add r10, r0, r12 @ r10 = opaddress + pcbase + add1cycle + cpushutdown +1111: +.endm +.macro op50 + asmrelative + branchcheck0 + tst r4, #(64<<(24)) @ 6 @ 4 @ neg, z!=0, ne + bne 1111f + add r10, r0, r12 @ r10 = opaddress + pcbase + add1cycle + cpushutdown +1111: +.endm +.macro op70 + asmrelative + branchcheck0 + tst r4, #(64<<(24)) @ 6 @ 4 @ neg, z!=0, ne + beq 1111f + add r10, r0, r12 @ r10 = opaddress + pcbase + add1cycle + cpushutdown +1111: +.endm +.macro op80 + asmrelative + add r10, r0, r12 @ r10 = opaddress + pcbase + add1cycle + cpushutdown +1111: +.endm + + + +.macro op38 + orr r4, r4, #(1<<(24)) @ 0 @ 1 : or mask 00000100000 : set c to one + add1cycle +.endm +.macro opf8 + setdecimal + add1cycle +.endm +.macro op78 + setirq + add1cycle +.endm + + + + +.macro op18 + bic r4, r4, #(1<<(24)) @ 0 + add1cycle +.endm +.macro opd8 + cleardecimal + add1cycle +.endm +.macro op58 + clearirq + add1cycle + @ check_for_irq +.endm +.macro opb8 + bic r4, r4, #(64<<(24)) @ 6 @ 4 + add1cycle +.endm + + + + +.macro opcax1 + mov r2,#0 + subs r7, r7, #0x01000000 + str r2,[r14,#40] + update_zn + add1cycle +.endm +.macro opcax0 + mov r2,#0 + subs r7, r7, #0x00010000 + str r2,[r14,#40] + update_zn + add1cycle +.endm +.macro op88x1 + mov r2,#0 + subs r9, r9, #0x01000000 + str r2,[r14,#40] + update_zn + add1cycle +.endm +.macro op88x0 + mov r2,#0 + subs r9, r9, #0x00010000 + str r2,[r14,#40] + update_zn + add1cycle +.endm + + + +.macro ope8x1 + mov r2,#0 + adds r7, r7, #0x01000000 + str r2,[r14,#40] + update_zn + add1cycle +.endm +.macro ope8x0 + mov r2,#0 + adds r7, r7, #0x00010000 + str r2,[r14,#40] + update_zn + add1cycle +.endm +.macro opc8x1 + mov r2,#0 + adds r9, r9, #0x01000000 + str r2,[r14,#40] + update_zn + add1cycle +.endm +.macro opc8x0 + mov r2,#0 + adds r9, r9, #0x00010000 + str r2,[r14,#40] + update_zn + add1cycle +.endm + + + + +.macro opea + add1cycle +.endm + + + +.macro opf4 + absolute + pushwrlow +.endm +.macro opd4 + directindirect + pushwrlow +.endm +.macro op62 + asmrelativelong + pushwrlow +.endm +.macro op48m0 + pushw r5 + add1cycle +.endm +.macro op48m1 + pushb r5 + add1cycle +.endm +.macro op8b + and r1, r4, #0xff + pushblow r1 + add1cycle +.endm +.macro op0b + pushw r6 + add1cycle +.endm +.macro op4b + pushblow r6 + add1cycle +.endm +.macro op08 + pushb r4 + add1cycle +.endm +.macro opdax1 + pushb r7 + add1cycle +.endm +.macro opdax0 + pushw r7 + add1cycle +.endm +.macro op5ax1 + pushb r9 + add1cycle +.endm +.macro op5ax0 + pushw r9 + add1cycle +.endm + + +.macro op68m1 + pullbs r5 + update_zn + add2cycle +.endm +.macro op68m0 + pullws r5 + update_zn + add2cycle +.endm +.macro opab + bic r4,r4, #0xff + pullbrs + orr r4,r4,r0, lsr #24 + update_zn + add2cycle +.endm +.macro op2b + bic r6,r6, #0xff000000 + bic r6,r6, #0x00ff0000 + pullwrs + orr r6,r0,r6 + update_zn + add2cycle +.endm +.macro op28x1m1 + @ index set, memory set + bic r4,r4,#0xff000000 + pullbr + orr r4,r0,r4 + tst r4, #(16<<(24)) @ 4 @ 1 + @ index clear & was set : 8->16 + moveq r7,r7,lsr #8 + moveq r9,r9,lsr #8 + tst r4, #(32<<(24)) @ 5 @ 2 + @ memory cleared & was set : 8->16 + ldreqb r0,[r14,#13] + moveq r5,r5,lsr #8 + orreq r5,r5,r0, lsl #24 + s9xfixcycles + add2cycle +.endm +.macro op28x0m1 + @ index cleared, memory set + bic r4,r4,#0xff000000 + pullbr + orr r4,r0,r4 + tst r4, #(16<<(24)) @ 4 @ 1 + @ index set & was cleared : 16->8 + movne r7,r7,lsl #8 + movne r9,r9,lsl #8 + tst r4, #(32<<(24)) @ 5 @ 2 + @ memory cleared & was set : 8->16 + ldreqb r0,[r14,#13] + moveq r5,r5,lsr #8 + orreq r5,r5,r0, lsl #24 + s9xfixcycles + add2cycle +.endm +.macro op28x1m0 + @ index set, memory set + bic r4,r4,#0xff000000 + pullbr + orr r4,r0,r4 + tst r4, #(16<<(24)) @ 4 @ 1 + @ index clear & was set : 8->16 + moveq r7,r7,lsr #8 + moveq r9,r9,lsr #8 + tst r4, #(32<<(24)) @ 5 @ 2 + @ memory set & was cleared : 16->8 + movne r0,r5,lsr #24 + movne r5,r5,lsl #8 + strneb r0,[r14,#13] + s9xfixcycles + add2cycle +.endm +.macro op28x0m0 + @ index set, memory set + bic r4,r4,#0xff000000 + pullbr + orr r4,r0,r4 + tst r4, #(16<<(24)) @ 4 @ 1 + @ index set & was cleared : 16->8 + movne r7,r7,lsl #8 + movne r9,r9,lsl #8 + tst r4, #(32<<(24)) @ 5 @ 2 + @ memory set & was cleared : 16->8 + movne r0,r5,lsr #24 + movne r5,r5,lsl #8 + strneb r0,[r14,#13] + s9xfixcycles + add2cycle +.endm +.macro opfax1 + pullbs r7 + update_zn + add2cycle +.endm +.macro opfax0 + pullws r7 + update_zn + add2cycle +.endm +.macro op7ax1 + pullbs r9 + update_zn + add2cycle +.endm +.macro op7ax0 + pullws r9 + update_zn + add2cycle +.endm + + + +.macro opaax1m1 + movs r7, r5 + update_zn + add1cycle +.endm +.macro opaax0m1 + ldrb r7, [r14,#13] + mov r7, r7,lsl #24 + orrs r7, r7,r5, lsr #8 + update_zn + add1cycle +.endm +.macro opaax1m0 + movs r7, r5, lsl #8 + update_zn + add1cycle +.endm +.macro opaax0m0 + movs r7, r5 + update_zn + add1cycle +.endm +.macro opa8x1m1 + movs r9, r5 + update_zn + add1cycle +.endm +.macro opa8x0m1 + ldrb r9, [r14,#13] + mov r9, r9,lsl #24 + orrs r9, r9,r5, lsr #8 + update_zn + add1cycle +.endm +.macro opa8x1m0 + movs r9, r5, lsl #8 + update_zn + add1cycle +.endm +.macro opa8x0m0 + movs r9, r5 + update_zn + add1cycle +.endm +.macro op5bm1 + ldrb r0, [r14,#13] + mov r6,r6,lsl #16 + mov r0,r0,lsl #24 + orrs r0,r0,r5, lsr #8 + update_zn + orr r6,r0,r6,lsr #16 + add1cycle +.endm +.macro op5bm0 + mov r6,r6,lsl #16 + movs r5,r5 + update_zn + orr r6,r5,r6,lsr #16 + add1cycle +.endm +.macro op1bm1 + tst r4, #(1<<(24 -1)) + movne r8, r5, lsr #24 + orrne r8, r8, #0x100 + ldreqb r8, [r14,#13] + orreq r8, r8, r5 + moveq r8, r8, ror #24 + add1cycle +.endm +.macro op1bm0 + mov r8, r5, lsr #16 + add1cycle +.endm +.macro op7bm1 + movs r5, r6, asr #16 + update_zn + mov r0,r5,lsr #8 + mov r5,r5, lsl #24 + strb r0, [r14,#13] + add1cycle +.endm +.macro op7bm0 + movs r5, r6, asr #16 + update_zn + mov r5,r5, lsl #16 + add1cycle +.endm +.macro op3bm1 + mov r0,r8, lsr #8 + movs r5, r8, lsl #16 + strb r0, [r14,#13] + update_zn + mov r5,r5, lsl #8 + add1cycle +.endm +.macro op3bm0 + movs r5, r8, lsl #16 + update_zn + add1cycle +.endm +.macro opbax1 + movs r7, r8, lsl #24 + update_zn + add1cycle +.endm +.macro opbax0 + movs r7, r8, lsl #16 + update_zn + add1cycle +.endm +.macro op8am1x1 + movs r5, r7 + update_zn + add1cycle +.endm +.macro op8am1x0 + movs r5, r7, lsl #8 + update_zn + add1cycle +.endm +.macro op8am0x1 + movs r5, r7, lsr #8 + update_zn + add1cycle +.endm +.macro op8am0x0 + movs r5, r7 + update_zn + add1cycle +.endm +.macro op9ax1 + mov r8, r7, lsr #24 + tst r4, #(1<<(24 -1)) + orrne r8, r8, #0x100 + add1cycle +.endm +.macro op9ax0 + mov r8, r7, lsr #16 + add1cycle +.endm +.macro op9bx1 + movs r9, r7 + update_zn + add1cycle +.endm +.macro op9bx0 + movs r9, r7 + update_zn + add1cycle +.endm +.macro op98m1x1 + movs r5, r9 + update_zn + add1cycle +.endm +.macro op98m1x0 + movs r5, r9, lsl #8 + update_zn + add1cycle +.endm +.macro op98m0x1 + movs r5, r9, lsr #8 + update_zn + add1cycle +.endm +.macro op98m0x0 + movs r5, r9 + update_zn + add1cycle +.endm +.macro opbbx1 + movs r7, r9 + update_zn + add1cycle +.endm +.macro opbbx0 + movs r7, r9 + update_zn + add1cycle +.endm + + + + +.macro opfb + tst r4,#(1<<(24)) @ 0 + beq 1111f + @ carry is set + tst r4,#(1<<(24 -1)) + bne 1112f + @ emul is cleared + bic r4,r4,#(1<<(24)) @ 0 + tst r4,#(16<<(24)) @ 4 @ 1 + @ x & y were 16bits before + moveq r7,r7,lsl #8 + moveq r9,r9,lsl #8 + tst r4,#(32<<(24)) @ 5 @ 2 + @ a was 16bits before + @ save ah + moveq r0,r5,lsr #24 + streqb r0,[r14,#13] + moveq r5,r5,lsl #8 + orr r4,r4,#813694976 + and r8,r8,#0xff + orr r8,r8,#0x100 + b 1113f +1112: + @ emul is set + tst r4,#(16<<(24)) @ 4 @ 1 + @ x & y were 16bits before + moveq r7,r7,lsl #8 + moveq r9,r9,lsl #8 + tst r4,#(32<<(24)) @ 5 @ 2 + @ a was 16bits before + @ save ah + moveq r0,r5,lsr #24 + streqb r0,[r14,#13] + moveq r5,r5,lsl #8 + orr r4,r4,#822083584 + and r8,r8,#0xff + orr r8,r8,#0x100 + b 1113f +1111: + @ carry is cleared + tst r4,#(1<<(24 -1)) + beq 1115f + @ emul was set : x,y & a were 8bits + @ now have to check memory & index for potential conversions to 16bits + tst r4,#(16<<(24)) @ 4 @ 1 + @ x & y are now 16bits + moveq r7,r7,lsr #8 + moveq r9,r9,lsr #8 + tst r4,#(32<<(24)) @ 5 @ 2 + @ a is now 16bits + moveq r5,r5,lsr #8 + @ restore ah + ldreqb r0,[r14,#13] + orreq r5,r5,r0,lsl #24 +1115: + bic r4,r4,#(1<<(24 -1)) + orr r4,r4,#(1<<(24)) @ 0 +1113: + add1cycle + s9xfixcycles +.endm + + + +.macro op00 + mov r0,#1 + strb r0,[r14,#87] + + tst r4, #(1<<(24 -1)) + @ eq is flag to zero (!checkemu) + bne 2001f@ elseop00 + pushblow r6 + sub r0, r10, r12 + add r1, r0, #1 + pushwlow r1 + @ packstatus + pushb r4 + cleardecimal + setirq + bic r6, r6, #0xff + mov r0, #0xe6 + orr r0, r0, #0xff00 + s9xgetwordlow + s9xsetpcbase + add2cycle + b 2002f@ endop00 +2001:@ elseop00 + sub r1, r10, r12 + pushwlow r1 + @ packstatus + pushb r4 + cleardecimal + setirq + bic r6,r6, #0xff + mov r0, #0xfe + orr r0, r0, #0xff00 + s9xgetwordlow + s9xsetpcbase + add1cycle +2002:@ endop00 +.endm + + + + +.macro op82 + asmrelativelong + orr r0, r0, r6, lsl #16 + s9xsetpcbase +.endm + + +@ void s9xopcode_irq (void) +.macro s9xopcode_irq @ irq + tst r4, #(1<<(24 -1)) + @ eq is flag to zero (!checkemu) + bne 2121f@ elseop02 + pushblow r6 + sub r1, r10, r12 + pushwlow r1 + @ packstatus + pushb r4 + cleardecimal + setirq + bic r6, r6,#0xff + mov r0, #0xee + orr r0, r0, #0xff00 + s9xgetwordlow + s9xsetpcbase + add2cycle + b 2122f +2121:@ else + sub r1, r10, r12 + pushwlow r1 + @ packstatus + pushb r4 + cleardecimal + setirq + bic r6,r6, #0xff + mov r0, #0xfe + orr r0, r0, #0xff00 + s9xgetwordlow + s9xsetpcbase + add1cycle +2122: +.endm +# 3564 "os9x_65c816.S" +@ void s9xopcode_nmi (void) +.macro s9xopcode_nmi @ nmi + tst r4, #(1<<(24 -1)) + @ eq is flag to zero (!checkemu) + bne 2123f@ elseop02 + pushblow r6 + sub r1, r10, r12 + pushwlow r1 + @ packstatus + pushb r4 + cleardecimal + setirq + bic r6, r6,#0xff + mov r0, #0xea + orr r0, r0, #0xff00 + s9xgetwordlow + s9xsetpcbase + add2cycle + b 2124f +2123:@ else + sub r1, r10, r12 + pushwlow r1 + @ packstatus + pushb r4 + cleardecimal + setirq + bic r6,r6, #0xff + mov r0, #0xfa + orr r0, r0, #0xff00 + s9xgetwordlow + s9xsetpcbase + add1cycle +2124: +.endm +# 3629 "os9x_65c816.S" +.macro op02 + tst r4, #(1<<(24 -1)) + @ eq is flag to zero (!checkemu) + bne 2021f@ elseop02 + pushblow r6 + sub r0, r10, r12 + add r1, r0, #1 + pushwlow r1 + @ packstatus + pushb r4 + cleardecimal + setirq + bic r6, r6,#0xff + mov r0, #0xe4 + orr r0, r0, #0xff00 + s9xgetwordlow + s9xsetpcbase + add2cycle + b 2022f@ endop02 +2021:@ elseop02 + sub r1, r10, r12 + pushwlow r1 + @ packstatus + pushb r4 + cleardecimal + setirq + bic r6,r6, #0xff + mov r0, #0xf4 + orr r0, r0, #0xff00 + s9xgetwordlow + s9xsetpcbase + add1cycle +2022:@ endop02 +.endm + + + +.macro opdc + absoluteindirectlong + bic r6,r6,#0xff + orr r6,r6, r0, lsr #16 + s9xsetpcbase + add2cycle +.endm +.macro op5c + absolutelong + bic r6,r6,#0xff + orr r6,r6, r0, lsr #16 + s9xsetpcbase +.endm + + + +.macro op4c + absolute + bic r0, r0, #0xff0000 + orr r0, r0, r6, lsl #16 + s9xsetpcbase + cpushutdown +.endm +.macro op6c + absoluteindirect + bic r0, r0, #0xff0000 + orr r0, r0, r6, lsl #16 + s9xsetpcbase +.endm +.macro op7c + add r0, r0, r6, lsl #16 + s9xsetpcbase + add1cycle +.endm + + + +.macro op22 + pushblow r6 + sub r0, r10, r12 + @ sub r1, r1, #1 + add r1, r0, #2 + pushwlow r1 + absolutelong + bic r6,r6,#0xff + orr r6, r6, r0, lsr #16 + s9xsetpcbase +.endm +.macro op6b + pullwlow r10 + bic r6,r6,#0xff + pullbrlow + orr r6, r6, r0 + add r0, r10, #1 + bic r0, r0,#0xff0000 + orr r0, r0, r6, lsl #16 + s9xsetpcbase + add2cycle +.endm + + +.macro op20 + sub r0, r10, r12 + @ sub r1, r1, #1 + add r1, r0, #1 + pushwlow r1 + absolute + bic r0, r0, #0xff0000 + orr r0, r0, r6, lsl #16 + s9xsetpcbase + add1cycle +.endm +.macro opfcx0 + sub r0, r10, r12 + @ sub r1, r1, #1 + add r1, r0, #1 + pushwlow r1 + absoluteindexedindirectx0 + orr r0, r0, r6, lsl #16 + s9xsetpcbase + add1cycle +.endm +.macro opfcx1 + sub r0, r10, r12 + @ sub r1, r1, #1 + add r1, r0, #1 + pushwlow r1 + absoluteindexedindirectx1 + orr r0, r0, r6, lsl #16 + s9xsetpcbase + add1cycle +.endm +.macro op60 + pullwlow r10 + add r0, r10, #1 + bic r0, r0,#0x10000 + orr r0, r0, r6, lsl #16 + s9xsetpcbase + add3cycle +.endm + + + +.macro op54x1m1 + @ save regstatus = r4 >> 24 + mov r0, r4, lsr #16 + ldrb r4 , [r10], #1 + ldrb r1 , [r10], #1 + @ restore regstatus = r4 >> 24 + orr r4, r4, r0, lsl #16 + mov r0 , r7, lsr #24 + orr r0 , r0, r1, lsl #16 + s9xgetbytelow + mov r1, r0 + mov r0 , r9, lsr #24 + orr r0 , r0, r4, lsl #16 + s9xsetbytelow r1 + @ load 16bits a + ldrb r0,[r14,#13] + mov r5,r5,lsr #8 + orr r5,r5,r0, lsl #24 + add r7, r7, #0x01000000 + sub r5, r5, #0x00010000 + add r9, r9, #0x01000000 + cmp r5, #0xffff0000 + subne r10, r10, #3 + @ update ah + mov r0, r5, lsr #24 + mov r5,r5,lsl #8 + strb r0,[r14,#13] + add2cycle2mem +.endm +.macro op54x1m0 + @ save regstatus = r4 >> 24 + mov r0, r4, lsr #16 + ldrb r4 , [r10], #1 + ldrb r1 , [r10], #1 + @ restore regstatus = r4 >> 24 + orr r4, r4, r0, lsl #16 + mov r0 , r7, lsr #24 + orr r0 , r0, r1, lsl #16 + s9xgetbytelow + mov r1, r0 + mov r0 , r9, lsr #24 + orr r0 , r0, r4, lsl #16 + s9xsetbytelow r1 + add r7, r7, #0x01000000 + sub r5, r5, #0x00010000 + add r9, r9, #0x01000000 + cmp r5, #0xffff0000 + subne r10, r10, #3 + add2cycle2mem +.endm +.macro op54x0m1 + @ save regstatus = r4 >> 24 + mov r0, r4, lsr #16 + ldrb r4 , [r10], #1 + ldrb r1 , [r10], #1 + @ restore regstatus = r4 >> 24 + orr r4, r4, r0, lsl #16 + mov r0 , r7, lsr #16 + orr r0 , r0, r1, lsl #16 + s9xgetbytelow + mov r1, r0 + mov r0 , r9, lsr #16 + orr r0 , r0, r4, lsl #16 + s9xsetbytelow r1 + @ load 16bits a + ldrb r0,[r14,#13] + mov r5,r5,lsr #8 + orr r5,r5,r0, lsl #24 + add r7, r7, #0x00010000 + sub r5, r5, #0x00010000 + add r9, r9, #0x00010000 + cmp r5, #0xffff0000 + subne r10, r10, #3 + @ update ah + mov r0, r5, lsr #24 + mov r5,r5,lsl #8 + strb r0,[r14,#13] + add2cycle2mem +.endm +.macro op54x0m0 + @ save regstatus = r4 >> 24 + mov r0, r4, lsr #16 + ldrb r4 , [r10], #1 + ldrb r1 , [r10], #1 + @ restore regstatus = r4 >> 24 + orr r4, r4, r0, lsl #16 + mov r0 , r7, lsr #16 + orr r0 , r0, r1, lsl #16 + s9xgetbytelow + mov r1, r0 + mov r0 , r9, lsr #16 + orr r0 , r0, r4, lsl #16 + s9xsetbytelow r1 + add r7, r7, #0x00010000 + sub r5, r5, #0x00010000 + add r9, r9, #0x00010000 + cmp r5, #0xffff0000 + subne r10, r10, #3 + add2cycle2mem +.endm + +.macro op44x1m1 + @ save regstatus = r4 >> 24 + mov r0, r4, lsr #16 + ldrb r4 , [r10], #1 + ldrb r1 , [r10], #1 + @ restore regstatus = r4 >> 24 + orr r4, r4, r0, lsl #16 + mov r0 , r7, lsr #24 + orr r0 , r0, r1, lsl #16 + s9xgetbytelow + mov r1, r0 + mov r0 , r9, lsr #24 + orr r0 , r0, r4, lsl #16 + s9xsetbytelow r1 + @ load 16bits a + ldrb r0,[r14,#13] + mov r5,r5,lsr #8 + orr r5,r5,r0, lsl #24 + sub r7, r7, #0x01000000 + sub r5, r5, #0x00010000 + sub r9, r9, #0x01000000 + cmp r5, #0xffff0000 + subne r10, r10, #3 + @ update ah + mov r0, r5, lsr #24 + mov r5,r5,lsl #8 + strb r0,[r14,#13] + add2cycle2mem +.endm +.macro op44x1m0 + @ save regstatus = r4 >> 24 + mov r0, r4, lsr #16 + ldrb r4 , [r10], #1 + ldrb r1 , [r10], #1 + @ restore regstatus = r4 >> 24 + orr r4, r4, r0, lsl #16 + mov r0 , r7, lsr #24 + orr r0 , r0, r1, lsl #16 + s9xgetbytelow + mov r1, r0 + mov r0 , r9, lsr #24 + orr r0 , r0, r4, lsl #16 + s9xsetbytelow r1 + sub r7, r7, #0x01000000 + sub r5, r5, #0x00010000 + sub r9, r9, #0x01000000 + cmp r5, #0xffff0000 + subne r10, r10, #3 + add2cycle2mem +.endm +.macro op44x0m1 + @ save regstatus = r4 >> 24 + mov r0, r4, lsr #16 + ldrb r4 , [r10], #1 + ldrb r1 , [r10], #1 + @ restore regstatus = r4 >> 24 + orr r4, r4, r0, lsl #16 + mov r0 , r7, lsr #16 + orr r0 , r0, r1, lsl #16 + s9xgetbytelow + mov r1, r0 + mov r0 , r9, lsr #16 + orr r0 , r0, r4, lsl #16 + s9xsetbytelow r1 + @ load 16bits a + ldrb r0,[r14,#13] + mov r5,r5,lsr #8 + orr r5,r5,r0, lsl #24 + sub r7, r7, #0x00010000 + sub r5, r5, #0x00010000 + sub r9, r9, #0x00010000 + cmp r5, #0xffff0000 + subne r10, r10, #3 + @ update ah + mov r0, r5, lsr #24 + mov r5,r5,lsl #8 + strb r0,[r14,#13] + add2cycle2mem +.endm +.macro op44x0m0 + @ save regstatus = r4 >> 24 + mov r0, r4, lsr #16 + ldrb r4 , [r10], #1 + ldrb r1 , [r10], #1 + @ restore regstatus = r4 >> 24 + orr r4, r4, r0, lsl #16 + mov r0 , r7, lsr #16 + orr r0 , r0, r1, lsl #16 + s9xgetbytelow + mov r1, r0 + mov r0 , r9, lsr #16 + orr r0 , r0, r4, lsl #16 + s9xsetbytelow r1 + sub r7, r7, #0x00010000 + sub r5, r5, #0x00010000 + sub r9, r9, #0x00010000 + cmp r5, #0xffff0000 + subne r10, r10, #3 + add2cycle2mem +.endm + + + +.macro opc2 + @ status&=~(*r10++); + @ so possible changes are : + @ index = 1 -> 0 : x,y 8bits -> 16bits + @ mem = 1 -> 0 : a 8bits -> 16bits + @ save old status for (16<<(24)) @ 4 @ 1 & (32<<(24)) @ 5 @ 2 comparison + mov r2, r4 + ldrb r0, [r10], #1 + mvn r0, r0 + and r4,r4,r0, ror #8 @ 32 - 24 + tst r4,#(1<<(24 -1)) + beq 1111f + @ emulation mode on : no changes since it was on before opcode + @ just be sure to reset mem & index accordingly + orr r4,r4,#805306368 + b 1112f +1111: + @ not in emulation mode, check index & memory bits + @ now check index + tst r2,#(16<<(24)) @ 4 @ 1 + beq 1113f + @ x & y were 8bit before + tst r4,#(16<<(24)) @ 4 @ 1 + bne 1113f + @ x & y are now 16bits + mov r7,r7,lsr #8 + mov r9,r9,lsr #8 +1113: @ x & y still in 16bits + @ now check memory + tst r2,#(32<<(24)) @ 5 @ 2 + beq 1112f + @ a was 8bit before + tst r4,#(32<<(24)) @ 5 @ 2 + bne 1112f + @ a is now 16bits + mov r5,r5,lsr #8 + @ restore ah + ldreqb r0,[r14,#13] + orreq r5,r5,r0,lsl #24 +1112: + s9xfixcycles + add1cycle1mem +.endm +.macro ope2 + @ status|=*r10++; + @ so possible changes are : + @ index = 0 -> 1 : x,y 16bits -> 8bits + @ mem = 0 -> 1 : a 16bits -> 8bits + @ save old status for (16<<(24)) @ 4 @ 1 & (32<<(24)) @ 5 @ 2 comparison + mov r2, r4 + ldrb r0, [r10], #1 + orr r4,r4,r0, lsl #24 + tst r4,#(1<<(24 -1)) + beq 10111f + @ emulation mode on : no changes sinc eit was on before opcode + @ just be sure to have mem & index set accordingly + orr r4,r4,#805306368 + b 10112f +10111: + @ not in emulation mode, check index & memory bits + @ now check index + tst r2,#(16<<(24)) @ 4 @ 1 + bne 10113f + @ x & y were 16bit before + tst r4,#(16<<(24)) @ 4 @ 1 + beq 10113f + @ x & y are now 8bits + mov r7,r7,lsl #8 + mov r9,r9,lsl #8 +10113: @ x & y still in 16bits + @ now check memory + tst r2,#(32<<(24)) @ 5 @ 2 + bne 10112f + @ a was 16bit before + tst r4,#(32<<(24)) @ 5 @ 2 + beq 10112f + @ a is now 8bits + @ save ah + mov r0,r5,lsr #24 + mov r5,r5,lsl #8 + strb r0,[r14,#13] +10112: + s9xfixcycles + add1cycle1mem +.endm + + + +.macro opebm1 + @ a is 8bits + add r0,r14,#13 + mov r5,r5, lsr #24 + swpb r5,r5,[r0] + movs r5,r5, lsl #24 + update_zn + add2cycle +.endm +.macro opebm0 + @ a is 16bits + mov r0, r5, ror #24 @ ll0000hh + orr r0, r0, r5, lsr #8@ ll0000hh + 00hhll00 -> llhhllhh + mov r5, r0, lsl #16@ llhhllhh -> llhh0000 + movs r0,r0,lsl #24 @ to set z & n flags with al + update_zn + add2cycle +.endm + + + + +.macro op40x1m1 + @ index set, memory set + bic r4,r4,#0xff000000 + pullbr + orr r4,r0,r4 + pullwlow r10 + tst r4, #(1<<(24 -1)) + orrne r4, r4, #805306368 + bne 2401f + pullbrlow + bic r6,r6,#0xff + orr r6,r6,r0 +2401: + add r0, r10, r6, lsl #16 + s9xsetpcbase + tst r4, #(16<<(24)) @ 4 @ 1 + @ index cleared & was set : 8->16 + moveq r7,r7,lsr #8 + moveq r9,r9,lsr #8 + tst r4, #(32<<(24)) @ 5 @ 2 + @ memory cleared & was set : 8->16 + ldreqb r0,[r14,#13] + moveq r5,r5,lsr #8 + orreq r5,r5,r0, lsl #24 + add2cycle + s9xfixcycles +.endm +.macro op40x0m1 + @ index cleared, memory set + bic r4,r4,#0xff000000 + pullbr + orr r4,r0,r4 + pullwlow r10 + tst r4, #(1<<(24 -1)) + orrne r4, r4, #805306368 + bne 2401f + pullbrlow + bic r6,r6,#0xff + orr r6,r6,r0 +2401: + add r0, r10, r6, lsl #16 + s9xsetpcbase + tst r4, #(16<<(24)) @ 4 @ 1 + @ index set & was cleared : 16->8 + movne r7,r7,lsl #8 + movne r9,r9,lsl #8 + tst r4, #(32<<(24)) @ 5 @ 2 + @ memory cleared & was set : 8->16 + ldreqb r0,[r14,#13] + moveq r5,r5,lsr #8 + orreq r5,r5,r0, lsl #24 + add2cycle + s9xfixcycles +.endm +.macro op40x1m0 + @ index set, memory cleared + bic r4,r4,#0xff000000 + pullbr + orr r4,r0,r4 + pullwlow r10 + tst r4, #(1<<(24 -1)) + orrne r4, r4, #805306368 + bne 2401f + pullbrlow + bic r6,r6,#0xff + orr r6,r6,r0 +2401: + add r0, r10, r6, lsl #16 + s9xsetpcbase + tst r4, #(16<<(24)) @ 4 @ 1 + @ index cleared & was set : 8->16 + moveq r7,r7,lsr #8 + moveq r9,r9,lsr #8 + tst r4, #(32<<(24)) @ 5 @ 2 + @ memory set & was cleared : 16->8 + movne r0,r5,lsr #24 + movne r5,r5,lsl #8 + strneb r0,[r14,#13] + add2cycle + s9xfixcycles +.endm +.macro op40x0m0 + @ index cleared, memory cleared + bic r4,r4,#0xff000000 + pullbr + orr r4,r0,r4 + pullwlow r10 + tst r4, #(1<<(24 -1)) + orrne r4, r4, #805306368 + bne 2401f + pullbrlow + bic r6,r6,#0xff + orr r6,r6,r0 +2401: + add r0, r10, r6, lsl #16 + s9xsetpcbase + tst r4, #(16<<(24)) @ 4 @ 1 + @ index set & was cleared : 16->8 + movne r7,r7,lsl #8 + movne r9,r9,lsl #8 + tst r4, #(32<<(24)) @ 5 @ 2 + @ memory set & was cleared : 16->8 + @ memory set & was cleared : 16->8 + movne r0,r5,lsr #24 + movne r5,r5,lsl #8 + strneb r0,[r14,#13] + add2cycle + s9xfixcycles +.endm + + + + +@ wai +.macro opcb + ldrb r0,[r14,#6] + movs r0,r0 + @ (cpu.irqactive) + add2cyclene + bne 1234f + + + + mov r0,#1 + sub r10,r10,#1 + + + + strb r0,[r14,#7] + ldr r11,[r14,#48] +# 4224 "os9x_65c816.S" + ldrb r0,[r14,#122] + movs r0,r0 + beq 1234f + asmapu_execute2 + +1234: +.endm +.macro opdb + sub r10,r10,#1 + @ cpu.flags |= debug_mode_flag; +.endm +.macro op42 +.endm + + + +.macro op29m1 + ldrb r0 , [r10], #1 + ands r5 , r5, r0, lsl #24 + update_zn + add1mem +.endm +.macro op29m0 + ldrb r1 , [r10,#1] + ldrb r0 , [r10], #2 + orr r0, r0, r1, lsl #8 + ands r5 , r5, r0, lsl #16 + update_zn + add2mem +.endm +# 4271 "os9x_65c816.S" +.macro op49m0 + ldrb r1 , [r10, #1] + ldrb r0 , [r10], #2 + orr r0, r0, r1,lsl #8 + eors r5, r5, r0,lsl #16 + update_zn + add2mem +.endm + + +.macro op49m1 + ldrb r0 , [r10], #1 + eors r5, r5, r0,lsl #24 + update_zn + add1mem +.endm + + + + +.macro op81m1 + sta8 + @ tst r4, #(16<<(24)) @ 4 @ 1 + @ add1cyclene +.endm +.macro op81m0 + sta16 + @ tst r4, #(16<<(24)) @ 4 @ 1 + @ add1cyclene +.endm + + + + +.macro op89m1 + ldrb r0 , [r10], #1 + tst r5, r0, lsl #24 + update_z + add1mem +.endm +.macro op89m0 + ldrb r1 , [r10, #1] + ldrb r0 , [r10], #2 + orr r0, r0, r1, lsl #8 + tst r5, r0, lsl #16 + update_z + add2mem +.endm +# 4327 "os9x_65c816.S" +.macro opa0x1 + ldrb r0 , [r10], #1 + movs r9, r0, lsl #24 + update_zn + add1mem +.endm +.macro opa0x0 + ldrb r1 , [r10, #1] + ldrb r0 , [r10], #2 + orr r0, r0, r1, lsl #8 + movs r9, r0, lsl #16 + update_zn + add2mem +.endm + + + +.macro opa2x1 + ldrb r0 , [r10], #1 + movs r7, r0, lsl #24 + update_zn + add1mem +.endm +.macro opa2x0 + ldrb r1 , [r10, #1] + ldrb r0 , [r10], #2 + orr r0, r0, r1, lsl #8 + movs r7, r0, lsl #16 + update_zn + add2mem +.endm + + + +.macro opa9m1 + ldrb r0 , [r10], #1 + movs r5, r0, lsl #24 + update_zn + add1mem +.endm +.macro opa9m0 + ldrb r1 , [r10, #1] + ldrb r0 , [r10], #2 + orr r0, r0, r1, lsl #8 + movs r5, r0, lsl #16 + update_zn + add2mem +.endm + + + +.macro opc0x1 + ldrb r0 , [r10], #1 + subs r1 , r9 , r0, lsl #24 + biccc r4, r4, #(1<<(24)) @ 0 + orrcs r4, r4, #(1<<(24)) @ 0 + update_zn + add1mem +.endm +.macro opc0x0 + ldrb r1 , [r10, #1] + ldrb r0 , [r10], #2 + orr r0, r0, r1, lsl #8 + subs r1 , r9, r0, lsl #16 + biccc r4, r4, #(1<<(24)) @ 0 + orrcs r4, r4, #(1<<(24)) @ 0 + update_zn + add2mem +.endm + + + + + + + +.macro opc9m1 + ldrb r0 , [r10], #1 + subs r1 , r5 , r0, lsl #24 + biccc r4, r4, #(1<<(24)) @ 0 + orrcs r4, r4, #(1<<(24)) @ 0 + update_zn + add1mem +.endm +.macro opc9m0 + ldrb r1 , [r10,#1] + ldrb r0 , [r10], #2 + orr r0, r0, r1, lsl #8 + subs r1 , r5, r0, lsl #16 + biccc r4, r4, #(1<<(24)) @ 0 + orrcs r4, r4, #(1<<(24)) @ 0 + update_zn + add2mem +.endm + + + +.macro ope0x1 + ldrb r0 , [r10], #1 + subs r1 , r7 , r0, lsl #24 + biccc r4, r4, #(1<<(24)) @ 0 + orrcs r4, r4, #(1<<(24)) @ 0 + update_zn + add1mem +.endm +.macro ope0x0 + ldrb r1 , [r10,#1] + ldrb r0 , [r10], #2 + orr r0, r0, r1, lsl #8 + subs r1 , r7, r0, lsl #16 + biccc r4, r4, #(1<<(24)) @ 0 + orrcs r4, r4, #(1<<(24)) @ 0 + update_zn + add2mem +.endm +# 4477 "os9x_65c816.S" + .globl _test_opcode + .globl _asmMainLoop + +1: + .long jumptable1 +2: + .long jumptable2 +3: + .long jumptable3 +4: + .long jumptable4 + +@ void asmmainloop(asm_cpu_var_t *asmcpuptr); +_asmMainLoop: + @ save registers + stmfd r13!,{r4-r11,lr} + @ init pointer to cpuvar structure + mov r14,r0 + ldr r1, 1b + str r1, [r14,#136] + ldr r1, 2b + str r1, [r14,#140] + ldr r1, 3b + str r1, [r14,#144] + ldr r1, 4b + str r1, [r14,#148] + str r9,[r14,#128] + prepare_c_call + bl _test_print + restore_c_call + @ init registers + load_regs + @ get cpu mode from flag and init jump table + s9xfixcycles + +mainloop: + @ apu execute + asmapu_execute + + @ test flags + ldr r0,[r14,#0] + movs r0,r0 + bne cpuflags_set @ if flags => check for irq/nmi/scan_keys... + + exec_op @ execute next opcode + +cpuflags_set: @ check flags (!=0) + tst r0,#(1 << 7) @ check nmi + beq cpuflagsnmi_flag_cleared + ldr r1,[r14,#76] + subs r1,r1,#1 + str r1,[r14,#76] + bne cpuflagsnmi_flag_cleared + bic r0,r0,#(1 << 7) + str r0,[r14,#0] + ldrb r1,[r14,#7] + movs r1,r1 + beq notcpuaitingforinterruptnmi + mov r1,#0 + add r10,r10,#1 + strb r1,[r14,#7] +notcpuaitingforinterruptnmi: + s9xopcode_nmi + ldr r0,[r14,#0] +cpuflagsnmi_flag_cleared: + tst r0,#(1 << 11) @ check (1 << 11) + beq cpuflagsirq_pending_flag_cleared + ldr r1,[r14,#80] + movs r1,r1 + bne cpuirqcyclecount_notzero + ldrb r1,[r14,#7] + movs r1,r1 + beq notcpuaitingforinterruptirq + mov r1,#0 + add r10,r10,#1 + strb r1,[r14,#7] +notcpuaitingforinterruptirq: + ldrb r1,[r14,#6] + movs r1,r1 + beq cpuirqactive_cleared + tst r4,#(4<<(24)) @ 2 + bne cpuflagsirq_pending_flag_cleared + s9xopcode_irq + ldr r0,[r14,#0] + b cpuflagsirq_pending_flag_cleared +cpuirqactive_cleared: + bic r0,r0,#(1 << 11) + str r0,[r14,#0] + b cpuflagsirq_pending_flag_cleared +cpuirqcyclecount_notzero: + sub r1,r1,#1 + str r1,[r14,#80] +cpuflagsirq_pending_flag_cleared: + + tst r0,#(1 << 4) @ check (1 << 4) + bne endmainloop + + exec_op @ execute next opcode + +endmainloop: +# 4589 "os9x_65c816.S" + save_regs + ldmfd r13!,{r4-r11,lr} + mov pc,lr +@@.pool + +@ void test_opcode(struct asm_cpu_var *asm_var); +_test_opcode: + @ save registers + stmfd r13!,{r4-r11,lr} + @ init pointer to cpuvar structure + mov r14,r0 + @ init registers + load_regs + @ get cpu mode from flag and init jump table + s9xfixcycles + + exec_op +@@.pool + + + + + + +jumptable1: .long op00mod1 + .long op01m1mod1 + .long op02mod1 + .long op03m1mod1 + .long op04m1mod1 + .long op05m1mod1 + .long op06m1mod1 + .long op07m1mod1 + .long op08mod1 + .long op09m1mod1 + .long op0am1mod1 + .long op0bmod1 + .long op0cm1mod1 + .long op0dm1mod1 + .long op0em1mod1 + .long op0fm1mod1 + .long op10mod1 + .long op11m1mod1 + .long op12m1mod1 + .long op13m1mod1 + .long op14m1mod1 + .long op15m1mod1 + .long op16m1mod1 + .long op17m1mod1 + .long op18mod1 + .long op19m1mod1 + .long op1am1mod1 + .long op1bmod1 + .long op1cm1mod1 + .long op1dm1mod1 + .long op1em1mod1 + .long op1fm1mod1 + .long op20mod1 + .long op21m1mod1 + .long op22mod1 + .long op23m1mod1 + .long op24m1mod1 + .long op25m1mod1 + .long op26m1mod1 + .long op27m1mod1 + .long op28mod1 + .long op29m1mod1 + .long op2am1mod1 + .long op2bmod1 + .long op2cm1mod1 + .long op2dm1mod1 + .long op2em1mod1 + .long op2fm1mod1 + .long op30mod1 + .long op31m1mod1 + .long op32m1mod1 + .long op33m1mod1 + .long op34m1mod1 + .long op35m1mod1 + .long op36m1mod1 + .long op37m1mod1 + .long op38mod1 + .long op39m1mod1 + .long op3am1mod1 + .long op3bmod1 + .long op3cm1mod1 + .long op3dm1mod1 + .long op3em1mod1 + .long op3fm1mod1 + .long op40mod1 + .long op41m1mod1 + .long op42mod1 + .long op43m1mod1 + .long op44x1mod1 + .long op45m1mod1 + .long op46m1mod1 + .long op47m1mod1 + .long op48m1mod1 + .long op49m1mod1 + .long op4am1mod1 + .long op4bmod1 + .long op4cmod1 + .long op4dm1mod1 + .long op4em1mod1 + .long op4fm1mod1 + .long op50mod1 + .long op51m1mod1 + .long op52m1mod1 + .long op53m1mod1 + .long op54x1mod1 + .long op55m1mod1 + .long op56m1mod1 + .long op57m1mod1 + .long op58mod1 + .long op59m1mod1 + .long op5ax1mod1 + .long op5bmod1 + .long op5cmod1 + .long op5dm1mod1 + .long op5em1mod1 + .long op5fm1mod1 + .long op60mod1 + .long op61m1mod1 + .long op62mod1 + .long op63m1mod1 + .long op64m1mod1 + .long op65m1mod1 + .long op66m1mod1 + .long op67m1mod1 + .long op68m1mod1 + .long op69m1mod1 + .long op6am1mod1 + .long op6bmod1 + .long op6cmod1 + .long op6dm1mod1 + .long op6em1mod1 + .long op6fm1mod1 + .long op70mod1 + .long op71m1mod1 + .long op72m1mod1 + .long op73m1mod1 + .long op74m1mod1 + .long op75m1mod1 + .long op76m1mod1 + .long op77m1mod1 + .long op78mod1 + .long op79m1mod1 + .long op7ax1mod1 + .long op7bmod1 + .long op7cmod1 + .long op7dm1mod1 + .long op7em1mod1 + .long op7fm1mod1 + .long op80mod1 + .long op81m1mod1 + .long op82mod1 + .long op83m1mod1 + .long op84x1mod1 + .long op85m1mod1 + .long op86x1mod1 + .long op87m1mod1 + .long op88x1mod1 + .long op89m1mod1 + .long op8am1mod1 + .long op8bmod1 + .long op8cx1mod1 + .long op8dm1mod1 + .long op8ex1mod1 + .long op8fm1mod1 + .long op90mod1 + .long op91m1mod1 + .long op92m1mod1 + .long op93m1mod1 + .long op94x1mod1 + .long op95m1mod1 + .long op96x1mod1 + .long op97m1mod1 + .long op98m1mod1 + .long op99m1mod1 + .long op9amod1 + .long op9bx1mod1 + .long op9cm1mod1 + .long op9dm1mod1 + .long op9em1mod1 + .long op9fm1mod1 + .long opa0x1mod1 + .long opa1m1mod1 + .long opa2x1mod1 + .long opa3m1mod1 + .long opa4x1mod1 + .long opa5m1mod1 + .long opa6x1mod1 + .long opa7m1mod1 + .long opa8x1mod1 + .long opa9m1mod1 + .long opaax1mod1 + .long opabmod1 + .long opacx1mod1 + .long opadm1mod1 + .long opaex1mod1 + .long opafm1mod1 + .long opb0mod1 + .long opb1m1mod1 + .long opb2m1mod1 + .long opb3m1mod1 + .long opb4x1mod1 + .long opb5m1mod1 + .long opb6x1mod1 + .long opb7m1mod1 + .long opb8mod1 + .long opb9m1mod1 + .long opbax1mod1 + .long opbbx1mod1 + .long opbcx1mod1 + .long opbdm1mod1 + .long opbex1mod1 + .long opbfm1mod1 + .long opc0x1mod1 + .long opc1m1mod1 + .long opc2mod1 + .long opc3m1mod1 + .long opc4x1mod1 + .long opc5m1mod1 + .long opc6m1mod1 + .long opc7m1mod1 + .long opc8x1mod1 + .long opc9m1mod1 + .long opcax1mod1 + .long opcbmod1 + .long opccx1mod1 + .long opcdm1mod1 + .long opcem1mod1 + .long opcfm1mod1 + .long opd0mod1 + .long opd1m1mod1 + .long opd2m1mod1 + .long opd3m1mod1 + .long opd4mod1 + .long opd5m1mod1 + .long opd6m1mod1 + .long opd7m1mod1 + .long opd8mod1 + .long opd9m1mod1 + .long opdax1mod1 + .long opdbmod1 + .long opdcmod1 + .long opddm1mod1 + .long opdem1mod1 + .long opdfm1mod1 + .long ope0x1mod1 + .long ope1m1mod1 + .long ope2mod1 + .long ope3m1mod1 + .long ope4x1mod1 + .long ope5m1mod1 + .long ope6m1mod1 + .long ope7m1mod1 + .long ope8x1mod1 + .long ope9m1mod1 + .long opeamod1 + .long opebmod1 + .long opecx1mod1 + .long opedm1mod1 + .long opeem1mod1 + .long opefm1mod1 + .long opf0mod1 + .long opf1m1mod1 + .long opf2m1mod1 + .long opf3m1mod1 + .long opf4mod1 + .long opf5m1mod1 + .long opf6m1mod1 + .long opf7m1mod1 + .long opf8mod1 + .long opf9m1mod1 + .long opfax1mod1 + .long opfbmod1 + .long opfcmod1 + .long opfdm1mod1 + .long opfem1mod1 + .long opffm1mod1 + +op00mod1: testmod1 1 +lbl00mod1: testmod1 1 +op00 + nextopcode +op01m1mod1: testmod1 1 +lbl01mod1a: directindexedindirect1 +lbl01mod1b: ora8 + nextopcode +op02mod1: testmod1 1 +lbl02mod1: testmod1 1 +op02 + nextopcode +op03m1mod1: testmod1 1 +lbl03mod1a: stackasmrelative +lbl03mod1b: ora8 + nextopcode +op04m1mod1: testmod1 1 +lbl04mod1a: direct +lbl04mod1b: tsb8 + nextopcode +op05m1mod1: testmod1 1 +lbl05mod1a: direct +lbl05mod1b: ora8 + nextopcode +op06m1mod1: testmod1 1 +lbl06mod1a: direct +lbl06mod1b: asl8 + nextopcode +op07m1mod1: testmod1 1 +lbl07mod1a: directindirectlong +lbl07mod1b: ora8 + nextopcode +op08mod1: testmod1 1 +lbl08mod1: testmod1 1 + op08 + nextopcode +op09m1mod1: testmod1 1 +lbl09mod1: testmod1 1 + op09m1 + nextopcode +op0am1mod1: testmod1 2 +lbl0amod1a: a_asl8 + nextopcode +op0bmod1: testmod1 2 +lbl0bmod1: testmod1 2 +op0b + nextopcode +op0cm1mod1: testmod1 2 +lbl0cmod1a: absolute +lbl0cmod1b: tsb8 + nextopcode +op0dm1mod1: testmod1 2 +lbl0dmod1a: absolute +lbl0dmod1b: ora8 + nextopcode +op0em1mod1: testmod1 2 +lbl0emod1a: absolute +lbl0emod1b: asl8 + nextopcode +op0fm1mod1: testmod1 2 +lbl0fmod1a: absolutelong +lbl0fmod1b: ora8 + nextopcode +op10mod1: testmod1 2 +lbl10mod1: testmod1 2 +op10 + nextopcode +op11m1mod1: testmod1 2 +lbl11mod1a: directindirectindexed1 +lbl11mod1b: ora8 + nextopcode +op12m1mod1: testmod1 2 +lbl12mod1a: directindirect +lbl12mod1b: ora8 + nextopcode +op13m1mod1: testmod1 2 +lbl13mod1a: stackasmrelativeindirectindexed1 +lbl13mod1b: ora8 + nextopcode +op14m1mod1: testmod1 2 +lbl14mod1a: direct +lbl14mod1b: trb8 + nextopcode +op15m1mod1: testmod1 2 +lbl15mod1a: directindexedx1 +lbl15mod1b: ora8 + nextopcode +op16m1mod1: testmod1 2 +lbl16mod1a: directindexedx1 +lbl16mod1b: asl8 + nextopcode +op17m1mod1: testmod1 2 +lbl17mod1a: directindirectindexedlong1 +lbl17mod1b: ora8 + nextopcode +op18mod1: testmod1 2 +lbl18mod1: testmod1 2 +op18 + nextopcode +op19m1mod1: testmod1 2 +lbl19mod1a: absoluteindexedy1 +lbl19mod1b: ora8 + nextopcode +op1am1mod1: testmod1 2 +lbl1amod1a: a_inc8 + nextopcode +op1bmod1: testmod1 3 +lbl1bmod1: testmod1 3 +op1bm1 + nextopcode +op1cm1mod1: testmod1 3 +lbl1cmod1a: absolute +lbl1cmod1b: trb8 + nextopcode +op1dm1mod1: testmod1 3 +lbl1dmod1a: absoluteindexedx1 +lbl1dmod1b: ora8 + nextopcode +op1em1mod1: testmod1 3 +lbl1emod1a: absoluteindexedx1 +lbl1emod1b: asl8 + nextopcode +op1fm1mod1: testmod1 3 +lbl1fmod1a: absolutelongindexedx1 +lbl1fmod1b: ora8 + nextopcode +op20mod1: testmod1 3 +lbl20mod1: testmod1 3 +op20 + nextopcode +op21m1mod1: testmod1 3 +lbl21mod1a: directindexedindirect1 +lbl21mod1b: and8 + nextopcode +op22mod1: testmod1 3 +lbl22mod1: testmod1 3 +op22 + nextopcode +op23m1mod1: testmod1 3 +lbl23mod1a: stackasmrelative +lbl23mod1b: and8 + nextopcode +op24m1mod1: testmod1 3 +lbl24mod1a: direct +lbl24mod1b: bit8 + nextopcode +op25m1mod1: testmod1 3 +lbl25mod1a: direct +lbl25mod1b: and8 + nextopcode +op26m1mod1: testmod1 3 +lbl26mod1a: direct +lbl26mod1b: rol8 + nextopcode +op27m1mod1: testmod1 3 +lbl27mod1a: directindirectlong +lbl27mod1b: and8 + nextopcode +op28mod1: testmod1 3 +lbl28mod1: testmod1 3 +op28x1m1 + nextopcode +@@.pool +op29m1mod1: testmod1 3 +lbl29mod1: testmod1 3 +op29m1 + nextopcode +op2am1mod1: testmod1 3 +lbl2amod1a: a_rol8 + nextopcode +op2bmod1: testmod1 3 +lbl2bmod1: testmod1 3 +op2b + nextopcode +op2cm1mod1: testmod1 4 +lbl2cmod1a: absolute +lbl2cmod1b: bit8 + nextopcode +op2dm1mod1: testmod1 4 +lbl2dmod1a: absolute +lbl2dmod1b: and8 + nextopcode +op2em1mod1: testmod1 4 +lbl2emod1a: absolute +lbl2emod1b: rol8 + nextopcode +op2fm1mod1: testmod1 4 +lbl2fmod1a: absolutelong +lbl2fmod1b: and8 + nextopcode +op30mod1: testmod1 4 +lbl30mod1: testmod1 4 +op30 + nextopcode +op31m1mod1: testmod1 4 +lbl31mod1a: directindirectindexed1 +lbl31mod1b: and8 + nextopcode +op32m1mod1: testmod1 4 +lbl32mod1a: directindirect +lbl32mod1b: and8 + nextopcode +op33m1mod1: testmod1 4 +lbl33mod1a: stackasmrelativeindirectindexed1 +lbl33mod1b: and8 + nextopcode +op34m1mod1: testmod1 4 +lbl34mod1a: directindexedx1 +lbl34mod1b: bit8 + nextopcode +op35m1mod1: testmod1 4 +lbl35mod1a: directindexedx1 +lbl35mod1b: and8 + nextopcode +op36m1mod1: testmod1 4 +lbl36mod1a: directindexedx1 +lbl36mod1b: rol8 + nextopcode +op37m1mod1: testmod1 4 +lbl37mod1a: directindirectindexedlong1 +lbl37mod1b: and8 + nextopcode +op38mod1: testmod1 4 +lbl38mod1: testmod1 4 +op38 + nextopcode +op39m1mod1: testmod1 4 +lbl39mod1a: absoluteindexedy1 +lbl39mod1b: and8 + nextopcode +op3am1mod1: testmod1 5 +lbl3amod1a: a_dec8 + nextopcode +op3bmod1: testmod1 5 +lbl3bmod1: testmod1 5 +op3bm1 + nextopcode +op3cm1mod1: testmod1 5 +lbl3cmod1a: absoluteindexedx1 +lbl3cmod1b: bit8 + nextopcode +op3dm1mod1: testmod1 5 +lbl3dmod1a: absoluteindexedx1 +lbl3dmod1b: and8 + nextopcode +op3em1mod1: testmod1 5 +lbl3emod1a: absoluteindexedx1 +lbl3emod1b: rol8 + nextopcode +op3fm1mod1: testmod1 5 +lbl3fmod1a: absolutelongindexedx1 +lbl3fmod1b: and8 + nextopcode +op40mod1: testmod1 5 +lbl40mod1: testmod1 5 +op40x1m1 + nextopcode +@@.pool +op41m1mod1: testmod1 5 +lbl41mod1a: directindexedindirect1 +lbl41mod1b: eor8 + nextopcode +op42mod1: testmod1 5 +lbl42mod1: testmod1 5 +op42 + nextopcode +op43m1mod1: testmod1 5 +lbl43mod1a: stackasmrelative +lbl43mod1b: eor8 + nextopcode +op44x1mod1: testmod1 5 +lbl44mod1: testmod1 5 +op44x1m1 + nextopcode +op45m1mod1: testmod1 5 +lbl45mod1a: direct +lbl45mod1b: eor8 + nextopcode +op46m1mod1: testmod1 5 +lbl46mod1a: direct +lbl46mod1b: lsr8 + nextopcode +op47m1mod1: testmod1 5 +lbl47mod1a: directindirectlong +lbl47mod1b: eor8 + nextopcode +op48m1mod1: testmod1 5 +lbl48mod1: testmod1 5 +op48m1 + nextopcode +op49m1mod1: testmod1 5 +lbl49mod1: testmod1 5 +op49m1 + nextopcode +op4am1mod1: testmod1 5 +lbl4amod1a: a_lsr8 + nextopcode +op4bmod1: testmod1 5 +lbl4bmod1: testmod1 6 +op4b + nextopcode +op4cmod1: testmod1 6 +lbl4cmod1: testmod1 6 +op4c + nextopcode +op4dm1mod1: testmod1 6 +lbl4dmod1a: absolute +lbl4dmod1b: eor8 + nextopcode +op4em1mod1: testmod1 6 +lbl4emod1a: absolute +lbl4emod1b: lsr8 + nextopcode +op4fm1mod1: testmod1 6 +lbl4fmod1a: absolutelong +lbl4fmod1b: eor8 + nextopcode +op50mod1: testmod1 6 +lbl50mod1: testmod1 6 +op50 + nextopcode +op51m1mod1: testmod1 6 +lbl51mod1a: directindirectindexed1 +lbl51mod1b: eor8 + nextopcode +op52m1mod1: testmod1 6 +lbl52mod1a: directindirect +lbl52mod1b: eor8 + nextopcode +op53m1mod1: testmod1 6 +lbl53mod1a: stackasmrelativeindirectindexed1 +lbl53mod1b: eor8 + nextopcode +op54x1mod1: testmod1 6 +lbl54mod1: testmod1 6 +op54x1m1 + nextopcode +op55m1mod1: testmod1 6 +lbl55mod1a: directindexedx1 +lbl55mod1b: eor8 + nextopcode +op56m1mod1: testmod1 6 +lbl56mod1a: directindexedx1 +lbl56mod1b: lsr8 + nextopcode +op57m1mod1: testmod1 6 +lbl57mod1a: directindirectindexedlong1 +lbl57mod1b: eor8 + nextopcode +op58mod1: testmod1 6 +lbl58mod1: testmod1 6 +op58 + nextopcode +op59m1mod1: testmod1 6 +lbl59mod1a: absoluteindexedy1 +lbl59mod1b: eor8 + nextopcode +op5ax1mod1: testmod1 6 +lbl5amod1: testmod1 6 +op5ax1 + nextopcode +op5bmod1: testmod1 6 +lbl5bmod1: testmod1 6 +op5bm1 + nextopcode +op5cmod1: testmod1 7 +lbl5cmod1: testmod1 7 +op5c + nextopcode +op5dm1mod1: testmod1 7 +lbl5dmod1a: absoluteindexedx1 +lbl5dmod1b: eor8 + nextopcode +op5em1mod1: testmod1 7 +lbl5emod1a: absoluteindexedx1 +lbl5emod1b: lsr8 + nextopcode +op5fm1mod1: testmod1 7 +lbl5fmod1a: absolutelongindexedx1 +lbl5fmod1b: eor8 + nextopcode +op60mod1: testmod1 7 +lbl60mod1: testmod1 7 +op60 + nextopcode +op61m1mod1: testmod1 7 +lbl61mod1a: directindexedindirect1 +lbl61mod1b: adc8 + nextopcode +op62mod1: testmod1 7 +lbl62mod1: testmod1 7 +op62 + nextopcode +op63m1mod1: testmod1 7 +lbl63mod1a: stackasmrelative +lbl63mod1b: adc8 + nextopcode +op64m1mod1: testmod1 7 +lbl64mod1a: direct +lbl64mod1b: stz8 + nextopcode +op65m1mod1: testmod1 7 +lbl65mod1a: direct +lbl65mod1b: adc8 + nextopcode +op66m1mod1: testmod1 7 +lbl66mod1a: direct +lbl66mod1b: ror8 + nextopcode +op67m1mod1: testmod1 7 +lbl67mod1a: directindirectlong +lbl67mod1b: adc8 + nextopcode +op68m1mod1: testmod1 7 +lbl68mod1: testmod1 7 +op68m1 + nextopcode +op69m1mod1: testmod1 7 +lbl69mod1a: immediate8 +lbl69mod1b: adc8 + nextopcode +op6am1mod1: testmod1 7 +lbl6amod1a: a_ror8 + nextopcode +op6bmod1: testmod1 8 +lbl6bmod1: testmod1 8 +op6b + nextopcode +op6cmod1: testmod1 8 +lbl6cmod1: testmod1 8 +op6c + nextopcode +op6dm1mod1: testmod1 8 +lbl6dmod1a: absolute +lbl6dmod1b: adc8 + nextopcode +op6em1mod1: testmod1 8 +lbl6emod1a: absolute +lbl6emod1b: ror8 + nextopcode +op6fm1mod1: testmod1 8 +lbl6fmod1a: absolutelong +lbl6fmod1b: adc8 + nextopcode +op70mod1: testmod1 8 +lbl70mod1: testmod1 8 +op70 + nextopcode +op71m1mod1: testmod1 8 +lbl71mod1a: directindirectindexed1 +lbl71mod1b: adc8 + nextopcode +op72m1mod1: testmod1 8 +lbl72mod1a: directindirect +lbl72mod1b: adc8 + nextopcode +op73m1mod1: testmod1 8 +lbl73mod1a: stackasmrelativeindirectindexed1 +lbl73mod1b: adc8 + nextopcode + +op74m1mod1: testmod1 8 +lbl74mod1a: directindexedx1 +lbl74mod1b: stz8 + nextopcode +op75m1mod1: testmod1 8 +lbl75mod1a: directindexedx1 +lbl75mod1b: adc8 + nextopcode +op76m1mod1: testmod1 8 +lbl76mod1a: directindexedx1 +lbl76mod1b: ror8 + nextopcode +op77m1mod1: testmod1 8 +lbl77mod1a: directindirectindexedlong1 +lbl77mod1b: adc8 + nextopcode +op78mod1: testmod1 8 +lbl78mod1: testmod1 8 +op78 + nextopcode +op79m1mod1: testmod1 8 +lbl79mod1a: absoluteindexedy1 +lbl79mod1b: adc8 + nextopcode +op7ax1mod1: testmod1 9 +lbl7amod1: testmod1 9 +op7ax1 + nextopcode +op7bmod1: testmod1 9 +lbl7bmod1: testmod1 9 +op7bm1 + nextopcode +op7cmod1: testmod1 9 +lbl7cmod1: testmod1 9 + absoluteindexedindirectx1 + op7c + nextopcode +op7dm1mod1: testmod1 9 +lbl7dmod1a: absoluteindexedx1 +lbl7dmod1b: adc8 + nextopcode +op7em1mod1: testmod1 9 +lbl7emod1a: absoluteindexedx1 +lbl7emod1b: ror8 + nextopcode +op7fm1mod1: testmod1 9 +lbl7fmod1a: absolutelongindexedx1 +lbl7fmod1b: adc8 + nextopcode + + +op80mod1: testmod1 9 +lbl80mod1: testmod1 9 +op80 + nextopcode +op81m1mod1: testmod1 9 +lbl81mod1a: directindexedindirect1 +lbl81mod1b: op81m1 + nextopcode +op82mod1: testmod1 9 +lbl82mod1: testmod1 9 +op82 + nextopcode +op83m1mod1: testmod1 9 +lbl83mod1a: stackasmrelative +lbl83mod1b: sta8 + nextopcode +op84x1mod1: testmod1 9 +lbl84mod1a: direct +lbl84mod1b: sty8 + nextopcode +op85m1mod1: testmod1 9 +lbl85mod1a: direct +lbl85mod1b: sta8 + nextopcode +op86x1mod1: testmod1 9 +lbl86mod1a: direct +lbl86mod1b: stx8 + nextopcode +op87m1mod1: testmod1 9 +lbl87mod1a: directindirectlong +lbl87mod1b: sta8 + nextopcode +op88x1mod1: testmod1 9 +lbl88mod1: testmod1 9 +op88x1 + nextopcode +op89m1mod1: testmod1 10 +lbl89mod1: testmod1 10 +op89m1 + nextopcode +op8am1mod1: testmod1 10 +lbl8amod1: testmod1 10 +op8am1x1 + nextopcode +op8bmod1: testmod1 10 +lbl8bmod1: testmod1 10 +op8b + nextopcode +op8cx1mod1: testmod1 10 +lbl8cmod1a: absolute +lbl8cmod1b: sty8 + nextopcode +op8dm1mod1: testmod1 10 +lbl8dmod1a: absolute +lbl8dmod1b: sta8 + nextopcode +op8ex1mod1: testmod1 10 +lbl8emod1a: absolute +lbl8emod1b: stx8 + nextopcode +op8fm1mod1: testmod1 10 +lbl8fmod1a: absolutelong +lbl8fmod1b: sta8 + nextopcode +op90mod1: testmod1 10 +lbl90mod1: testmod1 10 +op90 + nextopcode +op91m1mod1: testmod1 10 +lbl91mod1a: directindirectindexed1 +lbl91mod1b: sta8 + nextopcode +op92m1mod1: testmod1 10 +lbl92mod1a: directindirect +lbl92mod1b: sta8 + nextopcode +op93m1mod1: testmod1 10 +lbl93mod1a: stackasmrelativeindirectindexed1 +lbl93mod1b: sta8 + nextopcode +op94x1mod1: testmod1 10 +lbl94mod1a: directindexedx1 +lbl94mod1b: sty8 + nextopcode +op95m1mod1: testmod1 10 +lbl95mod1a: directindexedx1 +lbl95mod1b: sta8 + nextopcode +op96x1mod1: testmod1 10 +lbl96mod1a: directindexedy1 +lbl96mod1b: stx8 + nextopcode +op97m1mod1: testmod1 10 +lbl97mod1a: directindirectindexedlong1 +lbl97mod1b: sta8 + nextopcode +op98m1mod1: testmod1 10 +lbl98mod1: testmod1 10 +op98m1x1 + nextopcode +op99m1mod1: testmod1 11 +lbl99mod1a: absoluteindexedy1 +lbl99mod1b: sta8 + nextopcode +op9amod1: testmod1 11 +lbl9amod1: testmod1 11 +op9ax1 + nextopcode +op9bx1mod1: testmod1 11 +lbl9bmod1: testmod1 11 +op9bx1 + nextopcode +op9cm1mod1: testmod1 11 +lbl9cmod1a: absolute +lbl9cmod1b: stz8 + nextopcode +op9dm1mod1: testmod1 11 +lbl9dmod1a: absoluteindexedx1 +lbl9dmod1b: sta8 + nextopcode +op9em1mod1: testmod1 11 +lbl9emod1: testmod1 11 +absoluteindexedx1 + stz8 + nextopcode +op9fm1mod1: testmod1 11 +lbl9fmod1a: absolutelongindexedx1 +lbl9fmod1b: sta8 + nextopcode +opa0x1mod1: testmod1 11 +lbla0mod1: testmod1 11 +opa0x1 + nextopcode +opa1m1mod1: testmod1 11 +lbla1mod1a: directindexedindirect1 +lbla1mod1b: lda8 + nextopcode +opa2x1mod1: testmod1 11 +lbla2mod1: testmod1 11 +opa2x1 + nextopcode +opa3m1mod1: testmod1 11 +lbla3mod1a: stackasmrelative +lbla3mod1b: lda8 + nextopcode +opa4x1mod1: testmod1 11 +lbla4mod1a: direct +lbla4mod1b: ldy8 + nextopcode +opa5m1mod1: testmod1 11 +lbla5mod1a: direct +lbla5mod1b: lda8 + nextopcode +opa6x1mod1: testmod1 11 +lbla6mod1a: direct +lbla6mod1b: ldx8 + nextopcode +opa7m1mod1: testmod1 11 +lbla7mod1a: directindirectlong +lbla7mod1b: lda8 + nextopcode +opa8x1mod1: testmod1 11 +lbla8mod1: testmod1 11 +opa8x1m1 + nextopcode +opa9m1mod1: testmod1 11 +lbla9mod1: testmod1 11 +opa9m1 + nextopcode +opaax1mod1: testmod1 11 +lblaamod1: testmod1 11 +opaax1m1 + nextopcode +opabmod1: testmod1 12 +lblabmod1: testmod1 12 +opab + nextopcode +opacx1mod1: testmod1 12 +lblacmod1a: absolute +lblacmod1b: ldy8 + nextopcode +opadm1mod1: testmod1 12 +lbladmod1a: absolute +lbladmod1b: lda8 + nextopcode +opaex1mod1: testmod1 12 +lblaemod1a: absolute +lblaemod1b: ldx8 + nextopcode +opafm1mod1: testmod1 12 +lblafmod1a: absolutelong +lblafmod1b: lda8 + nextopcode +opb0mod1: testmod1 12 +lblb0mod1: testmod1 12 +opb0 + nextopcode +opb1m1mod1: testmod1 12 +lblb1mod1a: directindirectindexed1 +lblb1mod1b: lda8 + nextopcode +opb2m1mod1: testmod1 12 +lblb2mod1a: directindirect +lblb2mod1b: lda8 + nextopcode +opb3m1mod1: testmod1 12 +lblb3mod1a: stackasmrelativeindirectindexed1 +lblb3mod1b: lda8 + nextopcode +opb4x1mod1: testmod1 12 +lblb4mod1a: directindexedx1 +lblb4mod1b: ldy8 + nextopcode +opb5m1mod1: testmod1 12 +lblb5mod1a: directindexedx1 +lblb5mod1b: lda8 + nextopcode +opb6x1mod1: testmod1 12 +lblb6mod1a: directindexedy1 +lblb6mod1b: ldx8 + nextopcode +opb7m1mod1: testmod1 12 +lblb7mod1a: directindirectindexedlong1 +lblb7mod1b: lda8 + nextopcode +opb8mod1: testmod1 12 +lblb8mod1: testmod1 12 +opb8 + nextopcode +opb9m1mod1: testmod1 12 +lblb9mod1a: absoluteindexedy1 +lblb9mod1b: lda8 + nextopcode +opbax1mod1: testmod1 12 +lblbamod1: testmod1 12 +opbax1 + nextopcode +opbbx1mod1: testmod1 12 +lblbbmod1: testmod1 12 +opbbx1 + nextopcode +opbcx1mod1: testmod1 12 +lblbcmod1a: absoluteindexedx1 +lblbcmod1b: ldy8 + nextopcode +opbdm1mod1: testmod1 12 +lblbdmod1a: absoluteindexedx1 +lblbdmod1b: lda8 + nextopcode +opbex1mod1: testmod1 12 +lblbemod1a: absoluteindexedy1 +lblbemod1b: ldx8 + nextopcode +opbfm1mod1: testmod1 12 +lblbfmod1a: absolutelongindexedx1 +lblbfmod1b: lda8 + nextopcode +opc0x1mod1: testmod1 12 +lblc0mod1: testmod1 12 +opc0x1 + nextopcode +opc1m1mod1: testmod1 12 +lblc1mod1a: directindexedindirect1 +lblc1mod1b: cmp8 + nextopcode +opc2mod1: testmod1 12 +lblc2mod1: testmod1 12 +opc2 + nextopcode +@@.pool +opc3m1mod1: testmod1 13 +lblc3mod1a: stackasmrelative +lblc3mod1b: cmp8 + nextopcode +opc4x1mod1: testmod1 13 +lblc4mod1a: direct +lblc4mod1b: cmy8 + nextopcode +opc5m1mod1: testmod1 13 +lblc5mod1a: direct +lblc5mod1b: cmp8 + nextopcode +opc6m1mod1: testmod1 13 +lblc6mod1a: direct +lblc6mod1b: dec8 + nextopcode +opc7m1mod1: testmod1 13 +lblc7mod1a: directindirectlong +lblc7mod1b: cmp8 + nextopcode +opc8x1mod1: testmod1 13 +lblc8mod1: testmod1 13 +opc8x1 + nextopcode +opc9m1mod1: testmod1 13 +lblc9mod1: testmod1 13 +opc9m1 + nextopcode +opcax1mod1: testmod1 13 +lblcamod1: testmod1 13 +opcax1 + nextopcode +opcbmod1: testmod1 13 +lblcbmod1: testmod1 13 +opcb + nextopcode +opccx1mod1: testmod1 13 +lblccmod1a: absolute +lblccmod1b: cmy8 + nextopcode +opcdm1mod1: testmod1 13 +lblcdmod1a: absolute +lblcdmod1b: cmp8 + nextopcode +opcem1mod1: testmod1 13 +lblcemod1a: absolute +lblcemod1b: dec8 + nextopcode +opcfm1mod1: testmod1 13 +lblcfmod1a: absolutelong +lblcfmod1b: cmp8 + nextopcode +opd0mod1: testmod1 13 +lbld0mod1: testmod1 13 +opd0 + nextopcode +opd1m1mod1: testmod1 13 +lbld1mod1a: directindirectindexed1 +lbld1mod1b: cmp8 + nextopcode +opd2m1mod1: testmod1 13 +lbld2mod1a: directindirect +lbld2mod1b: cmp8 + nextopcode +opd3m1mod1: testmod1 13 +lbld3mod1a: stackasmrelativeindirectindexed1 +lbld3mod1b: cmp8 + nextopcode +opd4mod1: testmod1 14 +lbld4mod1: testmod1 14 +opd4 + nextopcode +opd5m1mod1: testmod1 14 +lbld5mod1a: directindexedx1 +lbld5mod1b: cmp8 + nextopcode +opd6m1mod1: testmod1 14 +lbld6mod1a: directindexedx1 +lbld6mod1b: dec8 + nextopcode +opd7m1mod1: testmod1 14 +lbld7mod1a: directindirectindexedlong1 +lbld7mod1b: cmp8 + nextopcode +opd8mod1: testmod1 14 +lbld8mod1: testmod1 14 +opd8 + nextopcode +opd9m1mod1: testmod1 14 +lbld9mod1a: absoluteindexedy1 +lbld9mod1b: cmp8 + nextopcode +opdax1mod1: testmod1 14 +lbldamod1: testmod1 14 +opdax1 + nextopcode +opdbmod1: testmod1 14 +lbldbmod1: testmod1 14 +opdb + nextopcode +opdcmod1: testmod1 14 +lbldcmod1: testmod1 14 +opdc + nextopcode +opddm1mod1: testmod1 14 +lblddmod1a: absoluteindexedx1 +lblddmod1b: cmp8 + nextopcode +opdem1mod1: testmod1 14 +lbldemod1a: absoluteindexedx1 +lbldemod1b: dec8 + nextopcode +opdfm1mod1: testmod1 14 +lbldfmod1a: absolutelongindexedx1 +lbldfmod1b: cmp8 + nextopcode +ope0x1mod1: testmod1 14 +lble0mod1: testmod1 14 +ope0x1 + nextopcode +ope1m1mod1: testmod1 14 +lble1mod1a: directindexedindirect1 +lble1mod1b: sbc8 + nextopcode +ope2mod1: testmod1 14 +lble2mod1: testmod1 14 +ope2 + nextopcode +@@.pool +ope3m1mod1: testmod1 14 +lble3mod1a: stackasmrelative +lble3mod1b: sbc8 + nextopcode +ope4x1mod1: testmod1 14 +lble4mod1a: direct +lble4mod1b: cmx8 + nextopcode +ope5m1mod1: testmod1 15 +lble5mod1a: direct +lble5mod1b: sbc8 + nextopcode +ope6m1mod1: testmod1 15 +lble6mod1a: direct +lble6mod1b: inc8 + nextopcode +ope7m1mod1: testmod1 15 +lble7mod1a: directindirectlong +lble7mod1b: sbc8 + nextopcode +ope8x1mod1: testmod1 15 +lble8mod1: testmod1 15 +ope8x1 + nextopcode +ope9m1mod1: testmod1 15 +lble9mod1a: immediate8 +lble9mod1b: sbc8 + nextopcode +opeamod1: testmod1 15 +lbleamod1: testmod1 15 +opea + nextopcode +opebmod1: testmod1 15 +lblebmod1: testmod1 15 +opebm1 + nextopcode +opecx1mod1: testmod1 15 +lblecmod1a: absolute +lblecmod1b: cmx8 + nextopcode +opedm1mod1: testmod1 15 +lbledmod1a: absolute +lbledmod1b: sbc8 + nextopcode +opeem1mod1: testmod1 15 +lbleemod1a: absolute +lbleemod1b: inc8 + nextopcode +opefm1mod1: testmod1 15 +lblefmod1a: absolutelong +lblefmod1b: sbc8 + nextopcode +opf0mod1: testmod1 15 +lblf0mod1: testmod1 15 +opf0 + nextopcode +opf1m1mod1: testmod1 15 +lblf1mod1a: directindirectindexed1 +lblf1mod1b: sbc8 + nextopcode +opf2m1mod1: testmod1 15 +lblf2mod1a: directindirect +lblf2mod1b: sbc8 + nextopcode +opf3m1mod1: testmod1 15 +lblf3mod1a: stackasmrelativeindirectindexed1 +lblf3mod1b: sbc8 + nextopcode +opf4mod1: testmod1 15 +lblf4mod1: testmod1 15 +opf4 + nextopcode +opf5m1mod1: testmod1 15 +lblf5mod1a: directindexedx1 +lblf5mod1b: sbc8 + nextopcode +opf6m1mod1: testmod1 15 +lblf6mod1a: directindexedx1 +lblf6mod1b: inc8 + nextopcode +opf7m1mod1: testmod1 15 +lblf7mod1a: directindirectindexedlong1 +lblf7mod1b: sbc8 + nextopcode +opf8mod1: testmod1 15 +lblf8mod1: testmod1 15 +opf8 + nextopcode +opf9m1mod1: testmod1 15 +lblf9mod1a: absoluteindexedy1 +lblf9mod1b: sbc8 + nextopcode +opfax1mod1: testmod1 15 +lblfamod1: testmod1 15 +opfax1 + nextopcode +opfbmod1: testmod1 15 +lblfbmod1: testmod1 15 +opfb + nextopcode +opfcmod1: testmod1 15 +lblfcmod1: testmod1 15 +opfcx1 + nextopcode +opfdm1mod1: testmod1 15 +lblfdmod1a: absoluteindexedx1 +lblfdmod1b: sbc8 + nextopcode +opfem1mod1: testmod1 15 +lblfemod1a: absoluteindexedx1 +lblfemod1b: inc8 + nextopcode +opffm1mod1: testmod1 15 +lblffmod1a: absolutelongindexedx1 +lblffmod1b: sbc8 + nextopcode +@@.pool + + +jumptable2: .long op00mod2 + .long op01m1mod2 + .long op02mod2 + .long op03m1mod2 + .long op04m1mod2 + .long op05m1mod2 + .long op06m1mod2 + .long op07m1mod2 + .long op08mod2 + .long op09m1mod2 + .long op0am1mod2 + .long op0bmod2 + .long op0cm1mod2 + .long op0dm1mod2 + .long op0em1mod2 + .long op0fm1mod2 + .long op10mod2 + .long op11m1mod2 + .long op12m1mod2 + .long op13m1mod2 + .long op14m1mod2 + .long op15m1mod2 + .long op16m1mod2 + .long op17m1mod2 + .long op18mod2 + .long op19m1mod2 + .long op1am1mod2 + .long op1bmod2 + .long op1cm1mod2 + .long op1dm1mod2 + .long op1em1mod2 + .long op1fm1mod2 + .long op20mod2 + .long op21m1mod2 + .long op22mod2 + .long op23m1mod2 + .long op24m1mod2 + .long op25m1mod2 + .long op26m1mod2 + .long op27m1mod2 + .long op28mod2 + .long op29m1mod2 + .long op2am1mod2 + .long op2bmod2 + .long op2cm1mod2 + .long op2dm1mod2 + .long op2em1mod2 + .long op2fm1mod2 + .long op30mod2 + .long op31m1mod2 + .long op32m1mod2 + .long op33m1mod2 + .long op34m1mod2 + .long op35m1mod2 + .long op36m1mod2 + .long op37m1mod2 + .long op38mod2 + .long op39m1mod2 + .long op3am1mod2 + .long op3bmod2 + .long op3cm1mod2 + .long op3dm1mod2 + .long op3em1mod2 + .long op3fm1mod2 + .long op40mod2 + .long op41m1mod2 + .long op42mod2 + .long op43m1mod2 + .long op44x0mod2 + .long op45m1mod2 + .long op46m1mod2 + .long op47m1mod2 + .long op48m1mod2 + .long op49m1mod2 + .long op4am1mod2 + .long op4bmod2 + .long op4cmod2 + .long op4dm1mod2 + .long op4em1mod2 + .long op4fm1mod2 + .long op50mod2 + .long op51m1mod2 + .long op52m1mod2 + .long op53m1mod2 + .long op54x0mod2 + .long op55m1mod2 + .long op56m1mod2 + .long op57m1mod2 + .long op58mod2 + .long op59m1mod2 + .long op5ax0mod2 + .long op5bmod2 + .long op5cmod2 + .long op5dm1mod2 + .long op5em1mod2 + .long op5fm1mod2 + .long op60mod2 + .long op61m1mod2 + .long op62mod2 + .long op63m1mod2 + .long op64m1mod2 + .long op65m1mod2 + .long op66m1mod2 + .long op67m1mod2 + .long op68m1mod2 + .long op69m1mod2 + .long op6am1mod2 + .long op6bmod2 + .long op6cmod2 + .long op6dm1mod2 + .long op6em1mod2 + .long op6fm1mod2 + .long op70mod2 + .long op71m1mod2 + .long op72m1mod2 + .long op73m1mod2 + .long op74m1mod2 + .long op75m1mod2 + .long op76m1mod2 + .long op77m1mod2 + .long op78mod2 + .long op79m1mod2 + .long op7ax0mod2 + .long op7bmod2 + .long op7cmod2 + .long op7dm1mod2 + .long op7em1mod2 + .long op7fm1mod2 + .long op80mod2 + .long op81m1mod2 + .long op82mod2 + .long op83m1mod2 + .long op84x0mod2 + .long op85m1mod2 + .long op86x0mod2 + .long op87m1mod2 + .long op88x0mod2 + .long op89m1mod2 + .long op8am1mod2 + .long op8bmod2 + .long op8cx0mod2 + .long op8dm1mod2 + .long op8ex0mod2 + .long op8fm1mod2 + .long op90mod2 + .long op91m1mod2 + .long op92m1mod2 + .long op93m1mod2 + .long op94x0mod2 + .long op95m1mod2 + .long op96x0mod2 + .long op97m1mod2 + .long op98m1mod2 + .long op99m1mod2 + .long op9amod2 + .long op9bx0mod2 + .long op9cm1mod2 + .long op9dm1mod2 + .long op9em1mod2 + .long op9fm1mod2 + .long opa0x0mod2 + .long opa1m1mod2 + .long opa2x0mod2 + .long opa3m1mod2 + .long opa4x0mod2 + .long opa5m1mod2 + .long opa6x0mod2 + .long opa7m1mod2 + .long opa8x0mod2 + .long opa9m1mod2 + .long opaax0mod2 + .long opabmod2 + .long opacx0mod2 + .long opadm1mod2 + .long opaex0mod2 + .long opafm1mod2 + .long opb0mod2 + .long opb1m1mod2 + .long opb2m1mod2 + .long opb3m1mod2 + .long opb4x0mod2 + .long opb5m1mod2 + .long opb6x0mod2 + .long opb7m1mod2 + .long opb8mod2 + .long opb9m1mod2 + .long opbax0mod2 + .long opbbx0mod2 + .long opbcx0mod2 + .long opbdm1mod2 + .long opbex0mod2 + .long opbfm1mod2 + .long opc0x0mod2 + .long opc1m1mod2 + .long opc2mod2 + .long opc3m1mod2 + .long opc4x0mod2 + .long opc5m1mod2 + .long opc6m1mod2 + .long opc7m1mod2 + .long opc8x0mod2 + .long opc9m1mod2 + .long opcax0mod2 + .long opcbmod2 + .long opccx0mod2 + .long opcdm1mod2 + .long opcem1mod2 + .long opcfm1mod2 + .long opd0mod2 + .long opd1m1mod2 + .long opd2m1mod2 + .long opd3m1mod2 + .long opd4mod2 + .long opd5m1mod2 + .long opd6m1mod2 + .long opd7m1mod2 + .long opd8mod2 + .long opd9m1mod2 + .long opdax0mod2 + .long opdbmod2 + .long opdcmod2 + .long opddm1mod2 + .long opdem1mod2 + .long opdfm1mod2 + .long ope0x0mod2 + .long ope1m1mod2 + .long ope2mod2 + .long ope3m1mod2 + .long ope4x0mod2 + .long ope5m1mod2 + .long ope6m1mod2 + .long ope7m1mod2 + .long ope8x0mod2 + .long ope9m1mod2 + .long opeamod2 + .long opebmod2 + .long opecx0mod2 + .long opedm1mod2 + .long opeem1mod2 + .long opefm1mod2 + .long opf0mod2 + .long opf1m1mod2 + .long opf2m1mod2 + .long opf3m1mod2 + .long opf4mod2 + .long opf5m1mod2 + .long opf6m1mod2 + .long opf7m1mod2 + .long opf8mod2 + .long opf9m1mod2 + .long opfax0mod2 + .long opfbmod2 + .long opfcmod2 + .long opfdm1mod2 + .long opfem1mod2 + .long opffm1mod2 +op00mod2: testmod1 20 + +lbl00mod2: testmod1 20 + op00 + nextopcode +op01m1mod2: testmod1 20 + +lbl01mod2a: directindexedindirect0 +lbl01mod2b: ora8 + nextopcode +op02mod2: testmod1 20 + +lbl02mod2: testmod1 20 + op02 + nextopcode +op03m1mod2: testmod1 20 + +lbl03mod2a: stackasmrelative +lbl03mod2b: ora8 + nextopcode +op04m1mod2: testmod1 20 + +lbl04mod2a: direct +lbl04mod2b: tsb8 + nextopcode +op05m1mod2: testmod1 20 + +lbl05mod2a: direct +lbl05mod2b: ora8 + nextopcode +op06m1mod2: testmod1 20 + +lbl06mod2a: direct +lbl06mod2b: asl8 + nextopcode +op07m1mod2: testmod1 20 + +lbl07mod2a: directindirectlong +lbl07mod2b: ora8 + nextopcode +op08mod2: testmod1 20 + +lbl08mod2: testmod1 20 + op08 + nextopcode +op09m1mod2: testmod1 20 + +lbl09mod2: testmod1 20 + op09m1 + nextopcode +op0am1mod2: testmod1 20 + +lbl0amod2a: a_asl8 + nextopcode +op0bmod2: testmod1 20 + +lbl0bmod2: testmod1 20 + op0b + nextopcode +op0cm1mod2: testmod1 20 + +lbl0cmod2a: absolute +lbl0cmod2b: tsb8 + nextopcode +op0dm1mod2: testmod1 20 + +lbl0dmod2a: absolute +lbl0dmod2b: ora8 + nextopcode +op0em1mod2: testmod1 20 + +lbl0emod2a: absolute +lbl0emod2b: asl8 + nextopcode +op0fm1mod2: testmod1 20 + +lbl0fmod2a: absolutelong +lbl0fmod2b: ora8 + nextopcode +op10mod2: testmod1 20 + +lbl10mod2: testmod1 20 + op10 + nextopcode +op11m1mod2: testmod1 20 + +lbl11mod2a: directindirectindexed0 +lbl11mod2b: ora8 + nextopcode +op12m1mod2: testmod1 20 + +lbl12mod2a: directindirect +lbl12mod2b: ora8 + nextopcode +op13m1mod2: testmod1 20 + +lbl13mod2a: stackasmrelativeindirectindexed0 +lbl13mod2b: ora8 + nextopcode +op14m1mod2: testmod1 20 + +lbl14mod2a: direct +lbl14mod2b: trb8 + nextopcode +op15m1mod2: testmod1 20 + +lbl15mod2a: directindexedx0 +lbl15mod2b: ora8 + nextopcode +op16m1mod2: testmod1 20 + +lbl16mod2a: directindexedx0 +lbl16mod2b: asl8 + nextopcode +op17m1mod2: testmod1 20 + +lbl17mod2a: directindirectindexedlong0 +lbl17mod2b: ora8 + nextopcode +op18mod2: testmod1 20 + +lbl18mod2: testmod1 20 + op18 + nextopcode +op19m1mod2: testmod1 20 + +lbl19mod2a: absoluteindexedy0 +lbl19mod2b: ora8 + nextopcode +op1am1mod2: testmod1 20 + +lbl1amod2a: a_inc8 + nextopcode +op1bmod2: testmod1 20 + +lbl1bmod2: testmod1 20 + op1bm1 + nextopcode +op1cm1mod2: testmod1 20 + +lbl1cmod2a: absolute +lbl1cmod2b: trb8 + nextopcode +op1dm1mod2: testmod1 20 + +lbl1dmod2a: absoluteindexedx0 +lbl1dmod2b: ora8 + nextopcode +op1em1mod2: testmod1 20 + +lbl1emod2a: absoluteindexedx0 +lbl1emod2b: asl8 + nextopcode +op1fm1mod2: testmod1 20 + +lbl1fmod2a: absolutelongindexedx0 +lbl1fmod2b: ora8 + nextopcode +op20mod2: testmod1 20 + +lbl20mod2: testmod1 20 + op20 + nextopcode +op21m1mod2: testmod1 20 + +lbl21mod2a: directindexedindirect0 +lbl21mod2b: and8 + nextopcode +op22mod2: testmod1 20 + +lbl22mod2: testmod1 20 + op22 + nextopcode +op23m1mod2: testmod1 20 + +lbl23mod2a: stackasmrelative +lbl23mod2b: and8 + nextopcode +op24m1mod2: testmod1 20 + +lbl24mod2a: direct +lbl24mod2b: bit8 + nextopcode +op25m1mod2: testmod1 20 + +lbl25mod2a: direct +lbl25mod2b: and8 + nextopcode +op26m1mod2: testmod1 20 + +lbl26mod2a: direct +lbl26mod2b: rol8 + nextopcode +op27m1mod2: testmod1 20 + +lbl27mod2a: directindirectlong +lbl27mod2b: and8 + nextopcode +op28mod2: testmod1 20 + +lbl28mod2: testmod1 20 + op28x0m1 + nextopcode +@@.pool +op29m1mod2: testmod1 20 + +lbl29mod2: testmod1 20 + op29m1 + nextopcode +op2am1mod2: testmod1 20 + +lbl2amod2a: a_rol8 + nextopcode +op2bmod2: testmod1 20 + +lbl2bmod2: testmod1 20 + op2b + nextopcode +op2cm1mod2: testmod1 20 + +lbl2cmod2a: absolute +lbl2cmod2b: bit8 + nextopcode +op2dm1mod2: testmod1 20 + +lbl2dmod2a: absolute +lbl2dmod2b: and8 + nextopcode +op2em1mod2: testmod1 20 + +lbl2emod2a: absolute +lbl2emod2b: rol8 + nextopcode +op2fm1mod2: testmod1 20 + +lbl2fmod2a: absolutelong +lbl2fmod2b: and8 + nextopcode +op30mod2: testmod1 20 + +lbl30mod2: testmod1 20 + op30 + nextopcode +op31m1mod2: testmod1 20 + +lbl31mod2a: directindirectindexed0 +lbl31mod2b: and8 + nextopcode +op32m1mod2: testmod1 20 + +lbl32mod2a: directindirect +lbl32mod2b: and8 + nextopcode +op33m1mod2: testmod1 20 + +lbl33mod2a: stackasmrelativeindirectindexed0 +lbl33mod2b: and8 + nextopcode +op34m1mod2: testmod1 20 + +lbl34mod2a: directindexedx0 +lbl34mod2b: bit8 + nextopcode +op35m1mod2: testmod1 20 + +lbl35mod2a: directindexedx0 +lbl35mod2b: and8 + nextopcode +op36m1mod2: testmod1 20 + +lbl36mod2a: directindexedx0 +lbl36mod2b: rol8 + nextopcode +op37m1mod2: testmod1 20 + +lbl37mod2a: directindirectindexedlong0 +lbl37mod2b: and8 + nextopcode +op38mod2: testmod1 20 + +lbl38mod2: testmod1 20 + op38 + nextopcode +op39m1mod2: testmod1 20 + +lbl39mod2a: absoluteindexedy0 +lbl39mod2b: and8 + nextopcode +op3am1mod2: testmod1 20 + +lbl3amod2a: a_dec8 + nextopcode +op3bmod2: testmod1 20 + +lbl3bmod2: testmod1 20 + op3bm1 + nextopcode +op3cm1mod2: testmod1 20 + +lbl3cmod2a: absoluteindexedx0 +lbl3cmod2b: bit8 + nextopcode +op3dm1mod2: testmod1 20 + +lbl3dmod2a: absoluteindexedx0 +lbl3dmod2b: and8 + nextopcode +op3em1mod2: testmod1 20 + +lbl3emod2a: absoluteindexedx0 +lbl3emod2b: rol8 + nextopcode +op3fm1mod2: testmod1 20 + +lbl3fmod2a: absolutelongindexedx0 +lbl3fmod2b: and8 + nextopcode +op40mod2: testmod1 20 + +lbl40mod2: testmod1 20 + op40x0m1 + nextopcode +@@.pool +op41m1mod2: testmod1 20 + +lbl41mod2a: directindexedindirect0 +lbl41mod2b: eor8 + nextopcode +op42mod2: testmod1 20 + +lbl42mod2: testmod1 20 + op42 + nextopcode +op43m1mod2: testmod1 20 + +lbl43mod2a: stackasmrelative +lbl43mod2b: eor8 + nextopcode +op44x0mod2: testmod1 20 + +lbl44mod2: testmod1 20 + op44x0m1 + nextopcode +op45m1mod2: testmod1 20 + +lbl45mod2a: direct +lbl45mod2b: eor8 + nextopcode +op46m1mod2: testmod1 20 + +lbl46mod2a: direct +lbl46mod2b: lsr8 + nextopcode +op47m1mod2: testmod1 20 + +lbl47mod2a: directindirectlong +lbl47mod2b: eor8 + nextopcode +op48m1mod2: testmod1 20 + +lbl48mod2: testmod1 20 + op48m1 + nextopcode +op49m1mod2: testmod1 20 + +lbl49mod2: testmod1 20 + op49m1 + nextopcode +op4am1mod2: testmod1 20 + +lbl4amod2a: a_lsr8 + nextopcode +op4bmod2: testmod1 20 + +lbl4bmod2: testmod1 20 + op4b + nextopcode +op4cmod2: testmod1 20 + +lbl4cmod2: testmod1 20 + op4c + nextopcode +op4dm1mod2: testmod1 20 + +lbl4dmod2a: absolute +lbl4dmod2b: eor8 + nextopcode +op4em1mod2: testmod1 20 + +lbl4emod2a: absolute +lbl4emod2b: lsr8 + nextopcode +op4fm1mod2: testmod1 20 + +lbl4fmod2a: absolutelong +lbl4fmod2b: eor8 + nextopcode +op50mod2: testmod1 20 + +lbl50mod2: testmod1 20 + op50 + nextopcode +op51m1mod2: testmod1 20 + +lbl51mod2a: directindirectindexed0 +lbl51mod2b: eor8 + nextopcode +op52m1mod2: testmod1 20 + +lbl52mod2a: directindirect +lbl52mod2b: eor8 + nextopcode +op53m1mod2: testmod1 20 + +lbl53mod2a: stackasmrelativeindirectindexed0 +lbl53mod2b: eor8 + nextopcode +op54x0mod2: testmod1 20 + +lbl54mod2: testmod1 20 + op54x0m1 + nextopcode +op55m1mod2: testmod1 20 + +lbl55mod2a: directindexedx0 +lbl55mod2b: eor8 + nextopcode +op56m1mod2: testmod1 20 + +lbl56mod2a: directindexedx0 +lbl56mod2b: lsr8 + nextopcode +op57m1mod2: testmod1 20 + +lbl57mod2a: directindirectindexedlong0 +lbl57mod2b: eor8 + nextopcode +op58mod2: testmod1 20 + +lbl58mod2: testmod1 20 + op58 + nextopcode +op59m1mod2: testmod1 20 + +lbl59mod2a: absoluteindexedy0 +lbl59mod2b: eor8 + nextopcode +op5ax0mod2: testmod1 20 + +lbl5amod2: testmod1 20 + op5ax0 + nextopcode +op5bmod2: testmod1 20 + +lbl5bmod2: testmod1 20 + op5bm1 + nextopcode +op5cmod2: testmod1 20 + +lbl5cmod2: testmod1 20 + op5c + nextopcode +op5dm1mod2: testmod1 20 + +lbl5dmod2a: absoluteindexedx0 +lbl5dmod2b: eor8 + nextopcode +op5em1mod2: testmod1 20 + +lbl5emod2a: absoluteindexedx0 +lbl5emod2b: lsr8 + nextopcode +op5fm1mod2: testmod1 20 + +lbl5fmod2a: absolutelongindexedx0 +lbl5fmod2b: eor8 + nextopcode +op60mod2: testmod1 20 + +lbl60mod2: testmod1 20 + op60 + nextopcode +op61m1mod2: testmod1 20 + +lbl61mod2a: directindexedindirect0 +lbl61mod2b: adc8 + nextopcode +op62mod2: testmod1 20 + +lbl62mod2: testmod1 20 + op62 + nextopcode +op63m1mod2: testmod1 20 + +lbl63mod2a: stackasmrelative +lbl63mod2b: adc8 + nextopcode +op64m1mod2: testmod1 20 + +lbl64mod2a: direct +lbl64mod2b: stz8 + nextopcode +op65m1mod2: testmod1 20 + +lbl65mod2a: direct +lbl65mod2b: adc8 + nextopcode +op66m1mod2: testmod1 20 + +lbl66mod2a: direct +lbl66mod2b: ror8 + nextopcode +op67m1mod2: testmod1 20 + +lbl67mod2a: directindirectlong +lbl67mod2b: adc8 + nextopcode +op68m1mod2: testmod1 20 + +lbl68mod2: testmod1 20 + op68m1 + nextopcode +op69m1mod2: testmod1 20 + +lbl69mod2a: immediate8 +lbl69mod2b: adc8 + nextopcode +op6am1mod2: testmod1 20 + +lbl6amod2a: a_ror8 + nextopcode +op6bmod2: testmod1 20 + +lbl6bmod2: testmod1 20 + op6b + nextopcode +op6cmod2: testmod1 20 + +lbl6cmod2: testmod1 20 + op6c + nextopcode +op6dm1mod2: testmod1 20 + +lbl6dmod2a: absolute +lbl6dmod2b: adc8 + nextopcode +op6em1mod2: testmod1 20 + +lbl6emod2a: absolute +lbl6emod2b: ror8 + nextopcode +op6fm1mod2: testmod1 20 + +lbl6fmod2a: absolutelong +lbl6fmod2b: adc8 + nextopcode +op70mod2: testmod1 20 + +lbl70mod2: testmod1 20 + op70 + nextopcode +op71m1mod2: testmod1 20 + +lbl71mod2a: directindirectindexed0 +lbl71mod2b: adc8 + nextopcode +op72m1mod2: testmod1 20 + +lbl72mod2a: directindirect +lbl72mod2b: adc8 + nextopcode +op73m1mod2: testmod1 20 + +lbl73mod2a: stackasmrelativeindirectindexed0 +lbl73mod2b: adc8 + nextopcode +op74m1mod2: testmod1 20 + +lbl74mod2a: directindexedx0 +lbl74mod2b: stz8 + nextopcode +op75m1mod2: testmod1 20 + +lbl75mod2a: directindexedx0 +lbl75mod2b: adc8 + nextopcode +op76m1mod2: testmod1 20 + +lbl76mod2a: directindexedx0 +lbl76mod2b: ror8 + nextopcode +op77m1mod2: testmod1 20 + +lbl77mod2a: directindirectindexedlong0 +lbl77mod2b: adc8 + nextopcode +op78mod2: testmod1 20 + +lbl78mod2: testmod1 20 + op78 + nextopcode +op79m1mod2: testmod1 20 + +lbl79mod2a: absoluteindexedy0 +lbl79mod2b: adc8 + nextopcode +op7ax0mod2: testmod1 20 + +lbl7amod2: testmod1 20 + op7ax0 + nextopcode +op7bmod2: testmod1 20 + +lbl7bmod2: testmod1 20 + op7bm1 + nextopcode +op7cmod2: testmod1 20 + +lbl7cmod2: testmod1 20 + absoluteindexedindirectx0 + op7c + nextopcode +op7dm1mod2: testmod1 20 + +lbl7dmod2a: absoluteindexedx0 +lbl7dmod2b: adc8 + nextopcode +op7em1mod2: testmod1 20 + +lbl7emod2a: absoluteindexedx0 +lbl7emod2b: ror8 + nextopcode +op7fm1mod2: testmod1 20 + +lbl7fmod2a: absolutelongindexedx0 +lbl7fmod2b: adc8 + nextopcode + + +op80mod2: testmod1 20 + +lbl80mod2: testmod1 20 + op80 + nextopcode +op81m1mod2: testmod1 20 + +lbl81mod2a: directindexedindirect0 +lbl81mod2b: op81m1 + nextopcode +op82mod2: testmod1 20 + +lbl82mod2: testmod1 20 + op82 + nextopcode +op83m1mod2: testmod1 20 + +lbl83mod2a: stackasmrelative +lbl83mod2b: sta8 + nextopcode +op84x0mod2: testmod1 20 + +lbl84mod2a: direct +lbl84mod2b: sty16 + nextopcode +op85m1mod2: testmod1 20 + +lbl85mod2a: direct +lbl85mod2b: sta8 + nextopcode +op86x0mod2: testmod1 20 + +lbl86mod2a: direct +lbl86mod2b: stx16 + nextopcode +op87m1mod2: testmod1 20 + +lbl87mod2a: directindirectlong +lbl87mod2b: sta8 + nextopcode +op88x0mod2: testmod1 20 + +lbl88mod2: testmod1 20 + op88x0 + nextopcode +op89m1mod2: testmod1 20 + +lbl89mod2: testmod1 20 + op89m1 + nextopcode +op8am1mod2: testmod1 20 + +lbl8amod2: testmod1 20 + op8am1x0 + nextopcode +op8bmod2: testmod1 20 + +lbl8bmod2: testmod1 20 + op8b + nextopcode +op8cx0mod2: testmod1 20 + +lbl8cmod2a: absolute +lbl8cmod2b: sty16 + nextopcode +op8dm1mod2: testmod1 20 + +lbl8dmod2a: absolute +lbl8dmod2b: sta8 + nextopcode +op8ex0mod2: testmod1 20 + +lbl8emod2a: absolute +lbl8emod2b: stx16 + nextopcode +op8fm1mod2: testmod1 20 + +lbl8fmod2a: absolutelong +lbl8fmod2b: sta8 + nextopcode +op90mod2: testmod1 20 + +lbl90mod2: testmod1 20 + op90 + nextopcode +op91m1mod2: testmod1 20 + +lbl91mod2a: directindirectindexed0 +lbl91mod2b: sta8 + nextopcode +op92m1mod2: testmod1 20 + +lbl92mod2a: directindirect +lbl92mod2b: sta8 + nextopcode +op93m1mod2: testmod1 20 + +lbl93mod2a: stackasmrelativeindirectindexed0 +lbl93mod2b: sta8 + nextopcode +op94x0mod2: testmod1 20 + +lbl94mod2a: directindexedx0 +lbl94mod2b: sty16 + nextopcode +op95m1mod2: testmod1 20 + +lbl95mod2a: directindexedx0 +lbl95mod2b: sta8 + nextopcode +op96x0mod2: testmod1 20 + +lbl96mod2a: directindexedy0 +lbl96mod2b: stx16 + nextopcode +op97m1mod2: testmod1 20 + +lbl97mod2a: directindirectindexedlong0 +lbl97mod2b: sta8 + nextopcode +op98m1mod2: testmod1 20 + +lbl98mod2: testmod1 20 + op98m1x0 + nextopcode +op99m1mod2: testmod1 20 + +lbl99mod2a: absoluteindexedy0 +lbl99mod2b: sta8 + nextopcode +op9amod2: testmod1 20 + +lbl9amod2: testmod1 20 + op9ax0 + nextopcode +op9bx0mod2: testmod1 20 + +lbl9bmod2: testmod1 20 + op9bx0 + nextopcode +op9cm1mod2: testmod1 20 + +lbl9cmod2a: absolute +lbl9cmod2b: stz8 + nextopcode +op9dm1mod2: testmod1 20 + +lbl9dmod2a: absoluteindexedx0 +lbl9dmod2b: sta8 + nextopcode +op9em1mod2: testmod1 20 + +lbl9emod2: testmod1 20 + absoluteindexedx0 + stz8 + nextopcode +op9fm1mod2: testmod1 20 + +lbl9fmod2a: absolutelongindexedx0 +lbl9fmod2b: sta8 + nextopcode +opa0x0mod2: testmod1 20 + +lbla0mod2: testmod1 20 + opa0x0 + nextopcode +opa1m1mod2: testmod1 20 + +lbla1mod2a: directindexedindirect0 +lbla1mod2b: lda8 + nextopcode +opa2x0mod2: testmod1 20 + +lbla2mod2: testmod1 20 + opa2x0 + nextopcode +opa3m1mod2: testmod1 20 + +lbla3mod2a: stackasmrelative +lbla3mod2b: lda8 + nextopcode +opa4x0mod2: testmod1 20 + +lbla4mod2a: direct +lbla4mod2b: ldy16 + nextopcode +opa5m1mod2: testmod1 20 + +lbla5mod2a: direct +lbla5mod2b: lda8 + nextopcode +opa6x0mod2: testmod1 20 + +lbla6mod2a: direct +lbla6mod2b: ldx16 + nextopcode +opa7m1mod2: testmod1 20 + +lbla7mod2a: directindirectlong +lbla7mod2b: lda8 + nextopcode +opa8x0mod2: testmod1 20 + +lbla8mod2: testmod1 20 + opa8x0m1 + nextopcode +opa9m1mod2: testmod1 20 + +lbla9mod2: testmod1 20 + opa9m1 + nextopcode +opaax0mod2: testmod1 20 + +lblaamod2: testmod1 20 + opaax0m1 + nextopcode +opabmod2: testmod1 20 + +lblabmod2: testmod1 20 + opab + nextopcode +opacx0mod2: testmod1 20 + +lblacmod2a: absolute +lblacmod2b: ldy16 + nextopcode +opadm1mod2: testmod1 20 + +lbladmod2a: absolute +lbladmod2b: lda8 + nextopcode +opaex0mod2: testmod1 20 + +lblaemod2a: absolute +lblaemod2b: ldx16 + nextopcode +opafm1mod2: testmod1 20 + +lblafmod2a: absolutelong +lblafmod2b: lda8 + nextopcode +opb0mod2: testmod1 20 + +lblb0mod2: testmod1 20 + opb0 + nextopcode +opb1m1mod2: testmod1 20 + +lblb1mod2a: directindirectindexed0 +lblb1mod2b: lda8 + nextopcode +opb2m1mod2: testmod1 20 + +lblb2mod2a: directindirect +lblb2mod2b: lda8 + nextopcode +opb3m1mod2: testmod1 20 + +lblb3mod2a: stackasmrelativeindirectindexed0 +lblb3mod2b: lda8 + nextopcode +opb4x0mod2: testmod1 20 + +lblb4mod2a: directindexedx0 +lblb4mod2b: ldy16 + nextopcode +opb5m1mod2: testmod1 20 + +lblb5mod2a: directindexedx0 +lblb5mod2b: lda8 + nextopcode +opb6x0mod2: testmod1 20 + +lblb6mod2a: directindexedy0 +lblb6mod2b: ldx16 + nextopcode +opb7m1mod2: testmod1 20 + +lblb7mod2a: directindirectindexedlong0 +lblb7mod2b: lda8 + nextopcode +opb8mod2: testmod1 20 + +lblb8mod2: testmod1 20 + opb8 + nextopcode +opb9m1mod2: testmod1 20 + +lblb9mod2a: absoluteindexedy0 +lblb9mod2b: lda8 + nextopcode +opbax0mod2: testmod1 20 + +lblbamod2: testmod1 20 + opbax0 + nextopcode +opbbx0mod2: testmod1 20 + +lblbbmod2: testmod1 20 + opbbx0 + nextopcode +opbcx0mod2: testmod1 20 + +lblbcmod2a: absoluteindexedx0 +lblbcmod2b: ldy16 + nextopcode +opbdm1mod2: testmod1 20 + +lblbdmod2a: absoluteindexedx0 +lblbdmod2b: lda8 + nextopcode +opbex0mod2: testmod1 20 + +lblbemod2a: absoluteindexedy0 +lblbemod2b: ldx16 + nextopcode +opbfm1mod2: testmod1 20 + +lblbfmod2a: absolutelongindexedx0 +lblbfmod2b: lda8 + nextopcode +opc0x0mod2: testmod1 20 + +lblc0mod2: testmod1 20 + opc0x0 + nextopcode +opc1m1mod2: testmod1 20 + +lblc1mod2a: directindexedindirect0 +lblc1mod2b: cmp8 + nextopcode +opc2mod2: testmod1 20 + +lblc2mod2: testmod1 20 + opc2 + nextopcode +@@.pool +opc3m1mod2: testmod1 20 + +lblc3mod2a: stackasmrelative +lblc3mod2b: cmp8 + nextopcode +opc4x0mod2: testmod1 20 + +lblc4mod2a: direct +lblc4mod2b: cmy16 + nextopcode +opc5m1mod2: testmod1 20 + +lblc5mod2a: direct +lblc5mod2b: cmp8 + nextopcode +opc6m1mod2: testmod1 20 + +lblc6mod2a: direct +lblc6mod2b: dec8 + nextopcode +opc7m1mod2: testmod1 20 + +lblc7mod2a: directindirectlong +lblc7mod2b: cmp8 + nextopcode +opc8x0mod2: testmod1 20 + +lblc8mod2: testmod1 20 + opc8x0 + nextopcode +opc9m1mod2: testmod1 20 + +lblc9mod2: testmod1 20 + opc9m1 + nextopcode +opcax0mod2: testmod1 20 + +lblcamod2: testmod1 20 + opcax0 + nextopcode +opcbmod2: testmod1 20 + +lblcbmod2: testmod1 20 + opcb + nextopcode +opccx0mod2: testmod1 20 + +lblccmod2a: absolute +lblccmod2b: cmy16 + nextopcode +opcdm1mod2: testmod1 20 + +lblcdmod2a: absolute +lblcdmod2b: cmp8 + nextopcode +opcem1mod2: testmod1 20 + +lblcemod2a: absolute +lblcemod2b: dec8 + nextopcode +opcfm1mod2: testmod1 20 + +lblcfmod2a: absolutelong +lblcfmod2b: cmp8 + nextopcode +opd0mod2: testmod1 20 + +lbld0mod2: testmod1 20 + opd0 + nextopcode +opd1m1mod2: testmod1 20 + +lbld1mod2a: directindirectindexed0 +lbld1mod2b: cmp8 + nextopcode +opd2m1mod2: testmod1 20 + +lbld2mod2a: directindirect +lbld2mod2b: cmp8 + nextopcode +opd3m1mod2: testmod1 20 + +lbld3mod2a: stackasmrelativeindirectindexed0 +lbld3mod2b: cmp8 + nextopcode +opd4mod2: testmod1 20 + +lbld4mod2: testmod1 20 + opd4 + nextopcode +opd5m1mod2: testmod1 20 + +lbld5mod2a: directindexedx0 +lbld5mod2b: cmp8 + nextopcode +opd6m1mod2: testmod1 20 + +lbld6mod2a: directindexedx0 +lbld6mod2b: dec8 + nextopcode +opd7m1mod2: testmod1 20 + +lbld7mod2a: directindirectindexedlong0 +lbld7mod2b: cmp8 + nextopcode +opd8mod2: testmod1 20 + +lbld8mod2: testmod1 20 + opd8 + nextopcode +opd9m1mod2: testmod1 20 + +lbld9mod2a: absoluteindexedy0 +lbld9mod2b: cmp8 + nextopcode +opdax0mod2: testmod1 20 + +lbldamod2: testmod1 20 + opdax0 + nextopcode +opdbmod2: testmod1 20 + +lbldbmod2: testmod1 20 + opdb + nextopcode +opdcmod2: testmod1 20 + +lbldcmod2: testmod1 20 + opdc + nextopcode +opddm1mod2: testmod1 20 + +lblddmod2a: absoluteindexedx0 +lblddmod2b: cmp8 + nextopcode +opdem1mod2: testmod1 20 + +lbldemod2a: absoluteindexedx0 +lbldemod2b: dec8 + nextopcode +opdfm1mod2: testmod1 20 + +lbldfmod2a: absolutelongindexedx0 +lbldfmod2b: cmp8 + nextopcode +ope0x0mod2: testmod1 20 + +lble0mod2: testmod1 20 + ope0x0 + nextopcode +ope1m1mod2: testmod1 20 + +lble1mod2a: directindexedindirect0 +lble1mod2b: sbc8 + nextopcode +ope2mod2: testmod1 20 + +lble2mod2: testmod1 20 + ope2 + nextopcode +@@.pool +ope3m1mod2: testmod1 20 + +lble3mod2a: stackasmrelative +lble3mod2b: sbc8 + nextopcode +ope4x0mod2: testmod1 20 + +lble4mod2a: direct +lble4mod2b: cmx16 + nextopcode +ope5m1mod2: testmod1 20 + +lble5mod2a: direct +lble5mod2b: sbc8 + nextopcode +ope6m1mod2: testmod1 20 + +lble6mod2a: direct +lble6mod2b: inc8 + nextopcode +ope7m1mod2: testmod1 20 + +lble7mod2a: directindirectlong +lble7mod2b: sbc8 + nextopcode +ope8x0mod2: testmod1 20 + +lble8mod2: testmod1 20 + ope8x0 + nextopcode +ope9m1mod2: testmod1 20 + +lble9mod2a: immediate8 +lble9mod2b: sbc8 + nextopcode +opeamod2: testmod1 20 + +lbleamod2: testmod1 20 + opea + nextopcode +opebmod2: testmod1 20 + +lblebmod2: testmod1 20 + opebm1 + nextopcode +opecx0mod2: testmod1 20 + +lblecmod2a: absolute +lblecmod2b: cmx16 + nextopcode +opedm1mod2: testmod1 20 + +lbledmod2a: absolute +lbledmod2b: sbc8 + nextopcode +opeem1mod2: testmod1 20 + +lbleemod2a: absolute +lbleemod2b: inc8 + nextopcode +opefm1mod2: testmod1 20 + +lblefmod2a: absolutelong +lblefmod2b: sbc8 + nextopcode +opf0mod2: testmod1 20 + +lblf0mod2: testmod1 20 + opf0 + nextopcode +opf1m1mod2: testmod1 20 + +lblf1mod2a: directindirectindexed0 +lblf1mod2b: sbc8 + nextopcode +opf2m1mod2: testmod1 20 + +lblf2mod2a: directindirect +lblf2mod2b: sbc8 + nextopcode +opf3m1mod2: testmod1 20 + +lblf3mod2a: stackasmrelativeindirectindexed0 +lblf3mod2b: sbc8 + nextopcode +opf4mod2: testmod1 20 + +lblf4mod2: testmod1 20 + opf4 + nextopcode +opf5m1mod2: testmod1 20 + +lblf5mod2a: directindexedx0 +lblf5mod2b: sbc8 + nextopcode +opf6m1mod2: testmod1 20 + +lblf6mod2a: directindexedx0 +lblf6mod2b: inc8 + nextopcode +opf7m1mod2: testmod1 20 + +lblf7mod2a: directindirectindexedlong0 +lblf7mod2b: sbc8 + nextopcode +opf8mod2: testmod1 20 + +lblf8mod2: testmod1 20 + opf8 + nextopcode +opf9m1mod2: testmod1 20 + +lblf9mod2a: absoluteindexedy0 +lblf9mod2b: sbc8 + nextopcode +opfax0mod2: testmod1 20 + +lblfamod2: testmod1 20 + opfax0 + nextopcode +opfbmod2: testmod1 20 + +lblfbmod2: testmod1 20 + opfb + nextopcode +opfcmod2: testmod1 20 + +lblfcmod2: testmod1 20 + opfcx0 + nextopcode +opfdm1mod2: testmod1 20 + +lblfdmod2a: absoluteindexedx0 +lblfdmod2b: sbc8 + nextopcode +opfem1mod2: testmod1 20 + +lblfemod2a: absoluteindexedx0 +lblfemod2b: inc8 + nextopcode +opffm1mod2: testmod1 20 + +lblffmod2a: absolutelongindexedx0 +lblffmod2b: sbc8 + nextopcode + +@@.pool + + +jumptable3: .long op00mod3 + .long op01m0mod3 + .long op02mod3 + .long op03m0mod3 + .long op04m0mod3 + .long op05m0mod3 + .long op06m0mod3 + .long op07m0mod3 + .long op08mod3 + .long op09m0mod3 + .long op0am0mod3 + .long op0bmod3 + .long op0cm0mod3 + .long op0dm0mod3 + .long op0em0mod3 + .long op0fm0mod3 + .long op10mod3 + .long op11m0mod3 + .long op12m0mod3 + .long op13m0mod3 + .long op14m0mod3 + .long op15m0mod3 + .long op16m0mod3 + .long op17m0mod3 + .long op18mod3 + .long op19m0mod3 + .long op1am0mod3 + .long op1bmod3 + .long op1cm0mod3 + .long op1dm0mod3 + .long op1em0mod3 + .long op1fm0mod3 + .long op20mod3 + .long op21m0mod3 + .long op22mod3 + .long op23m0mod3 + .long op24m0mod3 + .long op25m0mod3 + .long op26m0mod3 + .long op27m0mod3 + .long op28mod3 + .long op29m0mod3 + .long op2am0mod3 + .long op2bmod3 + .long op2cm0mod3 + .long op2dm0mod3 + .long op2em0mod3 + .long op2fm0mod3 + .long op30mod3 + .long op31m0mod3 + .long op32m0mod3 + .long op33m0mod3 + .long op34m0mod3 + .long op35m0mod3 + .long op36m0mod3 + .long op37m0mod3 + .long op38mod3 + .long op39m0mod3 + .long op3am0mod3 + .long op3bmod3 + .long op3cm0mod3 + .long op3dm0mod3 + .long op3em0mod3 + .long op3fm0mod3 + .long op40mod3 + .long op41m0mod3 + .long op42mod3 + .long op43m0mod3 + .long op44x0mod3 + .long op45m0mod3 + .long op46m0mod3 + .long op47m0mod3 + .long op48m0mod3 + .long op49m0mod3 + .long op4am0mod3 + .long op4bmod3 + .long op4cmod3 + .long op4dm0mod3 + .long op4em0mod3 + .long op4fm0mod3 + .long op50mod3 + .long op51m0mod3 + .long op52m0mod3 + .long op53m0mod3 + .long op54x0mod3 + .long op55m0mod3 + .long op56m0mod3 + .long op57m0mod3 + .long op58mod3 + .long op59m0mod3 + .long op5ax0mod3 + .long op5bmod3 + .long op5cmod3 + .long op5dm0mod3 + .long op5em0mod3 + .long op5fm0mod3 + .long op60mod3 + .long op61m0mod3 + .long op62mod3 + .long op63m0mod3 + .long op64m0mod3 + .long op65m0mod3 + .long op66m0mod3 + .long op67m0mod3 + .long op68m0mod3 + .long op69m0mod3 + .long op6am0mod3 + .long op6bmod3 + .long op6cmod3 + .long op6dm0mod3 + .long op6em0mod3 + .long op6fm0mod3 + .long op70mod3 + .long op71m0mod3 + .long op72m0mod3 + .long op73m0mod3 + .long op74m0mod3 + .long op75m0mod3 + .long op76m0mod3 + .long op77m0mod3 + .long op78mod3 + .long op79m0mod3 + .long op7ax0mod3 + .long op7bmod3 + .long op7cmod3 + .long op7dm0mod3 + .long op7em0mod3 + .long op7fm0mod3 + .long op80mod3 + .long op81m0mod3 + .long op82mod3 + .long op83m0mod3 + .long op84x0mod3 + .long op85m0mod3 + .long op86x0mod3 + .long op87m0mod3 + .long op88x0mod3 + .long op89m0mod3 + .long op8am0mod3 + .long op8bmod3 + .long op8cx0mod3 + .long op8dm0mod3 + .long op8ex0mod3 + .long op8fm0mod3 + .long op90mod3 + .long op91m0mod3 + .long op92m0mod3 + .long op93m0mod3 + .long op94x0mod3 + .long op95m0mod3 + .long op96x0mod3 + .long op97m0mod3 + .long op98m0mod3 + .long op99m0mod3 + .long op9amod3 + .long op9bx0mod3 + .long op9cm0mod3 + .long op9dm0mod3 + .long op9em0mod3 + .long op9fm0mod3 + .long opa0x0mod3 + .long opa1m0mod3 + .long opa2x0mod3 + .long opa3m0mod3 + .long opa4x0mod3 + .long opa5m0mod3 + .long opa6x0mod3 + .long opa7m0mod3 + .long opa8x0mod3 + .long opa9m0mod3 + .long opaax0mod3 + .long opabmod3 + .long opacx0mod3 + .long opadm0mod3 + .long opaex0mod3 + .long opafm0mod3 + .long opb0mod3 + .long opb1m0mod3 + .long opb2m0mod3 + .long opb3m0mod3 + .long opb4x0mod3 + .long opb5m0mod3 + .long opb6x0mod3 + .long opb7m0mod3 + .long opb8mod3 + .long opb9m0mod3 + .long opbax0mod3 + .long opbbx0mod3 + .long opbcx0mod3 + .long opbdm0mod3 + .long opbex0mod3 + .long opbfm0mod3 + .long opc0x0mod3 + .long opc1m0mod3 + .long opc2mod3 + .long opc3m0mod3 + .long opc4x0mod3 + .long opc5m0mod3 + .long opc6m0mod3 + .long opc7m0mod3 + .long opc8x0mod3 + .long opc9m0mod3 + .long opcax0mod3 + .long opcbmod3 + .long opccx0mod3 + .long opcdm0mod3 + .long opcem0mod3 + .long opcfm0mod3 + .long opd0mod3 + .long opd1m0mod3 + .long opd2m0mod3 + .long opd3m0mod3 + .long opd4mod3 + .long opd5m0mod3 + .long opd6m0mod3 + .long opd7m0mod3 + .long opd8mod3 + .long opd9m0mod3 + .long opdax0mod3 + .long opdbmod3 + .long opdcmod3 + .long opddm0mod3 + .long opdem0mod3 + .long opdfm0mod3 + .long ope0x0mod3 + .long ope1m0mod3 + .long ope2mod3 + .long ope3m0mod3 + .long ope4x0mod3 + .long ope5m0mod3 + .long ope6m0mod3 + .long ope7m0mod3 + .long ope8x0mod3 + .long ope9m0mod3 + .long opeamod3 + .long opebmod3 + .long opecx0mod3 + .long opedm0mod3 + .long opeem0mod3 + .long opefm0mod3 + .long opf0mod3 + .long opf1m0mod3 + .long opf2m0mod3 + .long opf3m0mod3 + .long opf4mod3 + .long opf5m0mod3 + .long opf6m0mod3 + .long opf7m0mod3 + .long opf8mod3 + .long opf9m0mod3 + .long opfax0mod3 + .long opfbmod3 + .long opfcmod3 + .long opfdm0mod3 + .long opfem0mod3 + .long opffm0mod3 +op00mod3: testmod1 300 + +lbl00mod3: testmod1 300 + op00 + nextopcode +op01m0mod3: testmod1 300 + +lbl01mod3a: directindexedindirect0 +lbl01mod3b: ora16 + nextopcode +op02mod3: testmod1 300 + +lbl02mod3: testmod1 300 + op02 + nextopcode +op03m0mod3: testmod1 300 + +lbl03mod3a: stackasmrelative +lbl03mod3b: ora16 + nextopcode +op04m0mod3: testmod1 300 + +lbl04mod3a: direct +lbl04mod3b: tsb16 + nextopcode +op05m0mod3: testmod1 300 + +lbl05mod3a: direct +lbl05mod3b: ora16 + nextopcode +op06m0mod3: testmod1 300 + +lbl06mod3a: direct +lbl06mod3b: asl16 + nextopcode +op07m0mod3: testmod1 300 + +lbl07mod3a: directindirectlong +lbl07mod3b: ora16 + nextopcode +op08mod3: testmod1 300 + +lbl08mod3: testmod1 300 + op08 + nextopcode +op09m0mod3: testmod1 300 + +lbl09mod3: testmod1 300 + op09m0 + nextopcode +op0am0mod3: testmod1 300 + +lbl0amod3a: a_asl16 + nextopcode +op0bmod3: testmod1 300 + +lbl0bmod3: testmod1 300 + op0b + nextopcode +op0cm0mod3: testmod1 300 + +lbl0cmod3a: absolute +lbl0cmod3b: tsb16 + nextopcode +op0dm0mod3: testmod1 300 + +lbl0dmod3a: absolute +lbl0dmod3b: ora16 + nextopcode +op0em0mod3: testmod1 300 + +lbl0emod3a: absolute +lbl0emod3b: asl16 + nextopcode +op0fm0mod3: testmod1 300 + +lbl0fmod3a: absolutelong +lbl0fmod3b: ora16 + nextopcode +op10mod3: testmod1 300 + +lbl10mod3: testmod1 300 + op10 + nextopcode +op11m0mod3: testmod1 300 + +lbl11mod3a: directindirectindexed0 +lbl11mod3b: ora16 + nextopcode +op12m0mod3: testmod1 300 + +lbl12mod3a: directindirect +lbl12mod3b: ora16 + nextopcode +op13m0mod3: testmod1 300 + +lbl13mod3a: stackasmrelativeindirectindexed0 +lbl13mod3b: ora16 + nextopcode +op14m0mod3: testmod1 300 + +lbl14mod3a: direct +lbl14mod3b: trb16 + nextopcode +op15m0mod3: testmod1 300 + +lbl15mod3a: directindexedx0 +lbl15mod3b: ora16 + nextopcode +op16m0mod3: testmod1 300 + +lbl16mod3a: directindexedx0 +lbl16mod3b: asl16 + nextopcode +op17m0mod3: testmod1 300 + +lbl17mod3a: directindirectindexedlong0 +lbl17mod3b: ora16 + nextopcode +op18mod3: testmod1 300 + +lbl18mod3: testmod1 300 + op18 + nextopcode +op19m0mod3: testmod1 300 + +lbl19mod3a: absoluteindexedy0 +lbl19mod3b: ora16 + nextopcode +op1am0mod3: testmod1 300 + +lbl1amod3a: a_inc16 + nextopcode +op1bmod3: testmod1 300 + +lbl1bmod3: testmod1 300 + op1bm0 + nextopcode +op1cm0mod3: testmod1 300 + +lbl1cmod3a: absolute +lbl1cmod3b: trb16 + nextopcode +op1dm0mod3: testmod1 300 + +lbl1dmod3a: absoluteindexedx0 +lbl1dmod3b: ora16 + nextopcode +op1em0mod3: testmod1 300 + +lbl1emod3a: absoluteindexedx0 +lbl1emod3b: asl16 + nextopcode +op1fm0mod3: testmod1 300 + +lbl1fmod3a: absolutelongindexedx0 +lbl1fmod3b: ora16 + nextopcode +op20mod3: testmod1 300 + +lbl20mod3: testmod1 300 + op20 + nextopcode +op21m0mod3: testmod1 300 + +lbl21mod3a: directindexedindirect0 +lbl21mod3b: and16 + nextopcode +op22mod3: testmod1 300 + +lbl22mod3: testmod1 300 + op22 + nextopcode +op23m0mod3: testmod1 300 + +lbl23mod3a: stackasmrelative +lbl23mod3b: and16 + nextopcode +op24m0mod3: testmod1 300 + +lbl24mod3a: direct +lbl24mod3b: bit16 + nextopcode +op25m0mod3: testmod1 300 + +lbl25mod3a: direct +lbl25mod3b: and16 + nextopcode +op26m0mod3: testmod1 300 + +lbl26mod3a: direct +lbl26mod3b: rol16 + nextopcode +op27m0mod3: testmod1 300 + +lbl27mod3a: directindirectlong +lbl27mod3b: and16 + nextopcode +op28mod3: testmod1 300 + +lbl28mod3: testmod1 300 + op28x0m0 + nextopcode +@@.pool +op29m0mod3: testmod1 300 + +lbl29mod3: testmod1 300 + op29m0 + nextopcode +op2am0mod3: testmod1 300 + +lbl2amod3a: a_rol16 + nextopcode +op2bmod3: testmod1 300 + +lbl2bmod3: testmod1 300 + op2b + nextopcode +op2cm0mod3: testmod1 300 + +lbl2cmod3a: absolute +lbl2cmod3b: bit16 + nextopcode +op2dm0mod3: testmod1 300 + +lbl2dmod3a: absolute +lbl2dmod3b: and16 + nextopcode +op2em0mod3: testmod1 300 + +lbl2emod3a: absolute +lbl2emod3b: rol16 + nextopcode +op2fm0mod3: testmod1 300 + +lbl2fmod3a: absolutelong +lbl2fmod3b: and16 + nextopcode +op30mod3: testmod1 300 + +lbl30mod3: testmod1 300 + op30 + nextopcode +op31m0mod3: testmod1 300 + +lbl31mod3a: directindirectindexed0 +lbl31mod3b: and16 + nextopcode +op32m0mod3: testmod1 300 + +lbl32mod3a: directindirect +lbl32mod3b: and16 + nextopcode +op33m0mod3: testmod1 300 + +lbl33mod3a: stackasmrelativeindirectindexed0 +lbl33mod3b: and16 + nextopcode +op34m0mod3: testmod1 300 + +lbl34mod3a: directindexedx0 +lbl34mod3b: bit16 + nextopcode +op35m0mod3: testmod1 300 + +lbl35mod3a: directindexedx0 +lbl35mod3b: and16 + nextopcode +op36m0mod3: testmod1 300 + +lbl36mod3a: directindexedx0 +lbl36mod3b: rol16 + nextopcode +op37m0mod3: testmod1 300 + +lbl37mod3a: directindirectindexedlong0 +lbl37mod3b: and16 + nextopcode +op38mod3: testmod1 300 + +lbl38mod3: testmod1 300 + op38 + nextopcode +op39m0mod3: testmod1 300 + +lbl39mod3a: absoluteindexedy0 +lbl39mod3b: and16 + nextopcode +op3am0mod3: testmod1 300 + +lbl3amod3a: a_dec16 + nextopcode +op3bmod3: testmod1 300 + +lbl3bmod3: testmod1 300 + op3bm0 + nextopcode +op3cm0mod3: testmod1 300 + +lbl3cmod3a: absoluteindexedx0 +lbl3cmod3b: bit16 + nextopcode +op3dm0mod3: testmod1 300 + +lbl3dmod3a: absoluteindexedx0 +lbl3dmod3b: and16 + nextopcode +op3em0mod3: testmod1 300 + +lbl3emod3a: absoluteindexedx0 +lbl3emod3b: rol16 + nextopcode +op3fm0mod3: testmod1 300 + +lbl3fmod3a: absolutelongindexedx0 +lbl3fmod3b: and16 + nextopcode +op40mod3: testmod1 300 + +lbl40mod3: testmod1 300 + op40x0m0 + nextopcode +@@.pool +op41m0mod3: testmod1 300 + +lbl41mod3a: directindexedindirect0 +lbl41mod3b: eor16 + nextopcode +op42mod3: testmod1 300 + +lbl42mod3: testmod1 300 + op42 + nextopcode +op43m0mod3: testmod1 300 + +lbl43mod3a: stackasmrelative +lbl43mod3b: eor16 + nextopcode +op44x0mod3: testmod1 300 + +lbl44mod3: testmod1 300 + op44x0m0 + nextopcode +op45m0mod3: testmod1 300 + +lbl45mod3a: direct +lbl45mod3b: eor16 + nextopcode +op46m0mod3: testmod1 300 + +lbl46mod3a: direct +lbl46mod3b: lsr16 + nextopcode +op47m0mod3: testmod1 300 + +lbl47mod3a: directindirectlong +lbl47mod3b: eor16 + nextopcode +op48m0mod3: testmod1 300 + +lbl48mod3: testmod1 300 + op48m0 + nextopcode +op49m0mod3: testmod1 300 + +lbl49mod3: testmod1 300 + op49m0 + nextopcode +op4am0mod3: testmod1 300 + +lbl4amod3a: a_lsr16 + nextopcode +op4bmod3: testmod1 300 + +lbl4bmod3: testmod1 300 + op4b + nextopcode +op4cmod3: testmod1 300 + +lbl4cmod3: testmod1 300 + op4c + nextopcode +op4dm0mod3: testmod1 300 + +lbl4dmod3a: absolute +lbl4dmod3b: eor16 + nextopcode +op4em0mod3: testmod1 300 + +lbl4emod3a: absolute +lbl4emod3b: lsr16 + nextopcode +op4fm0mod3: testmod1 300 + +lbl4fmod3a: absolutelong +lbl4fmod3b: eor16 + nextopcode +op50mod3: testmod1 300 + +lbl50mod3: testmod1 300 + op50 + nextopcode +op51m0mod3: testmod1 300 + +lbl51mod3a: directindirectindexed0 +lbl51mod3b: eor16 + nextopcode +op52m0mod3: testmod1 300 + +lbl52mod3a: directindirect +lbl52mod3b: eor16 + nextopcode +op53m0mod3: testmod1 300 + +lbl53mod3a: stackasmrelativeindirectindexed0 +lbl53mod3b: eor16 + nextopcode +op54x0mod3: testmod1 300 + +lbl54mod3: testmod1 300 + op54x0m0 + nextopcode +op55m0mod3: testmod1 300 + +lbl55mod3a: directindexedx0 +lbl55mod3b: eor16 + nextopcode +op56m0mod3: testmod1 300 + +lbl56mod3a: directindexedx0 +lbl56mod3b: lsr16 + nextopcode +op57m0mod3: testmod1 300 + +lbl57mod3a: directindirectindexedlong0 +lbl57mod3b: eor16 + nextopcode +op58mod3: testmod1 300 + +lbl58mod3: testmod1 300 + op58 + nextopcode +op59m0mod3: testmod1 300 + +lbl59mod3a: absoluteindexedy0 +lbl59mod3b: eor16 + nextopcode +op5ax0mod3: testmod1 300 + +lbl5amod3: testmod1 300 + op5ax0 + nextopcode +op5bmod3: testmod1 300 + +lbl5bmod3: testmod1 300 + op5bm0 + nextopcode +op5cmod3: testmod1 300 + +lbl5cmod3: testmod1 300 + op5c + nextopcode +op5dm0mod3: testmod1 300 + +lbl5dmod3a: absoluteindexedx0 +lbl5dmod3b: eor16 + nextopcode +op5em0mod3: testmod1 300 + +lbl5emod3a: absoluteindexedx0 +lbl5emod3b: lsr16 + nextopcode +op5fm0mod3: testmod1 300 + +lbl5fmod3a: absolutelongindexedx0 +lbl5fmod3b: eor16 + nextopcode +op60mod3: testmod1 300 + +lbl60mod3: testmod1 300 + op60 + nextopcode +op61m0mod3: testmod1 300 + +lbl61mod3a: directindexedindirect0 +lbl61mod3b: adc16 + nextopcode +op62mod3: testmod1 300 + +lbl62mod3: testmod1 300 + op62 + nextopcode +op63m0mod3: testmod1 300 + +lbl63mod3a: stackasmrelative +lbl63mod3b: adc16 + nextopcode +@@.pool +op64m0mod3: testmod1 300 + +lbl64mod3a: direct +lbl64mod3b: stz16 + nextopcode +op65m0mod3: testmod1 300 + +lbl65mod3a: direct +lbl65mod3b: adc16 + nextopcode +@@.pool +op66m0mod3: testmod1 300 + +lbl66mod3a: direct +lbl66mod3b: ror16 + nextopcode +op67m0mod3: testmod1 300 + +lbl67mod3a: directindirectlong +lbl67mod3b: adc16 + nextopcode +@@.pool +op68m0mod3: testmod1 300 + +lbl68mod3: testmod1 300 + op68m0 + nextopcode +op69m0mod3: testmod1 300 + +lbl69mod3a: immediate16 +lbl69mod3b: adc16 + nextopcode +@.pool +op6am0mod3: testmod1 300 + +lbl6amod3a: a_ror16 + nextopcode +op6bmod3: testmod1 300 + +lbl6bmod3: testmod1 300 + op6b + nextopcode +op6cmod3: testmod1 300 + +lbl6cmod3: testmod1 300 + op6c + nextopcode +op6dm0mod3: testmod1 300 + +lbl6dmod3a: absolute +lbl6dmod3b: adc16 + nextopcode +op6em0mod3: testmod1 300 + +lbl6emod3a: absolute +lbl6emod3b: ror16 + nextopcode +op6fm0mod3: testmod1 300 + +lbl6fmod3a: absolutelong +lbl6fmod3b: adc16 + nextopcode +op70mod3: testmod1 300 + +lbl70mod3: testmod1 300 + op70 + nextopcode +op71m0mod3: testmod1 300 + +lbl71mod3a: directindirectindexed0 +lbl71mod3b: adc16 + nextopcode +op72m0mod3: testmod1 300 + +lbl72mod3a: directindirect +lbl72mod3b: adc16 + nextopcode +op73m0mod3: testmod1 300 + +lbl73mod3a: stackasmrelativeindirectindexed0 +lbl73mod3b: adc16 + nextopcode +@.pool +op74m0mod3: testmod1 300 + +lbl74mod3a: directindexedx0 +lbl74mod3b: stz16 + nextopcode +op75m0mod3: testmod1 300 + +lbl75mod3a: directindexedx0 +lbl75mod3b: adc16 + nextopcode +@.pool +op76m0mod3: testmod1 300 + +lbl76mod3a: directindexedx0 +lbl76mod3b: ror16 + nextopcode +op77m0mod3: testmod1 300 + +lbl77mod3a: directindirectindexedlong0 +lbl77mod3b: adc16 + nextopcode +op78mod3: testmod1 300 + +lbl78mod3: testmod1 300 + op78 + nextopcode +op79m0mod3: testmod1 300 + +lbl79mod3a: absoluteindexedy0 +lbl79mod3b: adc16 + nextopcode +op7ax0mod3: testmod1 300 + +lbl7amod3: testmod1 300 + op7ax0 + nextopcode +op7bmod3: testmod1 300 + +lbl7bmod3: testmod1 300 + op7bm0 + nextopcode +op7cmod3: testmod1 300 + +lbl7cmod3: testmod1 300 + absoluteindexedindirectx0 + op7c + nextopcode +op7dm0mod3: testmod1 300 + +lbl7dmod3a: absoluteindexedx0 +lbl7dmod3b: adc16 + nextopcode +op7em0mod3: testmod1 300 + +lbl7emod3a: absoluteindexedx0 +lbl7emod3b: ror16 + nextopcode +op7fm0mod3: testmod1 300 + +lbl7fmod3a: absolutelongindexedx0 +lbl7fmod3b: adc16 + nextopcode +@.pool +op80mod3: testmod1 300 + +lbl80mod3: testmod1 300 + op80 + nextopcode +op81m0mod3: testmod1 300 + +lbl81mod3a: directindexedindirect0 +lbl81mod3b: op81m0 + nextopcode +op82mod3: testmod1 300 + +lbl82mod3: testmod1 300 + op82 + nextopcode +op83m0mod3: testmod1 300 + +lbl83mod3a: stackasmrelative +lbl83mod3b: sta16 + nextopcode +op84x0mod3: testmod1 300 + +lbl84mod3a: direct +lbl84mod3b: sty16 + nextopcode +op85m0mod3: testmod1 300 + +lbl85mod3a: direct +lbl85mod3b: sta16 + nextopcode +op86x0mod3: testmod1 300 + +lbl86mod3a: direct +lbl86mod3b: stx16 + nextopcode +op87m0mod3: testmod1 300 + +lbl87mod3a: directindirectlong +lbl87mod3b: sta16 + nextopcode +op88x0mod3: testmod1 300 + +lbl88mod3: testmod1 300 + op88x0 + nextopcode +op89m0mod3: testmod1 300 + +lbl89mod3: testmod1 300 + op89m0 + nextopcode +op8am0mod3: testmod1 300 + +lbl8amod3: testmod1 300 + op8am0x0 + nextopcode +op8bmod3: testmod1 300 + +lbl8bmod3: testmod1 300 + op8b + nextopcode +op8cx0mod3: testmod1 300 + +lbl8cmod3a: absolute +lbl8cmod3b: sty16 + nextopcode +op8dm0mod3: testmod1 300 + +lbl8dmod3a: absolute +lbl8dmod3b: sta16 + nextopcode +op8ex0mod3: testmod1 300 + +lbl8emod3a: absolute +lbl8emod3b: stx16 + nextopcode +op8fm0mod3: testmod1 300 + +lbl8fmod3a: absolutelong +lbl8fmod3b: sta16 + nextopcode +op90mod3: testmod1 300 + +lbl90mod3: testmod1 300 + op90 + nextopcode +op91m0mod3: testmod1 300 + +lbl91mod3a: directindirectindexed0 +lbl91mod3b: sta16 + nextopcode +op92m0mod3: testmod1 300 + +lbl92mod3a: directindirect +lbl92mod3b: sta16 + nextopcode +op93m0mod3: testmod1 300 + +lbl93mod3a: stackasmrelativeindirectindexed0 +lbl93mod3b: sta16 + nextopcode +op94x0mod3: testmod1 300 + +lbl94mod3a: directindexedx0 +lbl94mod3b: sty16 + nextopcode +op95m0mod3: testmod1 300 + +lbl95mod3a: directindexedx0 +lbl95mod3b: sta16 + nextopcode +op96x0mod3: testmod1 300 + +lbl96mod3a: directindexedy0 +lbl96mod3b: stx16 + nextopcode +op97m0mod3: testmod1 300 + +lbl97mod3a: directindirectindexedlong0 +lbl97mod3b: sta16 + nextopcode +op98m0mod3: testmod1 300 + +lbl98mod3: testmod1 300 + op98m0x0 + nextopcode +op99m0mod3: testmod1 300 + +lbl99mod3a: absoluteindexedy0 +lbl99mod3b: sta16 + nextopcode +op9amod3: testmod1 300 + +lbl9amod3: testmod1 300 + op9ax0 + nextopcode +op9bx0mod3: testmod1 300 + +lbl9bmod3: testmod1 300 + op9bx0 + nextopcode +op9cm0mod3: testmod1 300 + +lbl9cmod3a: absolute +lbl9cmod3b: stz16 + nextopcode +op9dm0mod3: testmod1 300 + +lbl9dmod3a: absoluteindexedx0 +lbl9dmod3b: sta16 + nextopcode +op9em0mod3: testmod1 300 + +lbl9emod3: testmod1 300 + absoluteindexedx0 + stz16 + nextopcode +op9fm0mod3: testmod1 300 + +lbl9fmod3a: absolutelongindexedx0 +lbl9fmod3b: sta16 + nextopcode +opa0x0mod3: testmod1 300 + +lbla0mod3: testmod1 300 + opa0x0 + nextopcode +opa1m0mod3: testmod1 300 + +lbla1mod3a: directindexedindirect0 +lbla1mod3b: lda16 + nextopcode +opa2x0mod3: testmod1 300 + +lbla2mod3: testmod1 300 + opa2x0 + nextopcode +opa3m0mod3: testmod1 300 + +lbla3mod3a: stackasmrelative +lbla3mod3b: lda16 + nextopcode +opa4x0mod3: testmod1 300 + +lbla4mod3a: direct +lbla4mod3b: ldy16 + nextopcode +opa5m0mod3: testmod1 300 + +lbla5mod3a: direct +lbla5mod3b: lda16 + nextopcode +opa6x0mod3: testmod1 300 + +lbla6mod3a: direct +lbla6mod3b: ldx16 + nextopcode +opa7m0mod3: testmod1 300 + +lbla7mod3a: directindirectlong +lbla7mod3b: lda16 + nextopcode +opa8x0mod3: testmod1 300 + +lbla8mod3: testmod1 300 + opa8x0m0 + nextopcode +opa9m0mod3: testmod1 300 + +lbla9mod3: testmod1 300 + opa9m0 + nextopcode +opaax0mod3: testmod1 300 + +lblaamod3: testmod1 300 + opaax0m0 + nextopcode +opabmod3: testmod1 300 + +lblabmod3: testmod1 300 + opab + nextopcode +opacx0mod3: testmod1 300 + +lblacmod3a: absolute +lblacmod3b: ldy16 + nextopcode +opadm0mod3: testmod1 300 + +lbladmod3a: absolute +lbladmod3b: lda16 + nextopcode +opaex0mod3: testmod1 300 + +lblaemod3a: absolute +lblaemod3b: ldx16 + nextopcode +opafm0mod3: testmod1 300 + +lblafmod3a: absolutelong +lblafmod3b: lda16 + nextopcode +opb0mod3: testmod1 300 + +lblb0mod3: testmod1 300 + opb0 + nextopcode +opb1m0mod3: testmod1 300 + +lblb1mod3a: directindirectindexed0 +lblb1mod3b: lda16 + nextopcode +opb2m0mod3: testmod1 300 + +lblb2mod3a: directindirect +lblb2mod3b: lda16 + nextopcode +opb3m0mod3: testmod1 300 + +lblb3mod3a: stackasmrelativeindirectindexed0 +lblb3mod3b: lda16 + nextopcode +opb4x0mod3: testmod1 300 + +lblb4mod3a: directindexedx0 +lblb4mod3b: ldy16 + nextopcode +opb5m0mod3: testmod1 300 + +lblb5mod3a: directindexedx0 +lblb5mod3b: lda16 + nextopcode +opb6x0mod3: testmod1 300 + +lblb6mod3a: directindexedy0 +lblb6mod3b: ldx16 + nextopcode +opb7m0mod3: testmod1 300 + +lblb7mod3a: directindirectindexedlong0 +lblb7mod3b: lda16 + nextopcode +opb8mod3: testmod1 300 + +lblb8mod3: testmod1 300 + opb8 + nextopcode +opb9m0mod3: testmod1 300 + +lblb9mod3a: absoluteindexedy0 +lblb9mod3b: lda16 + nextopcode +opbax0mod3: testmod1 300 + +lblbamod3: testmod1 300 + opbax0 + nextopcode +opbbx0mod3: testmod1 300 + +lblbbmod3: testmod1 300 + opbbx0 + nextopcode +opbcx0mod3: testmod1 300 + +lblbcmod3a: absoluteindexedx0 +lblbcmod3b: ldy16 + nextopcode +opbdm0mod3: testmod1 300 + +lblbdmod3a: absoluteindexedx0 +lblbdmod3b: lda16 + nextopcode +opbex0mod3: testmod1 300 + +lblbemod3a: absoluteindexedy0 +lblbemod3b: ldx16 + nextopcode +opbfm0mod3: testmod1 300 + +lblbfmod3a: absolutelongindexedx0 +lblbfmod3b: lda16 + nextopcode +opc0x0mod3: testmod1 300 + +lblc0mod3: testmod1 300 + opc0x0 + nextopcode +opc1m0mod3: testmod1 300 + +lblc1mod3a: directindexedindirect0 +lblc1mod3b: cmp16 + nextopcode +opc2mod3: testmod1 300 + +lblc2mod3: testmod1 300 + opc2 + nextopcode +@.pool +opc3m0mod3: testmod1 300 + +lblc3mod3a: stackasmrelative +lblc3mod3b: cmp16 + nextopcode +opc4x0mod3: testmod1 300 + +lblc4mod3a: direct +lblc4mod3b: cmy16 + nextopcode +opc5m0mod3: testmod1 300 + +lblc5mod3a: direct +lblc5mod3b: cmp16 + nextopcode +opc6m0mod3: testmod1 300 + +lblc6mod3a: direct +lblc6mod3b: dec16 + nextopcode +opc7m0mod3: testmod1 300 + +lblc7mod3a: directindirectlong +lblc7mod3b: cmp16 + nextopcode +opc8x0mod3: testmod1 300 + +lblc8mod3: testmod1 300 + opc8x0 + nextopcode +opc9m0mod3: testmod1 300 + +lblc9mod3: testmod1 300 + opc9m0 + nextopcode +opcax0mod3: testmod1 300 + +lblcamod3: testmod1 300 + opcax0 + nextopcode +opcbmod3: testmod1 300 + +lblcbmod3: testmod1 300 + opcb + nextopcode +opccx0mod3: testmod1 300 + +lblccmod3a: absolute +lblccmod3b: cmy16 + nextopcode +opcdm0mod3: testmod1 300 + +lblcdmod3a: absolute +lblcdmod3b: cmp16 + nextopcode +opcem0mod3: testmod1 300 + +lblcemod3a: absolute +lblcemod3b: dec16 + nextopcode +opcfm0mod3: testmod1 300 + +lblcfmod3a: absolutelong +lblcfmod3b: cmp16 + nextopcode +opd0mod3: testmod1 300 + +lbld0mod3: testmod1 300 + opd0 + nextopcode +opd1m0mod3: testmod1 300 + +lbld1mod3a: directindirectindexed0 +lbld1mod3b: cmp16 + nextopcode +opd2m0mod3: testmod1 300 + +lbld2mod3a: directindirect +lbld2mod3b: cmp16 + nextopcode +opd3m0mod3: testmod1 300 + +lbld3mod3a: stackasmrelativeindirectindexed0 +lbld3mod3b: cmp16 + nextopcode +opd4mod3: testmod1 300 + +lbld4mod3: testmod1 300 + opd4 + nextopcode +opd5m0mod3: testmod1 300 + +lbld5mod3a: directindexedx0 +lbld5mod3b: cmp16 + nextopcode +opd6m0mod3: testmod1 300 + +lbld6mod3a: directindexedx0 +lbld6mod3b: dec16 + nextopcode +opd7m0mod3: testmod1 300 + +lbld7mod3a: directindirectindexedlong0 +lbld7mod3b: cmp16 + nextopcode +opd8mod3: testmod1 300 + +lbld8mod3: testmod1 300 + opd8 + nextopcode +opd9m0mod3: testmod1 300 + +lbld9mod3a: absoluteindexedy0 +lbld9mod3b: cmp16 + nextopcode +opdax0mod3: testmod1 300 + +lbldamod3: testmod1 300 + opdax0 + nextopcode +opdbmod3: testmod1 300 + +lbldbmod3: testmod1 300 + opdb + nextopcode +opdcmod3: testmod1 300 + +lbldcmod3: testmod1 300 + opdc + nextopcode +opddm0mod3: testmod1 300 + +lblddmod3a: absoluteindexedx0 +lblddmod3b: cmp16 + nextopcode +opdem0mod3: testmod1 300 + +lbldemod3a: absoluteindexedx0 +lbldemod3b: dec16 + nextopcode +opdfm0mod3: testmod1 300 + +lbldfmod3a: absolutelongindexedx0 +lbldfmod3b: cmp16 + nextopcode +ope0x0mod3: testmod1 300 + +lble0mod3: testmod1 300 + ope0x0 + nextopcode +ope1m0mod3: testmod1 300 + +lble1mod3a: directindexedindirect0 +lble1mod3b: sbc16 + nextopcode +ope2mod3: testmod1 300 + +lble2mod3: testmod1 300 + ope2 + nextopcode +@.pool +ope3m0mod3: testmod1 300 + +lble3mod3a: stackasmrelative +lble3mod3b: sbc16 + nextopcode +ope4x0mod3: testmod1 300 + +lble4mod3a: direct +lble4mod3b: cmx16 + nextopcode +ope5m0mod3: testmod1 300 + +lble5mod3a: direct +lble5mod3b: sbc16 + nextopcode +ope6m0mod3: testmod1 300 + +lble6mod3a: direct +lble6mod3b: inc16 + nextopcode +ope7m0mod3: testmod1 300 + +lble7mod3a: directindirectlong +lble7mod3b: sbc16 + nextopcode +ope8x0mod3: testmod1 300 + +lble8mod3: testmod1 300 + ope8x0 + nextopcode +ope9m0mod3: testmod1 300 + +lble9mod3a: immediate16 +lble9mod3b: sbc16 + nextopcode +opeamod3: testmod1 300 + +lbleamod3: testmod1 300 + opea + nextopcode +opebmod3: testmod1 300 + +lblebmod3: testmod1 300 + opebm0 + nextopcode +opecx0mod3: testmod1 300 + +lblecmod3a: absolute +lblecmod3b: cmx16 + nextopcode +opedm0mod3: testmod1 300 + +lbledmod3a: absolute +lbledmod3b: sbc16 + nextopcode +opeem0mod3: testmod1 300 + +lbleemod3a: absolute +lbleemod3b: inc16 + nextopcode +opefm0mod3: testmod1 300 + +lblefmod3a: absolutelong +lblefmod3b: sbc16 + nextopcode +opf0mod3: testmod1 300 + +lblf0mod3: testmod1 300 + opf0 + nextopcode +opf1m0mod3: testmod1 300 + +lblf1mod3a: directindirectindexed0 +lblf1mod3b: sbc16 + nextopcode +opf2m0mod3: testmod1 300 + +lblf2mod3a: directindirect +lblf2mod3b: sbc16 + nextopcode +opf3m0mod3: testmod1 300 + +lblf3mod3a: stackasmrelativeindirectindexed0 +lblf3mod3b: sbc16 + nextopcode +opf4mod3: testmod1 300 + +lblf4mod3: testmod1 300 + opf4 + nextopcode +opf5m0mod3: testmod1 300 + +lblf5mod3a: directindexedx0 +lblf5mod3b: sbc16 + nextopcode +opf6m0mod3: testmod1 300 + +lblf6mod3a: directindexedx0 +lblf6mod3b: inc16 + nextopcode +opf7m0mod3: testmod1 300 + +lblf7mod3a: directindirectindexedlong0 +lblf7mod3b: sbc16 + nextopcode +opf8mod3: testmod1 300 + +lblf8mod3: testmod1 300 + opf8 + nextopcode +opf9m0mod3: testmod1 300 + +lblf9mod3a: absoluteindexedy0 +lblf9mod3b: sbc16 + nextopcode +opfax0mod3: testmod1 300 + +lblfamod3: testmod1 300 + opfax0 + nextopcode +opfbmod3: testmod1 300 + +lblfbmod3: testmod1 300 + opfb + nextopcode +opfcmod3: testmod1 300 + +lblfcmod3: testmod1 300 + opfcx0 + nextopcode +opfdm0mod3: testmod1 300 + +lblfdmod3a: absoluteindexedx0 +lblfdmod3b: sbc16 + nextopcode +opfem0mod3: testmod1 300 + +lblfemod3a: absoluteindexedx0 +lblfemod3b: inc16 + nextopcode +opffm0mod3: testmod1 300 + +lblffmod3a: absolutelongindexedx0 +lblffmod3b: sbc16 + nextopcode +@.pool + +jumptable4: .long op00mod4 + .long op01m0mod4 + .long op02mod4 + .long op03m0mod4 + .long op04m0mod4 + .long op05m0mod4 + .long op06m0mod4 + .long op07m0mod4 + .long op08mod4 + .long op09m0mod4 + .long op0am0mod4 + .long op0bmod4 + .long op0cm0mod4 + .long op0dm0mod4 + .long op0em0mod4 + .long op0fm0mod4 + .long op10mod4 + .long op11m0mod4 + .long op12m0mod4 + .long op13m0mod4 + .long op14m0mod4 + .long op15m0mod4 + .long op16m0mod4 + .long op17m0mod4 + .long op18mod4 + .long op19m0mod4 + .long op1am0mod4 + .long op1bmod4 + .long op1cm0mod4 + .long op1dm0mod4 + .long op1em0mod4 + .long op1fm0mod4 + .long op20mod4 + .long op21m0mod4 + .long op22mod4 + .long op23m0mod4 + .long op24m0mod4 + .long op25m0mod4 + .long op26m0mod4 + .long op27m0mod4 + .long op28mod4 + .long op29m0mod4 + .long op2am0mod4 + .long op2bmod4 + .long op2cm0mod4 + .long op2dm0mod4 + .long op2em0mod4 + .long op2fm0mod4 + .long op30mod4 + .long op31m0mod4 + .long op32m0mod4 + .long op33m0mod4 + .long op34m0mod4 + .long op35m0mod4 + .long op36m0mod4 + .long op37m0mod4 + .long op38mod4 + .long op39m0mod4 + .long op3am0mod4 + .long op3bmod4 + .long op3cm0mod4 + .long op3dm0mod4 + .long op3em0mod4 + .long op3fm0mod4 + .long op40mod4 + .long op41m0mod4 + .long op42mod4 + .long op43m0mod4 + .long op44x1mod4 + .long op45m0mod4 + .long op46m0mod4 + .long op47m0mod4 + .long op48m0mod4 + .long op49m0mod4 + .long op4am0mod4 + .long op4bmod4 + .long op4cmod4 + .long op4dm0mod4 + .long op4em0mod4 + .long op4fm0mod4 + .long op50mod4 + .long op51m0mod4 + .long op52m0mod4 + .long op53m0mod4 + .long op54x1mod4 + .long op55m0mod4 + .long op56m0mod4 + .long op57m0mod4 + .long op58mod4 + .long op59m0mod4 + .long op5ax1mod4 + .long op5bmod4 + .long op5cmod4 + .long op5dm0mod4 + .long op5em0mod4 + .long op5fm0mod4 + .long op60mod4 + .long op61m0mod4 + .long op62mod4 + .long op63m0mod4 + .long op64m0mod4 + .long op65m0mod4 + .long op66m0mod4 + .long op67m0mod4 + .long op68m0mod4 + .long op69m0mod4 + .long op6am0mod4 + .long op6bmod4 + .long op6cmod4 + .long op6dm0mod4 + .long op6em0mod4 + .long op6fm0mod4 + .long op70mod4 + .long op71m0mod4 + .long op72m0mod4 + .long op73m0mod4 + .long op74m0mod4 + .long op75m0mod4 + .long op76m0mod4 + .long op77m0mod4 + .long op78mod4 + .long op79m0mod4 + .long op7ax1mod4 + .long op7bmod4 + .long op7cmod4 + .long op7dm0mod4 + .long op7em0mod4 + .long op7fm0mod4 + .long op80mod4 + .long op81m0mod4 + .long op82mod4 + .long op83m0mod4 + .long op84x1mod4 + .long op85m0mod4 + .long op86x1mod4 + .long op87m0mod4 + .long op88x1mod4 + .long op89m0mod4 + .long op8am0mod4 + .long op8bmod4 + .long op8cx1mod4 + .long op8dm0mod4 + .long op8ex1mod4 + .long op8fm0mod4 + .long op90mod4 + .long op91m0mod4 + .long op92m0mod4 + .long op93m0mod4 + .long op94x1mod4 + .long op95m0mod4 + .long op96x1mod4 + .long op97m0mod4 + .long op98m0mod4 + .long op99m0mod4 + .long op9amod4 + .long op9bx1mod4 + .long op9cm0mod4 + .long op9dm0mod4 + .long op9em0mod4 + .long op9fm0mod4 + .long opa0x1mod4 + .long opa1m0mod4 + .long opa2x1mod4 + .long opa3m0mod4 + .long opa4x1mod4 + .long opa5m0mod4 + .long opa6x1mod4 + .long opa7m0mod4 + .long opa8x1mod4 + .long opa9m0mod4 + .long opaax1mod4 + .long opabmod4 + .long opacx1mod4 + .long opadm0mod4 + .long opaex1mod4 + .long opafm0mod4 + .long opb0mod4 + .long opb1m0mod4 + .long opb2m0mod4 + .long opb3m0mod4 + .long opb4x1mod4 + .long opb5m0mod4 + .long opb6x1mod4 + .long opb7m0mod4 + .long opb8mod4 + .long opb9m0mod4 + .long opbax1mod4 + .long opbbx1mod4 + .long opbcx1mod4 + .long opbdm0mod4 + .long opbex1mod4 + .long opbfm0mod4 + .long opc0x1mod4 + .long opc1m0mod4 + .long opc2mod4 + .long opc3m0mod4 + .long opc4x1mod4 + .long opc5m0mod4 + .long opc6m0mod4 + .long opc7m0mod4 + .long opc8x1mod4 + .long opc9m0mod4 + .long opcax1mod4 + .long opcbmod4 + .long opccx1mod4 + .long opcdm0mod4 + .long opcem0mod4 + .long opcfm0mod4 + .long opd0mod4 + .long opd1m0mod4 + .long opd2m0mod4 + .long opd3m0mod4 + .long opd4mod4 + .long opd5m0mod4 + .long opd6m0mod4 + .long opd7m0mod4 + .long opd8mod4 + .long opd9m0mod4 + .long opdax1mod4 + .long opdbmod4 + .long opdcmod4 + .long opddm0mod4 + .long opdem0mod4 + .long opdfm0mod4 + .long ope0x1mod4 + .long ope1m0mod4 + .long ope2mod4 + .long ope3m0mod4 + .long ope4x1mod4 + .long ope5m0mod4 + .long ope6m0mod4 + .long ope7m0mod4 + .long ope8x1mod4 + .long ope9m0mod4 + .long opeamod4 + .long opebmod4 + .long opecx1mod4 + .long opedm0mod4 + .long opeem0mod4 + .long opefm0mod4 + .long opf0mod4 + .long opf1m0mod4 + .long opf2m0mod4 + .long opf3m0mod4 + .long opf4mod4 + .long opf5m0mod4 + .long opf6m0mod4 + .long opf7m0mod4 + .long opf8mod4 + .long opf9m0mod4 + .long opfax1mod4 + .long opfbmod4 + .long opfcmod4 + .long opfdm0mod4 + .long opfem0mod4 + .long opffm0mod4 +op00mod4: testmod1 1 + +lbl00mod4: testmod1 2 + op00 + nextopcode +op01m0mod4: testmod1 3 + +lbl01mod4a: directindexedindirect1 +lbl01mod4b: ora16 + nextopcode +op02mod4: testmod1 4 + +lbl02mod4: testmod1 5 + op02 + nextopcode +op03m0mod4: testmod1 6 + +lbl03mod4a: stackasmrelative +lbl03mod4b: ora16 + nextopcode +op04m0mod4: testmod1 7 + +lbl04mod4a: direct +lbl04mod4b: tsb16 + nextopcode +op05m0mod4: testmod1 8 + +lbl05mod4a: direct +lbl05mod4b: ora16 + nextopcode +op06m0mod4: testmod1 9 + +lbl06mod4a: direct +lbl06mod4b: asl16 + nextopcode +op07m0mod4: testmod1 10 + +lbl07mod4a: directindirectlong +lbl07mod4b: ora16 + nextopcode +op08mod4: testmod1 11 + +lbl08mod4: testmod1 12 + op08 + nextopcode +op09m0mod4: testmod1 13 + +lbl09mod4: testmod1 14 + op09m0 + nextopcode +op0am0mod4: testmod1 15 + +lbl0amod4a: a_asl16 + nextopcode +op0bmod4: testmod1 16 + +lbl0bmod4: testmod1 17 + op0b + nextopcode +op0cm0mod4: testmod1 18 + +lbl0cmod4a: absolute +lbl0cmod4b: tsb16 + nextopcode +op0dm0mod4: testmod1 19 + +lbl0dmod4a: absolute +lbl0dmod4b: ora16 + nextopcode +op0em0mod4: testmod1 20 + +lbl0emod4a: absolute +lbl0emod4b: asl16 + nextopcode +op0fm0mod4: testmod1 21 + +lbl0fmod4a: absolutelong +lbl0fmod4b: ora16 + nextopcode +op10mod4: testmod1 22 + +lbl10mod4: testmod1 23 + op10 + nextopcode +op11m0mod4: testmod1 24 + +lbl11mod4a: directindirectindexed1 +lbl11mod4b: ora16 + nextopcode +op12m0mod4: testmod1 25 + +lbl12mod4a: directindirect +lbl12mod4b: ora16 + nextopcode +op13m0mod4: testmod1 26 + +lbl13mod4a: stackasmrelativeindirectindexed1 +lbl13mod4b: ora16 + nextopcode +op14m0mod4: testmod1 27 + +lbl14mod4a: direct +lbl14mod4b: trb16 + nextopcode +op15m0mod4: testmod1 28 + +lbl15mod4a: directindexedx1 +lbl15mod4b: ora16 + nextopcode +op16m0mod4: testmod1 29 + +lbl16mod4a: directindexedx1 +lbl16mod4b: asl16 + nextopcode +op17m0mod4: testmod1 30 + +lbl17mod4a: directindirectindexedlong1 +lbl17mod4b: ora16 + nextopcode +op18mod4: testmod1 31 + +lbl18mod4: testmod1 32 + op18 + nextopcode +op19m0mod4: testmod1 33 + +lbl19mod4a: absoluteindexedy1 +lbl19mod4b: ora16 + nextopcode +op1am0mod4: testmod1 34 + +lbl1amod4a: a_inc16 + nextopcode +op1bmod4: testmod1 35 + +lbl1bmod4: testmod1 36 + op1bm0 + nextopcode +op1cm0mod4: testmod1 37 + +lbl1cmod4a: absolute +lbl1cmod4b: trb16 + nextopcode +op1dm0mod4: testmod1 38 + +lbl1dmod4a: absoluteindexedx1 +lbl1dmod4b: ora16 + nextopcode +op1em0mod4: testmod1 39 + +lbl1emod4a: absoluteindexedx1 +lbl1emod4b: asl16 + nextopcode +op1fm0mod4: testmod1 440 + +lbl1fmod4a: absolutelongindexedx1 +lbl1fmod4b: ora16 + nextopcode +op20mod4: testmod1 440 + +lbl20mod4: testmod1 440 + op20 + nextopcode +op21m0mod4: testmod1 440 + +lbl21mod4a: directindexedindirect1 +lbl21mod4b: and16 + nextopcode +op22mod4: testmod1 440 + +lbl22mod4: testmod1 440 + op22 + nextopcode +op23m0mod4: testmod1 440 + +lbl23mod4a: stackasmrelative +lbl23mod4b: and16 + nextopcode +op24m0mod4: testmod1 440 + +lbl24mod4a: direct +lbl24mod4b: bit16 + nextopcode +op25m0mod4: testmod1 440 + +lbl25mod4a: direct +lbl25mod4b: and16 + nextopcode +op26m0mod4: testmod1 440 + +lbl26mod4a: direct +lbl26mod4b: rol16 + nextopcode +op27m0mod4: testmod1 440 + +lbl27mod4a: directindirectlong +lbl27mod4b: and16 + nextopcode +op28mod4: testmod1 440 + +lbl28mod4: testmod1 440 + op28x1m0 + nextopcode +@.pool +op29m0mod4: testmod1 440 + +lbl29mod4: testmod1 440 + op29m0 + nextopcode +op2am0mod4: testmod1 440 + +lbl2amod4a: a_rol16 + nextopcode +op2bmod4: testmod1 440 + +lbl2bmod4: testmod1 460 + op2b + nextopcode +op2cm0mod4: testmod1 460 + +lbl2cmod4a: absolute +lbl2cmod4b: bit16 + nextopcode +op2dm0mod4: testmod1 460 + +lbl2dmod4a: absolute +lbl2dmod4b: and16 + nextopcode +op2em0mod4: testmod1 460 + +lbl2emod4a: absolute +lbl2emod4b: rol16 + nextopcode +op2fm0mod4: testmod1 460 + +lbl2fmod4a: absolutelong +lbl2fmod4b: and16 + nextopcode +op30mod4: testmod1 460 + +lbl30mod4: testmod1 460 + op30 + nextopcode +op31m0mod4: testmod1 460 + +lbl31mod4a: directindirectindexed1 +lbl31mod4b: and16 + nextopcode +op32m0mod4: testmod1 460 + +lbl32mod4a: directindirect +lbl32mod4b: and16 + nextopcode +op33m0mod4: testmod1 460 + +lbl33mod4a: stackasmrelativeindirectindexed1 +lbl33mod4b: and16 + nextopcode +op34m0mod4: testmod1 460 + +lbl34mod4a: directindexedx1 +lbl34mod4b: bit16 + nextopcode +op35m0mod4: testmod1 460 + +lbl35mod4a: directindexedx1 +lbl35mod4b: and16 + nextopcode +op36m0mod4: testmod1 460 + +lbl36mod4a: directindexedx1 +lbl36mod4b: rol16 + nextopcode +op37m0mod4: testmod1 460 + +lbl37mod4a: directindirectindexedlong1 +lbl37mod4b: and16 + nextopcode +op38mod4: testmod1 460 + +lbl38mod4: testmod1 460 + op38 + nextopcode +op39m0mod4: testmod1 460 + +lbl39mod4a: absoluteindexedy1 +lbl39mod4b: and16 + nextopcode +op3am0mod4: testmod1 460 + +lbl3amod4a: a_dec16 + nextopcode +op3bmod4: testmod1 460 + +lbl3bmod4: testmod1 480 + op3bm0 + nextopcode +op3cm0mod4: testmod1 480 + +lbl3cmod4a: absoluteindexedx1 +lbl3cmod4b: bit16 + nextopcode +op3dm0mod4: testmod1 480 + +lbl3dmod4a: absoluteindexedx1 +lbl3dmod4b: and16 + nextopcode +op3em0mod4: testmod1 480 + +lbl3emod4a: absoluteindexedx1 +lbl3emod4b: rol16 + nextopcode +op3fm0mod4: testmod1 480 + +lbl3fmod4a: absolutelongindexedx1 +lbl3fmod4b: and16 + nextopcode +op40mod4: testmod1 480 + +lbl40mod4: testmod1 480 + op40x1m0 + nextopcode +@.pool +op41m0mod4: testmod1 480 + +lbl41mod4a: directindexedindirect1 +lbl41mod4b: eor16 + nextopcode +op42mod4: testmod1 480 + +lbl42mod4: testmod1 480 + op42 + nextopcode +op43m0mod4: testmod1 480 + +lbl43mod4a: stackasmrelative +lbl43mod4b: eor16 + nextopcode +op44x1mod4: testmod1 480 + +lbl44mod4: testmod1 480 + op44x1m0 + nextopcode +op45m0mod4: testmod1 480 + +lbl45mod4a: direct +lbl45mod4b: eor16 + nextopcode +op46m0mod4: testmod1 480 + +lbl46mod4a: direct +lbl46mod4b: lsr16 + nextopcode +op47m0mod4: testmod1 480 + +lbl47mod4a: directindirectlong +lbl47mod4b: eor16 + nextopcode +op48m0mod4: testmod1 480 + +lbl48mod4: testmod1 480 + op48m0 + nextopcode +op49m0mod4: testmod1 480 + +lbl49mod4: testmod1 480 + op49m0 + nextopcode +op4am0mod4: testmod1 480 + +lbl4amod4a: a_lsr16 + nextopcode +op4bmod4: testmod1 480 + +lbl4bmod4: testmod1 480 + op4b + nextopcode +op4cmod4: testmod1 500 + +lbl4cmod4: testmod1 500 + op4c + nextopcode +op4dm0mod4: testmod1 500 + +lbl4dmod4a: absolute +lbl4dmod4b: eor16 + nextopcode +op4em0mod4: testmod1 500 + +lbl4emod4a: absolute +lbl4emod4b: lsr16 + nextopcode +op4fm0mod4: testmod1 500 + +lbl4fmod4a: absolutelong +lbl4fmod4b: eor16 + nextopcode +op50mod4: testmod1 500 + +lbl50mod4: testmod1 500 + op50 + nextopcode +op51m0mod4: testmod1 500 + +lbl51mod4a: directindirectindexed1 +lbl51mod4b: eor16 + nextopcode +op52m0mod4: testmod1 500 + +lbl52mod4a: directindirect +lbl52mod4b: eor16 + nextopcode +op53m0mod4: testmod1 500 + +lbl53mod4a: stackasmrelativeindirectindexed1 +lbl53mod4b: eor16 + nextopcode +op54x1mod4: testmod1 500 + +lbl54mod4: testmod1 500 + op54x1m0 + nextopcode +op55m0mod4: testmod1 500 + +lbl55mod4a: directindexedx1 +lbl55mod4b: eor16 + nextopcode +op56m0mod4: testmod1 500 + +lbl56mod4a: directindexedx1 +lbl56mod4b: lsr16 + nextopcode +op57m0mod4: testmod1 500 + +lbl57mod4a: directindirectindexedlong1 +lbl57mod4b: eor16 + nextopcode +op58mod4: testmod1 500 + +lbl58mod4: testmod1 500 + op58 + nextopcode +op59m0mod4: testmod1 500 + +lbl59mod4a: absoluteindexedy1 +lbl59mod4b: eor16 + nextopcode +op5ax1mod4: testmod1 500 + +lbl5amod4: testmod1 500 + op5ax1 + nextopcode +op5bmod4: testmod1 500 + +lbl5bmod4: testmod1 500 + op5bm0 + nextopcode +op5cmod4: testmod1 520 + +lbl5cmod4: testmod1 520 + op5c + nextopcode +op5dm0mod4: testmod1 520 + +lbl5dmod4a: absoluteindexedx1 +lbl5dmod4b: eor16 + nextopcode +op5em0mod4: testmod1 520 + +lbl5emod4a: absoluteindexedx1 +lbl5emod4b: lsr16 + nextopcode +op5fm0mod4: testmod1 520 + +lbl5fmod4a: absolutelongindexedx1 +lbl5fmod4b: eor16 + nextopcode +op60mod4: testmod1 520 + +lbl60mod4: testmod1 520 + op60 + nextopcode +op61m0mod4: testmod1 520 + +lbl61mod4a: directindexedindirect1 +lbl61mod4b: adc16 + nextopcode +op62mod4: testmod1 520 + +lbl62mod4: testmod1 520 + op62 + nextopcode +op63m0mod4: testmod1 520 + +lbl63mod4a: stackasmrelative +lbl63mod4b: adc16 + nextopcode +@.pool +op64m0mod4: testmod1 520 + +lbl64mod4a: direct +lbl64mod4b: stz16 + nextopcode +op65m0mod4: testmod1 520 + +lbl65mod4a: direct +lbl65mod4b: adc16 + nextopcode +@.pool +op66m0mod4: testmod1 540 + +lbl66mod4a: direct +lbl66mod4b: ror16 + nextopcode +op67m0mod4: testmod1 540 + +lbl67mod4a: directindirectlong +lbl67mod4b: adc16 + nextopcode +@.pool +op68m0mod4: testmod1 540 + +lbl68mod4: testmod1 540 + op68m0 + nextopcode +op69m0mod4: testmod1 540 + +lbl69mod4a: immediate16 +lbl69mod4b: adc16 + nextopcode +@.pool +op6am0mod4: testmod1 540 + +lbl6amod4a: a_ror16 + nextopcode +op6bmod4: testmod1 540 + +lbl6bmod4: testmod1 540 + op6b + nextopcode +op6cmod4: testmod1 540 + +lbl6cmod4: testmod1 540 + op6c + nextopcode +op6dm0mod4: testmod1 540 + +lbl6dmod4a: absolute +lbl6dmod4b: adc16 + nextopcode +op6em0mod4: testmod1 540 + +lbl6emod4a: absolute +lbl6emod4b: ror16 + nextopcode +op6fm0mod4: testmod1 540 + +lbl6fmod4a: absolutelong +lbl6fmod4b: adc16 + nextopcode +op70mod4: testmod1 540 + +lbl70mod4: testmod1 540 + op70 + nextopcode +op71m0mod4: testmod1 540 + +lbl71mod4a: directindirectindexed1 +lbl71mod4b: adc16 + nextopcode +op72m0mod4: testmod1 540 + +lbl72mod4a: directindirect +lbl72mod4b: adc16 + nextopcode +op73m0mod4: testmod1 540 + +lbl73mod4a: stackasmrelativeindirectindexed1 +lbl73mod4b: adc16 + nextopcode +@.pool +op74m0mod4: testmod1 540 + +lbl74mod4a: directindexedx1 +lbl74mod4b: stz16 + nextopcode +op75m0mod4: testmod1 540 + +lbl75mod4a: directindexedx1 +lbl75mod4b: adc16 + nextopcode +@.pool +op76m0mod4: testmod1 540 + +lbl76mod4a: directindexedx1 +lbl76mod4b: ror16 + nextopcode +op77m0mod4: testmod1 540 + +lbl77mod4a: directindirectindexedlong1 +lbl77mod4b: adc16 + nextopcode +op78mod4: testmod1 540 + +lbl78mod4: testmod1 540 + op78 + nextopcode +op79m0mod4: testmod1 560 + +lbl79mod4a: absoluteindexedy1 +lbl79mod4b: adc16 + nextopcode +op7ax1mod4: testmod1 560 + +lbl7amod4: testmod1 560 + op7ax1 + nextopcode +op7bmod4: testmod1 560 + +lbl7bmod4: testmod1 560 + op7bm0 + nextopcode +op7cmod4: testmod1 560 + +lbl7cmod4: testmod1 560 + absoluteindexedindirectx1 + op7c + nextopcode +op7dm0mod4: testmod1 560 + +lbl7dmod4a: absoluteindexedx1 +lbl7dmod4b: adc16 + nextopcode +op7em0mod4: testmod1 560 + +lbl7emod4a: absoluteindexedx1 +lbl7emod4b: ror16 + nextopcode +op7fm0mod4: testmod1 560 + +lbl7fmod4a: absolutelongindexedx1 +lbl7fmod4b: adc16 + nextopcode +@.pool +op80mod4: testmod1 560 + +lbl80mod4: testmod1 560 + op80 + nextopcode +op81m0mod4: testmod1 560 + +lbl81mod4a: directindexedindirect1 +lbl81mod4b: op81m0 + nextopcode +op82mod4: testmod1 560 + +lbl82mod4: testmod1 560 + op82 + nextopcode +op83m0mod4: testmod1 560 + +lbl83mod4a: stackasmrelative +lbl83mod4b: sta16 + nextopcode +op84x1mod4: testmod1 560 + +lbl84mod4a: direct +lbl84mod4b: sty8 + nextopcode +op85m0mod4: testmod1 560 + +lbl85mod4a: direct +lbl85mod4b: sta16 + nextopcode +op86x1mod4: testmod1 560 + +lbl86mod4a: direct +lbl86mod4b: stx8 + nextopcode +op87m0mod4: testmod1 560 + +lbl87mod4a: directindirectlong +lbl87mod4b: sta16 + nextopcode +op88x1mod4: testmod1 560 + +lbl88mod4: testmod1 560 + op88x1 + nextopcode +op89m0mod4: testmod1 560 + +lbl89mod4: testmod1 560 + op89m0 + nextopcode +op8am0mod4: testmod1 560 + +lbl8amod4: testmod1 560 + op8am0x1 + nextopcode +op8bmod4: testmod1 580 + +lbl8bmod4: testmod1 580 + op8b + nextopcode +op8cx1mod4: testmod1 580 + +lbl8cmod4a: absolute +lbl8cmod4b: sty8 + nextopcode +op8dm0mod4: testmod1 580 + +lbl8dmod4a: absolute +lbl8dmod4b: sta16 + nextopcode +op8ex1mod4: testmod1 580 + +lbl8emod4a: absolute +lbl8emod4b: stx8 + nextopcode +op8fm0mod4: testmod1 580 + +lbl8fmod4a: absolutelong +lbl8fmod4b: sta16 + nextopcode +op90mod4: testmod1 580 + +lbl90mod4: testmod1 580 + op90 + nextopcode +op91m0mod4: testmod1 580 + +lbl91mod4a: directindirectindexed1 +lbl91mod4b: sta16 + nextopcode +op92m0mod4: testmod1 580 + +lbl92mod4a: directindirect +lbl92mod4b: sta16 + nextopcode +op93m0mod4: testmod1 580 + +lbl93mod4a: stackasmrelativeindirectindexed1 +lbl93mod4b: sta16 + nextopcode +op94x1mod4: testmod1 580 + +lbl94mod4a: directindexedx1 +lbl94mod4b: sty8 + nextopcode +op95m0mod4: testmod1 580 + +lbl95mod4a: directindexedx1 +lbl95mod4b: sta16 + nextopcode +op96x1mod4: testmod1 580 + +lbl96mod4a: directindexedy1 +lbl96mod4b: stx8 + nextopcode +op97m0mod4: testmod1 580 + +lbl97mod4a: directindirectindexedlong1 +lbl97mod4b: sta16 + nextopcode +op98m0mod4: testmod1 580 + +lbl98mod4: testmod1 580 + op98m0x1 + nextopcode +op99m0mod4: testmod1 580 + +lbl99mod4a: absoluteindexedy1 +lbl99mod4b: sta16 + nextopcode +op9amod4: testmod1 580 + +lbl9amod4: testmod1 580 + op9ax1 + nextopcode +op9bx1mod4: testmod1 580 + +lbl9bmod4: testmod1 580 + op9bx1 + nextopcode +op9cm0mod4: testmod1 580 + +lbl9cmod4a: absolute +lbl9cmod4b: stz16 + nextopcode +op9dm0mod4: testmod1 580 + +lbl9dmod4a: absoluteindexedx1 +lbl9dmod4b: sta16 + nextopcode +op9em0mod4: testmod1 580 + +lbl9emod4: testmod1 580 + absoluteindexedx1 + stz16 + nextopcode +op9fm0mod4: testmod1 580 + +lbl9fmod4a: absolutelongindexedx1 +lbl9fmod4b: sta16 + nextopcode +opa0x1mod4: testmod1 580 + +lbla0mod4: testmod1 580 + opa0x1 + nextopcode +opa1m0mod4: testmod1 600 + +lbla1mod4a: directindexedindirect1 +lbla1mod4b: lda16 + nextopcode +opa2x1mod4: testmod1 600 + +lbla2mod4: testmod1 600 + opa2x1 + nextopcode +opa3m0mod4: testmod1 600 + +lbla3mod4a: stackasmrelative +lbla3mod4b: lda16 + nextopcode +opa4x1mod4: testmod1 600 + +lbla4mod4a: direct +lbla4mod4b: ldy8 + nextopcode +opa5m0mod4: testmod1 600 + +lbla5mod4a: direct +lbla5mod4b: lda16 + nextopcode +opa6x1mod4: testmod1 600 + +lbla6mod4a: direct +lbla6mod4b: ldx8 + nextopcode +opa7m0mod4: testmod1 600 + +lbla7mod4a: directindirectlong +lbla7mod4b: lda16 + nextopcode +opa8x1mod4: testmod1 600 + +lbla8mod4: testmod1 600 + opa8x1m0 + nextopcode +opa9m0mod4: testmod1 600 + +lbla9mod4: testmod1 600 + opa9m0 + nextopcode +opaax1mod4: testmod1 600 + +lblaamod4: testmod1 600 + opaax1m0 + nextopcode +opabmod4: testmod1 600 + +lblabmod4: testmod1 600 + opab + nextopcode +opacx1mod4: testmod1 600 + +lblacmod4a: absolute +lblacmod4b: ldy8 + nextopcode +opadm0mod4: testmod1 600 + +lbladmod4a: absolute +lbladmod4b: lda16 + nextopcode +opaex1mod4: testmod1 600 + +lblaemod4a: absolute +lblaemod4b: ldx8 + nextopcode +opafm0mod4: testmod1 600 + +lblafmod4a: absolutelong +lblafmod4b: lda16 + nextopcode +opb0mod4: testmod1 600 + +lblb0mod4: testmod1 600 + opb0 + nextopcode +opb1m0mod4: testmod1 600 + +lblb1mod4a: directindirectindexed1 +lblb1mod4b: lda16 + nextopcode +opb2m0mod4: testmod1 620 + +lblb2mod4a: directindirect +lblb2mod4b: lda16 + nextopcode +opb3m0mod4: testmod1 620 + +lblb3mod4a: stackasmrelativeindirectindexed1 +lblb3mod4b: lda16 + nextopcode +opb4x1mod4: testmod1 620 + +lblb4mod4a: directindexedx1 +lblb4mod4b: ldy8 + nextopcode +opb5m0mod4: testmod1 620 + +lblb5mod4a: directindexedx1 +lblb5mod4b: lda16 + nextopcode +opb6x1mod4: testmod1 620 + +lblb6mod4a: directindexedy1 +lblb6mod4b: ldx8 + nextopcode +opb7m0mod4: testmod1 620 + +lblb7mod4a: directindirectindexedlong1 +lblb7mod4b: lda16 + nextopcode +opb8mod4: testmod1 620 + +lblb8mod4: testmod1 620 + opb8 + nextopcode +opb9m0mod4: testmod1 620 + +lblb9mod4a: absoluteindexedy1 +lblb9mod4b: lda16 + nextopcode +opbax1mod4: testmod1 620 + +lblbamod4: testmod1 620 + opbax1 + nextopcode +opbbx1mod4: testmod1 620 + +lblbbmod4: testmod1 620 + opbbx1 + nextopcode +opbcx1mod4: testmod1 620 + +lblbcmod4a: absoluteindexedx1 +lblbcmod4b: ldy8 + nextopcode +opbdm0mod4: testmod1 620 + +lblbdmod4a: absoluteindexedx1 +lblbdmod4b: lda16 + nextopcode +opbex1mod4: testmod1 620 + +lblbemod4a: absoluteindexedy1 +lblbemod4b: ldx8 + nextopcode +opbfm0mod4: testmod1 620 + +lblbfmod4a: absolutelongindexedx1 +lblbfmod4b: lda16 + nextopcode +opc0x1mod4: testmod1 620 + +lblc0mod4: testmod1 620 + opc0x1 + nextopcode +opc1m0mod4: testmod1 620 + +lblc1mod4a: directindexedindirect1 +lblc1mod4b: cmp16 + nextopcode +opc2mod4: testmod1 640 + +lblc2mod4: testmod1 640 + opc2 + nextopcode +@.pool +opc3m0mod4: testmod1 640 + +lblc3mod4a: stackasmrelative +lblc3mod4b: cmp16 + nextopcode +opc4x1mod4: testmod1 640 + +lblc4mod4a: direct +lblc4mod4b: cmy8 + nextopcode +opc5m0mod4: testmod1 640 + +lblc5mod4a: direct +lblc5mod4b: cmp16 + nextopcode +opc6m0mod4: testmod1 640 + +lblc6mod4a: direct +lblc6mod4b: dec16 + nextopcode +opc7m0mod4: testmod1 640 + +lblc7mod4a: directindirectlong +lblc7mod4b: cmp16 + nextopcode +opc8x1mod4: testmod1 640 + +lblc8mod4: testmod1 640 + opc8x1 + nextopcode +opc9m0mod4: testmod1 640 + +lblc9mod4: testmod1 640 + opc9m0 + nextopcode +opcax1mod4: testmod1 640 + +lblcamod4: testmod1 640 + opcax1 + nextopcode +opcbmod4: testmod1 640 + +lblcbmod4: testmod1 640 + opcb + nextopcode +opccx1mod4: testmod1 640 + +lblccmod4a: absolute +lblccmod4b: cmy8 + nextopcode +opcdm0mod4: testmod1 640 + +lblcdmod4a: absolute +lblcdmod4b: cmp16 + nextopcode +opcem0mod4: testmod1 640 + +lblcemod4a: absolute +lblcemod4b: dec16 + nextopcode +opcfm0mod4: testmod1 640 + +lblcfmod4a: absolutelong +lblcfmod4b: cmp16 + nextopcode +opd0mod4: testmod1 660 + +lbld0mod4: testmod1 660 + opd0 + nextopcode +opd1m0mod4: testmod1 660 + +lbld1mod4a: directindirectindexed1 +lbld1mod4b: cmp16 + nextopcode +opd2m0mod4: testmod1 660 + +lbld2mod4a: directindirect +lbld2mod4b: cmp16 + nextopcode +opd3m0mod4: testmod1 660 + +lbld3mod4a: stackasmrelativeindirectindexed1 +lbld3mod4b: cmp16 + nextopcode +opd4mod4: testmod1 660 + +lbld4mod4: testmod1 660 + opd4 + nextopcode +opd5m0mod4: testmod1 660 + +lbld5mod4a: directindexedx1 +lbld5mod4b: cmp16 + nextopcode +opd6m0mod4: testmod1 660 + +lbld6mod4a: directindexedx1 +lbld6mod4b: dec16 + nextopcode +opd7m0mod4: testmod1 660 + +lbld7mod4a: directindirectindexedlong1 +lbld7mod4b: cmp16 + nextopcode +opd8mod4: testmod1 660 + +lbld8mod4: testmod1 660 + opd8 + nextopcode +opd9m0mod4: testmod1 660 + +lbld9mod4a: absoluteindexedy1 +lbld9mod4b: cmp16 + nextopcode +opdax1mod4: testmod1 660 + +lbldamod4: testmod1 660 + opdax1 + nextopcode +opdbmod4: testmod1 660 + +lbldbmod4: testmod1 660 + opdb + nextopcode +opdcmod4: testmod1 660 + +lbldcmod4: testmod1 660 + opdc + nextopcode +opddm0mod4: testmod1 660 + +lblddmod4a: absoluteindexedx1 +lblddmod4b: cmp16 + nextopcode +opdem0mod4: testmod1 660 + +lbldemod4a: absoluteindexedx1 +lbldemod4b: dec16 + nextopcode +opdfm0mod4: testmod1 660 + +lbldfmod4a: absolutelongindexedx1 +lbldfmod4b: cmp16 + nextopcode +ope0x1mod4: testmod1 660 + +lble0mod4: testmod1 660 + ope0x1 + nextopcode +ope1m0mod4: testmod1 660 + +lble1mod4a: directindexedindirect1 +lble1mod4b: sbc16 + nextopcode +ope2mod4: testmod1 660 + +lble2mod4: testmod1 660 + ope2 + nextopcode +@.pool +ope3m0mod4: testmod1 680 + +lble3mod4a: stackasmrelative +lble3mod4b: sbc16 + nextopcode +ope4x1mod4: testmod1 680 + +lble4mod4a: direct +lble4mod4b: cmx8 + nextopcode +ope5m0mod4: testmod1 680 + +lble5mod4a: direct +lble5mod4b: sbc16 + nextopcode +ope6m0mod4: testmod1 680 + +lble6mod4a: direct +lble6mod4b: inc16 + nextopcode +ope7m0mod4: testmod1 680 + +lble7mod4a: directindirectlong +lble7mod4b: sbc16 + nextopcode +ope8x1mod4: testmod1 680 + +lble8mod4: testmod1 680 + ope8x1 + nextopcode +ope9m0mod4: testmod1 680 + +lble9mod4a: immediate16 +lble9mod4b: sbc16 + nextopcode +opeamod4: testmod1 680 + +lbleamod4: testmod1 680 + opea + nextopcode +opebmod4: testmod1 680 + +lblebmod4: testmod1 680 + opebm0 + nextopcode +opecx1mod4: testmod1 680 + +lblecmod4a: absolute +lblecmod4b: cmx8 + nextopcode +opedm0mod4: testmod1 680 + +lbledmod4a: absolute +lbledmod4b: sbc16 + nextopcode +opeem0mod4: testmod1 680 + +lbleemod4a: absolute +lbleemod4b: inc16 + nextopcode +opefm0mod4: testmod1 680 + +lblefmod4a: absolutelong +lblefmod4b: sbc16 + nextopcode +opf0mod4: testmod1 680 + +lblf0mod4: testmod1 680 + opf0 + nextopcode +opf1m0mod4: testmod1 680 + +lblf1mod4a: directindirectindexed1 +lblf1mod4b: sbc16 + nextopcode +opf2m0mod4: testmod1 700 + +lblf2mod4a: directindirect +lblf2mod4b: sbc16 + nextopcode +opf3m0mod4: testmod1 700 + +lblf3mod4a: stackasmrelativeindirectindexed1 +lblf3mod4b: sbc16 + nextopcode +opf4mod4: testmod1 700 + +lblf4mod4: testmod1 700 + opf4 + nextopcode +opf5m0mod4: testmod1 700 + +lblf5mod4a: directindexedx1 +lblf5mod4b: sbc16 + nextopcode +opf6m0mod4: testmod1 700 + +lblf6mod4a: directindexedx1 +lblf6mod4b: inc16 + nextopcode +opf7m0mod4: testmod1 700 + +lblf7mod4a: directindirectindexedlong1 +lblf7mod4b: sbc16 + nextopcode +opf8mod4: testmod1 700 + +lblf8mod4: testmod1 700 + opf8 + nextopcode +opf9m0mod4: testmod1 700 + +lblf9mod4a: absoluteindexedy1 +lblf9mod4b: sbc16 + nextopcode +opfax1mod4: testmod1 700 + +lblfamod4: testmod1 700 + opfax1 + nextopcode +opfbmod4: testmod1 700 + +lblfbmod4: testmod1 700 + opfb + nextopcode +opfcmod4: testmod1 700 + +lblfcmod4: testmod1 700 + opfcx1 + nextopcode +opfdm0mod4: testmod1 700 + +lblfdmod4a: absoluteindexedx1 +lblfdmod4b: sbc16 + nextopcode +opfem0mod4: testmod1 700 + +lblfemod4a: absoluteindexedx1 +lblfemod4b: inc16 + nextopcode +opffm0mod4: testmod1 700 + +lblffmod4a: absolutelongindexedx1 +lblffmod4b: sbc16 + nextopcode + + + @.pool diff --git a/src/snes4iphone_src/os9x_65c816_def.h b/src/snes4iphone_src/os9x_65c816_def.h new file mode 100755 index 0000000..a078bca --- /dev/null +++ b/src/snes4iphone_src/os9x_65c816_def.h @@ -0,0 +1,76 @@ +//#define __PALMOS__ + +//#define __TESTING__ + +#define MAP_LAST 12 + +#define regA R11 //format : 0xhhll0000 or 0xll000000 +#define rstatus R4 //format : 0xff800000 +#define regDBank R4 //format : 0x000000ll +#define regX R5 //format : 0xhhll0000 or 0xll000000 +#define regY R6 //format : 0xhhll0000 or 0xll000000 + +#define rpc R7 //32bits address +#define regD R8 //format : 0xhhll0000 +#define regPBank R8 //format : 0x000000ll +#define regCycles R9 //32bits counter +#define regS R10 //format : 0x0000hhll + +#define rscratch R0 //format : 0xhhll0000 if data and calculation or return of S9XREADBYTE or WORD +#define regopcode R0 //format : 0x000000ll +#define rscratch2 R1 //format : 0xhhll for calculation and value +#define rscratch3 R2 // +#define rscratch4 R3 //?????? + + +#define rscratch5 R5 //?????? +#define rscratch6 R6 //?????? +#define rscratch7 R8 //?????? +#define rscratch8 R9 //?????? +#define rscratch9 R10 //?????? + +#define regpcbase R12 //32bits address + +#define regCPUvar R14 + + + +//not used +//R13 //Pointer 32 bit on a struct. + +//R15 = pc (sic!) + + +/*#define Carry 1 +#define Zero 2 +#define IRQ 4 +#define Decimal 8 +#define IndexFlag 16 +#define MemoryFlag 32 +#define Overflow 64 +#define Negative 128 +#define Emulation 256*/ + +#define STATUS_SHIFTER 24 +#define MASK_EMUL (1<<(STATUS_SHIFTER-1)) +#define MASK_SHIFTER_CARRY (STATUS_SHIFTER+1) +#define MASK_CARRY (1<<(STATUS_SHIFTER)) //0 +#define MASK_ZERO (2<<(STATUS_SHIFTER)) //1 +#define MASK_IRQ (4<<(STATUS_SHIFTER)) //2 +#define MASK_DECIMAL (8<<(STATUS_SHIFTER)) //3 +#define MASK_INDEX (16<<(STATUS_SHIFTER)) //4 //1 +#define MASK_MEM (32<<(STATUS_SHIFTER)) //5 //2 +#define MASK_OVERFLOW (64<<(STATUS_SHIFTER)) //6 //4 +#define MASK_NEG (128<<(STATUS_SHIFTER))//7 //8 + +#define ONE_CYCLE 6 +#define SLOW_ONE_CYCLE 8 + +#define NMI_FLAG (1 << 7) +#define IRQ_PENDING_FLAG (1 << 11) +#define SCAN_KEYS_FLAG (1 << 4) + + +#define MEMMAP_BLOCK_SIZE (0x1000) +#define MEMMAP_SHIFT 12 +#define MEMMAP_MASK (0xFFF) diff --git a/src/snes4iphone_src/os9x_65c816_mac_gen.h b/src/snes4iphone_src/os9x_65c816_mac_gen.h new file mode 100755 index 0000000..eaeddc9 --- /dev/null +++ b/src/snes4iphone_src/os9x_65c816_mac_gen.h @@ -0,0 +1,595 @@ + +/*****************************************************************/ +/* Offset in SCPUState structure */ +/*****************************************************************/ +#define Flags_ofs 0 +#define BranchSkip_ofs 4 +#define NMIActive_ofs 5 +#define IRQActive_ofs 6 +#define WaitingForInterrupt_ofs 7 +#define InDMA_ofs 8 +#define WhichEvent 9 +#define SRAMModified_ofs 10 +#define BRKTriggered_ofs 11 +#define PC_ofs 12 +#define PCBase_ofs 16 + +#define PCAtOpcodeStart_ofs 20 + +#define WaitAddress_ofs 24 + +#define WaitCounter_ofs 28 +#define Cycles_ofs 32 +#define NextEvent_ofs 36 +#define V_Counter_ofs 40 +#define MemSpeed_ofs 44 +#define MemSpeedx2_ofs 48 +#define FastROMSpeed_ofs 52 +#define AutoSaveTimer_ofs 56 +#define NMITriggerPoint_ofs 60 +#define NMICycleCount_ofs 64 +#define IRQCycleCount_ofs 68 + +#define RPB_ofs 72 +#define RDB_ofs 73 +#define RP_ofs 74 +#define RA_ofs 76 +#define RAH_ofs RA_ofs+1 +#define RD_ofs 78 +#define RS_ofs 80 +#define RX_ofs 82 +#define RY_ofs 84 +#define RPC_ofs 86 + + +#define asm_OPTABLE_ofs 88 +#define TriedInterleavedMode2_ofs 92 + + + +#define Map_ofs 96 +#define WriteMap_ofs 100 +#define MemorySpeed_ofs 104 +#define BlockIsRAM_ofs 108 +#define SRAM 112 +#define BWRAM 116 +#define SRAMMask 120 + +#define APUExecuting_ofs 122 + +#define PALMOS_R9_ofs 124 +#define PALMOS_R10_ofs 128 +/*****************************************************************/ + + +#ifdef __PALMOS__ +/* prepare */ +.macro PREPARE_C_CALL + STMFD R13!,{R9,R10,R12,R14} + LDR R9,[regCPUvar,#PALMOS_R9_ofs] + LDR R10,[regCPUvar,#PALMOS_R10_ofs] +.endm +.macro PREPARE_C_CALL_R0 + STMFD R13!,{R0,R9,R10,R12,R14} + LDR R9,[regCPUvar,#PALMOS_R9_ofs] + LDR R10,[regCPUvar,#PALMOS_R10_ofs] +.endm +.macro PREPARE_C_CALL_R0R1 + STMFD R13!,{R0,R1,R9,R10,R12,R14} + LDR R9,[regCPUvar,#PALMOS_R9_ofs] + LDR R10,[regCPUvar,#PALMOS_R10_ofs] +.endm +.macro PREPARE_C_CALL_LIGHT + STMFD R13!,{R14} + LDR R9,[regCPUvar,#PALMOS_R9_ofs] + LDR R10,[regCPUvar,#PALMOS_R10_ofs] +.endm +.macro PREPARE_C_CALL_LIGHTR12 + STMFD R13!,{R9,R10,R12,R14} + LDR R9,[regCPUvar,#PALMOS_R9_ofs] + LDR R10,[regCPUvar,#PALMOS_R10_ofs] +.endm +/* restore */ +.macro RESTORE_C_CALL + LDMFD R13!,{R9,R10,R12,R14} + +.endm +.macro RESTORE_C_CALL_R0 + LDMFD R13!,{R0,R9,R10,R12,R14} +.endm +.macro RESTORE_C_CALL_R1 + LDMFD R13!,{R1,R9,R10,R12,R14} +.endm +.macro RESTORE_C_CALL_LIGHT + LDMFD R13!,{R14} +.endm +.macro RESTORE_C_CALL_LIGHTR12 + LDMFD R13!,{R9,R10,R12,R14} +.endm +#else +/* prepare */ +.macro PREPARE_C_CALL + STMFD R13!,{R12,R14} +.endm +.macro PREPARE_C_CALL_R0 + STMFD R13!,{R0,R12,R14} +.endm +.macro PREPARE_C_CALL_R0R1 + STMFD R13!,{R0,R1,R12,R14} +.endm +.macro PREPARE_C_CALL_LIGHT + STMFD R13!,{R14} +.endm +.macro PREPARE_C_CALL_LIGHTR12 + STMFD R13!,{R12,R14} +.endm +/* restore */ +.macro RESTORE_C_CALL + LDMFD R13!,{R12,R14} +.endm +.macro RESTORE_C_CALL_R0 + LDMFD R13!,{R0,R12,R14} +.endm +.macro RESTORE_C_CALL_R1 + LDMFD R13!,{R1,R12,R14} +.endm +.macro RESTORE_C_CALL_LIGHT + LDMFD R13!,{R14} +.endm +.macro RESTORE_C_CALL_LIGHTR12 + LDMFD R13!,{R12,R14} +.endm +#endif + +//-------------- +.macro LOAD_REGS + //regD & regPBank share the same register + LDRB regPBank,[regCPUvar,#RPB_ofs] + LDRH rscratch,[regCPUvar,#RD_ofs] + ORR regD,regD,rscratch, LSL #16 + //rstatus & regDBank share the same register + LDRB regDBank,[regCPUvar,#RDB_ofs] + LDRH rscratch,[regCPUvar,#RP_ofs] + ORRS rstatus, rstatus, rscratch,LSL #STATUS_SHIFTER + //if Carry set, then EMULATION bit was set + ORRCS rstatus,rstatus,#MASK_EMUL + // + LDRH regA,[regCPUvar,#RA_ofs] + LDRH regX,[regCPUvar,#RX_ofs] + LDRH regY,[regCPUvar,#RY_ofs] + LDRH regS,[regCPUvar,#RS_ofs] + //Shift X,Y & A according to the current mode (INDEX, MEMORY bits) + TST rstatus,#MASK_INDEX + MOVNE regX,regX,LSL #24 + MOVNE regY,regY,LSL #24 + MOVEQ regX,regX,LSL #16 + MOVEQ regY,regY,LSL #16 + TST rstatus,#MASK_MEM + MOVNE regA,regA,LSL #24 + MOVEQ regA,regA,LSL #16 + + LDR regpcbase,[regCPUvar,#PCBase_ofs] + LDR rpc,[regCPUvar,#PC_ofs] + LDR regCycles,[regCPUvar,#Cycles_ofs] +.endm + + +.macro SAVE_REGS + //regD & regPBank is same register + STRB regPBank,[regCPUvar,#RPB_ofs] + MOV rscratch,regD, LSR #16 + STRH rscratch,[regCPUvar,#RD_ofs] + //rstatus & regDBank is same register + STRB regDBank,[regCPUvar,#RDB_ofs] + MOVS rscratch, rstatus, LSR #STATUS_SHIFTER + ORRCS rscratch,rscratch,#0x100 //EMULATION bit + STRH rscratch,[regCPUvar,#RP_ofs] + // + //Shift X,Y & A according to the current mode (INDEX, MEMORY bits) + TST rstatus,#MASK_INDEX + MOVNE rscratch,regX,LSR #24 + MOVNE rscratch2,regY,LSR #24 + MOVEQ rscratch,regX,LSR #16 + MOVEQ rscratch2,regY,LSR #16 + STRH rscratch,[regCPUvar,#RX_ofs] + STRH rscratch2,[regCPUvar,#RY_ofs] + TST rstatus,#MASK_MEM + LDRNEH rscratch,[regCPUvar,#RA_ofs] + BICNE rscratch,rscratch,#0xFF + ORRNE rscratch,rscratch,regA,LSR #24 + MOVEQ rscratch,regA,LSR #16 + STRH rscratch,[regCPUvar,#RA_ofs] + + STRH regS,[regCPUvar,#RS_ofs] + STR regpcbase,[regCPUvar,#PCBase_ofs] + STR rpc,[regCPUvar,#PC_ofs] + + STR regCycles,[regCPUvar,#Cycles_ofs] +.endm + +/*****************************************************************/ +.macro ADD1CYCLE + add regCycles,regCycles, #ONE_CYCLE +.endm +.macro ADD1CYCLENE + addne regCycles,regCycles, #ONE_CYCLE +.endm +.macro ADD1CYCLEEQ + addeq regCycles,regCycles, #ONE_CYCLE +.endm + +.macro ADD2CYCLE + add regCycles,regCycles, #(ONE_CYCLE*2) +.endm +.macro ADD2CYCLENE + addne regCycles,regCycles, #(ONE_CYCLE*2) +.endm +.macro ADD2CYCLE2MEM + ldr rscratch,[regCPUvar,#MemSpeed_ofs] + add regCycles,regCycles, #(ONE_CYCLE*2) + add regCycles, regCycles, rscratch, LSL #1 +.endm +.macro ADD2CYCLE1MEM + ldr rscratch,[regCPUvar,#MemSpeed_ofs] + add regCycles,regCycles, #(ONE_CYCLE*2) + add regCycles, regCycles, rscratch +.endm + +.macro ADD3CYCLE + add regCycles,regCycles, #(ONE_CYCLE*3) +.endm + +.macro ADD1CYCLE1MEM + ldr rscratch,[regCPUvar,#MemSpeed_ofs] + add regCycles,regCycles, #ONE_CYCLE + add regCycles, regCycles, rscratch +.endm + +.macro ADD1CYCLE2MEM + ldr rscratch,[regCPUvar,#MemSpeed_ofs] + add regCycles,regCycles, #ONE_CYCLE + add regCycles, regCycles, rscratch, lsl #1 +.endm + +.macro ADD1MEM + ldr rscratch,[regCPUvar,#MemSpeed_ofs] + add regCycles, regCycles, rscratch +.endm + +.macro ADD2MEM + ldr rscratch,[regCPUvar,#MemSpeed_ofs] + add regCycles, regCycles, rscratch, lsl #1 +.endm + +.macro ADD3MEM + ldr rscratch,[regCPUvar,#MemSpeed_ofs] + add regCycles, rscratch, regCycles + add regCycles, regCycles, rscratch, lsl #1 +.endm + +/**************/ +.macro ClearDecimal + BIC rstatus,rstatus,#MASK_DECIMAL +.endm +.macro SetDecimal + ORR rstatus,rstatus,#MASK_DECIMAL +.endm +.macro SetIRQ + ORR rstatus,rstatus,#MASK_IRQ +.endm +.macro ClearIRQ + BIC rstatus,rstatus,#MASK_IRQ +.endm + +.macro CPUShutdown +//if (Settings.Shutdown && CPU.PC == CPU.WaitAddress) + LDR rscratch,[regCPUvar,#WaitAddress_ofs] + CMP rpc,rscratch + BNE 5431f +//if (CPU.WaitCounter == 0 && !(CPU.Flags & (IRQ_PENDING_FLAG | NMI_FLAG))) + LDR rscratch,[regCPUvar,#Flags_ofs] + LDR rscratch2,[regCPUvar,#WaitCounter_ofs] + TST rscratch,#(IRQ_PENDING_FLAG|NMI_FLAG) + BNE 5432f + MOVS rscratch2,rscratch2 + BNE 5432f +//CPU.WaitAddress = NULL; + MOV rscratch,#0 + STR rscratch,[regCPUvar,#WaitAddress_ofs] +//if (Settings.SA1) +// S9xSA1ExecuteDuringSleep (); : TODO + +// CPU.Cycles = CPU.NextEvent; + LDR regCycles,[regCPUvar,#NextEvent_ofs] + LDRB r0,[regCPUvar,#APUExecuting_ofs] + MOVS r0,r0 + BEQ 5431f +// if (IAPU.APUExecuting) +/* { + ICPU.CPUExecuting = FALSE; + do + { + APU_EXECUTE1(); + } while (APU.Cycles < CPU.NextEvent); + ICPU.CPUExecuting = TRUE; + } + */ + asmAPU_EXECUTE2 + B 5431f +.pool +5432: +/* else + if (CPU.WaitCounter >= 2) + CPU.WaitCounter = 1; + else + CPU.WaitCounter--; +*/ + CMP rscratch2,#1 + MOVHI rscratch2,#1 + //SUBLS rscratch2,rscratch2,#1 + MOVLS rscratch2,#0 + STR rscratch2,[regCPUvar,#WaitCounter_ofs] +5431: + +.endm +.macro BranchCheck0 + /*in rsctach : OpAddress + /*destroy rscratch2*/ + LDRB rscratch2,[regCPUvar,#BranchSkip_ofs] + MOVS rscratch2,rscratch2 + BEQ 1110f + MOV rscratch2,#0 + STRB rscratch2,[regCPUvar,#BranchSkip_ofs] + SUB rscratch2,rpc,regpcbase + //if( CPU.PC - CPU.PCBase > OpAddress) return; + CMP rscratch2,rscratch + BHI 1111f +1110: +.endm +.macro BranchCheck1 + /*in rsctach : OpAddress + /*destroy rscratch2*/ + LDRB rscratch2,[regCPUvar,#BranchSkip_ofs] + MOVS rscratch2,rscratch2 + BEQ 1110f + MOV rscratch2,#0 + STRB rscratch2,[regCPUvar,#BranchSkip_ofs] + SUB rscratch2,rpc,regpcbase + //if( CPU.PC - CPU.PCBase > OpAddress) return; + CMP rscratch2,rscratch + BHI 1111f +1110: +.endm +.macro BranchCheck2 + /*in rsctach : OpAddress + /*destroy rscratch2*/ + LDRB rscratch2,[regCPUvar,#BranchSkip_ofs] + MOVS rscratch2,rscratch2 + BEQ 1110f + MOV rscratch2,#0 + STRB rscratch2,[regCPUvar,#BranchSkip_ofs] + SUB rscratch2,rpc,regpcbase + //if( CPU.PC - CPU.PCBase > OpAddress) return; + CMP rscratch2,rscratch + BHI 1111f +1110: +.endm + +.macro S9xSetPCBase + // in : rscratch (0x00hhmmll) + PREPARE_C_CALL + BL asm_S9xSetPCBase + RESTORE_C_CALL + LDR rpc,[regCPUvar,#PC_ofs] + LDR regpcbase,[regCPUvar,#PCBase_ofs] +.endm + +.macro S9xFixCycles +#ifdef __PALMOS__ + LDR rscratch2,[regCPUvar,#PALMOS_R10_ofs] +#endif + TST rstatus,#MASK_EMUL + LDRNE rscratch, = jumptable1 //Mode 0 : M=1,X=1 + BNE 991111f + //EMULATION=0 + TST rstatus,#MASK_MEM + BEQ 991112f + //MEMORY=1 + TST rstatus,#MASK_INDEX + //INDEX=1 //Mode 0 : M=1,X=1 + LDRNE rscratch, = jumptable1 + //INDEX=0 //Mode 1 : M=1,X=0 + LDREQ rscratch, = jumptable2 + B 991111f +991112: //MEMORY=0 + TST rstatus,#MASK_INDEX + //INDEX=1 //Mode 3 : M=0,X=1 + LDRNE rscratch, = jumptable4 + //INDEX=0 //Mode 2 : M=0,X=0 + LDREQ rscratch, = jumptable3 +991111: +#ifdef __PALMOS__ + ADD rscratch,rscratch,rscratch2 +#endif + STR rscratch,[regCPUvar,#asm_OPTABLE_ofs] +.endm +.macro S9xOpcode_NMI + SAVE_REGS + PREPARE_C_CALL_LIGHT + BL asm_S9xOpcode_NMI + RESTORE_C_CALL_LIGHT + LOAD_REGS +.endm +.macro S9xOpcode_IRQ + SAVE_REGS + PREPARE_C_CALL_LIGHT + BL asm_S9xOpcode_IRQ + RESTORE_C_CALL_LIGHT + LOAD_REGS +.endm +.macro S9xDoHBlankProcessing + SAVE_REGS + PREPARE_C_CALL_LIGHT + BL asm_S9xDoHBlankProcessing + RESTORE_C_CALL_LIGHT + LOAD_REGS +.endm + +/********************************/ +.macro EXEC_OP + LDR R1,[regCPUvar,#asm_OPTABLE_ofs] + STR rpc,[regCPUvar,#PCAtOpcodeStart_ofs] + ADD1MEM + LDRB R0, [rpc], #1 + +#ifdef __PALMOS__ + LDR R2,[regCPUvar,#PALMOS_R10_ofs] + LDR R3,[R1,R0,LSL #2] + ADD PC,R2,R3 +#else + LDR PC, [R1,R0, LSL #2] +#endif +.endm +.macro NEXTOPCODE +#ifdef __TESTING__ + B endmainLoop +#endif + LDR rscratch,[regCPUvar,#NextEvent_ofs] + CMP regCycles,rscratch + BLT mainLoop + S9xDoHBlankProcessing + B mainLoop +.endm + +.macro asmAPU_EXECUTE + LDRB R0,[regCPUvar,#APUExecuting_ofs] + MOVS R0,R0 + BEQ 43210f + //SAVE_REGS + STR regCycles,[regCPUvar,#Cycles_ofs] + PREPARE_C_CALL_LIGHTR12 + BL asm_APU_EXECUTE + RESTORE_C_CALL_LIGHTR12 + LDR regCycles,[regCPUvar,#Cycles_ofs] + //LOAD_REGS + //S9xFixCycles +43210: +.endm + +.macro asmAPU_EXECUTE2 + //SAVE_REGS + STR regCycles,[regCPUvar,#Cycles_ofs] + PREPARE_C_CALL_LIGHTR12 + BL asm_APU_EXECUTE2 + RESTORE_C_CALL_LIGHTR12 + LDR regCycles,[regCPUvar,#Cycles_ofs] + //LOAD_REGS +.endm + + +//void asmMainLoop(asm_cpu_var_t *asmcpuPtr); +asmMainLoop: + //save registers + STMFD R13!,{R4-R11,LR} + //init pointer to CPUvar structure + MOV regCPUvar,R0 + //init registers + LOAD_REGS + //get cpu mode from flag and init jump table + S9xFixCycles +mainLoop: + //APU Execute + asmAPU_EXECUTE + + //Test Flags + LDR rscratch,[regCPUvar,#Flags_ofs] + MOVS rscratch,rscratch + BNE CPUFlags_set //If flags => check for irq/nmi/scan_keys... + + EXEC_OP //Execute next opcode + +CPUFlags_set: //Check flags (!=0) + TST rscratch,#NMI_FLAG //Check NMI + BEQ CPUFlagsNMI_FLAG_cleared + LDR rscratch2,[regCPUvar,#NMICycleCount_ofs] + SUBS rscratch2,rscratch2,#1 + STR rscratch2,[regCPUvar,#NMICycleCount_ofs] + BNE CPUFlagsNMI_FLAG_cleared + BIC rscratch,rscratch,#NMI_FLAG + STR rscratch,[regCPUvar,#Flags_ofs] + LDRB rscratch2,[regCPUvar,#WaitingForInterrupt_ofs] + MOVS rscratch2,rscratch2 + BEQ NotCPUaitingForInterruptNMI + MOV rscratch2,#0 + ADD rpc,rpc,#1 + STRB rscratch2,[regCPUvar,#WaitingForInterrupt_ofs] +NotCPUaitingForInterruptNMI: + S9xOpcode_NMI + LDR rscratch,[regCPUvar,#Flags_ofs] +CPUFlagsNMI_FLAG_cleared: + TST rscratch,#IRQ_PENDING_FLAG //Check IRQ_PENDING_FLAG + BEQ CPUFlagsIRQ_PENDING_FLAG_cleared + LDR rscratch2,[regCPUvar,#IRQCycleCount_ofs] + MOVS rscratch2,rscratch2 + BNE CPUIRQCycleCount_NotZero + LDRB rscratch2,[regCPUvar,#WaitingForInterrupt_ofs] + MOVS rscratch2,rscratch2 + BEQ NotCPUaitingForInterruptIRQ + MOV rscratch2,#0 + ADD rpc,rpc,#1 + STRB rscratch2,[regCPUvar,#WaitingForInterrupt_ofs] +NotCPUaitingForInterruptIRQ: + LDRB rscratch2,[regCPUvar,#IRQActive_ofs] + MOVS rscratch2,rscratch2 + BEQ CPUIRQActive_cleared + TST rstatus,#MASK_IRQ + BNE CPUFlagsIRQ_PENDING_FLAG_cleared + S9xOpcode_IRQ + LDR rscratch,[regCPUvar,#Flags_ofs] + B CPUFlagsIRQ_PENDING_FLAG_cleared +CPUIRQActive_cleared: + BIC rscratch,rscratch,#IRQ_PENDING_FLAG + STR rscratch,[regCPUvar,#Flags_ofs] + B CPUFlagsIRQ_PENDING_FLAG_cleared +CPUIRQCycleCount_NotZero: + SUB rscratch2,rscratch2,#1 + STR rscratch2,[regCPUvar,#IRQCycleCount_ofs] +CPUFlagsIRQ_PENDING_FLAG_cleared: + + TST rscratch,#SCAN_KEYS_FLAG //Check SCAN_KEYS_FLAG + BNE endmainLoop + + EXEC_OP //Execute next opcode + +endmainLoop: + /*Registers.PC = CPU.PC - CPU.PCBase; + S9xPackStatus (); + APURegisters.PC = IAPU.PC - IAPU.RAM; + S9xAPUPackStatus (); + + if (CPU.Flags & SCAN_KEYS_FLAG) + { + S9xSyncSpeed (); + CPU.Flags &= ~SCAN_KEYS_FLAG; + } */ +/********end*/ + SAVE_REGS + LDMFD R13!,{R4-R11,LR} + MOV PC,LR + + +.pool + +//void test_opcode(struct asm_cpu_var *asm_var); +test_opcode: + //save registers + STMFD R13!,{R4-R11,LR} + //init pointer to CPUvar structure + MOV regCPUvar,R0 + //init registers + LOAD_REGS + //get cpu mode from flag and init jump table + S9xFixCycles + + EXEC_OP +.pool diff --git a/src/snes4iphone_src/os9x_65c816_mac_mem.h b/src/snes4iphone_src/os9x_65c816_mac_mem.h new file mode 100755 index 0000000..c2863d8 --- /dev/null +++ b/src/snes4iphone_src/os9x_65c816_mac_mem.h @@ -0,0 +1,1599 @@ +/***************************************************************** + +*****************************************************************/ + +//#define _C_GB_ +//#define _C_GW_ +//#define _C_SB_ +//#define _C_SW_ + +.macro S9xGetWord + // in : rscratch (0x00hhmmll) + // out : rscratch (0xhhll0000) +#ifdef _C_GW_ + STR regCycles,[regCPUvar,#Cycles_ofs] + PREPARE_C_CALL + BL asm_S9xGetWord + RESTORE_C_CALL + MOV R0, R0, LSL #16 + LDR regCycles,[regCPUvar,#Cycles_ofs] +#else + STMFD R13!,{PC} //Push return address + B asmS9xGetWord + MOV R0,R0 + MOV R0, R0, LSL #16 +#endif +.endm +.macro S9xGetWordLow + // in : rscratch (0x00hhmmll) + // out : rscratch (0x0000hhll) +#ifdef _C_GW_ + STR regCycles,[regCPUvar,#Cycles_ofs] + PREPARE_C_CALL + BL asm_S9xGetWord + RESTORE_C_CALL + LDR regCycles,[regCPUvar,#Cycles_ofs] +#else + STMFD R13!,{PC} //Push return address + B asmS9xGetWord + MOV R0,R0 +#endif +.endm +.macro S9xGetWordRegStatus reg + // in : rscratch (0x00hhmmll) + // out : reg (0xhhll0000) + // flags have to be updated with read value +#ifdef _C_GW_ + STR regCycles,[regCPUvar,#Cycles_ofs] + PREPARE_C_CALL + BL asm_S9xGetWord + RESTORE_C_CALL + MOVS \reg, R0, LSL #16 + LDR regCycles,[regCPUvar,#Cycles_ofs] +#else + STMFD R13!,{PC} //Push return address + B asmS9xGetWord + MOV R0,R0 + MOVS \reg, R0, LSL #16 +#endif +.endm +.macro S9xGetWordRegNS reg + // in : rscratch (0x00hhmmll) + // out : reg (0xhhll0000) + // DOES NOT DESTROY rscratch (R0) +#ifdef _C_GW_ + STR regCycles,[regCPUvar,#Cycles_ofs] + PREPARE_C_CALL_R0 + BL asm_S9xGetWord + MOV \reg, R0, LSL #16 + RESTORE_C_CALL_R0 + LDR regCycles,[regCPUvar,#Cycles_ofs] +#else + STMFD R13!,{R0} + STMFD R13!,{PC} //Push return address + B asmS9xGetWord + MOV R0,R0 + MOV \reg, R0, LSL #16 + LDMFD R13!,{R0} +#endif +.endm +.macro S9xGetWordLowRegNS reg + // in : rscratch (0x00hhmmll) + // out : reg (0xhhll0000) + // DOES NOT DESTROY rscratch (R0) +#ifdef _C_GW_ + STR regCycles,[regCPUvar,#Cycles_ofs] + PREPARE_C_CALL_R0 + BL asm_S9xGetWord + MOV \reg, R0 + RESTORE_C_CALL_R0 + LDR regCycles,[regCPUvar,#Cycles_ofs] +#else + STMFD R13!,{R0} + STMFD R13!,{PC} //Push return address + B asmS9xGetWord + MOV R0,R0 + MOV \reg, R0 + LDMFD R13!,{R0} +#endif +.endm + +.macro S9xGetByte + // in : rscratch (0x00hhmmll) + // out : rscratch (0xll000000) +#ifdef _C_GB_ + STR regCycles,[regCPUvar,#Cycles_ofs] + PREPARE_C_CALL + BL asm_S9xGetByte + RESTORE_C_CALL + MOV R0, R0, LSL #24 + LDR regCycles,[regCPUvar,#Cycles_ofs] +#else + STMFD R13!,{PC} //Push return address + B asmS9xGetByte + MOV R0,R0 + MOV R0, R0, LSL #24 +#endif +.endm +.macro S9xGetByteLow + // in : rscratch (0x00hhmmll) + // out : rscratch (0x000000ll) +#ifdef _C_GB_ + STR regCycles,[regCPUvar,#Cycles_ofs] + PREPARE_C_CALL + BL asm_S9xGetByte + RESTORE_C_CALL + LDR regCycles,[regCPUvar,#Cycles_ofs] +#else + STMFD R13!,{PC} + B asmS9xGetByte + MOV R0,R0 +#endif +.endm +.macro S9xGetByteRegStatus reg + // in : rscratch (0x00hhmmll) + // out : reg (0xll000000) + // flags have to be updated with read value +#ifdef _C_GB_ + STR regCycles,[regCPUvar,#Cycles_ofs] + PREPARE_C_CALL + BL asm_S9xGetByte + RESTORE_C_CALL + MOVS \reg, R0, LSL #24 + LDR regCycles,[regCPUvar,#Cycles_ofs] +#else + STMFD R13!,{PC} //Push return address + B asmS9xGetByte + MOV R0,R0 + MOVS \reg, R0, LSL #24 +#endif +.endm +.macro S9xGetByteRegNS reg + // in : rscratch (0x00hhmmll) + // out : reg (0xll000000) + // DOES NOT DESTROY rscratch (R0) +#ifdef _C_GB_ + STR regCycles,[regCPUvar,#Cycles_ofs] + PREPARE_C_CALL_R0 + BL asm_S9xGetByte + MOV \reg, R0, LSL #24 + RESTORE_C_CALL_R0 + LDR regCycles,[regCPUvar,#Cycles_ofs] +#else + STMFD R13!,{R0} + STMFD R13!,{PC} //Push return address + B asmS9xGetByte + MOV R0,R0 + MOVS \reg, R0, LSL #24 + LDMFD R13!,{R0} +#endif +.endm +.macro S9xGetByteLowRegNS reg + // in : rscratch (0x00hhmmll) + // out : reg (0x000000ll) + // DOES NOT DESTROY rscratch (R0) +#ifdef _C_GB_ + STR regCycles,[regCPUvar,#Cycles_ofs] + PREPARE_C_CALL_R0 + BL asm_S9xGetByte + MOV \reg, R0, LSL #24 + RESTORE_C_CALL_R0 + LDR regCycles,[regCPUvar,#Cycles_ofs] +#else + STMFD R13!,{R0} + STMFD R13!,{PC} //Push return address + B asmS9xGetByte + MOV R0,R0 + MOVS \reg, R0 + LDMFD R13!,{R0} +#endif +.endm + +.macro S9xSetWord regValue + // in : regValue (0xhhll0000) + // in : rscratch=address (0x00hhmmll) +#ifdef _C_SW_ + STR regCycles,[regCPUvar,#Cycles_ofs] + MOV R1,\regValue, LSR #16 + PREPARE_C_CALL + BL asm_S9xSetWord + RESTORE_C_CALL + LDR regCycles,[regCPUvar,#Cycles_ofs] +#else + STMFD R13!,{PC} //Push return address + MOV R1,\regValue, LSR #16 + B asmS9xSetWord + MOV R0,R0 +#endif +.endm +.macro S9xSetWordZero + // in : rscratch=address (0x00hhmmll) +#ifdef _C_SW_ + STR regCycles,[regCPUvar,#Cycles_ofs] + MOV R1,#0 + PREPARE_C_CALL + BL asm_S9xSetWord + RESTORE_C_CALL + LDR regCycles,[regCPUvar,#Cycles_ofs] +#else + STMFD R13!,{PC} //Push return address + MOV R1,#0 + B asmS9xSetWord + MOV R0,R0 +#endif +.endm +.macro S9xSetWordLow regValue + // in : regValue (0x0000hhll) + // in : rscratch=address (0x00hhmmll) +#ifdef _C_SW_ + STR regCycles,[regCPUvar,#Cycles_ofs] + MOV R1,\regValue + PREPARE_C_CALL + BL asm_S9xSetWord + RESTORE_C_CALL + LDR regCycles,[regCPUvar,#Cycles_ofs] +#else + STMFD R13!,{PC} //Push return address + MOV R1,\regValue + B asmS9xSetWord + MOV R0,R0 +#endif +.endm +.macro S9xSetByte regValue + // in : regValue (0xll000000) + // in : rscratch=address (0x00hhmmll) +#ifdef _C_SB_ + STR regCycles,[regCPUvar,#Cycles_ofs] + MOV R1,\regValue, LSR #24 + PREPARE_C_CALL + BL asm_S9xSetByte + RESTORE_C_CALL + LDR regCycles,[regCPUvar,#Cycles_ofs] +#else + STMFD R13!,{PC} //Push return address + MOV R1,\regValue, LSR #24 + B asmS9xSetByte + MOV R0,R0 +#endif +.endm +.macro S9xSetByteZero + // in : rscratch=address (0x00hhmmll) +#ifdef _C_SB_ + STR regCycles,[regCPUvar,#Cycles_ofs] + MOV R1,#0 + PREPARE_C_CALL + BL asm_S9xSetByte + RESTORE_C_CALL + LDR regCycles,[regCPUvar,#Cycles_ofs] +#else + STMFD R13!,{PC} //Push return address + MOV R1,#0 + B asmS9xSetByte + MOV R0,R0 +#endif +.endm +.macro S9xSetByteLow regValue + // in : regValue (0x000000ll) + // in : rscratch=address (0x00hhmmll) +#ifdef _C_SB_ + STR regCycles,[regCPUvar,#Cycles_ofs] + MOV R1,\regValue + PREPARE_C_CALL + BL asm_S9xSetByte + RESTORE_C_CALL + LDR regCycles,[regCPUvar,#Cycles_ofs] +#else + STMFD R13!,{PC} //Push return address + MOV R1,\regValue + B asmS9xSetByte + MOV R0,R0 +#endif +.endm + + +// =========================================== +// =========================================== +// Adressing mode +// =========================================== +// =========================================== + + +.macro Absolute + ADD2MEM + LDRB rscratch2 , [rpc, #1] + LDRB rscratch , [rpc],#2 + ORR rscratch , rscratch, rscratch2, LSL #8 + ORR rscratch , rscratch, regDBank, LSL #16 +.endm +.macro AbsoluteIndexedIndirectX0 + ADD2MEM + LDRB rscratch2 , [rpc, #1] + LDRB rscratch , [rpc], #2 + ORR rscratch , rscratch, rscratch2, LSL #8 + ADD rscratch , regX, rscratch, LSL #16 + MOV rscratch , rscratch, LSR #16 + ORR rscratch , rscratch, regPBank, LSL #16 + S9xGetWordLow + +.endm +.macro AbsoluteIndexedIndirectX1 + ADD2MEM + LDRB rscratch2 , [rpc, #1] + LDRB rscratch , [rpc], #2 + ORR rscratch , rscratch, rscratch2, LSL #8 + ADD rscratch , rscratch, regX, LSR #24 + BIC rscratch , rscratch, #0x00FF0000 + ORR rscratch , rscratch, regPBank, LSL #16 + S9xGetWordLow + +.endm +.macro AbsoluteIndirectLong + ADD2MEM + LDRB rscratch2 , [rpc, #1] + LDRB rscratch , [rpc], #2 + ORR rscratch , rscratch, rscratch2, LSL #8 + S9xGetWordLowRegNS rscratch2 + ADD rscratch , rscratch, #2 + STMFD r13!,{rscratch2} + S9xGetByteLow + LDMFD r13!,{rscratch2} + ORR rscratch , rscratch2, rscratch, LSL #16 +.endm +.macro AbsoluteIndirect + ADD2MEM + LDRB rscratch2 , [rpc,#1] + LDRB rscratch , [rpc], #2 + ORR rscratch , rscratch, rscratch2, LSL #8 + S9xGetWordLow + ORR rscratch , rscratch, regPBank, LSL #16 +.endm +.macro AbsoluteIndexedX0 + ADD2MEM + LDRB rscratch2 , [rpc, #1] + LDRB rscratch , [rpc], #2 + ORR rscratch , rscratch, rscratch2, LSL #8 + ORR rscratch , rscratch, regDBank, LSL #16 + ADD rscratch , rscratch, regX, LSR #16 +.endm +.macro AbsoluteIndexedX1 + ADD2MEM + LDRB rscratch2 , [rpc, #1] + LDRB rscratch , [rpc], #2 + ORR rscratch , rscratch, rscratch2, LSL #8 + ORR rscratch , rscratch, regDBank, LSL #16 + ADD rscratch , rscratch, regX, LSR #24 +.endm + + +.macro AbsoluteIndexedY0 + ADD2MEM + LDRB rscratch2 , [rpc, #1] + LDRB rscratch , [rpc], #2 + ORR rscratch , rscratch, rscratch2, LSL #8 + ORR rscratch , rscratch, regDBank, LSL #16 + ADD rscratch , rscratch, regY, LSR #16 +.endm +.macro AbsoluteIndexedY1 + ADD2MEM + LDRB rscratch2 , [rpc, #1] + LDRB rscratch , [rpc], #2 + ORR rscratch , rscratch, rscratch2, LSL #8 + ORR rscratch , rscratch, regDBank, LSL #16 + ADD rscratch , rscratch, regY, LSR #24 +.endm +.macro AbsoluteLong + ADD3MEM + LDRB rscratch2 , [rpc, #1] + LDRB rscratch , [rpc], #2 + ORR rscratch , rscratch, rscratch2, LSL #8 + LDRB rscratch2 , [rpc], #1 + ORR rscratch , rscratch, rscratch2, LSL #16 +.endm + + +.macro AbsoluteLongIndexedX0 + ADD3MEM + LDRB rscratch2 , [rpc, #1] + LDRB rscratch , [rpc], #2 + ORR rscratch , rscratch, rscratch2, LSL #8 + LDRB rscratch2 , [rpc], #1 + ORR rscratch , rscratch, rscratch2, LSL #16 + ADD rscratch , rscratch, regX, LSR #16 + BIC rscratch, rscratch, #0xFF000000 +.endm +.macro AbsoluteLongIndexedX1 + ADD3MEM + LDRB rscratch2 , [rpc, #1] + LDRB rscratch , [rpc], #2 + ORR rscratch , rscratch, rscratch2, LSL #8 + LDRB rscratch2 , [rpc], #1 + ORR rscratch , rscratch, rscratch2, LSL #16 + ADD rscratch , rscratch, regX, LSR #24 + BIC rscratch, rscratch, #0xFF000000 +.endm +.macro Direct + ADD1MEM + LDRB rscratch , [rpc], #1 + ADD rscratch , regD, rscratch, LSL #16 + MOV rscratch, rscratch, LSR #16 +.endm +.macro DirectIndirect + ADD1MEM + LDRB rscratch , [rpc], #1 + ADD rscratch , regD, rscratch, LSL #16 + MOV rscratch, rscratch, LSR #16 + S9xGetWordLow + ORR rscratch , rscratch, regDBank, LSL #16 +.endm +.macro DirectIndirectLong + ADD1MEM + LDRB rscratch , [rpc], #1 + ADD rscratch , regD, rscratch, LSL #16 + MOV rscratch, rscratch, LSR #16 + S9xGetWordLowRegNS rscratch2 + ADD rscratch , rscratch,#2 + STMFD r13!,{rscratch2} + S9xGetByteLow + LDMFD r13!,{rscratch2} + ORR rscratch , rscratch2, rscratch, LSL #16 +.endm +.macro DirectIndirectIndexed0 + ADD1MEM + LDRB rscratch , [rpc], #1 + ADD rscratch , regD, rscratch, LSL #16 + MOV rscratch, rscratch, LSR #16 + S9xGetWordLow + ORR rscratch, rscratch,regDBank, LSL #16 + ADD rscratch, rscratch,regY, LSR #16 +.endm +.macro DirectIndirectIndexed1 + ADD1MEM + LDRB rscratch , [rpc], #1 + ADD rscratch , regD, rscratch, LSL #16 + MOV rscratch, rscratch, LSR #16 + S9xGetWordLow + ORR rscratch, rscratch,regDBank, LSL #16 + ADD rscratch, rscratch,regY, LSR #24 +.endm +.macro DirectIndirectIndexedLong0 + ADD1MEM + LDRB rscratch , [rpc], #1 + ADD rscratch , regD, rscratch, LSL #16 + MOV rscratch, rscratch, LSR #16 + S9xGetWordLowRegNS rscratch2 + ADD rscratch , rscratch,#2 + STMFD r13!,{rscratch2} + S9xGetByteLow + LDMFD r13!,{rscratch2} + ORR rscratch , rscratch2, rscratch, LSL #16 + ADD rscratch, rscratch,regY, LSR #16 +.endm +.macro DirectIndirectIndexedLong1 + ADD1MEM + LDRB rscratch , [rpc], #1 + ADD rscratch , regD, rscratch, LSL #16 + MOV rscratch, rscratch, LSR #16 + S9xGetWordLowRegNS rscratch2 + ADD rscratch , rscratch,#2 + STMFD r13!,{rscratch2} + S9xGetByteLow + LDMFD r13!,{rscratch2} + ORR rscratch , rscratch2, rscratch, LSL #16 + ADD rscratch, rscratch,regY, LSR #24 +.endm +.macro DirectIndexedIndirect0 + ADD1CYCLE1MEM + LDRB rscratch , [rpc], #1 + ADD rscratch2 , regD , regX + ADD rscratch , rscratch2 , rscratch, LSL #16 + MOV rscratch, rscratch, LSR #16 + S9xGetWordLow + ORR rscratch , rscratch , regDBank, LSL #16 +.endm +.macro DirectIndexedIndirect1 + ADD1CYCLE1MEM + LDRB rscratch , [rpc], #1 + ADD rscratch2 , regD , regX, LSR #8 + ADD rscratch , rscratch2 , rscratch, LSL #16 + MOV rscratch, rscratch, LSR #16 + S9xGetWordLow + ORR rscratch , rscratch , regDBank, LSL #16 +.endm +.macro DirectIndexedX0 + ADD1CYCLE1MEM + LDRB rscratch , [rpc], #1 + ADD rscratch2 , regD , regX + ADD rscratch , rscratch2 , rscratch, LSL #16 + MOV rscratch, rscratch, LSR #16 +.endm +.macro DirectIndexedX1 + ADD1CYCLE1MEM + LDRB rscratch , [rpc], #1 + ADD rscratch2 , regD , regX, LSR #8 + ADD rscratch , rscratch2 , rscratch, LSL #16 + MOV rscratch, rscratch, LSR #16 +.endm +.macro DirectIndexedY0 + ADD1CYCLE1MEM + LDRB rscratch , [rpc], #1 + ADD rscratch2 , regD , regY + ADD rscratch , rscratch2 , rscratch, LSL #16 + MOV rscratch, rscratch, LSR #16 +.endm +.macro DirectIndexedY1 + ADD1CYCLE1MEM + LDRB rscratch , [rpc], #1 + ADD rscratch2 , regD , regY, LSR #8 + ADD rscratch , rscratch2 , rscratch, LSL #16 + MOV rscratch, rscratch, LSR #16 +.endm +.macro Immediate8 + ADD rscratch, rpc, regPBank, LSL #16 + SUB rscratch, rscratch, regpcbase + ADD rpc, rpc, #1 +.endm +.macro Immediate16 + ADD rscratch, rpc, regPBank, LSL #16 + SUB rscratch, rscratch, regpcbase + ADD rpc, rpc, #2 +.endm +.macro asmRelative + ADD1MEM + LDRSB rscratch , [rpc],#1 + ADD rscratch , rscratch , rpc + SUB rscratch , rscratch, regpcbase + BIC rscratch,rscratch,#0x00FF0000 + BIC rscratch,rscratch,#0xFF000000 +.endm +.macro asmRelativeLong + ADD1CYCLE2MEM + LDRB rscratch2 , [rpc, #1] + LDRB rscratch , [rpc], #2 + ORR rscratch , rscratch, rscratch2, LSL #8 + SUB rscratch2 , rpc, regpcbase + ADD rscratch , rscratch2, rscratch + BIC rscratch,rscratch,#0x00FF0000 +.endm + + +.macro StackasmRelative + ADD1CYCLE1MEM + LDRB rscratch , [rpc], #1 + ADD rscratch , rscratch, regS + BIC rscratch,rscratch,#0x00FF0000 +.endm +.macro StackasmRelativeIndirectIndexed0 + ADD2CYCLE1MEM + LDRB rscratch , [rpc], #1 + ADD rscratch , rscratch, regS + BIC rscratch,rscratch,#0x00FF0000 + S9xGetWordLow + ORR rscratch , rscratch, regDBank, LSL #16 + ADD rscratch , rscratch, regY, LSR #16 + BIC rscratch, rscratch, #0xFF000000 +.endm +.macro StackasmRelativeIndirectIndexed1 + ADD2CYCLE1MEM + LDRB rscratch , [rpc], #1 + ADD rscratch , rscratch, regS + BIC rscratch,rscratch,#0x00FF0000 + S9xGetWordLow + ORR rscratch , rscratch, regDBank, LSL #16 + ADD rscratch , rscratch, regY, LSR #24 + BIC rscratch, rscratch, #0xFF000000 +.endm + + +/****************************************/ +.macro PushB reg + MOV rscratch,regS + S9xSetByte \reg + SUB regS,regS,#1 +.endm +.macro PushBLow reg + MOV rscratch,regS + S9xSetByteLow \reg + SUB regS,regS,#1 +.endm +.macro PushWLow reg + SUB rscratch,regS,#1 + S9xSetWordLow \reg + SUB regS,regS,#2 +.endm +.macro PushWrLow + MOV rscratch2,rscratch + SUB rscratch,regS,#1 + S9xSetWordLow rscratch2 + SUB regS,regS,#2 +.endm +.macro PushW reg + SUB rscratch,regS,#1 + S9xSetWord \reg + SUB regS,regS,#2 +.endm + +/********/ + +.macro PullB reg + ADD rscratch,regS,#1 + S9xGetByteLow + ADD regS,regS,#1 + MOV \reg,rscratch,LSL #24 +.endm +.macro PullBr + ADD rscratch,regS,#1 + S9xGetByte + ADD regS,regS,#1 +.endm +.macro PullBLow reg + ADD rscratch,regS,#1 + S9xGetByteLow + ADD regS,regS,#1 + MOV \reg,rscratch +.endm +.macro PullBrLow + ADD rscratch,regS,#1 + S9xGetByteLow + ADD regS,regS,#1 +.endm +.macro PullW reg + ADD rscratch,regS,#1 + S9xGetWordLow + ADD regS,regS,#2 + MOV \reg,rscratch,LSL #16 +.endm + +.macro PullWLow reg + ADD rscratch,regS,#1 + S9xGetWordLow + ADD regS,regS,#2 + MOV \reg,rscratch +.endm + + +/*****************/ +.macro PullBS reg + ADD rscratch,regS,#1 + S9xGetByteLow + ADD regS,regS,#1 + MOVS \reg,rscratch,LSL #24 +.endm +.macro PullBrS + ADD rscratch,regS,#1 + S9xGetByteLow + ADD regS,regS,#1 + MOVS rscratch,rscratch,LSL #24 +.endm +.macro PullBLowS reg + ADD rscratch,regS,#1 + S9xGetByteLow + ADD regS,regS,#1 + MOVS \reg,rscratch +.endm +.macro PullBrLowS + ADD rscratch,regS,#1 + S9xGetByteLow + ADD regS,regS,#1 + MOVS rscratch,rscratch +.endm +.macro PullWS reg + ADD rscratch,regS,#1 + S9xGetWordLow + ADD regS,regS,#2 + MOVS \reg,rscratch, LSL #16 +.endm +.macro PullWrS + ADD rscratch,regS,#1 + S9xGetWordLow + ADD regS,regS,#2 + MOVS rscratch,rscratch, LSL #16 +.endm +.macro PullWLowS reg + ADD rscratch,regS,#1 + S9xGetWordLow + ADD regS,regS,#2 + MOVS \reg,rscratch +.endm +.macro PullWrLowS + ADD rscratch,regS,#1 + S9xGetWordLow + ADD regS,regS,#2 + MOVS rscratch,rscratch +.endm + + +.globl asmS9xGetByte +.globl asmS9xGetWord +.globl asmS9xSetByte +.globl asmS9xSetWord + +//uint8 aaS9xGetByte(uint32 address); +asmS9xGetByte: + // in : R0 = 0x00hhmmll + // out : R0 = 0x000000ll + // DESTROYED : R1,R2,R3 + // UPDATE : regCycles + //R1 <= block + MOV R1,R0,LSR #MEMMAP_SHIFT + //MEMMAP_SHIFT is 12, Address is 0xFFFFFFFF at max, so + //R1 is maxed by 0x000FFFFF, MEMMAP_MASK is 0x1000-1=0xFFF + //so AND MEMMAP_MASK is BIC 0xFF000 + BIC R1,R1,#0xFF000 + //R2 <= Map[block] (GetAddress) + LDR R2,[regCPUvar,#Map_ofs] + LDR R2,[R2,R1,LSL #2] + CMP R2,#MAP_LAST + BLO GBSpecial //special + // Direct ROM/RAM acess + //R2 <= GetAddress + Address & 0xFFFF + //R3 <= MemorySpeed[block] + LDR R3,[regCPUvar,#MemorySpeed_ofs] + MOV R0,R0,LSL #16 + LDRB R3,[R3,R1] + ADD R2,R2,R0,LSR #16 + //Update CPU.Cycles + ADD regCycles,regCycles,R3 + //R3 = BlockIsRAM[block] + LDR R3,[regCPUvar,#BlockIsRAM_ofs] + //Get value to return + LDRB R0,[R2] + LDRB R3,[R3,R1] + MOVS R3,R3 + // if BlockIsRAM => update for CPUShutdown + LDRNE R1,[regCPUvar,#PCAtOpcodeStart_ofs] + STRNE R1,[regCPUvar,#WaitAddress_ofs] + + LDMFD R13!,{PC} //Return +GBSpecial: + +#ifdef __PALMOS__ + LDR R3,[regCPUvar,#PALMOS_R10_ofs] + LDR R2,[PC,R2,LSL #2] + ADD PC,R2,R3 +#else + LDR PC,[PC,R2,LSL #2] + MOV R0,R0 //nop, for align +#endif + .long GBPPU + .long GBCPU + .long GBDSP + .long GBLSRAM + .long GBHSRAM + .long GBNONE + .long GBDEBUG + .long GBC4 + .long GBBWRAM + .long GBNONE + .long GBNONE + .long GBNONE + /*.long GB7ROM + .long GB7RAM + .long GB7SRM*/ +GBPPU: + //InDMA ? + LDRB R1,[regCPUvar,#InDMA_ofs] + MOVS R1,R1 + ADDEQ regCycles,regCycles,#ONE_CYCLE //No -> update Cycles + MOV R0,R0,LSL #16 //S9xGetPPU(Address&0xFFFF); + STR regCycles,[regCPUvar,#Cycles_ofs] //Save Cycles + MOV R0,R0,LSR #16 + PREPARE_C_CALL + BL S9xGetPPU + RESTORE_C_CALL + LDR regCycles,[regCPUvar,#Cycles_ofs] //Load Cycles + LDMFD R13!,{PC} //Return +GBCPU: + ADD regCycles,regCycles,#ONE_CYCLE //update Cycles + MOV R0,R0,LSL #16 //S9xGetCPU(Address&0xFFFF); + STR regCycles,[regCPUvar,#Cycles_ofs] //Save Cycles + MOV R0,R0,LSR #16 + PREPARE_C_CALL + BL S9xGetCPU + RESTORE_C_CALL + LDR regCycles,[regCPUvar,#Cycles_ofs] //Load Cycles + LDMFD R13!,{PC} //Return +GBDSP: + ADD regCycles,regCycles,#SLOW_ONE_CYCLE //update Cycles + MOV R0,R0,LSL #16 //S9xGetCPU(Address&0xFFFF); + STR regCycles,[regCPUvar,#Cycles_ofs] //Save Cycles + MOV R0,R0,LSR #16 + PREPARE_C_CALL + BL S9xGetDSP + RESTORE_C_CALL + LDR regCycles,[regCPUvar,#Cycles_ofs] //Load Cycles + LDMFD R13!,{PC} //Return +GBLSRAM: + ADD regCycles,regCycles,#SLOW_ONE_CYCLE //update Cycles + LDRH R2,[regCPUvar,#SRAMMask] + LDR R1,[regCPUvar,#SRAM] + AND R0,R2,R0 //Address&SRAMMask + LDRB R0,[R1,R0] //*Memory.SRAM + Address&SRAMMask + LDMFD R13!,{PC} +GB7SRM: +GBHSRAM: + ADD regCycles,regCycles,#SLOW_ONE_CYCLE //update Cycles + + MOV R1,R0,LSL #17 + AND R2,R0,#0xF0000 + MOV R1,R1,LSR #17 //Address&0x7FFF + MOV R2,R2,LSR #3 //(Address&0xF0000 >> 3) + ADD R0,R2,R1 + LDRH R2,[regCPUvar,#SRAMMask] + SUB R0,R0,#0x6000 //((Address & 0x7fff) - 0x6000 + ((Address & 0xf0000) >> 3)) + LDR R1,[regCPUvar,#SRAM] + AND R0,R2,R0 //Address&SRAMMask + LDRB R0,[R1,R0] //*Memory.SRAM + Address&SRAMMask + LDMFD R13!,{PC} //return +GB7ROM: +GB7RAM: +GBNONE: + MOV R0,R0,LSR #8 + ADD regCycles,regCycles,#SLOW_ONE_CYCLE //update Cycles + AND R0,R0,#0xFF + LDMFD R13!,{PC} +//GBDEBUG: + /*ADD regCycles,regCycles,#SLOW_ONE_CYCLE //update Cycles + MOV R0,#0 + LDMFD R13!,{PC}*/ +GBC4: + ADD regCycles,regCycles,#SLOW_ONE_CYCLE //update Cycles + MOV R0,R0,LSL #16 //S9xGetC4(Address&0xFFFF); + STR regCycles,[regCPUvar,#Cycles_ofs] //Save Cycles + MOV R0,R0,LSR #16 + PREPARE_C_CALL + BL S9xGetC4 + RESTORE_C_CALL + LDR regCycles,[regCPUvar,#Cycles_ofs] //Load Cycles + LDMFD R13!,{PC} //Return +GBDEBUG: +GBBWRAM: + MOV R0,R0,LSL #17 + ADD regCycles,regCycles,#SLOW_ONE_CYCLE //update Cycles + MOV R0,R0,LSR #17 //Address&0x7FFF + LDR R1,[regCPUvar,#BWRAM] + SUB R0,R0,#0x6000 //((Address & 0x7fff) - 0x6000) + LDRB R0,[R0,R1] //*Memory.BWRAM + ((Address & 0x7fff) - 0x6000) + LDMFD R13!,{PC} + + +//uint16 aaS9xGetWord(uint32 address); +asmS9xGetWord: + // in : R0 = 0x00hhmmll + // out : R0 = 0x000000ll + // DESTROYED : R1,R2,R3 + // UPDATE : regCycles + + + MOV R1,R0,LSL #19 + ADDS R1,R1,#0x80000 + //if = 0x1FFF => 0 + BNE GW_NotBoundary + + STMFD R13!,{R0} + STMFD R13!,{PC} + B asmS9xGetByte + MOV R0,R0 + LDMFD R13!,{R1} + STMFD R13!,{R0} + ADD R0,R1,#1 + STMFD R13!,{PC} + B asmS9xGetByte + MOV R0,R0 + LDMFD R13!,{R1} + ORR R0,R1,R0,LSL #8 + LDMFD R13!,{PC} + +GW_NotBoundary: + + //R1 <= block + MOV R1,R0,LSR #MEMMAP_SHIFT + //MEMMAP_SHIFT is 12, Address is 0xFFFFFFFF at max, so + //R1 is maxed by 0x000FFFFF, MEMMAP_MASK is 0x1000-1=0xFFF + //so AND MEMMAP_MASK is BIC 0xFF000 + BIC R1,R1,#0xFF000 + //R2 <= Map[block] (GetAddress) + LDR R2,[regCPUvar,#Map_ofs] + LDR R2,[R2,R1,LSL #2] + CMP R2,#MAP_LAST + BLO GWSpecial //special + // Direct ROM/RAM acess + + TST R0,#1 + BNE GW_Not_Aligned1 + //R2 <= GetAddress + Address & 0xFFFF + //R3 <= MemorySpeed[block] + LDR R3,[regCPUvar,#MemorySpeed_ofs] + MOV R0,R0,LSL #16 + LDRB R3,[R3,R1] + MOV R0,R0,LSR #16 + //Update CPU.Cycles + ADD regCycles,regCycles,R3, LSL #1 + //R3 = BlockIsRAM[block] + LDR R3,[regCPUvar,#BlockIsRAM_ofs] + //Get value to return + LDRH R0,[R2,R0] + LDRB R3,[R3,R1] + MOVS R3,R3 + // if BlockIsRAM => update for CPUShutdown + LDRNE R1,[regCPUvar,#PCAtOpcodeStart_ofs] + STRNE R1,[regCPUvar,#WaitAddress_ofs] + + LDMFD R13!,{PC} //Return +GW_Not_Aligned1: + + MOV R0,R0,LSL #16 + ADD R3,R0,#0x10000 + LDRB R3,[R2,R3,LSR #16] //GetAddress+ (Address+1)&0xFFFF + LDRB R0,[R2,R0,LSR #16] //GetAddress+ Address&0xFFFF + ORR R0,R0,R3,LSL #8 + + // if BlockIsRAM => update for CPUShutdown + LDR R3,[regCPUvar,#BlockIsRAM_ofs] + LDR R2,[regCPUvar,#MemorySpeed_ofs] + LDRB R3,[R3,R1] //R3 = BlockIsRAM[block] + LDRB R2,[R2,R1] //R2 <= MemorySpeed[block] + MOVS R3,R3 //IsRAM ? CPUShutdown stuff + LDRNE R1,[regCPUvar,#PCAtOpcodeStart_ofs] + STRNE R1,[regCPUvar,#WaitAddress_ofs] + ADD regCycles,regCycles,R2, LSL #1 //Update CPU.Cycles + LDMFD R13!,{PC} //Return +GWSpecial: +#ifdef __PALMOS__ + LDR R3,[regCPUvar,#PALMOS_R10_ofs] + LDR R2,[PC,R2,LSL #2] + ADD PC,R2,R3 +#else + LDR PC,[PC,R2,LSL #2] + MOV R0,R0 //nop, for align +#endif + .long GWPPU + .long GWCPU + .long GWDSP + .long GWLSRAM + .long GWHSRAM + .long GWNONE + .long GWDEBUG + .long GWC4 + .long GWBWRAM + .long GWNONE + .long GWNONE + .long GWNONE + /*.long GW7ROM + .long GW7RAM + .long GW7SRM*/ +/* MAP_PPU, MAP_CPU, MAP_DSP, MAP_LOROM_SRAM, MAP_HIROM_SRAM, + MAP_NONE, MAP_DEBUG, MAP_C4, MAP_BWRAM, MAP_BWRAM_BITMAP, + MAP_BWRAM_BITMAP2, MAP_SA1RAM, MAP_LAST*/ + +GWPPU: + //InDMA ? + LDRB R1,[regCPUvar,#InDMA_ofs] + MOVS R1,R1 + ADDEQ regCycles,regCycles,#(ONE_CYCLE*2) //No -> update Cycles + MOV R0,R0,LSL #16 //S9xGetPPU(Address&0xFFFF); + STR regCycles,[regCPUvar,#Cycles_ofs] //Save Cycles + MOV R0,R0,LSR #16 + PREPARE_C_CALL_R0 + BL S9xGetPPU + LDMFD R13!,{R1} + STMFD R13!,{R0} + ADD R0,R1,#1 + //BIC R0,R0,#0x10000 + BL S9xGetPPU + RESTORE_C_CALL_R1 + ORR R0,R1,R0,LSL #8 + LDR regCycles,[regCPUvar,#Cycles_ofs] //Load Cycles + LDMFD R13!,{PC} //Return +GWCPU: + ADD regCycles,regCycles,#(ONE_CYCLE*2) //update Cycles + MOV R0,R0,LSL #16 //S9xGetCPU(Address&0xFFFF); + STR regCycles,[regCPUvar,#Cycles_ofs] //Save Cycles + MOV R0,R0,LSR #16 + PREPARE_C_CALL_R0 + BL S9xGetCPU + LDMFD R13!,{R1} + STMFD R13!,{R0} + ADD R0,R1,#1 + //BIC R0,R0,#0x10000 + BL S9xGetCPU + RESTORE_C_CALL_R1 + ORR R0,R1,R0,LSL #8 + LDR regCycles,[regCPUvar,#Cycles_ofs] //Load Cycles + LDMFD R13!,{PC} //Return +GWDSP: + ADD regCycles,regCycles,#(SLOW_ONE_CYCLE*2) //update Cycles + MOV R0,R0,LSL #16 //S9xGetCPU(Address&0xFFFF); + STR regCycles,[regCPUvar,#Cycles_ofs] //Save Cycles + MOV R0,R0,LSR #16 + PREPARE_C_CALL_R0 + BL S9xGetDSP + LDMFD R13!,{R1} + STMFD R13!,{R0} + ADD R0,R1,#1 + //BIC R0,R0,#0x10000 + BL S9xGetDSP + RESTORE_C_CALL_R1 + ORR R0,R1,R0,LSL #8 + LDR regCycles,[regCPUvar,#Cycles_ofs] //Load Cycles + LDMFD R13!,{PC} //Return +GWLSRAM: + ADD regCycles,regCycles,#(SLOW_ONE_CYCLE*2) //update Cycles + + TST R0,#1 + BNE GW_Not_Aligned2 + LDRH R2,[regCPUvar,#SRAMMask] + LDR R1,[regCPUvar,#SRAM] + AND R3,R2,R0 //Address&SRAMMask + LDRH R0,[R3,R1] //*Memory.SRAM + Address&SRAMMask + LDMFD R13!,{PC} //return +GW_Not_Aligned2: + LDRH R2,[regCPUvar,#SRAMMask] + LDR R1,[regCPUvar,#SRAM] + AND R3,R2,R0 //Address&SRAMMask + ADD R0,R0,#1 + AND R2,R0,R2 //Address&SRAMMask + LDRB R3,[R1,R3] //*Memory.SRAM + Address&SRAMMask + LDRB R2,[R1,R2] //*Memory.SRAM + Address&SRAMMask + ORR R0,R3,R2,LSL #8 + LDMFD R13!,{PC} //return +GW7SRM: +GWHSRAM: + ADD regCycles,regCycles,#(SLOW_ONE_CYCLE*2) //update Cycles + + TST R0,#1 + BNE GW_Not_Aligned3 + + MOV R1,R0,LSL #17 + AND R2,R0,#0xF0000 + MOV R1,R1,LSR #17 //Address&0x7FFF + MOV R2,R2,LSR #3 //(Address&0xF0000 >> 3) + ADD R0,R2,R1 + LDRH R2,[regCPUvar,#SRAMMask] + SUB R0,R0,#0x6000 //((Address & 0x7fff) - 0x6000 + ((Address & 0xf0000) >> 3)) + LDR R1,[regCPUvar,#SRAM] + AND R0,R2,R0 //Address&SRAMMask + LDRH R0,[R1,R0] //*Memory.SRAM + Address&SRAMMask + LDMFD R13!,{PC} //return + +GW_Not_Aligned3: + MOV R3,R0,LSL #17 + AND R2,R0,#0xF0000 + MOV R3,R3,LSR #17 //Address&0x7FFF + MOV R2,R2,LSR #3 //(Address&0xF0000 >> 3) + ADD R2,R2,R3 + ADD R0,R0,#1 + SUB R2,R2,#0x6000 //((Address & 0x7fff) - 0x6000 + ((Address & 0xf0000) >> 3)) + MOV R3,R0,LSL #17 + AND R0,R0,#0xF0000 + MOV R3,R3,LSR #17 //(Address+1)&0x7FFF + MOV R0,R0,LSR #3 //((Address+1)&0xF0000 >> 3) + ADD R0,R0,R3 + LDRH R3,[regCPUvar,#SRAMMask] //reload mask + SUB R0,R0,#0x6000 //(((Address+1) & 0x7fff) - 0x6000 + (((Address+1) & 0xf0000) >> 3)) + AND R2,R3,R2 //Address...&SRAMMask + AND R0,R3,R0 //(Address+1...)&SRAMMask + + LDR R3,[regCPUvar,#SRAM] + LDRB R0,[R0,R3] //*Memory.SRAM + (Address...)&SRAMMask + LDRB R2,[R2,R3] //*Memory.SRAM + (Address+1...)&SRAMMask + ORR R0,R2,R0,LSL #8 + + LDMFD R13!,{PC} //return +GW7ROM: +GW7RAM: +GWNONE: + MOV R0,R0,LSL #16 + ADD regCycles,regCycles,#(SLOW_ONE_CYCLE*2) //update Cycles + MOV R0,R0,LSR #24 + ORR R0,R0,R0,LSL #8 + LDMFD R13!,{PC} +GWDEBUG: + ADD regCycles,regCycles,#(SLOW_ONE_CYCLE*2) //update Cycles + MOV R0,#0 + LDMFD R13!,{PC} +GWC4: + ADD regCycles,regCycles,#(SLOW_ONE_CYCLE*2) //update Cycles + MOV R0,R0,LSL #16 //S9xGetC4(Address&0xFFFF); + STR regCycles,[regCPUvar,#Cycles_ofs] //Save Cycles + MOV R0,R0,LSR #16 + PREPARE_C_CALL_R0 + BL S9xGetC4 + LDMFD R13!,{R1} + STMFD R13!,{R0} + ADD R0,R1,#1 + //BIC R0,R0,#0x10000 + BL S9xGetC4 + RESTORE_C_CALL_R1 + ORR R0,R1,R0,LSL #8 + LDR regCycles,[regCPUvar,#Cycles_ofs] //Load Cycles + LDMFD R13!,{PC} //Return +GWBWRAM: + TST R0,#1 + BNE GW_Not_Aligned4 + MOV R0,R0,LSL #17 + ADD regCycles,regCycles,#(SLOW_ONE_CYCLE*2) //update Cycles + MOV R0,R0,LSR #17 //Address&0x7FFF + LDR R1,[regCPUvar,#BWRAM] + SUB R0,R0,#0x6000 //((Address & 0x7fff) - 0x6000) + LDRH R0,[R1,R0] //*Memory.BWRAM + ((Address & 0x7fff) - 0x6000) + LDMFD R13!,{PC} //return +GW_Not_Aligned4: + MOV R0,R0,LSL #17 + ADD regCycles,regCycles,#(SLOW_ONE_CYCLE*2) //update Cycles + ADD R3,R0,#0x20000 + MOV R0,R0,LSR #17 //Address&0x7FFF + MOV R3,R3,LSR #17 //(Address+1)&0x7FFF + LDR R1,[regCPUvar,#BWRAM] + SUB R0,R0,#0x6000 //((Address & 0x7fff) - 0x6000) + SUB R3,R3,#0x6000 //(((Address+1) & 0x7fff) - 0x6000) + LDRB R0,[R1,R0] //*Memory.BWRAM + ((Address & 0x7fff) - 0x6000) + LDRB R3,[R1,R3] //*Memory.BWRAM + (((Address+1) & 0x7fff) - 0x6000) + ORR R0,R0,R3,LSL #8 + LDMFD R13!,{PC} //return + +.pool + + +//void aaS9xSetByte(uint32 address,uint8 val); +asmS9xSetByte: + // in : R0=0x00hhmmll R1=0x000000ll + // DESTROYED : R0,R1,R2,R3 + // UPDATE : regCycles + //cpu shutdown + MOV R2,#0 + STR R2,[regCPUvar,#WaitAddress_ofs] + // + + //R3 <= block + MOV R3,R0,LSR #MEMMAP_SHIFT + //MEMMAP_SHIFT is 12, Address is 0xFFFFFFFF at max, so + //R0 is maxed by 0x000FFFFF, MEMMAP_MASK is 0x1000-1=0xFFF + //so AND MEMMAP_MASK is BIC 0xFF000 + BIC R3,R3,#0xFF000 + //R2 <= Map[block] (SetAddress) + LDR R2,[regCPUvar,#WriteMap_ofs] + LDR R2,[R2,R3,LSL #2] + CMP R2,#MAP_LAST + BLO SBSpecial //special + // Direct ROM/RAM acess + + //R2 <= SetAddress + Address & 0xFFFF + MOV R0,R0,LSL #16 + ADD R2,R2,R0,LSR #16 + LDR R0,[regCPUvar,#MemorySpeed_ofs] + //Set byte + STRB R1,[R2] + //R0 <= MemorySpeed[block] + LDRB R0,[R0,R3] + //Update CPU.Cycles + ADD regCycles,regCycles,R0 + //CPUShutdown + //only SA1 here : TODO + //Return + LDMFD R13!,{PC} +SBSpecial: +#ifdef __PALMOS__ + LDR R3,[regCPUvar,#PALMOS_R10_ofs] + LDR R2,[PC,R2,LSL #2] + ADD PC,R2,R3 +#else + LDR PC,[PC,R2,LSL #2] + MOV R0,R0 //nop, for align +#endif + .long SBPPU + .long SBCPU + .long SBDSP + .long SBLSRAM + .long SBHSRAM + .long SBNONE + .long SBDEBUG + .long SBC4 + .long SBBWRAM + .long SBNONE + .long SBNONE + .long SBNONE + /*.long SB7ROM + .long SB7RAM + .long SB7SRM*/ +SBPPU: + //InDMA ? + LDRB R2,[regCPUvar,#InDMA_ofs] + MOVS R2,R2 + ADDEQ regCycles,regCycles,#ONE_CYCLE //No -> update Cycles + MOV R0,R0,LSL #16 + STR regCycles,[regCPUvar,#Cycles_ofs] //Save Cycles + MOV R0,R0,LSR #16 + PREPARE_C_CALL + MOV R12,R0 + MOV R0,R1 + MOV R1,R12 + BL S9xSetPPU + RESTORE_C_CALL + LDR regCycles,[regCPUvar,#Cycles_ofs] //Load Cycles + LDMFD R13!,{PC} //Return +SBCPU: + ADD regCycles,regCycles,#ONE_CYCLE //update Cycles + MOV R0,R0,LSL #16 + STR regCycles,[regCPUvar,#Cycles_ofs] //Save Cycles + MOV R0,R0,LSR #16 //Address&0xFFFF + PREPARE_C_CALL + MOV R12,R0 + MOV R0,R1 + MOV R1,R12 + BL S9xSetCPU + RESTORE_C_CALL + LDR regCycles,[regCPUvar,#Cycles_ofs] //Load Cycles + LDMFD R13!,{PC} //Return +SBDSP: + ADD regCycles,regCycles,#SLOW_ONE_CYCLE //update Cycles + MOV R0,R0,LSL #16 + STR regCycles,[regCPUvar,#Cycles_ofs] //Save Cycles + MOV R0,R0,LSR #16 //Address&0xFFFF + PREPARE_C_CALL + MOV R12,R0 + MOV R0,R1 + MOV R1,R12 + BL S9xSetDSP + RESTORE_C_CALL + LDR regCycles,[regCPUvar,#Cycles_ofs] //Load Cycles + LDMFD R13!,{PC} //Return +SBLSRAM: + ADD regCycles,regCycles,#SLOW_ONE_CYCLE //update Cycles + LDRH R2,[regCPUvar,#SRAMMask] + MOVS R2,R2 + LDMEQFD R13!,{PC} //return if SRAMMask=0 + LDR R3,[regCPUvar,#SRAM] + AND R0,R2,R0 //Address&SRAMMask + STRB R1,[R0,R3] //*Memory.SRAM + Address&SRAMMask + + MOV R0,#1 + STRB R0,[regCPUvar,#SRAMModified_ofs] + LDMFD R13!,{PC} //return +SB7SRM: +SBHSRAM: + ADD regCycles,regCycles,#SLOW_ONE_CYCLE //update Cycles + + MOV R3,R0,LSL #17 + AND R2,R0,#0xF0000 + MOV R3,R3,LSR #17 //Address&0x7FFF + MOV R2,R2,LSR #3 //(Address&0xF0000 >> 3) + ADD R0,R2,R3 + + LDRH R2,[regCPUvar,#SRAMMask] + MOVS R2,R2 + LDMEQFD R13!,{PC} //return if SRAMMask=0 + + SUB R0,R0,#0x6000 //((Address & 0x7fff) - 0x6000 + ((Address & 0xf0000) >> 3)) + LDR R3,[regCPUvar,#SRAM] + AND R0,R2,R0 //Address&SRAMMask + STRB R1,[R0,R3] //*Memory.SRAM + Address&SRAMMask + + MOV R0,#1 + STRB R0,[regCPUvar,#SRAMModified_ofs] + LDMFD R13!,{PC} //return +SB7ROM: +SB7RAM: +SBNONE: +SBDEBUG: + ADD regCycles,regCycles,#SLOW_ONE_CYCLE //update Cycles + LDMFD R13!,{PC} +SBC4: + ADD regCycles,regCycles,#SLOW_ONE_CYCLE //update Cycles + MOV R0,R0,LSL #16 + STR regCycles,[regCPUvar,#Cycles_ofs] //Save Cycles + MOV R0,R0,LSR #16 //Address&0xFFFF + PREPARE_C_CALL + MOV R12,R0 + MOV R0,R1 + MOV R1,R12 + BL S9xSetC4 + RESTORE_C_CALL + LDR regCycles,[regCPUvar,#Cycles_ofs] //Load Cycles + LDMFD R13!,{PC} //Return +SBBWRAM: + MOV R0,R0,LSL #17 + ADD regCycles,regCycles,#SLOW_ONE_CYCLE //update Cycles + MOV R0,R0,LSR #17 //Address&0x7FFF + LDR R2,[regCPUvar,#BWRAM] + SUB R0,R0,#0x6000 //((Address & 0x7fff) - 0x6000) + STRB R1,[R0,R2] //*Memory.BWRAM + ((Address & 0x7fff) - 0x6000) + + MOV R0,#1 + STRB R0,[regCPUvar,#SRAMModified_ofs] + + LDMFD R13!,{PC} + + + +//void aaS9xSetWord(uint32 address,uint16 val); +asmS9xSetWord: + // in : R0 = 0x00hhmmll R1=0x0000hhll + // DESTROYED : R0,R1,R2,R3 + // UPDATE : regCycles + //R1 <= block + + MOV R2,R0,LSL #19 + ADDS R2,R2,#0x80000 + //if = 0x1FFF => 0 + BNE SW_NotBoundary + + STMFD R13!,{R0,R1} + STMFD R13!,{PC} + B asmS9xSetByte + MOV R0,R0 + LDMFD R13!,{R0,R1} + ADD R0,R0,#1 + MOV R1,R1,LSR #8 + STMFD R13!,{PC} + B asmS9xSetByte + MOV R0,R0 + + LDMFD R13!,{PC} + +SW_NotBoundary: + + MOV R2,#0 + STR R2,[regCPUvar,#WaitAddress_ofs] + // + //R3 <= block + MOV R3,R0,LSR #MEMMAP_SHIFT + //MEMMAP_SHIFT is 12, Address is 0xFFFFFFFF at max, so + //R1 is maxed by 0x000FFFFF, MEMMAP_MASK is 0x1000-1=0xFFF + //so AND MEMMAP_MASK is BIC 0xFF000 + BIC R3,R3,#0xFF000 + //R2 <= Map[block] (SetAddress) + LDR R2,[regCPUvar,#WriteMap_ofs] + LDR R2,[R2,R3,LSL #2] + CMP R2,#MAP_LAST + BLO SWSpecial //special + // Direct ROM/RAM acess + + + //check if address is 16bits aligned or not + TST R0,#1 + BNE SW_not_aligned1 + //aligned + MOV R0,R0,LSL #16 + ADD R2,R2,R0,LSR #16 //address & 0xFFFF + SetAddress + LDR R0,[regCPUvar,#MemorySpeed_ofs] + //Set word + STRH R1,[R2] + //R1 <= MemorySpeed[block] + LDRB R0,[R0,R3] + //Update CPU.Cycles + ADD regCycles,regCycles,R0, LSL #1 + //CPUShutdown + //only SA1 here : TODO + //Return + LDMFD R13!,{PC} + +SW_not_aligned1: + //R1 = (Address&0xFFFF)<<16 + MOV R0,R0,LSL #16 + //First write @address + STRB R1,[R2,R0,LSR #16] + ADD R0,R0,#0x10000 + MOV R1,R1,LSR #8 + //Second write @address+1 + STRB R1,[R2,R0,LSR #16] + //R1 <= MemorySpeed[block] + LDR R0,[regCPUvar,#MemorySpeed_ofs] + LDRB R0,[R0,R3] + //Update CPU.Cycles + ADD regCycles,regCycles,R0,LSL #1 + //CPUShutdown + //only SA1 here : TODO + //Return + LDMFD R13!,{PC} +SWSpecial: +#ifdef __PALMOS__ + LDR R3,[regCPUvar,#PALMOS_R10_ofs] + LDR R2,[PC,R2,LSL #2] + ADD PC,R2,R3 +#else + LDR PC,[PC,R2,LSL #2] + MOV R0,R0 //nop, for align +#endif + .long SWPPU + .long SWCPU + .long SWDSP + .long SWLSRAM + .long SWHSRAM + .long SWNONE + .long SWDEBUG + .long SWC4 + .long SWBWRAM + .long SWNONE + .long SWNONE + .long SWNONE + /*.long SW7ROM + .long SW7RAM + .long SW7SRM*/ +SWPPU: + //InDMA ? + LDRB R2,[regCPUvar,#InDMA_ofs] + MOVS R2,R2 + ADDEQ regCycles,regCycles,#(ONE_CYCLE*2) //No -> update Cycles + MOV R0,R0,LSL #16 + STR regCycles,[regCPUvar,#Cycles_ofs] //Save Cycles + MOV R0,R0,LSR #16 + MOV R2,R1 + MOV R1,R0 + MOV R0,R2 + PREPARE_C_CALL_R0R1 + BL S9xSetPPU + LDMFD R13!,{R0,R1} + ADD R1,R1,#1 + MOV R0,R0,LSR #8 + BIC R1,R1,#0x10000 + BL S9xSetPPU + RESTORE_C_CALL + LDR regCycles,[regCPUvar,#Cycles_ofs] //Load Cycles + LDMFD R13!,{PC} //Return +SWCPU: + ADD regCycles,regCycles,#(ONE_CYCLE*2) //update Cycles + MOV R0,R0,LSL #16 + STR regCycles,[regCPUvar,#Cycles_ofs] //Save Cycles + MOV R0,R0,LSR #16 //Address&0xFFFF + MOV R2,R1 + MOV R1,R0 + MOV R0,R2 + PREPARE_C_CALL_R0R1 + BL S9xSetCPU + LDMFD R13!,{R0,R1} + ADD R1,R1,#1 + MOV R0,R0,LSR #8 + BIC R1,R1,#0x10000 + BL S9xSetCPU + RESTORE_C_CALL + LDR regCycles,[regCPUvar,#Cycles_ofs] //Load Cycles + LDMFD R13!,{PC} //Return +SWDSP: + ADD regCycles,regCycles,#SLOW_ONE_CYCLE //update Cycles + MOV R0,R0,LSL #16 + STR regCycles,[regCPUvar,#Cycles_ofs] //Save Cycles + MOV R0,R0,LSR #16 //Address&0xFFFF + MOV R2,R1 + MOV R1,R0 + MOV R0,R2 + PREPARE_C_CALL_R0R1 + BL S9xSetDSP + LDMFD R13!,{R0,R1} + ADD R1,R1,#1 + MOV R0,R0,LSR #8 + BIC R1,R1,#0x10000 + BL S9xSetDSP + RESTORE_C_CALL + LDR regCycles,[regCPUvar,#Cycles_ofs] //Load Cycles + LDMFD R13!,{PC} //Return +SWLSRAM: + ADD regCycles,regCycles,#(SLOW_ONE_CYCLE*2) //update Cycles + LDRH R2,[regCPUvar,#SRAMMask] + MOVS R2,R2 + LDMEQFD R13!,{PC} //return if SRAMMask=0 + + AND R3,R2,R0 //Address&SRAMMask + TST R0,#1 + BNE SW_not_aligned2 + //aligned + LDR R0,[regCPUvar,#SRAM] + STRH R1,[R0,R3] //*Memory.SRAM + Address&SRAMMask + MOV R0,#1 + STRB R0,[regCPUvar,#SRAMModified_ofs] + LDMFD R13!,{PC} //return +SW_not_aligned2: + + ADD R0,R0,#1 + AND R2,R2,R0 //(Address+1)&SRAMMask + LDR R0,[regCPUvar,#SRAM] + STRB R1,[R0,R3] //*Memory.SRAM + Address&SRAMMask + MOV R1,R1,LSR #8 + STRB R1,[R0,R2] //*Memory.SRAM + (Address+1)&SRAMMask + MOV R0,#1 + STRB R0,[regCPUvar,#SRAMModified_ofs] + LDMFD R13!,{PC} //return +SW7SRM: +SWHSRAM: + ADD regCycles,regCycles,#(SLOW_ONE_CYCLE*2) //update Cycles + + LDRH R2,[regCPUvar,#SRAMMask] + MOVS R2,R2 + LDMEQFD R13!,{PC} //return if SRAMMask=0 + + TST R0,#1 + BNE SW_not_aligned3 + //aligned + MOV R3,R0,LSL #17 + AND R2,R0,#0xF0000 + MOV R3,R3,LSR #17 //Address&0x7FFF + MOV R2,R2,LSR #3 //(Address&0xF0000 >> 3) + ADD R0,R2,R3 + SUB R0,R0,#0x6000 //((Address & 0x7fff) - 0x6000 + ((Address & 0xf0000) >> 3)) + LDRH R2,[regCPUvar,#SRAMMask] + LDR R3,[regCPUvar,#SRAM] + AND R0,R2,R0 //Address&SRAMMask + STRH R1,[R0,R3] //*Memory.SRAM + Address&SRAMMask + MOV R0,#1 + STRB R0,[regCPUvar,#SRAMModified_ofs] + LDMFD R13!,{PC} //return +SW_not_aligned3: + MOV R3,R0,LSL #17 + AND R2,R0,#0xF0000 + MOV R3,R3,LSR #17 //Address&0x7FFF + MOV R2,R2,LSR #3 //(Address&0xF0000 >> 3) + ADD R2,R2,R3 + SUB R2,R2,#0x6000 //((Address & 0x7fff) - 0x6000 + ((Address & 0xf0000) >> 3)) + + ADD R0,R0,#1 + MOV R3,R0,LSL #17 + AND R0,R0,#0xF0000 + MOV R3,R3,LSR #17 //(Address+1)&0x7FFF + MOV R0,R0,LSR #3 //((Address+1)&0xF0000 >> 3) + ADD R0,R0,R3 + LDRH R3,[regCPUvar,#SRAMMask] //reload mask + SUB R0,R0,#0x6000 //(((Address+1) & 0x7fff) - 0x6000 + (((Address+1) & 0xf0000) >> 3)) + AND R2,R3,R2 //Address...&SRAMMask + AND R0,R3,R0 //(Address+1...)&SRAMMask + + LDR R3,[regCPUvar,#SRAM] + STRB R1,[R2,R3] //*Memory.SRAM + (Address...)&SRAMMask + MOV R1,R1,LSR #8 + STRB R1,[R0,R3] //*Memory.SRAM + (Address+1...)&SRAMMask + + MOV R0,#1 + STRB R0,[regCPUvar,#SRAMModified_ofs] + LDMFD R13!,{PC} //return +SW7ROM: +SW7RAM: +SWNONE: +SWDEBUG: + ADD regCycles,regCycles,#(SLOW_ONE_CYCLE*2) //update Cycles + LDMFD R13!,{PC} //return +SWC4: + ADD regCycles,regCycles,#(SLOW_ONE_CYCLE*2) //update Cycles + MOV R0,R0,LSL #16 + STR regCycles,[regCPUvar,#Cycles_ofs] //Save Cycles + MOV R0,R0,LSR #16 //Address&0xFFFF + MOV R2,R1 + MOV R1,R0 + MOV R0,R2 + PREPARE_C_CALL_R0R1 + BL S9xSetC4 + LDMFD R13!,{R0,R1} + ADD R1,R1,#1 + MOV R0,R0,LSR #8 + BIC R1,R1,#0x10000 + BL S9xSetC4 + RESTORE_C_CALL + LDR regCycles,[regCPUvar,#Cycles_ofs] //Load Cycles + LDMFD R13!,{PC} //Return +SWBWRAM: + ADD regCycles,regCycles,#(SLOW_ONE_CYCLE*2) //update Cycles + TST R0,#1 + BNE SW_not_aligned4 + //aligned + MOV R0,R0,LSL #17 + LDR R2,[regCPUvar,#BWRAM] + MOV R0,R0,LSR #17 //Address&0x7FFF + SUB R0,R0,#0x6000 //((Address & 0x7fff) - 0x6000) + MOV R3,#1 + STRH R1,[R0,R2] //*Memory.BWRAM + ((Address & 0x7fff) - 0x6000) + STRB R3,[regCPUvar,#SRAMModified_ofs] + LDMFD R13!,{PC} //return +SW_not_aligned4: + MOV R0,R0,LSL #17 + ADD R3,R0,#0x20000 + MOV R0,R0,LSR #17 //Address&0x7FFF + MOV R3,R3,LSR #17 //(Address+1)&0x7FFF + LDR R2,[regCPUvar,#BWRAM] + SUB R0,R0,#0x6000 //((Address & 0x7fff) - 0x6000) + SUB R3,R3,#0x6000 //(((Address+1) & 0x7fff) - 0x6000) + STRB R1,[R2,R0] //*Memory.BWRAM + ((Address & 0x7fff) - 0x6000) + MOV R1,R1,LSR #8 + STRB R1,[R2,R3] //*Memory.BWRAM + (((Address+1) & 0x7fff) - 0x6000) + MOV R0,#1 + STRB R0,[regCPUvar,#SRAMModified_ofs] + LDMFD R13!,{PC} //return + + +.pool diff --git a/src/snes4iphone_src/os9x_65c816_mac_op.h b/src/snes4iphone_src/os9x_65c816_mac_op.h new file mode 100755 index 0000000..3dcbfaa --- /dev/null +++ b/src/snes4iphone_src/os9x_65c816_mac_op.h @@ -0,0 +1,2408 @@ +/***************************************************************** + FLAGS +*****************************************************************/ + +.macro UPDATE_C + // CC : ARM Carry Clear + BICCC rstatus, rstatus, #MASK_CARRY // 0 : AND mask 11111011111 : set C to zero + // CS : ARM Carry Set + ORRCS rstatus, rstatus, #MASK_CARRY // 1 : OR mask 00000100000 : set C to one +.endm +.macro UPDATE_Z + // NE : ARM Zero Clear + BICNE rstatus, rstatus, #MASK_ZERO // 0 : AND mask 11111011111 : set Z to zero + // EQ : ARM Zero Set + ORREQ rstatus, rstatus, #MASK_ZERO // 1 : OR mask 00000100000 : set Z to one +.endm +.macro UPDATE_ZN + // NE : ARM Zero Clear + BICNE rstatus, rstatus, #MASK_ZERO // 0 : AND mask 11111011111 : set Z to zero + // EQ : ARM Zero Set + ORREQ rstatus, rstatus, #MASK_ZERO // 1 : OR mask 00000100000 : set Z to one + // PL : ARM Neg Clear + BICPL rstatus, rstatus, #MASK_NEG // 0 : AND mask 11111011111 : set N to zero + // MI : ARM Neg Set + ORRMI rstatus, rstatus, #MASK_NEG // 1 : OR mask 00000100000 : set N to one +.endm + +/***************************************************************** + OPCODES_MAC +*****************************************************************/ + + + + +.macro ADC8 + TST rstatus, #MASK_DECIMAL + BEQ 1111f + S9xGetByte + + + STMFD R13!,{rscratch} + MOV rscratch4,#0x0F000000 + //rscratch2=xxW1xxxxxxxxxxxx + AND rscratch2, rscratch, rscratch4 + //rscratch=xxW2xxxxxxxxxxxx + AND rscratch, rscratch4, rscratch, LSR #4 + //rscratch3=xxA2xxxxxxxxxxxx + AND rscratch3, rscratch4, regA, LSR #4 + //rscratch4=xxA1xxxxxxxxxxxx + AND rscratch4,regA,rscratch4 + //R1=A1+W1+CARRY + TST rstatus, #MASK_CARRY + ADDNE rscratch2, rscratch2, #0x01000000 + ADD rscratch2,rscratch2,rscratch4 + // if R1 > 9 + CMP rscratch2, #0x09000000 + // then R1 -= 10 + SUBGT rscratch2, rscratch2, #0x0A000000 + // then A2++ + ADDGT rscratch3, rscratch3, #0x01000000 + // R2 = A2+W2 + ADD rscratch3, rscratch3, rscratch + // if R2 > 9 + CMP rscratch3, #0x09000000 + // then R2 -= 10// + SUBGT rscratch3, rscratch3, #0x0A000000 + // then SetCarry() + ORRGT rstatus, rstatus, #MASK_CARRY // 1 : OR mask 00000100000 : set C to one + // else ClearCarry() + BICLE rstatus, rstatus, #MASK_CARRY // 0 : AND mask 11111011111 : set C to zero + // gather rscratch3 and rscratch2 into ans8 + // rscratch3 : 0R2000000 + // rscratch2 : 0R1000000 + // -> 0xR2R1000000 + ORR rscratch2, rscratch2, rscratch3, LSL #4 + LDMFD R13!,{rscratch} + //only last bit + AND rscratch,rscratch,#0x80000000 + // (register.AL ^ Work8) + EORS rscratch3, regA, rscratch + BICNE rstatus, rstatus, #MASK_OVERFLOW // 0 : AND mask 11111011111 : set V to zero + BNE 1112f + // (Work8 ^ Ans8) + EORS rscratch3, rscratch2, rscratch + // & 0x80 + TSTNE rscratch3,#0x80000000 + BICEQ rstatus, rstatus, #MASK_OVERFLOW // 0 : AND mask 11111011111 : set V to zero + ORRNE rstatus, rstatus, #MASK_OVERFLOW // 1 : OR mask 00000100000 : set V to one +1112: + MOVS regA, rscratch2 + UPDATE_ZN + B 1113f +1111: + S9xGetByteLow + MOVS rscratch2, rstatus, LSR #MASK_SHIFTER_CARRY + SUBCS rscratch, rscratch, #0x100 + ADCS regA, regA, rscratch, ROR #8 + //OverFlow + ORRVS rstatus, rstatus, #MASK_OVERFLOW + BICVC rstatus, rstatus, #MASK_OVERFLOW + //Carry + UPDATE_C + //clear lower part + ANDS regA, regA, #0xFF000000 + //Update flag + UPDATE_ZN +1113: +.endm +/* TO TEST */ +.macro ADC16 + TST rstatus, #MASK_DECIMAL + BEQ 1111f + S9xGetWord + + //rscratch = W3W2W1W0........ + LDR rscratch4, = 0x0F0F0000 + // rscratch2 = xxW2xxW0xxxxxx + // rscratch3 = xxW3xxW1xxxxxx + AND rscratch2, rscratch4, rscratch + AND rscratch3, rscratch4, rscratch, LSR #4 + // rscratch2 = xxW3xxW1xxW2xxW0 + ORR rscratch2, rscratch3, rscratch2, LSR #16 + // rscratch3 = xxA2xxA0xxxxxx + // rscratch4 = xxA3xxA1xxxxxx + // rscratch2 = xxA3xxA1xxA2xxA0 + AND rscratch3, rscratch4, regA + AND rscratch4, rscratch4, regA, LSR #4 + ORR rscratch3, rscratch4, rscratch3, LSR #16 + ADD rscratch2, rscratch3, rscratch2 + LDR rscratch4, = 0x0F0F0000 + // rscratch2 = A + W + TST rstatus, #MASK_CARRY + ADDNE rscratch2, rscratch2, #0x1 + // rscratch2 = A + W + C + //A0 + AND rscratch3, rscratch2, #0x0000001F + CMP rscratch3, #0x00000009 + ADDHI rscratch2, rscratch2, #0x00010000 + SUBHI rscratch2, rscratch2, #0x0000000A + //A1 + AND rscratch3, rscratch2, #0x001F0000 + CMP rscratch3, #0x00090000 + ADDHI rscratch2, rscratch2, #0x00000100 + SUBHI rscratch2, rscratch2, #0x000A0000 + //A2 + AND rscratch3, rscratch2, #0x00001F00 + CMP rscratch3, #0x00000900 + SUBHI rscratch2, rscratch2, #0x00000A00 + ADDHI rscratch2, rscratch2, #0x01000000 + //A3 + AND rscratch3, rscratch2, #0x1F000000 + CMP rscratch3, #0x09000000 + SUBHI rscratch2, rscratch2, #0x0A000000 + //SetCarry + ORRHI rstatus, rstatus, #MASK_CARRY + //ClearCarry + BICLS rstatus, rstatus, #MASK_CARRY + //rscratch2 = xxR3xxR1xxR2xxR0 + //Pack result + //rscratch3 = xxR3xxR1xxxxxxxx + AND rscratch3, rscratch4, rscratch2 + //rscratch2 = xxR2xxR0xxxxxxxx + AND rscratch2, rscratch4, rscratch2,LSL #16 + //rscratch2 = R3R2R1R0xxxxxxxx + ORR rscratch2, rscratch2,rscratch3,LSL #4 +//only last bit + AND rscratch,rscratch,#0x80000000 + // (register.AL ^ Work8) + EORS rscratch3, regA, rscratch + BICNE rstatus, rstatus, #MASK_OVERFLOW // 0 : AND mask 11111011111 : set V to zero + BNE 1112f + // (Work8 ^ Ans8) + EORS rscratch3, rscratch2, rscratch + TSTNE rscratch3,#0x80000000 + BICEQ rstatus, rstatus, #MASK_OVERFLOW // 0 : AND mask 11111011111 : set V to zero + ORRNE rstatus, rstatus, #MASK_OVERFLOW // 1 : OR mask 00000100000 : set V to one +1112: + MOVS regA, rscratch2 + UPDATE_ZN + B 1113f +1111: + S9xGetWordLow + MOVS rscratch2, rstatus, LSR #MASK_SHIFTER_CARRY + SUBCS rscratch, rscratch, #0x10000 + ADCS regA, regA,rscratch, ROR #16 + //OverFlow + ORRVS rstatus, rstatus, #MASK_OVERFLOW + BICVC rstatus, rstatus, #MASK_OVERFLOW + MOV regA, regA, LSR #16 + //Carry + UPDATE_C + //clear lower parts + MOVS regA, regA, LSL #16 + //Update flag + UPDATE_ZN +1113: +.endm + + +.macro AND16 + S9xGetWord + ANDS regA, regA, rscratch + UPDATE_ZN +.endm +.macro AND8 + S9xGetByte + ANDS regA, regA, rscratch + UPDATE_ZN +.endm +.macro A_ASL8 + // 7 instr + MOVS regA, regA, LSL #1 + UPDATE_C + UPDATE_ZN + ADD1CYCLE +.endm +.macro A_ASL16 + // 7 instr + MOVS regA, regA, LSL #1 + UPDATE_C + UPDATE_ZN + ADD1CYCLE +.endm +.macro ASL16 + S9xGetWordRegNS rscratch2 // do not destroy Opadress in rscratch + MOVS rscratch2, rscratch2, LSL #1 + UPDATE_C + UPDATE_ZN + S9xSetWord rscratch2 + ADD1CYCLE +.endm +.macro ASL8 + S9xGetByteRegNS rscratch2 // do not destroy Opadress in rscratch + MOVS rscratch2, rscratch2, LSL #1 + UPDATE_C + UPDATE_ZN + S9xSetByte rscratch2 + ADD1CYCLE +.endm +.macro BIT8 + S9xGetByte + MOVS rscratch2, rscratch, LSL #1 + // Trick in ASM : shift one more bit : ARM C = Snes N + // ARM N = Snes V + // If Carry Set, then Set Neg in SNES + BICCC rstatus, rstatus, #MASK_NEG // 0 : AND mask 11111011111 : set C to zero + ORRCS rstatus, rstatus, #MASK_NEG // 1 : OR mask 00000100000 : set C to one + // If Neg Set, then Set Overflow in SNES + BICPL rstatus, rstatus, #MASK_OVERFLOW // 0 : AND mask 11111011111 : set N to zero + ORRMI rstatus, rstatus, #MASK_OVERFLOW // 1 : OR mask 00000100000 : set N to one + + // Now do a real AND with A register + // Set Zero Flag, bit test + ANDS rscratch2, regA, rscratch + BICNE rstatus, rstatus, #MASK_ZERO // 0 : AND mask 11111011111 : set Z to zero + ORREQ rstatus, rstatus, #MASK_ZERO // 1 : OR mask 00000100000 : set Z to one +.endm + +.macro BIT16 + S9xGetWord + MOVS rscratch2, rscratch, LSL #1 + // Trick in ASM : shift one more bit : ARM C = Snes N + // ARM N = Snes V + // If Carry Set, then Set Neg in SNES + BICCC rstatus, rstatus, #MASK_NEG // 0 : AND mask 11111011111 : set N to zero + ORRCS rstatus, rstatus, #MASK_NEG // 1 : OR mask 00000100000 : set N to one + // If Neg Set, then Set Overflow in SNES + BICPL rstatus, rstatus, #MASK_OVERFLOW // 0 : AND mask 11111011111 : set V to zero + ORRMI rstatus, rstatus, #MASK_OVERFLOW // 1 : OR mask 00000100000 : set V to one + // Now do a real AND with A register + // Set Zero Flag, bit test + ANDS rscratch2, regA, rscratch + // Bit set ->Z=0->xxxNE Clear flag + BICNE rstatus, rstatus, #MASK_ZERO // 0 : AND mask 11111011111 : set Z to zero + // Bit clear->Z=1->xxxEQ Set flag + ORREQ rstatus, rstatus, #MASK_ZERO // 1 : OR mask 00000100000 : set Z to one +.endm +.macro CMP8 + S9xGetByte + SUBS rscratch2,regA,rscratch + BICCC rstatus, rstatus, #MASK_CARRY + ORRCS rstatus, rstatus, #MASK_CARRY + UPDATE_ZN + +.endm +.macro CMP16 + S9xGetWord + SUBS rscratch2,regA,rscratch + BICCC rstatus, rstatus, #MASK_CARRY + ORRCS rstatus, rstatus, #MASK_CARRY + UPDATE_ZN + +.endm +.macro CMX16 + S9xGetWord + SUBS rscratch2,regX,rscratch + BICCC rstatus, rstatus, #MASK_CARRY + ORRCS rstatus, rstatus, #MASK_CARRY + UPDATE_ZN +.endm +.macro CMX8 + S9xGetByte + SUBS rscratch2,regX,rscratch + BICCC rstatus, rstatus, #MASK_CARRY + ORRCS rstatus, rstatus, #MASK_CARRY + UPDATE_ZN +.endm +.macro CMY16 + S9xGetWord + SUBS rscratch2,regY,rscratch + BICCC rstatus, rstatus, #MASK_CARRY + ORRCS rstatus, rstatus, #MASK_CARRY + UPDATE_ZN +.endm +.macro CMY8 + S9xGetByte + SUBS rscratch2,regY,rscratch + BICCC rstatus, rstatus, #MASK_CARRY + ORRCS rstatus, rstatus, #MASK_CARRY + UPDATE_ZN +.endm +.macro A_DEC8 + MOV rscratch,#0 + SUBS regA, regA, #0x01000000 + STR rscratch,[regCPUvar,#WaitAddress_ofs] + UPDATE_ZN + ADD1CYCLE +.endm +.macro A_DEC16 + MOV rscratch,#0 + SUBS regA, regA, #0x00010000 + STR rscratch,[regCPUvar,#WaitAddress_ofs] + UPDATE_ZN + ADD1CYCLE +.endm +.macro DEC16 + S9xGetWordRegNS rscratch2 // do not destroy Opadress in rscratch + MOV rscratch3,#0 + SUBS rscratch2, rscratch2, #0x00010000 + STR rscratch3,[regCPUvar,#WaitAddress_ofs] + UPDATE_ZN + S9xSetWord rscratch2 + ADD1CYCLE +.endm +.macro DEC8 + S9xGetByteRegNS rscratch2 // do not destroy Opadress in rscratch + MOV rscratch3,#0 + SUBS rscratch2, rscratch2, #0x01000000 + STR rscratch3,[regCPUvar,#WaitAddress_ofs] + UPDATE_ZN + S9xSetByte rscratch2 + ADD1CYCLE +.endm +.macro EOR16 + S9xGetWord + EORS regA, regA, rscratch + UPDATE_ZN +.endm +.macro EOR8 + S9xGetByte + EORS regA, regA, rscratch + UPDATE_ZN +.endm +.macro A_INC8 + MOV rscratch3,#0 + ADDS regA, regA, #0x01000000 + STR rscratch3,[regCPUvar,#WaitAddress_ofs] + UPDATE_ZN + ADD1CYCLE +.endm +.macro A_INC16 + MOV rscratch3,#0 + ADDS regA, regA, #0x00010000 + STR rscratch3,[regCPUvar,#WaitAddress_ofs] + UPDATE_ZN + ADD1CYCLE +.endm +.macro INC16 + S9xGetWordRegNS rscratch2 + MOV rscratch3,#0 + ADDS rscratch2, rscratch2, #0x00010000 + STR rscratch3,[regCPUvar,#WaitAddress_ofs] + UPDATE_ZN + S9xSetWord rscratch2 + ADD1CYCLE +.endm +.macro INC8 + S9xGetByteRegNS rscratch2 + MOV rscratch3,#0 + ADDS rscratch2, rscratch2, #0x01000000 + STR rscratch3,[regCPUvar,#WaitAddress_ofs] + UPDATE_ZN + S9xSetByte rscratch2 + ADD1CYCLE +.endm +.macro LDA16 + S9xGetWordRegStatus regA + UPDATE_ZN +.endm +.macro LDA8 + S9xGetByteRegStatus regA + UPDATE_ZN +.endm +.macro LDX16 + S9xGetWordRegStatus regX + UPDATE_ZN +.endm +.macro LDX8 + S9xGetByteRegStatus regX + UPDATE_ZN +.endm +.macro LDY16 + S9xGetWordRegStatus regY + UPDATE_ZN +.endm +.macro LDY8 + S9xGetByteRegStatus regY + UPDATE_ZN +.endm +.macro A_LSR16 + BIC rstatus, rstatus, #MASK_NEG // 0 : AND mask 11111011111 : set N to zero + MOVS regA, regA, LSR #17 // hhhhhhhh llllllll 00000000 00000000 -> 00000000 00000000 0hhhhhhh hlllllll + // Update Zero + BICNE rstatus, rstatus, #MASK_ZERO // 0 : AND mask 11111011111 : set Z to zero + MOV regA, regA, LSL #16 // -> 0lllllll 00000000 00000000 00000000 + ORREQ rstatus, rstatus, #MASK_ZERO // 1 : OR mask 00000100000 : set Z to one + // Note : the two MOV are included between instruction, to optimize + // the pipeline. + UPDATE_C + ADD1CYCLE +.endm +.macro A_LSR8 + BIC rstatus, rstatus, #MASK_NEG // 0 : AND mask 11111011111 : set N to zero + MOVS regA, regA, LSR #25 // llllllll 00000000 00000000 00000000 -> 00000000 00000000 00000000 0lllllll + // Update Zero + BICNE rstatus, rstatus, #MASK_ZERO // 0 : AND mask 11111011111 : set Z to zero + MOV regA, regA, LSL #24 // -> 00000000 00000000 00000000 0lllllll + ORREQ rstatus, rstatus, #MASK_ZERO // 1 : OR mask 00000100000 : set Z to one + // Note : the two MOV are included between instruction, to optimize + // the pipeline. + UPDATE_C + ADD1CYCLE +.endm +.macro LSR16 + S9xGetWordRegNS rscratch2 + // N set to zero by >> 1 LSR + BIC rstatus, rstatus, #MASK_NEG // 0 : AND mask 11111011111 : set N to zero + MOVS rscratch2, rscratch2, LSR #17 // llllllll 00000000 00000000 00000000 -> 00000000 00000000 00000000 0lllllll + // Update Carry + BICCC rstatus, rstatus, #MASK_CARRY // 0 : AND mask 11111011111 : set C to zero + ORRCS rstatus, rstatus, #MASK_CARRY // 1 : OR mask 00000100000 : set C to one + // Update Zero + BICNE rstatus, rstatus, #MASK_ZERO // 0 : AND mask 11111011111 : set Z to zero + ORREQ rstatus, rstatus, #MASK_ZERO // 1 : OR mask 00000100000 : set Z to one + S9xSetWordLow rscratch2 + ADD1CYCLE +.endm +.macro LSR8 + S9xGetByteRegNS rscratch2 + // N set to zero by >> 1 LSR + BIC rstatus, rstatus, #MASK_NEG // 0 : AND mask 11111011111 : set N to zero + MOVS rscratch2, rscratch2, LSR #25 // llllllll 00000000 00000000 00000000 -> 00000000 00000000 00000000 0lllllll + // Update Carry + BICCC rstatus, rstatus, #MASK_CARRY // 0 : AND mask 11111011111 : set C to zero + ORRCS rstatus, rstatus, #MASK_CARRY // 1 : OR mask 00000100000 : set C to one + // Update Zero + BICNE rstatus, rstatus, #MASK_ZERO // 0 : AND mask 11111011111 : set Z to zero + ORREQ rstatus, rstatus, #MASK_ZERO // 1 : OR mask 00000100000 : set Z to one + S9xSetByteLow rscratch2 + ADD1CYCLE +.endm +.macro ORA8 + S9xGetByte + ORRS regA, regA, rscratch + UPDATE_ZN +.endm +.macro ORA16 + S9xGetWord + ORRS regA, regA, rscratch + UPDATE_ZN +.endm +.macro A_ROL16 + TST rstatus, #MASK_CARRY + ORRNE regA, regA, #0x00008000 + MOVS regA, regA, LSL #1 + UPDATE_ZN + UPDATE_C + ADD1CYCLE +.endm +.macro A_ROL8 + TST rstatus, #MASK_CARRY + ORRNE regA, regA, #0x00800000 + MOVS regA, regA, LSL #1 + UPDATE_ZN + UPDATE_C + ADD1CYCLE +.endm +.macro ROL16 + S9xGetWordRegNS rscratch2 + TST rstatus, #MASK_CARRY + ORRNE rscratch2, rscratch2, #0x00008000 + MOVS rscratch2, rscratch2, LSL #1 + UPDATE_ZN + UPDATE_C + S9xSetWord rscratch2 + ADD1CYCLE +.endm +.macro ROL8 + S9xGetByteRegNS rscratch2 + TST rstatus, #MASK_CARRY + ORRNE rscratch2, rscratch2, #0x00800000 + MOVS rscratch2, rscratch2, LSL #1 + UPDATE_ZN + UPDATE_C + S9xSetByte rscratch2 + ADD1CYCLE +.endm +.macro A_ROR16 + MOV regA,regA, LSR #16 + TST rstatus, #MASK_CARRY + ORRNE regA, regA, #0x00010000 + ORRNE rstatus,rstatus,#MASK_NEG + BICEQ rstatus,rstatus,#MASK_NEG + MOVS regA,regA,LSR #1 + UPDATE_C + UPDATE_Z + MOV regA,regA, LSL #16 + ADD1CYCLE +.endm +.macro A_ROR8 + MOV regA,regA, LSR #24 + TST rstatus, #MASK_CARRY + ORRNE regA, regA, #0x00000100 + ORRNE rstatus,rstatus,#MASK_NEG + BICEQ rstatus,rstatus,#MASK_NEG + MOVS regA,regA,LSR #1 + UPDATE_C + UPDATE_Z + MOV regA,regA, LSL #24 + ADD1CYCLE +.endm +.macro ROR16 + S9xGetWordLowRegNS rscratch2 + TST rstatus, #MASK_CARRY + ORRNE rscratch2, rscratch2, #0x00010000 + ORRNE rstatus,rstatus,#MASK_NEG + BICEQ rstatus,rstatus,#MASK_NEG + MOVS rscratch2,rscratch2,LSR #1 + UPDATE_C + UPDATE_Z + S9xSetWordLow rscratch2 + ADD1CYCLE + +.endm +.macro ROR8 + S9xGetByteLowRegNS rscratch2 + TST rstatus, #MASK_CARRY + ORRNE rscratch2, rscratch2, #0x00000100 + ORRNE rstatus,rstatus,#MASK_NEG + BICEQ rstatus,rstatus,#MASK_NEG + MOVS rscratch2,rscratch2,LSR #1 + UPDATE_C + UPDATE_Z + S9xSetByteLow rscratch2 + ADD1CYCLE +.endm + +.macro SBC16 + TST rstatus, #MASK_DECIMAL + BEQ 1111f + //TODO + S9xGetWord + + STMFD R13!,{rscratch5,rscratch6,rscratch7,rscratch8,rscratch9} + MOV rscratch9,#0x000F0000 + //rscratch2=xxxxxxW1xxxxxxxxxx + !Carry + //rscratch3=xxxxxxW2xxxxxxxxxx + //rscratch4=xxxxxxW3xxxxxxxxxx + //rscratch5=xxxxxxW4xxxxxxxxxx + AND rscratch2, rscratch9, rscratch + TST rstatus, #MASK_CARRY + ADDEQ rscratch2, rscratch2, #0x00010000 //W1=W1+!Carry + AND rscratch3, rscratch9, rscratch, LSR #4 + AND rscratch4, rscratch9, rscratch, LSR #8 + AND rscratch5, rscratch9, rscratch, LSR #12 + + //rscratch6=xxxxxxA1xxxxxxxxxx + //rscratch7=xxxxxxA2xxxxxxxxxx + //rscratch8=xxxxxxA3xxxxxxxxxx + //rscratch9=xxxxxxA4xxxxxxxxxx + AND rscratch6, rscratch9, regA + AND rscratch7, rscratch9, regA, LSR #4 + AND rscratch8, rscratch9, regA, LSR #8 + AND rscratch9, rscratch9, regA, LSR #12 + + SUB rscratch2,rscratch6,rscratch2 //R1=A1-W1-!Carry + CMP rscratch2, #0x00090000 // if R1 > 9 + ADDHI rscratch2, rscratch2, #0x000A0000 // then R1 += 10 + ADDHI rscratch3, rscratch3, #0x00010000 // then (W2++) + SUB rscratch3,rscratch7,rscratch3 //R2=A2-W2 + CMP rscratch3, #0x00090000 // if R2 > 9 + ADDHI rscratch3, rscratch3, #0x000A0000 // then R2 += 10 + ADDHI rscratch4, rscratch4, #0x00010000 // then (W3++) + SUB rscratch4,rscratch8,rscratch4 //R3=A3-W3 + CMP rscratch4, #0x00090000 // if R3 > 9 + ADDHI rscratch4, rscratch4, #0x000A0000 // then R3 += 10 + ADDHI rscratch5, rscratch5, #0x00010000 // then (W3++) + SUB rscratch5,rscratch9,rscratch5 //R4=A4-W4 + CMP rscratch5, #0x00090000 // if R4 > 9 + ADDHI rscratch5, rscratch5, #0x000A0000 // then R4 += 10 + BICHI rstatus, rstatus, #MASK_CARRY // then ClearCarry + ORRLS rstatus, rstatus, #MASK_CARRY // else SetCarry + + MOV rscratch9,#0x000F0000 + AND rscratch2,rscratch9,rscratch2 + AND rscratch3,rscratch9,rscratch3 + AND rscratch4,rscratch9,rscratch4 + AND rscratch5,rscratch9,rscratch5 + ORR rscratch2,rscratch2,rscratch3,LSL #4 + ORR rscratch2,rscratch2,rscratch4,LSL #8 + ORR rscratch2,rscratch2,rscratch5,LSL #12 + + LDMFD R13!,{rscratch5,rscratch6,rscratch7,rscratch8,rscratch9} + //only last bit + AND regA,regA,#0x80000000 + // (register.A.W ^ Work8) + EORS rscratch3, regA, rscratch + BICEQ rstatus, rstatus, #MASK_OVERFLOW // 0 : AND mask 11111011111 : set V to zero + BEQ 1112f + // (register.A.W ^ Ans8) + EORS rscratch3, regA, rscratch2 + // & 0x80 + TSTNE rscratch3,#0x80000000 + BICEQ rstatus, rstatus, #MASK_OVERFLOW // 0 : AND mask 11111011111 : set V to zero + ORRNE rstatus, rstatus, #MASK_OVERFLOW // 1 : OR mask 00000100000 : set V to one +1112: + MOVS regA, rscratch2 + UPDATE_ZN + B 1113f +1111: + S9xGetWordLow + MOVS rscratch2,rstatus,LSR #MASK_SHIFTER_CARRY + SBCS regA, regA, rscratch, LSL #16 + //OverFlow + ORRVS rstatus, rstatus, #MASK_OVERFLOW + BICVC rstatus, rstatus, #MASK_OVERFLOW + MOV regA, regA, LSR #16 + //Carry + UPDATE_C + MOVS regA, regA, LSL #16 + //Update flag + UPDATE_ZN +1113: +.endm + +.macro SBC8 + TST rstatus, #MASK_DECIMAL + BEQ 1111f + S9xGetByte + STMFD R13!,{rscratch} + MOV rscratch4,#0x0F000000 + //rscratch2=xxW1xxxxxxxxxxxx + AND rscratch2, rscratch, rscratch4 + //rscratch=xxW2xxxxxxxxxxxx + AND rscratch, rscratch4, rscratch, LSR #4 + //rscratch3=xxA2xxxxxxxxxxxx + AND rscratch3, rscratch4, regA, LSR #4 + //rscratch4=xxA1xxxxxxxxxxxx + AND rscratch4,regA,rscratch4 + //R1=A1-W1-!CARRY + TST rstatus, #MASK_CARRY + ADDEQ rscratch2, rscratch2, #0x01000000 + SUB rscratch2,rscratch4,rscratch2 + // if R1 > 9 + CMP rscratch2, #0x09000000 + // then R1 += 10 + ADDHI rscratch2, rscratch2, #0x0A000000 + // then A2-- (W2++) + ADDHI rscratch, rscratch, #0x01000000 + // R2=A2-W2 + SUB rscratch3, rscratch3, rscratch + // if R2 > 9 + CMP rscratch3, #0x09000000 + // then R2 -= 10// + ADDHI rscratch3, rscratch3, #0x0A000000 + // then SetCarry() + BICHI rstatus, rstatus, #MASK_CARRY // 1 : OR mask 00000100000 : set C to one + // else ClearCarry() + ORRLS rstatus, rstatus, #MASK_CARRY // 0 : AND mask 11111011111 : set C to zero + // gather rscratch3 and rscratch2 into ans8 + AND rscratch3,rscratch3,#0x0F000000 + AND rscratch2,rscratch2,#0x0F000000 + // rscratch3 : 0R2000000 + // rscratch2 : 0R1000000 + // -> 0xR2R1000000 + ORR rscratch2, rscratch2, rscratch3, LSL #4 + LDMFD R13!,{rscratch} + //only last bit + AND regA,regA,#0x80000000 + // (register.AL ^ Work8) + EORS rscratch3, regA, rscratch + BICEQ rstatus, rstatus, #MASK_OVERFLOW // 0 : AND mask 11111011111 : set V to zero + BEQ 1112f + // (register.AL ^ Ans8) + EORS rscratch3, regA, rscratch2 + // & 0x80 + TSTNE rscratch3,#0x80000000 + BICEQ rstatus, rstatus, #MASK_OVERFLOW // 0 : AND mask 11111011111 : set V to zero + ORRNE rstatus, rstatus, #MASK_OVERFLOW // 1 : OR mask 00000100000 : set V to one +1112: + MOVS regA, rscratch2 + UPDATE_ZN + B 1113f +1111: + S9xGetByteLow + MOVS rscratch2,rstatus,LSR #MASK_SHIFTER_CARRY + SBCS regA, regA, rscratch, LSL #24 + //OverFlow + ORRVS rstatus, rstatus, #MASK_OVERFLOW + BICVC rstatus, rstatus, #MASK_OVERFLOW + //Carry + UPDATE_C + //Update flag + ANDS regA, regA, #0xFF000000 + UPDATE_ZN +1113: +.endm + +.macro STA16 + S9xSetWord regA +.endm +.macro STA8 + S9xSetByte regA +.endm +.macro STX16 + S9xSetWord regX +.endm +.macro STX8 + S9xSetByte regX +.endm +.macro STY16 + S9xSetWord regY +.endm +.macro STY8 + S9xSetByte regY +.endm +.macro STZ16 + S9xSetWordZero +.endm +.macro STZ8 + S9xSetByteZero +.endm +.macro TSB16 + S9xGetWordRegNS rscratch2 + TST regA, rscratch2 + BICNE rstatus, rstatus, #MASK_ZERO // 0 : AND mask 11111011111 : set Z to zero + ORREQ rstatus, rstatus, #MASK_ZERO // 1 : OR mask 00000100000 : set Z to one + ORR rscratch2, regA, rscratch2 + S9xSetWord rscratch2 + ADD1CYCLE +.endm +.macro TSB8 + S9xGetByteRegNS rscratch2 + TST regA, rscratch2 + BICNE rstatus, rstatus, #MASK_ZERO // 0 : AND mask 11111011111 : set Z to zero + ORREQ rstatus, rstatus, #MASK_ZERO // 1 : OR mask 00000100000 : set Z to one + ORR rscratch2, regA, rscratch2 + S9xSetByte rscratch2 + ADD1CYCLE +.endm +.macro TRB16 + S9xGetWordRegNS rscratch2 + TST regA, rscratch2 + BICNE rstatus, rstatus, #MASK_ZERO // 0 : AND mask 11111011111 : set Z to zero + ORREQ rstatus, rstatus, #MASK_ZERO // 1 : OR mask 00000100000 : set Z to one + MVN rscratch3, regA + AND rscratch2, rscratch3, rscratch2 + S9xSetWord rscratch2 + ADD1CYCLE +.endm +.macro TRB8 + S9xGetByteRegNS rscratch2 + TST regA, rscratch2 + BICNE rstatus, rstatus, #MASK_ZERO // 0 : AND mask 11111011111 : set Z to zero + ORREQ rstatus, rstatus, #MASK_ZERO // 1 : OR mask 00000100000 : set Z to one + MVN rscratch3, regA + AND rscratch2, rscratch3, rscratch2 + S9xSetByte rscratch2 + ADD1CYCLE +.endm +/**************************************************************************/ + + +/**************************************************************************/ + +.macro Op09M0 /*ORA*/ + LDRB rscratch2, [rpc,#1] + LDRB rscratch, [rpc], #2 + ORR rscratch2,rscratch,rscratch2,LSL #8 + ORRS regA,regA,rscratch2,LSL #16 + UPDATE_ZN + ADD2MEM +.endm +.macro Op09M1 /*ORA*/ + LDRB rscratch, [rpc], #1 + ORRS regA,regA,rscratch,LSL #24 + UPDATE_ZN + ADD1MEM +.endm +/***********************************************************************/ +.macro Op90 /*BCC*/ + asmRelative + BranchCheck0 + TST rstatus, #MASK_CARRY + BNE 1111f + ADD rpc, rscratch, regpcbase // rpc = OpAddress +PCBase + ADD1CYCLE + CPUShutdown +1111: +.endm +.macro OpB0 /*BCS*/ + asmRelative + BranchCheck0 + TST rstatus, #MASK_CARRY + BEQ 1111f + ADD rpc, rscratch, regpcbase // rpc = OpAddress +PCBase + ADD1CYCLE + CPUShutdown +1111: +.endm +.macro OpF0 /*BEQ*/ + asmRelative + BranchCheck2 + TST rstatus, #MASK_ZERO + BEQ 1111f + ADD rpc, rscratch, regpcbase // rpc = OpAddress +PCBase + ADD1CYCLE + CPUShutdown +1111: +.endm +.macro OpD0 /*BNE*/ + asmRelative + BranchCheck1 + TST rstatus, #MASK_ZERO + BNE 1111f + ADD rpc, rscratch, regpcbase // rpc = OpAddress +PCBase + ADD1CYCLE + CPUShutdown +1111: +.endm +.macro Op30 /*BMI*/ + asmRelative + BranchCheck0 + TST rstatus, #MASK_NEG + BEQ 1111f + ADD rpc, rscratch, regpcbase // rpc = OpAddress +PCBase + ADD1CYCLE + CPUShutdown +1111: +.endm +.macro Op10 /*BPL*/ + asmRelative + BranchCheck1 + TST rstatus, #MASK_NEG // neg, z!=0, NE + BNE 1111f + ADD rpc, rscratch, regpcbase // rpc = OpAddress + PCBase + ADD1CYCLE + CPUShutdown +1111: +.endm +.macro Op50 /*BVC*/ + asmRelative + BranchCheck0 + TST rstatus, #MASK_OVERFLOW // neg, z!=0, NE + BNE 1111f + ADD rpc, rscratch, regpcbase // rpc = OpAddress + PCBase + ADD1CYCLE + CPUShutdown +1111: +.endm +.macro Op70 /*BVS*/ + asmRelative + BranchCheck0 + TST rstatus, #MASK_OVERFLOW // neg, z!=0, NE + BEQ 1111f + ADD rpc, rscratch, regpcbase // rpc = OpAddress + PCBase + ADD1CYCLE + CPUShutdown +1111: +.endm +.macro Op80 /*BRA*/ + asmRelative + ADD rpc, rscratch, regpcbase // rpc = OpAddress + PCBase + ADD1CYCLE + CPUShutdown +1111: +.endm +/*******************************************************************************************/ +/************************************************************/ +/* SetFlag Instructions ********************************************************************** */ +.macro Op38 /*SEC*/ + ORR rstatus, rstatus, #MASK_CARRY // 1 : OR mask 00000100000 : set C to one + ADD1CYCLE +.endm +.macro OpF8 /*SED*/ + SetDecimal + ADD1CYCLE +.endm +.macro Op78 /*SEI*/ + SetIRQ + ADD1CYCLE +.endm + + +/****************************************************************************************/ +/* ClearFlag Instructions ******************************************************************** */ +.macro Op18 /*CLC*/ + BIC rstatus, rstatus, #MASK_CARRY + ADD1CYCLE +.endm +.macro OpD8 /*CLD*/ + ClearDecimal + ADD1CYCLE +.endm +.macro Op58 /*CLI*/ + ClearIRQ + ADD1CYCLE + //CHECK_FOR_IRQ +.endm +.macro OpB8 /*CLV*/ + BIC rstatus, rstatus, #MASK_OVERFLOW + ADD1CYCLE +.endm + +/******************************************************************************************/ +/* DEX/DEY *********************************************************************************** */ + +.macro OpCAX1 /*DEX*/ + MOV rscratch3,#0 + SUBS regX, regX, #0x01000000 + STR rscratch3,[regCPUvar,#WaitAddress_ofs] + UPDATE_ZN + ADD1CYCLE +.endm +.macro OpCAX0 /*DEX*/ + MOV rscratch3,#0 + SUBS regX, regX, #0x00010000 + STR rscratch3,[regCPUvar,#WaitAddress_ofs] + UPDATE_ZN + ADD1CYCLE +.endm +.macro Op88X1 /*DEY*/ + MOV rscratch3,#0 + SUBS regY, regY, #0x01000000 + STR rscratch3,[regCPUvar,#WaitAddress_ofs] + UPDATE_ZN + ADD1CYCLE +.endm +.macro Op88X0 /*DEY*/ + MOV rscratch3,#0 + SUBS regY, regY, #0x00010000 + STR rscratch3,[regCPUvar,#WaitAddress_ofs] + UPDATE_ZN + ADD1CYCLE +.endm + +/******************************************************************************************/ +/* INX/INY *********************************************************************************** */ +.macro OpE8X1 + MOV rscratch3,#0 + ADDS regX, regX, #0x01000000 + STR rscratch3,[regCPUvar,#WaitAddress_ofs] + UPDATE_ZN + ADD1CYCLE +.endm +.macro OpE8X0 + MOV rscratch3,#0 + ADDS regX, regX, #0x00010000 + STR rscratch3,[regCPUvar,#WaitAddress_ofs] + UPDATE_ZN + ADD1CYCLE +.endm +.macro OpC8X1 + MOV rscratch3,#0 + ADDS regY, regY, #0x01000000 + STR rscratch3,[regCPUvar,#WaitAddress_ofs] + UPDATE_ZN + ADD1CYCLE +.endm +.macro OpC8X0 + MOV rscratch3,#0 + ADDS regY, regY, #0x00010000 + STR rscratch3,[regCPUvar,#WaitAddress_ofs] + UPDATE_ZN + ADD1CYCLE +.endm + +/**********************************************************************************************/ + +/* NOP *************************************************************************************** */ +.macro OpEA + ADD1CYCLE +.endm + +/**************************************************************************/ +/* PUSH Instructions **************************************************** */ +.macro OpF4 + Absolute + PushWrLow +.endm +.macro OpD4 + DirectIndirect + PushWrLow +.endm +.macro Op62 + asmRelativeLong + PushWrLow +.endm +.macro Op48M0 + PushW regA + ADD1CYCLE +.endm +.macro Op48M1 + PushB regA + ADD1CYCLE +.endm +.macro Op8B + AND rscratch2, regDBank, #0xFF + PushBLow rscratch2 + ADD1CYCLE +.endm +.macro Op0B + PushW regD + ADD1CYCLE +.endm +.macro Op4B + PushBlow regPBank + ADD1CYCLE +.endm +.macro Op08 + PushB rstatus + ADD1CYCLE +.endm +.macro OpDAX1 + PushB regX + ADD1CYCLE +.endm +.macro OpDAX0 + PushW regX + ADD1CYCLE +.endm +.macro Op5AX1 + PushB regY + ADD1CYCLE +.endm +.macro Op5AX0 + PushW regY + ADD1CYCLE +.endm +/**************************************************************************/ +/* PULL Instructions **************************************************** */ +.macro Op68M1 + PullBS regA + UPDATE_ZN + ADD2CYCLE +.endm +.macro Op68M0 + PullWS regA + UPDATE_ZN + ADD2CYCLE +.endm +.macro OpAB + BIC regDBank,regDBank, #0xFF + PullBrS + ORR regDBank,regDBank,rscratch, LSR #24 + UPDATE_ZN + ADD2CYCLE +.endm +.macro Op2B + BIC regD,regD, #0xFF000000 + BIC regD,regD, #0x00FF0000 + PullWrS + ORR regD,rscratch,regD + UPDATE_ZN + ADD2CYCLE +.endm +.macro Op28X1M1 /*PLP*/ + //INDEX set, MEMORY set + BIC rstatus,rstatus,#0xFF000000 + PullBr + ORR rstatus,rscratch,rstatus + TST rstatus, #MASK_INDEX + //INDEX clear & was set : 8->16 + MOVEQ regX,regX,LSR #8 + MOVEQ regY,regY,LSR #8 + TST rstatus, #MASK_MEM + //MEMORY cleared & was set : 8->16 + LDREQB rscratch,[regCPUvar,#RAH_ofs] + MOVEQ regA,regA,LSR #8 + ORREQ regA,regA,rscratch, LSL #24 + S9xFixCycles + ADD2CYCLE +.endm +.macro Op28X0M1 /*PLP*/ + //INDEX cleared, MEMORY set + BIC rstatus,rstatus,#0xFF000000 + PullBr + ORR rstatus,rscratch,rstatus + TST rstatus, #MASK_INDEX + //INDEX set & was cleared : 16->8 + MOVNE regX,regX,LSL #8 + MOVNE regY,regY,LSL #8 + TST rstatus, #MASK_MEM + //MEMORY cleared & was set : 8->16 + LDREQB rscratch,[regCPUvar,#RAH_ofs] + MOVEQ regA,regA,LSR #8 + ORREQ regA,regA,rscratch, LSL #24 + S9xFixCycles + ADD2CYCLE +.endm +.macro Op28X1M0 /*PLP*/ + //INDEX set, MEMORY set + BIC rstatus,rstatus,#0xFF000000 + PullBr + ORR rstatus,rscratch,rstatus + TST rstatus, #MASK_INDEX + //INDEX clear & was set : 8->16 + MOVEQ regX,regX,LSR #8 + MOVEQ regY,regY,LSR #8 + TST rstatus, #MASK_MEM + //MEMORY set & was cleared : 16->8 + MOVNE rscratch,regA,LSR #24 + MOVNE regA,regA,LSL #8 + STRNEB rscratch,[regCPUvar,#RAH_ofs] + S9xFixCycles + ADD2CYCLE +.endm +.macro Op28X0M0 /*PLP*/ + //INDEX set, MEMORY set + BIC rstatus,rstatus,#0xFF000000 + PullBr + ORR rstatus,rscratch,rstatus + TST rstatus, #MASK_INDEX + //INDEX set & was cleared : 16->8 + MOVNE regX,regX,LSL #8 + MOVNE regY,regY,LSL #8 + TST rstatus, #MASK_MEM + //MEMORY set & was cleared : 16->8 + MOVNE rscratch,regA,LSR #24 + MOVNE regA,regA,LSL #8 + STRNEB rscratch,[regCPUvar,#RAH_ofs] + S9xFixCycles + ADD2CYCLE +.endm +.macro OpFAX1 + PullBS regX + UPDATE_ZN + ADD2CYCLE +.endm +.macro OpFAX0 + PullWS regX + UPDATE_ZN + ADD2CYCLE +.endm +.macro Op7AX1 + PullBS regY + UPDATE_ZN + ADD2CYCLE +.endm +.macro Op7AX0 + PullWS regY + UPDATE_ZN + ADD2CYCLE +.endm + +/**********************************************************************************************/ +/* Transfer Instructions ********************************************************************* */ +.macro OpAAX1M1 /*TAX8*/ + MOVS regX, regA + UPDATE_ZN + ADD1CYCLE +.endm +.macro OpAAX0M1 /*TAX16*/ + LDRB regX, [regCPUvar,#RAH_ofs] + MOV regX, regX,LSL #24 + ORRS regX, regX,regA, LSR #8 + UPDATE_ZN + ADD1CYCLE +.endm +.macro OpAAX1M0 /*TAX8*/ + MOVS regX, regA, LSL #8 + UPDATE_ZN + ADD1CYCLE +.endm +.macro OpAAX0M0 /*TAX16*/ + MOVS regX, regA + UPDATE_ZN + ADD1CYCLE +.endm +.macro OpA8X1M1 /*TAY8*/ + MOVS regY, regA + UPDATE_ZN + ADD1CYCLE +.endm +.macro OpA8X0M1 /*TAY16*/ + LDRB regY, [regCPUvar,#RAH_ofs] + MOV regY, regY,LSL #24 + ORRS regY, regY,regA, LSR #8 + UPDATE_ZN + ADD1CYCLE +.endm +.macro OpA8X1M0 /*TAY8*/ + MOVS regY, regA, LSL #8 + UPDATE_ZN + ADD1CYCLE +.endm +.macro OpA8X0M0 /*TAY16*/ + MOVS regY, regA + UPDATE_ZN + ADD1CYCLE +.endm +.macro Op5BM1 + LDRB rscratch, [regCPUvar,#RAH_ofs] + MOV regD,regD,LSL #16 + MOV rscratch,rscratch,LSL #24 + ORRS rscratch,rscratch,regA, LSR #8 + UPDATE_ZN + ORR regD,rscratch,regD,LSR #16 + ADD1CYCLE +.endm +.macro Op5BM0 + MOV regD,regD,LSL #16 + MOVS regA,regA + UPDATE_ZN + ORR regD,regA,regD,LSR #16 + ADD1CYCLE +.endm +.macro Op1BM1 + TST rstatus, #MASK_EMUL + MOVNE regS, regA, LSR #24 + ORRNE regS, regS, #0x100 + LDREQB regS, [regCPUvar,#RAH_ofs] + ORREQ regS, regS, regA + MOVEQ regS, regS, ROR #24 + ADD1CYCLE +.endm +.macro Op1BM0 + MOV regS, regA, LSR #16 + ADD1CYCLE +.endm +.macro Op7BM1 + MOVS regA, regD, ASR #16 + UPDATE_ZN + MOV rscratch,regA,LSR #8 + MOV regA,regA, LSL #24 + STRB rscratch, [regCPUvar,#RAH_ofs] + ADD1CYCLE +.endm +.macro Op7BM0 + MOVS regA, regD, ASR #16 + UPDATE_ZN + MOV regA,regA, LSL #16 + ADD1CYCLE +.endm +.macro Op3BM1 + MOV rscratch,regS, LSR #8 + MOVS regA, regS, LSL #16 + STRB rscratch, [regCPUvar,#RAH_ofs] + UPDATE_ZN + MOV regA,regA, LSL #8 + ADD1CYCLE +.endm +.macro Op3BM0 + MOVS regA, regS, LSL #16 + UPDATE_ZN + ADD1CYCLE +.endm +.macro OpBAX1 + MOVS regX, regS, LSL #24 + UPDATE_ZN + ADD1CYCLE +.endm +.macro OpBAX0 + MOVS regX, regS, LSL #16 + UPDATE_ZN + ADD1CYCLE +.endm +.macro Op8AM1X1 + MOVS regA, regX + UPDATE_ZN + ADD1CYCLE +.endm +.macro Op8AM1X0 + MOVS regA, regX, LSL #8 + UPDATE_ZN + ADD1CYCLE +.endm +.macro Op8AM0X1 + MOVS regA, regX, LSR #8 + UPDATE_ZN + ADD1CYCLE +.endm +.macro Op8AM0X0 + MOVS regA, regX + UPDATE_ZN + ADD1CYCLE +.endm +.macro Op9AX1 + MOV regS, regX, LSR #24 + TST rstatus, #MASK_EMUL + ORRNE regS, regS, #0x100 + ADD1CYCLE +.endm +.macro Op9AX0 + MOV regS, regX, LSR #16 + ADD1CYCLE +.endm +.macro Op9BX1 + MOVS regY, regX + UPDATE_ZN + ADD1CYCLE +.endm +.macro Op9BX0 + MOVS regY, regX + UPDATE_ZN + ADD1CYCLE +.endm +.macro Op98M1X1 + MOVS regA, regY + UPDATE_ZN + ADD1CYCLE +.endm +.macro Op98M1X0 + MOVS regA, regY, LSL #8 + UPDATE_ZN + ADD1CYCLE +.endm +.macro Op98M0X1 + MOVS regA, regY, LSR #8 + UPDATE_ZN + ADD1CYCLE +.endm +.macro Op98M0X0 + MOVS regA, regY + UPDATE_ZN + ADD1CYCLE +.endm +.macro OpBBX1 + MOVS regX, regY + UPDATE_ZN + ADD1CYCLE +.endm +.macro OpBBX0 + MOVS regX, regY + UPDATE_ZN + ADD1CYCLE +.endm + +/**********************************************************************************************/ +/* XCE *************************************************************************************** */ + +.macro OpFB + TST rstatus,#MASK_CARRY + BEQ 1111f + //CARRY is set + TST rstatus,#MASK_EMUL + BNE 1112f + //EMUL is cleared + BIC rstatus,rstatus,#(MASK_CARRY) + TST rstatus,#MASK_INDEX + //X & Y were 16bits before + MOVEQ regX,regX,LSL #8 + MOVEQ regY,regY,LSL #8 + TST rstatus,#MASK_MEM + //A was 16bits before + //save AH + MOVEQ rscratch,regA,LSR #24 + STREQB rscratch,[regCPUvar,#RAH_ofs] + MOVEQ regA,regA,LSL #8 + ORR rstatus,rstatus,#(MASK_EMUL|MASK_MEM|MASK_INDEX) + AND regS,regS,#0xFF + ORR regS,regS,#0x100 + B 1113f +1112: + //EMUL is set + TST rstatus,#MASK_INDEX + //X & Y were 16bits before + MOVEQ regX,regX,LSL #8 + MOVEQ regY,regY,LSL #8 + TST rstatus,#MASK_MEM + //A was 16bits before + //save AH + MOVEQ rscratch,regA,LSR #24 + STREQB rscratch,[regCPUvar,#RAH_ofs] + MOVEQ regA,regA,LSL #8 + ORR rstatus,rstatus,#(MASK_CARRY|MASK_MEM|MASK_INDEX) + AND regS,regS,#0xFF + ORR regS,regS,#0x100 + B 1113f +1111: + //CARRY is cleared + TST rstatus,#MASK_EMUL + BEQ 1115f + //EMUL was set : X,Y & A were 8bits + //Now have to check MEMORY & INDEX for potential conversions to 16bits + TST rstatus,#MASK_INDEX + // X & Y are now 16bits + MOVEQ regX,regX,LSR #8 + MOVEQ regY,regY,LSR #8 + TST rstatus,#MASK_MEM + // A is now 16bits + MOVEQ regA,regA,LSR #8 + //restore AH + LDREQB rscratch,[regCPUvar,#RAH_ofs] + ORREQ regA,regA,rscratch,LSL #24 +1115: + BIC rstatus,rstatus,#(MASK_EMUL) + ORR rstatus,rstatus,#(MASK_CARRY) +1113: + ADD1CYCLE + S9xFixCycles +.endm + +/*******************************************************************************/ +/* BRK *************************************************************************/ +.macro Op00 /*BRK*/ + MOV rscratch,#1 + STRB rscratch,[regCPUvar,#BRKTriggered_ofs] + + TST rstatus, #MASK_EMUL + // EQ is flag to zero (!CheckEmu) + BNE 2001f//elseOp00 + PushBLow regPBank + SUB rscratch, rpc, regpcbase + ADD rscratch2, rscratch, #1 + PushWLow rscratch2 + // PackStatus + PushB rstatus + ClearDecimal + SetIRQ + BIC regPBank, regPBank, #0xFF + MOV rscratch, #0xE6 + ORR rscratch, rscratch, #0xFF00 + S9xGetWordLow + S9xSetPCBase + ADD2CYCLE + B 2002f//endOp00 +2001://elseOp00 + SUB rscratch2, rpc, regpcbase + PushWLow rscratch2 + // PackStatus + PushB rstatus + ClearDecimal + SetIRQ + BIC regPBank,regPBank, #0xFF + MOV rscratch, #0xFE + ORR rscratch, rscratch, #0xFF00 + S9xGetWordLow + S9xSetPCBase + ADD1CYCLE +2002://endOp00 +.endm + + +/**********************************************************************************************/ +/* BRL ************************************************************************************** */ +.macro Op82 /*BRL*/ + asmRelativeLong + ORR rscratch, rscratch, regPBank, LSL #16 + S9xSetPCBase +.endm +/**********************************************************************************************/ +/* IRQ *************************************************************************************** */ +//void S9xOpcode_IRQ (void) +/* + if (!CheckEmulation()) + { + PushB (Registers.PB); + PushW (CPU.PC - CPU.PCBase); + S9xPackStatus (); + PushB (Registers.PL); + ClearDecimal (); + SetIRQ (); + + Registers.PB = 0; + ICPU.ShiftedPB = 0; + if (Settings.SA1 && (Memory.FillRAM [0x2209] & 0x40)) + S9xSetPCBase (Memory.FillRAM [0x220e] | + (Memory.FillRAM [0x220f] << 8)); + else + S9xSetPCBase (S9xGetWord (0xFFEE)); + CPU.Cycles += TWO_CYCLES; + } + else + { + PushW (CPU.PC - CPU.PCBase); + S9xPackStatus (); + PushB (Registers.PL); + ClearDecimal (); + SetIRQ (); + + Registers.PB = 0; + ICPU.ShiftedPB = 0; + if (Settings.SA1 && (Memory.FillRAM [0x2209] & 0x40)) + S9xSetPCBase (Memory.FillRAM [0x220e] | + (Memory.FillRAM [0x220f] << 8)); + else + S9xSetPCBase (S9xGetWord (0xFFFE)); + CPU.Cycles += ONE_CYCLE; + } + } +*/ + +/**********************************************************************************************/ +/* NMI *************************************************************************************** */ +//void S9xOpcode_NMI (void) +/*{ + if (!CheckEmulation()) + { + PushB (Registers.PB); + PushW (CPU.PC - CPU.PCBase); + S9xPackStatus (); + PushB (Registers.PL); + ClearDecimal (); + SetIRQ (); + + Registers.PB = 0; + ICPU.ShiftedPB = 0; + if (Settings.SA1 && (Memory.FillRAM [0x2209] & 0x20)) + S9xSetPCBase (Memory.FillRAM [0x220c] | + (Memory.FillRAM [0x220d] << 8)); + else + S9xSetPCBase (S9xGetWord (0xFFEA)); + CPU.Cycles += TWO_CYCLES; + } + else + { + PushW (CPU.PC - CPU.PCBase); + S9xPackStatus (); + PushB (Registers.PL); + ClearDecimal (); + SetIRQ (); + + Registers.PB = 0; + ICPU.ShiftedPB = 0; + if (Settings.SA1 && (Memory.FillRAM [0x2209] & 0x20)) + S9xSetPCBase (Memory.FillRAM [0x220c] | + (Memory.FillRAM [0x220d] << 8)); + else + S9xSetPCBase (S9xGetWord (0xFFFA)); + CPU.Cycles += ONE_CYCLE; + } +} +*/ + +/**********************************************************************************************/ +/* COP *************************************************************************************** */ +.macro Op02 /*COP*/ + TST rstatus, #MASK_EMUL + // EQ is flag to zero (!CheckEmu) + BNE 2021f//elseOp02 + PushBLow regPBank + SUB rscratch, rpc, regpcbase + ADD rscratch2, rscratch, #1 + PushWLow rscratch2 + // PackStatus + PushB rstatus + ClearDecimal + SetIRQ + BIC regPBank, regPBank,#0xFF + MOV rscratch, #0xE4 + ORR rscratch, rscratch, #0xFF00 + S9xGetWordLow + S9xSetPCBase + ADD2CYCLE + B 2022f//endOp02 +2021://elseOp02 + SUB rscratch2, rpc, regpcbase + PushWLow rscratch2 + // PackStatus + PushB rstatus + ClearDecimal + SetIRQ + BIC regPBank,regPBank, #0xFF + MOV rscratch, #0xF4 + ORR rscratch, rscratch, #0xFF00 + S9xGetWordLow + S9xSetPCBase + ADD1CYCLE +2022://endOp02 +.endm + +/**********************************************************************************************/ +/* JML *************************************************************************************** */ +.macro OpDC + AbsoluteIndirectLong + BIC regPBank,regPBank,#0xFF + ORR regPBank,regPBank, rscratch, LSR #16 + S9xSetPCBase + ADD2CYCLE +.endm +.macro Op5C + AbsoluteLong + BIC regPBank,regPBank,#0xFF + ORR regPBank,regPBank, rscratch, LSR #16 + S9xSetPCBase +.endm + +/**********************************************************************************************/ +/* JMP *************************************************************************************** */ +.macro Op4C + Absolute + BIC rscratch, rscratch, #0xFF0000 + ORR rscratch, rscratch, regPBank, LSL #16 + S9xSetPCBase + CPUShutdown +.endm +.macro Op6C + AbsoluteIndirect + BIC rscratch, rscratch, #0xFF0000 + ORR rscratch, rscratch, regPBank, LSL #16 + S9xSetPCBase +.endm +.macro Op7C + ADD rscratch, rscratch, regPBank, LSL #16 + S9xSetPCBase + ADD1CYCLE +.endm + +/**********************************************************************************************/ +/* JSL/RTL *********************************************************************************** */ +.macro Op22 + PushBlow regPBank + SUB rscratch, rpc, regpcbase + //SUB rscratch2, rscratch2, #1 + ADD rscratch2, rscratch, #2 + PushWlow rscratch2 + AbsoluteLong + BIC regPBank,regPBank,#0xFF + ORR regPBank, regPBank, rscratch, LSR #16 + S9xSetPCBase +.endm +.macro Op6B + PullWLow rpc + BIC regPBank,regPBank,#0xFF + PullBrLow + ORR regPBank, regPBank, rscratch + ADD rscratch, rpc, #1 + BIC rscratch, rscratch,#0xFF0000 + ORR rscratch, rscratch, regPBank, LSL #16 + S9xSetPCBase + ADD2CYCLE +.endm +/**********************************************************************************************/ +/* JSR/RTS *********************************************************************************** */ +.macro Op20 + SUB rscratch, rpc, regpcbase + //SUB rscratch2, rscratch2, #1 + ADD rscratch2, rscratch, #1 + PushWlow rscratch2 + Absolute + BIC rscratch, rscratch, #0xFF0000 + ORR rscratch, rscratch, regPBank, LSL #16 + S9xSetPCBase + ADD1CYCLE +.endm +.macro OpFCX0 + SUB rscratch, rpc, regpcbase + //SUB rscratch2, rscratch2, #1 + ADD rscratch2, rscratch, #1 + PushWlow rscratch2 + AbsoluteIndexedIndirectX0 + ORR rscratch, rscratch, regPBank, LSL #16 + S9xSetPCBase + ADD1CYCLE +.endm +.macro OpFCX1 + SUB rscratch, rpc, regpcbase + //SUB rscratch2, rscratch2, #1 + ADD rscratch2, rscratch, #1 + PushWlow rscratch2 + AbsoluteIndexedIndirectX1 + ORR rscratch, rscratch, regPBank, LSL #16 + S9xSetPCBase + ADD1CYCLE +.endm +.macro Op60 + PullWLow rpc + ADD rscratch, rpc, #1 + BIC rscratch, rscratch,#0x10000 + ORR rscratch, rscratch, regPBank, LSL #16 + S9xSetPCBase + ADD3CYCLE +.endm + +/**********************************************************************************************/ +/* MVN/MVP *********************************************************************************** */ +.macro Op54X1M1 + //Save RegStatus = regDBank >> 24 + MOV rscratch, regDBank, LSR #16 + LDRB regDBank , [rpc], #1 + LDRB rscratch2 , [rpc], #1 + //Restore RegStatus = regDBank >> 24 + ORR regDBank, regDBank, rscratch, LSL #16 + MOV rscratch , regX, LSR #24 + ORR rscratch , rscratch, rscratch2, LSL #16 + S9xGetByteLow + MOV rscratch2, rscratch + MOV rscratch , regY, LSR #24 + ORR rscratch , rscratch, regDBank, LSL #16 + S9xSetByteLow rscratch2 + //load 16bits A + LDRB rscratch,[regCPUvar,#RAH_ofs] + MOV regA,regA,LSR #8 + ORR regA,regA,rscratch, LSL #24 + ADD regX, regX, #0x01000000 + SUB regA, regA, #0x00010000 + ADD regY, regY, #0x01000000 + CMP regA, #0xFFFF0000 + SUBNE rpc, rpc, #3 + //update AH + MOV rscratch, regA, LSR #24 + MOV regA,regA,LSL #8 + STRB rscratch,[regCPUvar,#RAH_ofs] + ADD2CYCLE2MEM +.endm +.macro Op54X1M0 + //Save RegStatus = regDBank >> 24 + MOV rscratch, regDBank, LSR #16 + LDRB regDBank , [rpc], #1 + LDRB rscratch2 , [rpc], #1 + //Restore RegStatus = regDBank >> 24 + ORR regDBank, regDBank, rscratch, LSL #16 + MOV rscratch , regX, LSR #24 + ORR rscratch , rscratch, rscratch2, LSL #16 + S9xGetByteLow + MOV rscratch2, rscratch + MOV rscratch , regY, LSR #24 + ORR rscratch , rscratch, regDBank, LSL #16 + S9xSetByteLow rscratch2 + ADD regX, regX, #0x01000000 + SUB regA, regA, #0x00010000 + ADD regY, regY, #0x01000000 + CMP regA, #0xFFFF0000 + SUBNE rpc, rpc, #3 + ADD2CYCLE2MEM +.endm +.macro Op54X0M1 + //Save RegStatus = regDBank >> 24 + MOV rscratch, regDBank, LSR #16 + LDRB regDBank , [rpc], #1 + LDRB rscratch2 , [rpc], #1 + //Restore RegStatus = regDBank >> 24 + ORR regDBank, regDBank, rscratch, LSL #16 + MOV rscratch , regX, LSR #16 + ORR rscratch , rscratch, rscratch2, LSL #16 + S9xGetByteLow + MOV rscratch2, rscratch + MOV rscratch , regY, LSR #16 + ORR rscratch , rscratch, regDBank, LSL #16 + S9xSetByteLow rscratch2 + //load 16bits A + LDRB rscratch,[regCPUvar,#RAH_ofs] + MOV regA,regA,LSR #8 + ORR regA,regA,rscratch, LSL #24 + ADD regX, regX, #0x00010000 + SUB regA, regA, #0x00010000 + ADD regY, regY, #0x00010000 + CMP regA, #0xFFFF0000 + SUBNE rpc, rpc, #3 + //update AH + MOV rscratch, regA, LSR #24 + MOV regA,regA,LSL #8 + STRB rscratch,[regCPUvar,#RAH_ofs] + ADD2CYCLE2MEM +.endm +.macro Op54X0M0 + //Save RegStatus = regDBank >> 24 + MOV rscratch, regDBank, LSR #16 + LDRB regDBank , [rpc], #1 + LDRB rscratch2 , [rpc], #1 + //Restore RegStatus = regDBank >> 24 + ORR regDBank, regDBank, rscratch, LSL #16 + MOV rscratch , regX, LSR #16 + ORR rscratch , rscratch, rscratch2, LSL #16 + S9xGetByteLow + MOV rscratch2, rscratch + MOV rscratch , regY, LSR #16 + ORR rscratch , rscratch, regDBank, LSL #16 + S9xSetByteLow rscratch2 + ADD regX, regX, #0x00010000 + SUB regA, regA, #0x00010000 + ADD regY, regY, #0x00010000 + CMP regA, #0xFFFF0000 + SUBNE rpc, rpc, #3 + ADD2CYCLE2MEM +.endm + +.macro Op44X1M1 + //Save RegStatus = regDBank >> 24 + MOV rscratch, regDBank, LSR #16 + LDRB regDBank , [rpc], #1 + LDRB rscratch2 , [rpc], #1 + //Restore RegStatus = regDBank >> 24 + ORR regDBank, regDBank, rscratch, LSL #16 + MOV rscratch , regX, LSR #24 + ORR rscratch , rscratch, rscratch2, LSL #16 + S9xGetByteLow + MOV rscratch2, rscratch + MOV rscratch , regY, LSR #24 + ORR rscratch , rscratch, regDBank, LSL #16 + S9xSetByteLow rscratch2 + //load 16bits A + LDRB rscratch,[regCPUvar,#RAH_ofs] + MOV regA,regA,LSR #8 + ORR regA,regA,rscratch, LSL #24 + SUB regX, regX, #0x01000000 + SUB regA, regA, #0x00010000 + SUB regY, regY, #0x01000000 + CMP regA, #0xFFFF0000 + SUBNE rpc, rpc, #3 + //update AH + MOV rscratch, regA, LSR #24 + MOV regA,regA,LSL #8 + STRB rscratch,[regCPUvar,#RAH_ofs] + ADD2CYCLE2MEM +.endm +.macro Op44X1M0 + //Save RegStatus = regDBank >> 24 + MOV rscratch, regDBank, LSR #16 + LDRB regDBank , [rpc], #1 + LDRB rscratch2 , [rpc], #1 + //Restore RegStatus = regDBank >> 24 + ORR regDBank, regDBank, rscratch, LSL #16 + MOV rscratch , regX, LSR #24 + ORR rscratch , rscratch, rscratch2, LSL #16 + S9xGetByteLow + MOV rscratch2, rscratch + MOV rscratch , regY, LSR #24 + ORR rscratch , rscratch, regDBank, LSL #16 + S9xSetByteLow rscratch2 + SUB regX, regX, #0x01000000 + SUB regA, regA, #0x00010000 + SUB regY, regY, #0x01000000 + CMP regA, #0xFFFF0000 + SUBNE rpc, rpc, #3 + ADD2CYCLE2MEM +.endm +.macro Op44X0M1 + //Save RegStatus = regDBank >> 24 + MOV rscratch, regDBank, LSR #16 + LDRB regDBank , [rpc], #1 + LDRB rscratch2 , [rpc], #1 + //Restore RegStatus = regDBank >> 24 + ORR regDBank, regDBank, rscratch, LSL #16 + MOV rscratch , regX, LSR #16 + ORR rscratch , rscratch, rscratch2, LSL #16 + S9xGetByteLow + MOV rscratch2, rscratch + MOV rscratch , regY, LSR #16 + ORR rscratch , rscratch, regDBank, LSL #16 + S9xSetByteLow rscratch2 + //load 16bits A + LDRB rscratch,[regCPUvar,#RAH_ofs] + MOV regA,regA,LSR #8 + ORR regA,regA,rscratch, LSL #24 + SUB regX, regX, #0x00010000 + SUB regA, regA, #0x00010000 + SUB regY, regY, #0x00010000 + CMP regA, #0xFFFF0000 + SUBNE rpc, rpc, #3 + //update AH + MOV rscratch, regA, LSR #24 + MOV regA,regA,LSL #8 + STRB rscratch,[regCPUvar,#RAH_ofs] + ADD2CYCLE2MEM +.endm +.macro Op44X0M0 + //Save RegStatus = regDBank >> 24 + MOV rscratch, regDBank, LSR #16 + LDRB regDBank , [rpc], #1 + LDRB rscratch2 , [rpc], #1 + //Restore RegStatus = regDBank >> 24 + ORR regDBank, regDBank, rscratch, LSL #16 + MOV rscratch , regX, LSR #16 + ORR rscratch , rscratch, rscratch2, LSL #16 + S9xGetByteLow + MOV rscratch2, rscratch + MOV rscratch , regY, LSR #16 + ORR rscratch , rscratch, regDBank, LSL #16 + S9xSetByteLow rscratch2 + SUB regX, regX, #0x00010000 + SUB regA, regA, #0x00010000 + SUB regY, regY, #0x00010000 + CMP regA, #0xFFFF0000 + SUBNE rpc, rpc, #3 + ADD2CYCLE2MEM +.endm + +/**********************************************************************************************/ +/* REP/SEP *********************************************************************************** */ +.macro OpC2 + // status&=~(*rpc++); + // so possible changes are : + // INDEX = 1 -> 0 : X,Y 8bits -> 16bits + // MEM = 1 -> 0 : A 8bits -> 16bits + //SAVE OLD status for MASK_INDEX & MASK_MEM comparison + MOV rscratch3, rstatus + LDRB rscratch, [rpc], #1 + MVN rscratch, rscratch + AND rstatus,rstatus,rscratch, ROR #(32-STATUS_SHIFTER) + TST rstatus,#MASK_EMUL + BEQ 1111f + //emulation mode on : no changes since it was on before opcode + //just be sure to reset MEM & INDEX accordingly + ORR rstatus,rstatus,#(MASK_MEM|MASK_INDEX) + B 1112f +1111: + //NOT in Emulation mode, check INDEX & MEMORY bits + //Now check INDEX + TST rscratch3,#MASK_INDEX + BEQ 1113f + // X & Y were 8bit before + TST rstatus,#MASK_INDEX + BNE 1113f + // X & Y are now 16bits + MOV regX,regX,LSR #8 + MOV regY,regY,LSR #8 +1113: //X & Y still in 16bits + //Now check MEMORY + TST rscratch3,#MASK_MEM + BEQ 1112f + // A was 8bit before + TST rstatus,#MASK_MEM + BNE 1112f + // A is now 16bits + MOV regA,regA,LSR #8 + //restore AH + LDREQB rscratch,[regCPUvar,#RAH_ofs] + ORREQ regA,regA,rscratch,LSL #24 +1112: + S9xFixCycles + ADD1CYCLE1MEM +.endm +.macro OpE2 + // status|=*rpc++; + // so possible changes are : + // INDEX = 0 -> 1 : X,Y 16bits -> 8bits + // MEM = 0 -> 1 : A 16bits -> 8bits + //SAVE OLD status for MASK_INDEX & MASK_MEM comparison + MOV rscratch3, rstatus + LDRB rscratch, [rpc], #1 + ORR rstatus,rstatus,rscratch, LSL #STATUS_SHIFTER + TST rstatus,#MASK_EMUL + BEQ 10111f + //emulation mode on : no changes sinc eit was on before opcode + //just be sure to have mem & index set accordingly + ORR rstatus,rstatus,#(MASK_MEM|MASK_INDEX) + B 10112f +10111: + //NOT in Emulation mode, check INDEX & MEMORY bits + //Now check INDEX + TST rscratch3,#MASK_INDEX + BNE 10113f + // X & Y were 16bit before + TST rstatus,#MASK_INDEX + BEQ 10113f + // X & Y are now 8bits + MOV regX,regX,LSL #8 + MOV regY,regY,LSL #8 +10113: //X & Y still in 16bits + //Now check MEMORY + TST rscratch3,#MASK_MEM + BNE 10112f + // A was 16bit before + TST rstatus,#MASK_MEM + BEQ 10112f + // A is now 8bits + // save AH + MOV rscratch,regA,LSR #24 + MOV regA,regA,LSL #8 + STRB rscratch,[regCPUvar,#RAH_ofs] +10112: + S9xFixCycles + ADD1CYCLE1MEM +.endm + +/**********************************************************************************************/ +/* XBA *************************************************************************************** */ +.macro OpEBM1 + //A is 8bits + ADD rscratch,regCPUvar,#RAH_ofs + MOV regA,regA, LSR #24 + SWPB regA,regA,[rscratch] + MOVS regA,regA, LSL #24 + UPDATE_ZN + ADD2CYCLE +.endm +.macro OpEBM0 + //A is 16bits + MOV rscratch, regA, ROR #24 // ll0000hh + ORR rscratch, rscratch, regA, LSR #8// ll0000hh + 00hhll00 -> llhhllhh + MOV regA, rscratch, LSL #16// llhhllhh -> llhh0000 + MOVS rscratch,rscratch,LSL #24 //to set Z & N flags with AL + UPDATE_ZN + ADD2CYCLE +.endm + + +/**********************************************************************************************/ +/* RTI *************************************************************************************** */ +.macro Op40X1M1 + //INDEX set, MEMORY set + BIC rstatus,rstatus,#0xFF000000 + PullBr + ORR rstatus,rscratch,rstatus + PullWlow rpc + TST rstatus, #MASK_EMUL + ORRNE rstatus, rstatus, #(MASK_MEM|MASK_INDEX) + BNE 2401f + PullBrLow + BIC regPBank,regPBank,#0xFF + ORR regPBank,regPBank,rscratch +2401: + ADD rscratch, rpc, regPBank, LSL #16 + S9xSetPCBase + TST rstatus, #MASK_INDEX + //INDEX cleared & was set : 8->16 + MOVEQ regX,regX,LSR #8 + MOVEQ regY,regY,LSR #8 + TST rstatus, #MASK_MEM + //MEMORY cleared & was set : 8->16 + LDREQB rscratch,[regCPUvar,#RAH_ofs] + MOVEQ regA,regA,LSR #8 + ORREQ regA,regA,rscratch, LSL #24 + ADD2CYCLE + S9xFixCycles +.endm +.macro Op40X0M1 + //INDEX cleared, MEMORY set + BIC rstatus,rstatus,#0xFF000000 + PullBr + ORR rstatus,rscratch,rstatus + PullWlow rpc + TST rstatus, #MASK_EMUL + ORRNE rstatus, rstatus, #(MASK_MEM|MASK_INDEX) + BNE 2401f + PullBrLow + BIC regPBank,regPBank,#0xFF + ORR regPBank,regPBank,rscratch +2401: + ADD rscratch, rpc, regPBank, LSL #16 + S9xSetPCBase + TST rstatus, #MASK_INDEX + //INDEX set & was cleared : 16->8 + MOVNE regX,regX,LSL #8 + MOVNE regY,regY,LSL #8 + TST rstatus, #MASK_MEM + //MEMORY cleared & was set : 8->16 + LDREQB rscratch,[regCPUvar,#RAH_ofs] + MOVEQ regA,regA,LSR #8 + ORREQ regA,regA,rscratch, LSL #24 + ADD2CYCLE + S9xFixCycles +.endm +.macro Op40X1M0 + //INDEX set, MEMORY cleared + BIC rstatus,rstatus,#0xFF000000 + PullBr + ORR rstatus,rscratch,rstatus + PullWlow rpc + TST rstatus, #MASK_EMUL + ORRNE rstatus, rstatus, #(MASK_MEM|MASK_INDEX) + BNE 2401f + PullBrLow + BIC regPBank,regPBank,#0xFF + ORR regPBank,regPBank,rscratch +2401: + ADD rscratch, rpc, regPBank, LSL #16 + S9xSetPCBase + TST rstatus, #MASK_INDEX + //INDEX cleared & was set : 8->16 + MOVEQ regX,regX,LSR #8 + MOVEQ regY,regY,LSR #8 + TST rstatus, #MASK_MEM + //MEMORY set & was cleared : 16->8 + MOVNE rscratch,regA,LSR #24 + MOVNE regA,regA,LSL #8 + STRNEB rscratch,[regCPUvar,#RAH_ofs] + ADD2CYCLE + S9xFixCycles +.endm +.macro Op40X0M0 + //INDEX cleared, MEMORY cleared + BIC rstatus,rstatus,#0xFF000000 + PullBr + ORR rstatus,rscratch,rstatus + PullWlow rpc + TST rstatus, #MASK_EMUL + ORRNE rstatus, rstatus, #(MASK_MEM|MASK_INDEX) + BNE 2401f + PullBrLow + BIC regPBank,regPBank,#0xFF + ORR regPBank,regPBank,rscratch +2401: + ADD rscratch, rpc, regPBank, LSL #16 + S9xSetPCBase + TST rstatus, #MASK_INDEX + //INDEX set & was cleared : 16->8 + MOVNE regX,regX,LSL #8 + MOVNE regY,regY,LSL #8 + TST rstatus, #MASK_MEM + //MEMORY set & was cleared : 16->8 + //MEMORY set & was cleared : 16->8 + MOVNE rscratch,regA,LSR #24 + MOVNE regA,regA,LSL #8 + STRNEB rscratch,[regCPUvar,#RAH_ofs] + ADD2CYCLE + S9xFixCycles +.endm + + +/**********************************************************************************************/ +/* STP/WAI/DB ******************************************************************************** */ +// WAI +.macro OpCB /*WAI*/ + LDRB rscratch,[regCPUvar,#IRQActive_ofs] + MOVS rscratch,rscratch + //(CPU.IRQActive) + ADD2CYCLENE + BNE 1234f +/* + CPU.WaitingForInterrupt = TRUE; + CPU.PC--;*/ + MOV rscratch,#1 + SUB rpc,rpc,#1 +/* + CPU.Cycles = CPU.NextEvent; +*/ + STRB rscratch,[regCPUvar,#WaitingForInterrupt_ofs] + LDR regCycles,[regCPUvar,#NextEvent_ofs] +/* + if (IAPU.APUExecuting) + { + ICPU.CPUExecuting = FALSE; + do + { + APU_EXECUTE1 (); + } while (APU.Cycles < CPU.NextEvent); + ICPU.CPUExecuting = TRUE; + } +*/ + LDRB rscratch,[regCPUvar,#APUExecuting_ofs] + MOVS rscratch,rscratch + BEQ 1234f + asmAPU_EXECUTE2 + +1234: +.endm +.macro OpDB /*STP*/ + SUB rpc,rpc,#1 + //CPU.Flags |= DEBUG_MODE_FLAG; +.endm +.macro Op42 /*Reserved Snes9X*/ +.endm + +/**********************************************************************************************/ +/* AND ******************************************************************************** */ +.macro Op29M1 + LDRB rscratch , [rpc], #1 + ANDS regA , regA, rscratch, LSL #24 + UPDATE_ZN + ADD1MEM +.endm +.macro Op29M0 + LDRB rscratch2 , [rpc,#1] + LDRB rscratch , [rpc], #2 + ORR rscratch, rscratch, rscratch2, LSL #8 + ANDS regA , regA, rscratch, LSL #16 + UPDATE_ZN + ADD2MEM +.endm + + + + + + + + + + + + + + + +/**********************************************************************************************/ +/* EOR ******************************************************************************** */ +.macro Op49M0 + LDRB rscratch2 , [rpc, #1] + LDRB rscratch , [rpc], #2 + ORR rscratch, rscratch, rscratch2,LSL #8 + EORS regA, regA, rscratch,LSL #16 + UPDATE_ZN + ADD2MEM +.endm + + +.macro Op49M1 + LDRB rscratch , [rpc], #1 + EORS regA, regA, rscratch,LSL #24 + UPDATE_ZN + ADD1MEM +.endm + + +/**********************************************************************************************/ +/* STA *************************************************************************************** */ +.macro Op81M1 + STA8 + //TST rstatus, #MASK_INDEX + //ADD1CYCLENE +.endm +.macro Op81M0 + STA16 + //TST rstatus, #MASK_INDEX + //ADD1CYCLENE +.endm + + +/**********************************************************************************************/ +/* BIT *************************************************************************************** */ +.macro Op89M1 + LDRB rscratch , [rpc], #1 + TST regA, rscratch, LSL #24 + UPDATE_Z + ADD1MEM +.endm +.macro Op89M0 + LDRB rscratch2 , [rpc, #1] + LDRB rscratch , [rpc], #2 + ORR rscratch, rscratch, rscratch2, LSL #8 + TST regA, rscratch, LSL #16 + UPDATE_Z + ADD2MEM +.endm + + + + + + +/**********************************************************************************************/ +/* LDY *************************************************************************************** */ +.macro OpA0X1 + LDRB rscratch , [rpc], #1 + MOVS regY, rscratch, LSL #24 + UPDATE_ZN + ADD1MEM +.endm +.macro OpA0X0 + LDRB rscratch2 , [rpc, #1] + LDRB rscratch , [rpc], #2 + ORR rscratch, rscratch, rscratch2, LSL #8 + MOVS regY, rscratch, LSL #16 + UPDATE_ZN + ADD2MEM +.endm + +/**********************************************************************************************/ +/* LDX *************************************************************************************** */ +.macro OpA2X1 + LDRB rscratch , [rpc], #1 + MOVS regX, rscratch, LSL #24 + UPDATE_ZN + ADD1MEM +.endm +.macro OpA2X0 + LDRB rscratch2 , [rpc, #1] + LDRB rscratch , [rpc], #2 + ORR rscratch, rscratch, rscratch2, LSL #8 + MOVS regX, rscratch, LSL #16 + UPDATE_ZN + ADD2MEM +.endm + +/**********************************************************************************************/ +/* LDA *************************************************************************************** */ +.macro OpA9M1 + LDRB rscratch , [rpc], #1 + MOVS regA, rscratch, LSL #24 + UPDATE_ZN + ADD1MEM +.endm +.macro OpA9M0 + LDRB rscratch2 , [rpc, #1] + LDRB rscratch , [rpc], #2 + ORR rscratch, rscratch, rscratch2, LSL #8 + MOVS regA, rscratch, LSL #16 + UPDATE_ZN + ADD2MEM +.endm + +/**********************************************************************************************/ +/* CMY *************************************************************************************** */ +.macro OpC0X1 + LDRB rscratch , [rpc], #1 + SUBS rscratch2 , regY , rscratch, LSL #24 + BICCC rstatus, rstatus, #MASK_CARRY + ORRCS rstatus, rstatus, #MASK_CARRY + UPDATE_ZN + ADD1MEM +.endm +.macro OpC0X0 + LDRB rscratch2 , [rpc, #1] + LDRB rscratch , [rpc], #2 + ORR rscratch, rscratch, rscratch2, LSL #8 + SUBS rscratch2 , regY, rscratch, LSL #16 + BICCC rstatus, rstatus, #MASK_CARRY + ORRCS rstatus, rstatus, #MASK_CARRY + UPDATE_ZN + ADD2MEM +.endm + + + + + +/**********************************************************************************************/ +/* CMP *************************************************************************************** */ +.macro OpC9M1 + LDRB rscratch , [rpc], #1 + SUBS rscratch2 , regA , rscratch, LSL #24 + BICCC rstatus, rstatus, #MASK_CARRY + ORRCS rstatus, rstatus, #MASK_CARRY + UPDATE_ZN + ADD1MEM +.endm +.macro OpC9M0 + LDRB rscratch2 , [rpc,#1] + LDRB rscratch , [rpc], #2 + ORR rscratch, rscratch, rscratch2, LSL #8 + SUBS rscratch2 , regA, rscratch, LSL #16 + BICCC rstatus, rstatus, #MASK_CARRY + ORRCS rstatus, rstatus, #MASK_CARRY + UPDATE_ZN + ADD2MEM +.endm + +/**********************************************************************************************/ +/* CMX *************************************************************************************** */ +.macro OpE0X1 + LDRB rscratch , [rpc], #1 + SUBS rscratch2 , regX , rscratch, LSL #24 + BICCC rstatus, rstatus, #MASK_CARRY + ORRCS rstatus, rstatus, #MASK_CARRY + UPDATE_ZN + ADD1MEM +.endm +.macro OpE0X0 + LDRB rscratch2 , [rpc,#1] + LDRB rscratch , [rpc], #2 + ORR rscratch, rscratch, rscratch2, LSL #8 + SUBS rscratch2 , regX, rscratch, LSL #16 + BICCC rstatus, rstatus, #MASK_CARRY + ORRCS rstatus, rstatus, #MASK_CARRY + UPDATE_ZN + ADD2MEM +.endm + +/* + + +CLI_OPE_REC_Nos_Layer0 + nos.nos_ope_treasury_date = convert(DATETIME, @treasuryDate, 103) + nos.nos_ope_accounting_date = convert(DATETIME, @accountingDate, 103) + +CLI_OPE_Nos_Ope_Layer0 + n.nos_ope_treasury_date = convert(DATETIME, @LARD, 103) + n.nos_ope_accounting_date = convert(DATETIME, @LARD, 103) + +CLI_OPE_Nos_Layer0 + nos.nos_ope_treasury_date = convert(DATETIME, @LARD, 103) + nos.nos_ope_accounting_date = convert(DATETIME, @LARD, 103) + +Ecrans: +------ + + +[GNV] : utilisation de la lard (laccdate) pour afficher les openings. + +nécessité d'avoir des valeurs dans l'opening pour date tréso=date compta=laccdate + +[Accounting rec] : si laccdate pas bonne (pas = BD-1) -> message warning et pas de donnée +sinon : + +données nécessaires : opening date tréso=date compta=laccdate=BD-1 + +données nécessaires : opening date tréso=date compta=laccdate-1 + +données nécessaires : opening date tréso=laccdate-1 et date compta=laccdate + */ + + +/* + + + + + +*/ diff --git a/src/snes4iphone_src/os9x_asm_cpu.cpp b/src/snes4iphone_src/os9x_asm_cpu.cpp new file mode 100755 index 0000000..b8a9463 --- /dev/null +++ b/src/snes4iphone_src/os9x_asm_cpu.cpp @@ -0,0 +1,243 @@ +#include "snes9x.h" +#include "apu.h" +#include "ppu.h" +#include "cpuexec.h" +//#include "cpuops.h" + +#include "os9x_asm_cpu.h" + +//#define __debug_c_irq__ +//#define __debug_c_nmi__ +//#define __debug_c_hblank__ +//#define __debug_c_io__ + +START_EXTERN_C + +unsigned long test_print(unsigned long r0) +{ + static int county = 0; + fprintf(stderr, "county: %d 0x%x %d %d %d %d %d \n", county++, r0, (unsigned long)asmMainLoop, CPU.jump1, CPU.jump2, CPU.jump3, CPU.jump4); + return r0; +} + +void asm_S9xSetPCBase(uint32 Address) +{ +#ifdef __debug_c_setpc__ + printf("spcb\n"); +#endif + S9xSetPCBase(Address); +} + + +#if 0 +#define PushW(w) \ + S9xSetWord (w, Registers.S.W - 1);\ + Registers.S.W -= 2; +#define PushB(b)\ + S9xSetByte (b, Registers.S.W--); + + +void asm_S9xMainLoop(void) +{ + //S9xPackStatus(); + //printf("asmMainLoop Enter(0x%08x).\n", CPU.Flags); + asmMainLoop(&CPU); + //printf("asmMainLoop Exit(0x%08x, %d).\n", CPU.PC - CPU.PCBase, CPU.Cycles); + //S9xUnpackStatus(); +} + +void asm_S9xDoHBlankProcessing(void) +{ +#ifdef __debug_c_hblank__ + printf("hblank\n"); +#endif +// S9xUnpackStatus(); // not needed + S9xDoHBlankProcessing(); +// S9xPackStatus(); +} + + +uint8 asm_S9xGetByte(uint32 Address) +{ +#ifdef __debug_c_io__ + printf("gb\n"); +#endif + return S9xGetByte(Address); +} + +uint16 asm_S9xGetWord(uint32 Address) +{ +#ifdef __debug_c_io__ + printf("gw\n"); +#endif + return S9xGetWord(Address); +} + + +void asm_S9xSetByte(uint32 Address,uint8 value) +{ +#ifdef __debug_c_io__ + printf("sb\n"); +#endif + S9xSetByte(value,Address); +} + +void asm_S9xSetWord(uint32 Address,uint16 value) +{ +#ifdef __debug_c_io__ + printf("sw\n"); +#endif + S9xSetWord(value,Address); +} + + +void asm_S9xOpcode_NMI(void) +{ +#ifdef __debug_c_nmi__ + printf("nmi\n"); +#endif +// S9xUnpackStatus(); // not needed + + if (!CheckEmulation()) + { + PushB (Registers.PB); + PushW (CPU.PC - CPU.PCBase); +// S9xPackStatus (); + PushB (Registers.PL); + ClearDecimal (); + SetIRQ (); + + Registers.PB = 0; +// c = 0; // unused +#ifdef USE_SA1 + if (Settings.SA1 && (Memory.FillRAM [0x2209] & 0x20)) + S9xSetPCBase (Memory.FillRAM [0x220c] | + (Memory.FillRAM [0x220d] << 8)); + else +#endif + S9xSetPCBase (S9xGetWord (0xFFEA)); +#ifdef VAR_CYCLES + CPU.Cycles += TWO_CYCLES; +#else + CPU.Cycles += 8; +#endif + } + else + { + PushW (CPU.PC - CPU.PCBase); +// S9xPackStatus (); // not needed + PushB (Registers.PL); + ClearDecimal (); + SetIRQ (); + + Registers.PB = 0; +// ICPU.ShiftedPB = 0; // unused +#ifdef USE_SA1 + if (Settings.SA1 && (Memory.FillRAM [0x2209] & 0x20)) + S9xSetPCBase (Memory.FillRAM [0x220c] | + (Memory.FillRAM [0x220d] << 8)); + else +#endif + S9xSetPCBase (S9xGetWord (0xFFFA)); +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#else + CPU.Cycles += 6; +#endif + } + +// S9xPackStatus(); // not needed +} + +void asm_S9xOpcode_IRQ(void) +{ +#ifdef __debug_c_irq__ + printf("irq\n"); +#endif +// S9xUnpackStatus(); // not needed + + if (!CheckEmulation()) + { + PushB (Registers.PB); + PushW (CPU.PC - CPU.PCBase); +// S9xPackStatus (); // not needed + PushB (Registers.PL); + ClearDecimal (); + SetIRQ (); + + Registers.PB = 0; +// ICPU.ShiftedPB = 0; // unused + +#ifdef USE_SA1 + if (Settings.SA1 && (Memory.FillRAM [0x2209] & 0x40)) + S9xSetPCBase (Memory.FillRAM [0x220e] | + (Memory.FillRAM [0x220f] << 8)); + else +#endif + S9xSetPCBase (S9xGetWord (0xFFEE)); +#ifdef VAR_CYCLES + CPU.Cycles += TWO_CYCLES; +#else + CPU.Cycles += 8; +#endif + } + else + { + PushW (CPU.PC - CPU.PCBase); +// S9xPackStatus (); // not needed + PushB (Registers.PL); + ClearDecimal (); + SetIRQ (); + + Registers.PB = 0; +// ICPU.ShiftedPB = 0; // unused + +#ifdef USE_SA1 + if (Settings.SA1 && (Memory.FillRAM [0x2209] & 0x40)) + S9xSetPCBase (Memory.FillRAM [0x220e] | + (Memory.FillRAM [0x220f] << 8)); + else +#endif + S9xSetPCBase (S9xGetWord (0xFFFE)); +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#else + CPU.Cycles += 6; +#endif + } + +// S9xPackStatus(); // not needed +} +#endif + + +#ifndef ASM_SPC700 + +void asm_APU_EXECUTE(void) +{ +#ifdef __debug_c_apuex__ + printf("apuexec\n"); +#endif + if(CPU.APU_APUExecuting != 1) return; + + while (CPU.APU_Cycles <= CPU.Cycles) + { + APU_EXECUTE1(); + } +} + +void asm_APU_EXECUTE2(void) +{ + if(CPU.APU_APUExecuting != 1) return; + + ICPU.CPUExecuting = FALSE; + do + { + APU_EXECUTE1(); + } while (CPU.APU_Cycles < CPU.NextEvent); + ICPU.CPUExecuting = TRUE; +} + +#endif + +END_EXTERN_C diff --git a/src/snes4iphone_src/os9x_asm_cpu.h b/src/snes4iphone_src/os9x_asm_cpu.h new file mode 100755 index 0000000..22672c5 --- /dev/null +++ b/src/snes4iphone_src/os9x_asm_cpu.h @@ -0,0 +1,10 @@ +#ifndef __os9x_asm_cpu__ +#define __os9x_asm_cpu__ + +extern "C" void test_opcode(SCPUState *cpuptr); + +extern "C" void asmMainLoop(SCPUState *cpuptr); + +extern "C" void asm_S9xMainLoop(void); + +#endif diff --git a/src/snes4iphone_src/osnes9xgp_asmfunc.S b/src/snes4iphone_src/osnes9xgp_asmfunc.S new file mode 100755 index 0000000..7cdc3ec --- /dev/null +++ b/src/snes4iphone_src/osnes9xgp_asmfunc.S @@ -0,0 +1,101 @@ + .global asmClearScreenFast8 + .global asmClearScreenFast16 + +asmClearScreenFast16: +;@R0 = scr +;@R1 = starty +;@R2 = endy +;@R3 = col + stmfd R13!,{R4-R11} + + sub R12,R2,R1 + add R12,R12,#1 + ;@R12 = endy-starty+1 + + mov r2,#320 + mul r1,r2,r1 + ;@R1 = 320*starty + + add R0,R0,R1,lsl #1 + ;@R0 = screen + ((320*starty)<<1) + + mov R2,R3 + mov R4,R3 + mov R5,R3 + mov R6,R3 + mov R7,R3 + mov R8,R3 + mov R9,R3 +2: + stmia R0!,{R2,R3,R4,R5,R6,R7,R8,R9} + stmia R0!,{R2,R3,R4,R5,R6,R7,R8,R9} + stmia R0!,{R2,R3,R4,R5,R6,R7,R8,R9} + stmia R0!,{R2,R3,R4,R5,R6,R7,R8,R9} + stmia R0!,{R2,R3,R4,R5,R6,R7,R8,R9} + stmia R0!,{R2,R3,R4,R5,R6,R7,R8,R9} + stmia R0!,{R2,R3,R4,R5,R6,R7,R8,R9} + stmia R0!,{R2,R3,R4,R5,R6,R7,R8,R9} + + stmia R0!,{R2,R3,R4,R5,R6,R7,R8,R9} + stmia R0!,{R2,R3,R4,R5,R6,R7,R8,R9} + stmia R0!,{R2,R3,R4,R5,R6,R7,R8,R9} + stmia R0!,{R2,R3,R4,R5,R6,R7,R8,R9} + stmia R0!,{R2,R3,R4,R5,R6,R7,R8,R9} + stmia R0!,{R2,R3,R4,R5,R6,R7,R8,R9} + stmia R0!,{R2,R3,R4,R5,R6,R7,R8,R9} + stmia R0!,{R2,R3,R4,R5,R6,R7,R8,R9} + + add r0,r0,#32*4 + + subs R12,R12,#1 + bne 2b + + ldmfd R13!,{R4-R11} + mov PC,LR + + +asmClearScreenFast8: +;R0 = scr +;R1 = starty +;R2 = endy +;R3 = col + stmfd R13!,{R4-R11} + + sub R12,R2,R1 + add R12,R12,#1 + ;@R12 = endy-starty+1 + + mov r2,#320 + mul r1,r2,r1 + ;@R1 = 320*starty + + add R0,R0,R1 + ;@R0 = screen + ((320*starty)) + + mov R2,R3 + mov R4,R3 + mov R5,R3 + mov R6,R3 + mov R7,R3 + mov R8,R3 + mov R9,R3 + +2: + stmia R0!,{R2,R3,R4,R5,R6,R7,R8,R9} + stmia R0!,{R2,R3,R4,R5,R6,R7,R8,R9} + stmia R0!,{R2,R3,R4,R5,R6,R7,R8,R9} + stmia R0!,{R2,R3,R4,R5,R6,R7,R8,R9} + stmia R0!,{R2,R3,R4,R5,R6,R7,R8,R9} + stmia R0!,{R2,R3,R4,R5,R6,R7,R8,R9} + stmia R0!,{R2,R3,R4,R5,R6,R7,R8,R9} + stmia R0!,{R2,R3,R4,R5,R6,R7,R8,R9} + stmia R0!,{R2,R3,R4,R5,R6,R7,R8,R9} + stmia R0!,{R2,R3,R4,R5,R6,R7,R8,R9} + + subs R12,R12,#1 + bne 2b + + ldmfd R13!,{R4-R11} + mov PC,LR + + \ No newline at end of file diff --git a/src/snes4iphone_src/pixform.h b/src/snes4iphone_src/pixform.h new file mode 100755 index 0000000..c0a49c5 --- /dev/null +++ b/src/snes4iphone_src/pixform.h @@ -0,0 +1,272 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#ifndef _PIXFORM_H_ +#define _PIXFORM_H_ + +#ifdef GFX_MULTI_FORMAT + +enum { RGB565, RGB555, BGR565, BGR555, GBR565, GBR555, RGB5551 }; + +#define BUILD_PIXEL(R,G,B) ((*GFX.BuildPixel) (R, G, B)) +#define BUILD_PIXEL2(R,G,B) ((*GFX.BuildPixel2) (R, G, B)) +#define DECOMPOSE_PIXEL(Pixel,R,G,B) ((*GFX.DecomposePixel) (Pixel, R,G,B)) + +extern uint32 RED_LOW_BIT_MASK; +extern uint32 GREEN_LOW_BIT_MASK; +extern uint32 BLUE_LOW_BIT_MASK; +extern uint32 RED_HI_BIT_MASK; +extern uint32 GREEN_HI_BIT_MASK; +extern uint32 BLUE_HI_BIT_MASK; +extern uint32 MAX_RED; +extern uint32 MAX_GREEN; +extern uint32 MAX_BLUE; +extern uint32 SPARE_RGB_BIT_MASK; +extern uint32 GREEN_HI_BIT; +extern uint32 RGB_LOW_BITS_MASK; +extern uint32 RGB_HI_BITS_MASK; +extern uint32 RGB_HI_BITS_MASKx2; +extern uint32 RGB_REMOVE_LOW_BITS_MASK; +extern uint32 FIRST_COLOR_MASK; +extern uint32 SECOND_COLOR_MASK; +extern uint32 THIRD_COLOR_MASK; +extern uint32 ALPHA_BITS_MASK; +extern uint32 FIRST_THIRD_COLOR_MASK; +extern uint32 TWO_LOW_BITS_MASK; +extern uint32 HIGH_BITS_SHIFTED_TWO_MASK; + +#endif + +// RGB565 format +#define BUILD_PIXEL_RGB565(R,G,B) (((int) (R) << 11) | ((int) (G) << 6) | (int) (B)) +#define BUILD_PIXEL2_RGB565(R,G,B) (((int) (R) << 11) | ((int) (G) << 5) | (int) (B)) +#define DECOMPOSE_PIXEL_RGB565(PIX,R,G,B) {(R) = (PIX) >> 11; (G) = ((PIX) >> 6) & 0x1f; (B) = (PIX) & 0x1f; } +#define SPARE_RGB_BIT_MASK_RGB565 (1 << 5) + +#define MAX_RED_RGB565 31 +#define MAX_GREEN_RGB565 63 +#define MAX_BLUE_RGB565 31 +#define RED_LOW_BIT_MASK_RGB565 0x0800 +#define GREEN_LOW_BIT_MASK_RGB565 0x0020 +#define BLUE_LOW_BIT_MASK_RGB565 0x0001 +#define RED_HI_BIT_MASK_RGB565 0x8000 +#define GREEN_HI_BIT_MASK_RGB565 0x0400 +#define BLUE_HI_BIT_MASK_RGB565 0x0010 +#define FIRST_COLOR_MASK_RGB565 0xF800 +#define SECOND_COLOR_MASK_RGB565 0x07E0 +#define THIRD_COLOR_MASK_RGB565 0x001F +#define ALPHA_BITS_MASK_RGB565 0x0000 + +// RGB555 format +#define BUILD_PIXEL_RGB555(R,G,B) (((int) (R) << 10) | ((int) (G) << 5) | (int) (B)) +#define BUILD_PIXEL2_RGB555(R,G,B) (((int) (R) << 10) | ((int) (G) << 5) | (int) (B)) +#define DECOMPOSE_PIXEL_RGB555(PIX,R,G,B) {(R) = (PIX) >> 10; (G) = ((PIX) >> 5) & 0x1f; (B) = (PIX) & 0x1f; } +#define SPARE_RGB_BIT_MASK_RGB555 (1 << 15) + +#define MAX_RED_RGB555 31 +#define MAX_GREEN_RGB555 31 +#define MAX_BLUE_RGB555 31 +#define RED_LOW_BIT_MASK_RGB555 0x0400 +#define GREEN_LOW_BIT_MASK_RGB555 0x0020 +#define BLUE_LOW_BIT_MASK_RGB555 0x0001 +#define RED_HI_BIT_MASK_RGB555 0x4000 +#define GREEN_HI_BIT_MASK_RGB555 0x0200 +#define BLUE_HI_BIT_MASK_RGB555 0x0010 +#define FIRST_COLOR_MASK_RGB555 0x7C00 +#define SECOND_COLOR_MASK_RGB555 0x03E0 +#define THIRD_COLOR_MASK_RGB555 0x001F +#define ALPHA_BITS_MASK_RGB555 0x0000 + +// BGR565 format +#define BUILD_PIXEL_BGR565(R,G,B) (((int) (B) << 11) | ((int) (G) << 6) | (int) (R)) +#define BUILD_PIXEL2_BGR565(R,G,B) (((int) (B) << 11) | ((int) (G) << 5) | (int) (R)) +#define DECOMPOSE_PIXEL_BGR565(PIX,R,G,B) {(B) = (PIX) >> 11; (G) = ((PIX) >> 6) & 0x1f; (R) = (PIX) & 0x1f; } +#define SPARE_RGB_BIT_MASK_BGR565 (1 << 5) + +#define MAX_RED_BGR565 31 +#define MAX_GREEN_BGR565 63 +#define MAX_BLUE_BGR565 31 +#define RED_LOW_BIT_MASK_BGR565 0x0001 +#define GREEN_LOW_BIT_MASK_BGR565 0x0040 +#define BLUE_LOW_BIT_MASK_BGR565 0x0800 +#define RED_HI_BIT_MASK_BGR565 0x0010 +#define GREEN_HI_BIT_MASK_BGR565 0x0400 +#define BLUE_HI_BIT_MASK_BGR565 0x8000 +#define FIRST_COLOR_MASK_BGR565 0xF800 +#define SECOND_COLOR_MASK_BGR565 0x07E0 +#define THIRD_COLOR_MASK_BGR565 0x001F +#define ALPHA_BITS_MASK_BGR565 0x0000 + +// BGR555 format +#define BUILD_PIXEL_BGR555(R,G,B) (((int) (B) << 10) | ((int) (G) << 5) | (int) (R)) +#define BUILD_PIXEL2_BGR555(R,G,B) (((int) (B) << 10) | ((int) (G) << 5) | (int) (R)) +#define DECOMPOSE_PIXEL_BGR555(PIX,R,G,B) {(B) = (PIX) >> 10; (G) = ((PIX) >> 5) & 0x1f; (R) = (PIX) & 0x1f; } +#define SPARE_RGB_BIT_MASK_BGR555 (1 << 15) + +#define MAX_RED_BGR555 31 +#define MAX_GREEN_BGR555 31 +#define MAX_BLUE_BGR555 31 +#define RED_LOW_BIT_MASK_BGR555 0x0001 +#define GREEN_LOW_BIT_MASK_BGR555 0x0020 +#define BLUE_LOW_BIT_MASK_BGR555 0x0400 +#define RED_HI_BIT_MASK_BGR555 0x0010 +#define GREEN_HI_BIT_MASK_BGR555 0x0200 +#define BLUE_HI_BIT_MASK_BGR555 0x4000 +#define FIRST_COLOR_MASK_BGR555 0x7C00 +#define SECOND_COLOR_MASK_BGR555 0x03E0 +#define THIRD_COLOR_MASK_BGR555 0x001F +#define ALPHA_BITS_MASK_BGR555 0x0000 + +// GBR565 format +#define BUILD_PIXEL_GBR565(R,G,B) (((int) (G) << 11) | ((int) (B) << 6) | (int) (R)) +#define BUILD_PIXEL2_GBR565(R,G,B) (((int) (G) << 11) | ((int) (B) << 5) | (int) (R)) +#define DECOMPOSE_PIXEL_GBR565(PIX,R,G,B) {(G) = (PIX) >> 11; (B) = ((PIX) >> 6) & 0x1f; (R) = (PIX) & 0x1f; } +#define SPARE_RGB_BIT_MASK_GBR565 (1 << 5) + +#define MAX_RED_GBR565 31 +#define MAX_BLUE_GBR565 63 +#define MAX_GREEN_GBR565 31 +#define RED_LOW_BIT_MASK_GBR565 0x0001 +#define BLUE_LOW_BIT_MASK_GBR565 0x0040 +#define GREEN_LOW_BIT_MASK_GBR565 0x0800 +#define RED_HI_BIT_MASK_GBR565 0x0010 +#define BLUE_HI_BIT_MASK_GBR565 0x0400 +#define GREEN_HI_BIT_MASK_GBR565 0x8000 +#define FIRST_COLOR_MASK_GBR565 0xF800 +#define SECOND_COLOR_MASK_GBR565 0x07E0 +#define THIRD_COLOR_MASK_GBR565 0x001F +#define ALPHA_BITS_MASK_GBR565 0x0000 + +// GBR555 format +#define BUILD_PIXEL_GBR555(R,G,B) (((int) (G) << 10) | ((int) (B) << 5) | (int) (R)) +#define BUILD_PIXEL2_GBR555(R,G,B) (((int) (G) << 10) | ((int) (B) << 5) | (int) (R)) +#define DECOMPOSE_PIXEL_GBR555(PIX,R,G,B) {(G) = (PIX) >> 10; (B) = ((PIX) >> 5) & 0x1f; (R) = (PIX) & 0x1f; } +#define SPARE_RGB_BIT_MASK_GBR555 (1 << 15) + +#define MAX_RED_GBR555 31 +#define MAX_BLUE_GBR555 31 +#define MAX_GREEN_GBR555 31 +#define RED_LOW_BIT_MASK_GBR555 0x0001 +#define BLUE_LOW_BIT_MASK_GBR555 0x0020 +#define GREEN_LOW_BIT_MASK_GBR555 0x0400 +#define RED_HI_BIT_MASK_GBR555 0x0010 +#define BLUE_HI_BIT_MASK_GBR555 0x0200 +#define GREEN_HI_BIT_MASK_GBR555 0x4000 +#define FIRST_COLOR_MASK_GBR555 0x7C00 +#define SECOND_COLOR_MASK_GBR555 0x03E0 +#define THIRD_COLOR_MASK_GBR555 0x001F +#define ALPHA_BITS_MASK_GBR555 0x0000 + +// RGB5551 format +#define BUILD_PIXEL_RGB5551(R,G,B) (((int) (R) << 11) | ((int) (G) << 6) | (int) ((B) << 1) | 1) +#define BUILD_PIXEL2_RGB5551(R,G,B) (((int) (R) << 11) | ((int) (G) << 6) | (int) ((B) << 1) | 1) +#define DECOMPOSE_PIXEL_RGB5551(PIX,R,G,B) {(R) = (PIX) >> 11; (G) = ((PIX) >> 6) & 0x1f; (B) = ((PIX) >> 1) & 0x1f; } +#define SPARE_RGB_BIT_MASK_RGB5551 (1) + +#define MAX_RED_RGB5551 31 +#define MAX_GREEN_RGB5551 31 +#define MAX_BLUE_RGB5551 31 +#define RED_LOW_BIT_MASK_RGB5551 0x0800 +#define GREEN_LOW_BIT_MASK_RGB5551 0x0040 +#define BLUE_LOW_BIT_MASK_RGB5551 0x0002 +#define RED_HI_BIT_MASK_RGB5551 0x8000 +#define GREEN_HI_BIT_MASK_RGB5551 0x0400 +#define BLUE_HI_BIT_MASK_RGB5551 0x0020 +#define FIRST_COLOR_MASK_RGB5551 0xf800 +#define SECOND_COLOR_MASK_RGB5551 0x07c0 +#define THIRD_COLOR_MASK_RGB5551 0x003e +#define ALPHA_BITS_MASK_RGB5551 0x0001 + +#ifndef GFX_MULTI_FORMAT +#define CONCAT(X,Y) X##Y + +// C pre-processor needs a two stage macro define to enable it to concat +// to macro names together to form the name of another macro. +#define BUILD_PIXEL_D(F,R,G,B) CONCAT(BUILD_PIXEL_,F) (R,G,B) +#define BUILD_PIXEL2_D(F,R,G,B) CONCAT(BUILD_PIXEL2_,F) (R,G,B) +#define DECOMPOSE_PIXEL_D(F,PIX,R,G,B) CONCAT(DECOMPOSE_PIXEL_,F) (PIX,R,G,B) + +#define BUILD_PIXEL(R,G,B) BUILD_PIXEL_D(PIXEL_FORMAT,R,G,B) +#define BUILD_PIXEL2(R,G,B) BUILD_PIXEL2_D(PIXEL_FORMAT,R,G,B) +#define DECOMPOSE_PIXEL(PIX,R,G,B) DECOMPOSE_PIXEL_D(PIXEL_FORMAT,PIX,R,G,B) + +#define MAX_RED_D(F) CONCAT(MAX_RED_,F) +#define MAX_BLUE_D(F) CONCAT(MAX_BLUE_,F) +#define MAX_GREEN_D(F) CONCAT(MAX_GREEN_,F) +#define RED_LOW_BIT_MASK_D(F) CONCAT(RED_LOW_BIT_MASK_,F) +#define BLUE_LOW_BIT_MASK_D(F) CONCAT(BLUE_LOW_BIT_MASK_,F) +#define GREEN_LOW_BIT_MASK_D(F) CONCAT(GREEN_LOW_BIT_MASK_,F) +#define RED_HI_BIT_MASK_D(F) CONCAT(RED_HI_BIT_MASK_,F) +#define BLUE_HI_BIT_MASK_D(F) CONCAT(BLUE_HI_BIT_MASK_,F) +#define GREEN_HI_BIT_MASK_D(F) CONCAT(GREEN_HI_BIT_MASK_,F) +#define FIRST_COLOR_MASK_D(F) CONCAT(FIRST_COLOR_MASK_,F) +#define SECOND_COLOR_MASK_D(F) CONCAT(SECOND_COLOR_MASK_,F) +#define THIRD_COLOR_MASK_D(F) CONCAT(THIRD_COLOR_MASK_,F) +#define ALPHA_BITS_MASK_D(F) CONCAT(ALPHA_BITS_MASK_,F) + +#define MAX_RED MAX_RED_D(PIXEL_FORMAT) +#define MAX_BLUE MAX_BLUE_D(PIXEL_FORMAT) +#define MAX_GREEN MAX_GREEN_D(PIXEL_FORMAT) +#define RED_LOW_BIT_MASK RED_LOW_BIT_MASK_D(PIXEL_FORMAT) +#define BLUE_LOW_BIT_MASK BLUE_LOW_BIT_MASK_D(PIXEL_FORMAT) +#define GREEN_LOW_BIT_MASK GREEN_LOW_BIT_MASK_D(PIXEL_FORMAT) +#define RED_HI_BIT_MASK RED_HI_BIT_MASK_D(PIXEL_FORMAT) +#define BLUE_HI_BIT_MASK BLUE_HI_BIT_MASK_D(PIXEL_FORMAT) +#define GREEN_HI_BIT_MASK GREEN_HI_BIT_MASK_D(PIXEL_FORMAT) +#define FIRST_COLOR_MASK FIRST_COLOR_MASK_D(PIXEL_FORMAT) +#define SECOND_COLOR_MASK SECOND_COLOR_MASK_D(PIXEL_FORMAT) +#define THIRD_COLOR_MASK THIRD_COLOR_MASK_D(PIXEL_FORMAT) +#define ALPHA_BITS_MASK ALPHA_BITS_MASK_D(PIXEL_FORMAT) + +#define GREEN_HI_BIT ((MAX_GREEN + 1) >> 1) +#define RGB_LOW_BITS_MASK (RED_LOW_BIT_MASK | GREEN_LOW_BIT_MASK | \ + BLUE_LOW_BIT_MASK) +#define RGB_HI_BITS_MASK (RED_HI_BIT_MASK | GREEN_HI_BIT_MASK | \ + BLUE_HI_BIT_MASK) +#define RGB_HI_BITS_MASKx2 ((RED_HI_BIT_MASK | GREEN_HI_BIT_MASK | \ + BLUE_HI_BIT_MASK) << 1) +#define RGB_REMOVE_LOW_BITS_MASK (~RGB_LOW_BITS_MASK) +#define FIRST_THIRD_COLOR_MASK (FIRST_COLOR_MASK | THIRD_COLOR_MASK) +#define TWO_LOW_BITS_MASK (RGB_LOW_BITS_MASK | (RGB_LOW_BITS_MASK << 1)) +#define HIGH_BITS_SHIFTED_TWO_MASK (( (FIRST_COLOR_MASK | SECOND_COLOR_MASK | THIRD_COLOR_MASK) & \ + ~TWO_LOW_BITS_MASK ) >> 2) +#endif + +#endif diff --git a/src/snes4iphone_src/pocketpc.cpp b/src/snes4iphone_src/pocketpc.cpp new file mode 100755 index 0000000..e1e5dd9 --- /dev/null +++ b/src/snes4iphone_src/pocketpc.cpp @@ -0,0 +1,1872 @@ +#include "port.h" +#include "snes9x.h" +#include "memmap.h" +#include "debug.h" +#include "cpuexec.h" +#include "ppu.h" +#include "snapshot.h" +#include "apu.h" +#include "display.h" +#include "gfx.h" +#include "soundux.h" + +#include "resource.h" + +#include +#include +#include +#include +#include +#include +#include +#ifdef _WIN32_WCE_EMULATION +//#include "gapi.h" +#else +#include "gx.h" +#endif + +#include "pocketpc.h" + +extern HWND g_hWnd; + +#ifdef ARM +extern "C" ScreenCopyPort38(void *pBuffer, void *pDisplay, int xPitch, int yPitch); +extern "C" ScreenCopyLand38(void *pBuffer, void *pDisplay, int xPitch, int yPitch); +extern "C" ScreenCopyLand38r(void *pBuffer, void *pDisplay, int xPitch, int yPitch); +#endif + +// Local functions: +__inline void Blit16pPortrait(); //Casio E-125, EM-500, Jornada 54x/56x +__inline void Blit16uPortrait(); +#ifdef ARM +__inline void Blit1638portrait(); // iPAQ 38xx +#endif +__inline void Blit16mLandscapeLeft(); //@migo and iPAQ 36xx/37xx +__inline void Blit16uLandscapeLeft(); +__inline void Blit16uLandscapeRight(); +#ifdef ARM +__inline void Blit1638landscape(); //iPAQ 38xx +__inline void Blit1638right(); //iPAQ 38xx +#endif + +__inline void Blit16uStretchedLeft(); +__inline void Blit16uStretchedRight(); +__inline void Blit4uportrait(); +__inline void Blit4ulandscape(); + +bool LoadKeypad(); + +//**************************************************************** +// Globals +//**************************************************************** +GXDisplayProperties g_gxdp; +bool g_bGXBuffered; +GXKeyList g_gxkl; +HWND g_hWndCB; +TCHAR g_szTitle[64]; +EmulationMode g_emMode = emStopped; +bool g_bLandscape = false; //Landscape mode? +bool g_bLandLeft = true; //Rotate landscape left? +bool g_bAutoSkip = false; +bool g_bCompat = false; //Compatibility mode flag +bool g_bSmoothStretch = false; +bool g_bH3800 = false; //Is this PDA an iPAQ 38xx? +uint32 g_iSoundQuality; +uint32 g_iCycles = 100; +char * g_sFreezeGameDir; +bool g_bUseGameFolders = false; +void (*S9xBlit) (); +LARGE_INTEGER g_liFreq; //processor performance counter frequency + +//Thread globals +//HANDLE g_hDrawThread; +//CRITICAL_SECTION g_cWaitForNextFrame; +HANDLE g_hS9xMainLoopThread; + +long WINAPI S9xMainLoopThread(); + +#define THREADCPUQUANTUM 50 + +bool g_bResumeAfterLoadState = false; +bool g_bResumeAfterSaveState = false; + +typedef struct BMIWrapper +{ + BITMAPINFOHEADER bmiHeader; + DWORD bmiColors[3]; +} BMIWrapper; + +extern "C" void S9xSyncSpeed() +{ + static LARGE_INTEGER lastframe, thisframe; + + if(g_bAutoSkip) + { //If the time to render the last frame is less than 13ms (77fps), + //then blit this frame to the screen (with the ~7ms blit time, + //this makes for a total frame period of 20ms, which is ~50fps) + QueryPerformanceCounter(&thisframe); + if( ((double)thisframe.QuadPart-(double)lastframe.QuadPart)/ + ((double)g_liFreq.QuadPart) < .013 + || IPPU.SkippedFrames >= g_iFrameSkip ) + { + IPPU.RenderThisFrame = TRUE; + IPPU.SkippedFrames = 0; + } + else + { + IPPU.RenderThisFrame = FALSE; + IPPU.SkippedFrames++; + } + lastframe = thisframe; + } + else + { + if (IPPU.SkippedFrames < g_iFrameSkip) + { + IPPU.SkippedFrames++; + IPPU.RenderThisFrame = FALSE; + } + else + { + IPPU.RenderThisFrame = TRUE; + IPPU.SkippedFrames = 0; + } + } +} + +#define MONO_RED_MASK (0x1f << 11) +#define MONO_GREEN_MASK (0x3f << 5) +#define MONO_BLUE_MASK (0x1f) + +#define RGB565_TO_MONO(a) ((a & MONO_RED_MASK) >> 14) + \ + ((a & MONO_GREEN_MASK) >> 8) + \ + ((a & MONO_BLUE_MASK) >> 3) + +#define WAV_BUFFERS 64 +#define WAV_MASK 0x3F +#define WAV_BUFFER_SIZE 0x0400 + +static int sample16; +static int snd_sent, snd_completed; +HANDLE hData; +char *lpData; +HGLOBAL hWaveHdr; +LPWAVEHDR lpWaveHdr; +HWAVEOUT hWaveOut; +DWORD g_dwSoundBufferSize; + +void CloseSoundDevice() +{ + if (hWaveOut) + { + waveOutReset(hWaveOut); + + if (lpWaveHdr) + { + for (int i = 0; i < WAV_BUFFERS; i++) + waveOutUnprepareHeader(hWaveOut, lpWaveHdr + i, sizeof(WAVEHDR)); + } + + waveOutClose(hWaveOut); + + if (hWaveHdr) + { + GlobalUnlock(hWaveHdr); + GlobalFree(hWaveHdr); + } + + if (hData) + { + GlobalUnlock(hData); + GlobalFree(hData); + } + + } + + hWaveOut = 0; + hData = 0; + hWaveHdr = 0; + lpWaveHdr = NULL; +} + +static int iRates[8] = +{ + 0, 8000, 11025, 16000, 22050, 32000, 44100, 48000 +}; + +/* +static int iRates[8] = +{ + 0, 11025, 22050, 44100, 0, 0, 0, 0 +}; +*/ + +bool8_32 S9xOpenSoundDevice(int _iMode, bool8_32 _bStereo, int _iBufferSize) +{ + WAVEFORMATEX format; + int i; + HRESULT hr; + + so.buffer_size = WAV_BUFFER_SIZE; + so.mute_sound = FALSE; + so.stereo = FALSE; + so.playback_rate = iRates[_iMode & 7]; + so.encoded = 0; + + snd_sent = 0; + snd_completed = 0; + + memset(&format, 0, sizeof(format)); + format.wFormatTag = WAVE_FORMAT_PCM; + format.nChannels = _bStereo?(2):(1); + format.nSamplesPerSec = iRates[_iMode & 7]; + format.wBitsPerSample = Settings.SixteenBitSound?(16):(8); + format.nBlockAlign = format.nChannels * format.wBitsPerSample / 8; + format.cbSize = 0; + format.nAvgBytesPerSec = format.nSamplesPerSec * format.nBlockAlign; + + /* Open a waveform device for output using window callback. */ + while ((hr = waveOutOpen((LPHWAVEOUT)&hWaveOut, WAVE_MAPPER, &format, + 0, 0L, CALLBACK_NULL)) != MMSYSERR_NOERROR) + { + if (hr != MMSYSERR_ALLOCATED) + { + return false; + } + } + + // Allocate and lock memory for the waveform data. The memory + // for waveform data must be globally allocated with + // GMEM_MOVEABLE and GMEM_SHARE flags. + g_dwSoundBufferSize = WAV_BUFFERS*WAV_BUFFER_SIZE; + hData = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, g_dwSoundBufferSize); + if (!hData) + { + CloseSoundDevice(); + return false; + } + + lpData = (char *) GlobalLock(hData); + if (!lpData) + { + CloseSoundDevice(); + return false; + } + memset (lpData, 0, g_dwSoundBufferSize); + + // Allocate and lock memory for the header. This memory must + // also be globally allocated with GMEM_MOVEABLE and + // GMEM_SHARE flags. + hWaveHdr = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE, (DWORD) sizeof(WAVEHDR) * WAV_BUFFERS); + + if (hWaveHdr == NULL) + { + CloseSoundDevice(); + return false; + } + + lpWaveHdr = (LPWAVEHDR) GlobalLock(hWaveHdr); + + if (lpWaveHdr == NULL) + { + CloseSoundDevice(); + return false; + } + + memset (lpWaveHdr, 0, sizeof(WAVEHDR) * WAV_BUFFERS); + + /* After allocation, set up and prepare headers. */ + for (i=0 ; i> sample16) < 4) + { + h = lpWaveHdr + ( snd_sent&WAV_MASK ); + S9xMixSamplesO((unsigned char *) h->lpData, + (Settings.SixteenBitSound == TRUE)?(WAV_BUFFER_SIZE / 2):(WAV_BUFFER_SIZE), 0); + + snd_sent++; + + // Now the data block can be sent to the output device. The + // waveOutWrite function returns immediately and waveform + // data is sent to the output device in the background. + wResult = waveOutWrite(hWaveOut, h, sizeof(WAVEHDR)); + + if (wResult != MMSYSERR_NOERROR) + { + CloseSoundDevice(); + return; + } + } +} + +unsigned short *g_pBuffer; + +extern "C" bool8_32 S9xInitUpdate() +{ + return (TRUE); +} + +// Blitting functions +// +// Blitn[p|m|u|38][portrait|landscape|stretched|right] +// +// n = bits per pixel (16 or 4) +// p = optimized for +2 pitch (x for portrait, y for landscape) +// m = optimized for -2 pitch (x for portrait, y for landscape) +// u = not optimized (other pitch) +// 38 = optimized for iPAQ 38xx +// e.g. Blit16pportrait is 16 bpp with +// x pitch = +2 + +__inline void Blit16pPortrait() //Casio E-125, EM-500, Jornada 54x/56x +{ + if (g_bGXBuffered) + g_pBuffer = (unsigned short *) GXBeginDraw(); + + unsigned short *pBuffer; + unsigned short *pGFX = (unsigned short *) GFX.Screen + (SNES_WIDTH-g_gxdp.cxWidth)/2; + int iCbyPitch2 = g_gxdp.cbyPitch>>1; + unsigned int y; + + //while(!g_bLandscape) + //{ + //EnterCriticalSection(&g_cWaitForNextFrame); + //LeaveCriticalSection(&g_cWaitForNextFrame); + + pBuffer = g_pBuffer; + y = SNES_HEIGHT; + do + { + memcpy(pBuffer, pGFX, 480); + pGFX += SNES_WIDTH; + pBuffer += iCbyPitch2; + } while (--y); + pGFX -= SNES_WIDTH * SNES_HEIGHT; + //} + + if (g_bGXBuffered) + GXEndDraw(); +} + +__inline void Blit16uPortrait() +{ + if (g_bGXBuffered) + g_pBuffer = (unsigned short *) GXBeginDraw(); + + unsigned short *pBuffer; + unsigned short *pGFX; + int iCbxPitch2 = g_gxdp.cbxPitch >> 1; + int incBUF = (g_gxdp.cbyPitch>>1) - (240 * iCbxPitch2); + unsigned int x, y; + + //while(!g_bLandscape) + { + //EnterCriticalSection(&g_cWaitForNextFrame); + //LeaveCriticalSection(&g_cWaitForNextFrame); + + pBuffer = g_pBuffer; + pGFX = (unsigned short *) GFX.Screen + (SNES_WIDTH-g_gxdp.cxWidth)/2; + y = SNES_HEIGHT; + do + { + x=240; + do + { + *pBuffer = *pGFX++; + pBuffer += iCbxPitch2; + } while (--x); + + pGFX += SNES_WIDTH - 240; + pBuffer += incBUF; + } while (--y); + } + + if (g_bGXBuffered) + GXEndDraw(); +} + +#ifdef ARM +__inline void Blit1638portrait() // iPAQ 38xx +{ + unsigned short *pGFX = (unsigned short *) GFX.Screen + 8; // + (SNES_WIDTH-g_gxdp.cxWidth)/2; + unsigned short *pBuffer = (unsigned short *) g_pBuffer; + //while(!g_bLandscape) + { + //EnterCriticalSection(&g_cWaitForNextFrame); + //LeaveCriticalSection(&g_cWaitForNextFrame); + + ScreenCopyPort38(pGFX, g_pBuffer, g_gxdp.cbxPitch, g_gxdp.cbyPitch); + } +} +#endif + +__inline void Blit16mLandscapeLeft() //@migo and iPAQ 36xx/37xx +{ + if (g_bGXBuffered) + g_pBuffer = (unsigned short *) GXBeginDraw(); + + unsigned int y; + unsigned int copyGFX = SNES_WIDTH<<1; + int incBUF = g_gxdp.cbxPitch>>1; + unsigned short *pBuffer = (unsigned short *) g_pBuffer + + (g_gxdp.cbyPitch>>1)*((g_gxdp.cyHeight+SNES_WIDTH)/2-1) + + (g_gxdp.cbxPitch>>1)*((g_gxdp.cxWidth-SNES_HEIGHT)/2-1); + unsigned short *pGFX; + + //while(g_bLandscape && !g_bSmoothStretch) + { + //EnterCriticalSection(&g_cWaitForNextFrame); + //LeaveCriticalSection(&g_cWaitForNextFrame); + + pGFX = (unsigned short *) GFX.Screen; + y = SNES_HEIGHT; + do + { + memcpy(pBuffer, pGFX, copyGFX); + pBuffer += incBUF; + pGFX += SNES_WIDTH; + } while (--y); + pBuffer -= incBUF * SNES_HEIGHT; + } + + if (g_bGXBuffered) + GXEndDraw(); +} + +__inline void Blit16uLandscapeLeft() +{ + if (g_bGXBuffered) + g_pBuffer = (unsigned short *) GXBeginDraw(); + + int iCbyPitch2 = g_gxdp.cbyPitch >> 1; + unsigned int x, y; + unsigned short *pStart = g_pBuffer + + ((g_gxdp.cyHeight+SNES_WIDTH)/2-1)*(iCbyPitch2) + + ((g_gxdp.cxWidth-SNES_HEIGHT)/2-1)*(g_gxdp.cbxPitch>>1); + unsigned short *pBuffer; + unsigned short *pGFX; + + //while(g_bLandscape && !g_bSmoothStretch) + { + //EnterCriticalSection(&g_cWaitForNextFrame); + //LeaveCriticalSection(&g_cWaitForNextFrame); + + pGFX = (unsigned short *) GFX.Screen; + y = SNES_HEIGHT; + do + { + pBuffer = pStart + (SNES_HEIGHT-y)*(g_gxdp.cbxPitch>>1); + + x=SNES_WIDTH; + do + { + *pBuffer = *pGFX++; + pBuffer -= iCbyPitch2; + } while (--x); + + } while (--y); + } + + if (g_bGXBuffered) + GXEndDraw(); +} + +__inline void Blit16uLandscapeRight() +{ + if (g_bGXBuffered) + g_pBuffer = (unsigned short *) GXBeginDraw(); + + int iCbyPitch2 = g_gxdp.cbyPitch >> 1; + unsigned int x, y; + unsigned short *pStart = g_pBuffer + + ((g_gxdp.cxWidth-SNES_HEIGHT)/2-1)*(g_gxdp.cbxPitch>>1) - + ((g_gxdp.cyHeight+SNES_WIDTH)/2-1)*(iCbyPitch2); + + unsigned short *pBuffer; + unsigned short *pGFX; + pGFX = (unsigned short *) GFX.Screen; + y = 1; + do + { + pBuffer = pStart + (SNES_HEIGHT-y)*(g_gxdp.cbxPitch>>1); + + x=0; + do + { + *pBuffer = *pGFX++; + pBuffer += iCbyPitch2; + } while (++x < SNES_WIDTH); + + } while (++y < SNES_HEIGHT); + if (g_bGXBuffered) + GXEndDraw(); +} + +#ifdef ARM +__inline void Blit1638landscape() //iPAQ 38xx +{ + unsigned short* pBuffer = (unsigned short *) g_pBuffer + + (g_gxdp.cbyPitch>>1)*((g_gxdp.cyHeight+SNES_WIDTH)/2-1) + + (g_gxdp.cbxPitch>>1)*((g_gxdp.cxWidth-SNES_HEIGHT)/2-1); + + //while(g_bLandscape && !g_bSmoothStretch && g_bLandLeft) + { + //EnterCriticalSection(&g_cWaitForNextFrame); + //LeaveCriticalSection(&g_cWaitForNextFrame); + + ScreenCopyLand38(GFX.Screen, pBuffer, g_gxdp.cbxPitch, g_gxdp.cbyPitch); + } +} + +__inline void Blit1638right() //iPAQ 38xx, landscape rotated right +{ + unsigned short* pBuffer = (unsigned short *) g_pBuffer + + (g_gxdp.cbyPitch>>1)*((g_gxdp.cyHeight-SNES_WIDTH)/2-1) + + (g_gxdp.cbxPitch>>1)*((g_gxdp.cxWidth+SNES_HEIGHT)/2-1); + + //while(g_bLandscape && !g_bSmoothStretch && !g_bLandLeft) + { + //EnterCriticalSection(&g_cWaitForNextFrame); + //LeaveCriticalSection(&g_cWaitForNextFrame); + + ScreenCopyLand38r(GFX.Screen, pBuffer, g_gxdp.cbxPitch, g_gxdp.cbyPitch); + } +} +#endif + +__inline void Blit16uStretchedLeft() +{ + if (g_bGXBuffered) + g_pBuffer = (unsigned short *) GXBeginDraw(); + + unsigned short* pStart = (unsigned short *) g_pBuffer + ((g_gxdp.cyHeight-1) * (g_gxdp.cbyPitch >> 1)); + unsigned short* pGFX; + unsigned short* pBuffer; + unsigned int iOriginal1, iOriginal2, iOriginal3; + unsigned int x, y; + + //while(g_bSmoothStretch && g_bLandscape) + { + //EnterCriticalSection(&g_cWaitForNextFrame); + //LeaveCriticalSection(&g_cWaitForNextFrame); + + pGFX = (unsigned short *) GFX.Screen + 8; + y = SNES_HEIGHT; + do + { + pBuffer = pStart + ((g_gxdp.cxWidth>>1) + (SNES_HEIGHT>>1) - y) * (g_gxdp.cbxPitch >> 1); + x = 240; + do + { + iOriginal1 = *pGFX; + iOriginal2 = *(++pGFX); + iOriginal3 = *(++pGFX); + ++pGFX; + + *pBuffer = iOriginal1; + pBuffer -= g_gxdp.cbyPitch >> 1; + *pBuffer = (iOriginal1 & 0xf800)|(iOriginal2 &0x07ff); + pBuffer -= g_gxdp.cbyPitch >> 1; + *pBuffer = (iOriginal2 & 0xffe0)|(iOriginal3 &0x001f); + pBuffer -= g_gxdp.cbyPitch >> 1; + *pBuffer = iOriginal3; + pBuffer -= g_gxdp.cbyPitch >> 1; + + } while (x-=3); + + pGFX += 16; + } while (--y); + } + + if (g_bGXBuffered) + GXEndDraw(); +} + +__inline void Blit16uStretchedRight() +{ + if (g_bGXBuffered) + g_pBuffer = (unsigned short *) GXBeginDraw(); + + unsigned short* pStart = (unsigned short *) g_pBuffer + ((g_gxdp.cyHeight-1) * (g_gxdp.cbyPitch >> 1)); + unsigned short* pGFX; + unsigned short* pBuffer; + unsigned int iOriginal1, iOriginal2, iOriginal3; + unsigned int x, y; + +// while(g_bSmoothStretch && g_bLandscape) +// { + ////EnterCriticalSection(&g_cWaitForNextFrame); + ////LeaveCriticalSection(&g_cWaitForNextFrame); + + pGFX = (unsigned short *) GFX.Screen + 8; + y = 1; + do + { + pBuffer = pStart + ((g_gxdp.cxWidth>>1) + (SNES_HEIGHT>>1) - y) * (g_gxdp.cbxPitch >> 1); + x = 240; + do + { + iOriginal1 = *pGFX; + iOriginal2 = *(++pGFX); + iOriginal3 = *(++pGFX); + ++pGFX; + + *pBuffer = iOriginal1; + pBuffer += g_gxdp.cbyPitch >> 1; + *pBuffer = (iOriginal1 & 0xf800)|(iOriginal2 &0x07ff); + pBuffer += g_gxdp.cbyPitch >> 1; + *pBuffer = (iOriginal2 & 0xffe0)|(iOriginal3 &0x001f); + pBuffer += g_gxdp.cbyPitch >> 1; + *pBuffer = iOriginal3; + pBuffer += g_gxdp.cbyPitch >> 1; + + } while (x-=3); + + pGFX += 16; + } while (++y < SNES_HEIGHT); +// } + + if (g_bGXBuffered) + GXEndDraw(); +} + +__inline void Blit4uportrait() +{ + if (g_bGXBuffered) + g_pBuffer = (unsigned short *) GXBeginDraw(); + + //while(!g_bLandscape) + { + //EnterCriticalSection(&g_cWaitForNextFrame); + //LeaveCriticalSection(&g_cWaitForNextFrame); + + static int iXOffset = (SNES_WIDTH - g_gxdp.cxWidth) >> 1; + static int iYOffset = (g_gxdp.cxWidth - SNES_HEIGHT) >> 1; + static int iGFXPitch2 = GFX.Pitch >> 1; + static int iCbxPitch2 = (g_gxdp.cbxPitch) >> 1; + static int iCbyPitch2 = (g_gxdp.cbyPitch) / 2; + int iYGFXPitch = 0; + + unsigned char *pBuffer; + unsigned short *pGFX; + unsigned short iColor1, iColor2; + + if (g_pBuffer) + { + for (int y = 0; y < (SNES_HEIGHT >> 1); y++) + { + pBuffer = (unsigned char *) g_pBuffer - y - 1; + pGFX = (unsigned short *) GFX.Screen + iXOffset + iYGFXPitch; + + for (int x = 0; x < (int) g_gxdp.cxWidth; x++) + { + iColor1 = *pGFX; + iColor2 = *(pGFX + iGFXPitch2); + + pGFX++; + + iColor1 = RGB565_TO_MONO(iColor1); + iColor2 = RGB565_TO_MONO(iColor2); + + *pBuffer = 255 - ((iColor1)|(iColor2 << 4)); + + pBuffer += 160; + } + + iYGFXPitch += (iGFXPitch2 * 2); + } + } + } + + if (g_bGXBuffered) + GXEndDraw(); +} + +__inline void Blit4ulandscape() +{ + if (g_bGXBuffered) + g_pBuffer = (unsigned short *) GXBeginDraw(); + + //while(g_bLandscape) + { + // EnterCriticalSection(&g_cWaitForNextFrame); + // LeaveCriticalSection(&g_cWaitForNextFrame); + + static int iXOffset = (SNES_WIDTH - g_gxdp.cxWidth) >> 1; + static int iYOffset = (g_gxdp.cxWidth - SNES_HEIGHT) >> 1; + static int iGFXPitch2 = GFX.Pitch >> 1; + static int iCbxPitch2 = (g_gxdp.cbxPitch) >> 1; + static int iCbyPitch2 = (g_gxdp.cbyPitch) / 2; + int iYGFXPitch = 0; + + unsigned char *pBuffer; + unsigned short *pGFX; + unsigned short iColor1, iColor2; + + if (g_pBuffer) + { + for (int y = iYOffset; y < (SNES_HEIGHT + iYOffset); y++) + { + pBuffer = (unsigned char *) g_pBuffer + (y * 160) + ((g_gxdp.cyHeight - SNES_WIDTH) >> 2); + pGFX = (unsigned short *) GFX.Screen + iYGFXPitch; + + for (int x = 0; x < (SNES_WIDTH / 2); x++) + { + iColor1 = *pGFX++; + iColor2 = *pGFX++; + + iColor1 = RGB565_TO_MONO(iColor1); + iColor2 = RGB565_TO_MONO(iColor2); + + *pBuffer++ = 255 - ((iColor2)|(iColor1 << 4)); + } + + iYGFXPitch += iGFXPitch2; + } + } + } + if (g_bGXBuffered) + GXEndDraw(); +} + +void Initialize16() +{ + SetKeypad(); + + if (g_bGXBuffered && !g_bH3800) + g_pBuffer = (unsigned short *) GXBeginDraw(); + + // Clear screen + unsigned short *pBuffer; + + for (int y = 0; y < (int) g_gxdp.cyHeight; y++) + { + pBuffer = (unsigned short *) g_pBuffer + ((y * g_gxdp.cbyPitch) >> 1); + + for (int x = 0; x < (int) g_gxdp.cxWidth; x++) + { + *pBuffer = 0; + + pBuffer += (g_gxdp.cbxPitch >> 1); + } + } + + // Draw keypad + if (!g_bLandscape) + { + if (LoadKeypad()) + { + static int iXOffset = (256 - g_gxdp.cxWidth) >> 1; + int iCbxPitch2 = g_gxdp.cbxPitch >> 1; + unsigned short *pvBits = g_pKeypad + (240 * 96); + + for (int y = 319; y >= 224; y--) + { + pBuffer = g_pBuffer + (y * g_gxdp.cbyPitch / 2); + + for (int x = 0; x < (int) g_gxdp.cxWidth; x++) + { + *pBuffer = *pvBits; + + pBuffer += iCbxPitch2; + pvBits++; + } + } + } + } + + if (g_bGXBuffered && !g_bH3800) + GXEndDraw(); +} + +void Initialize4() +{ + SetKeypad(); + + if (g_bGXBuffered) + g_pBuffer = (unsigned short *) GXBeginDraw(); + + // Clear screen + unsigned char *pBuffer; + + for (int y = 0; y < (int) g_gxdp.cyHeight; y++) + { + pBuffer = (unsigned char *) g_pBuffer - (y >> 1) - 1; + + for (int x = 0; x < (int) g_gxdp.cxWidth; x++) + { + *pBuffer = 0xff; + + pBuffer += 160; + } + } + + // Draw keypad + if (!g_bLandscape) + { + if (LoadKeypad()) + { + static int iXOffset = (256 - g_gxdp.cxWidth) / 2; + int iCbxPitch2 = g_gxdp.cbxPitch / 2; + unsigned short *pvBits = g_pKeypad + (240 * 96); + unsigned short iColor1, iColor2; + + for (int y = 319; y >= 224; y--) + { + pBuffer = (unsigned char *) g_pBuffer - (y >> 1) - 1; + + for (int x = 0; x < (int) g_gxdp.cxWidth; x++) + { + iColor1 = *pvBits; + iColor2 = *(pvBits + 240); + + iColor1 = RGB565_TO_MONO(iColor1); + iColor2 = RGB565_TO_MONO(iColor2); + + *pBuffer = 255 - ((iColor2)|((iColor1) << 4)); + + pBuffer += 160; + pvBits++; + } + } + } + } + + if (g_bGXBuffered) + GXEndDraw(); +} + +/* +long WINAPI DrawThread() +{ + EnterCriticalSection(&g_cWaitForNextFrame); + LeaveCriticalSection(&g_cWaitForNextFrame); + + for(;;) + { + if (g_gxdp.cBPP == 16) + { + if (g_bLandscape) + { + if (g_bSmoothStretch) + { + Blit16stretched(); + } + else if (g_gxdp.cbyPitch == -2) + { + // Landscape optimized + Blit16mlandscape(); + } +#ifdef ARM + else if (g_bH3800) + { + // Landscape optimized (iPAQ 38xx) + if(g_bLandLeft) + Blit1638landscape(); + else + Blit1638right(); + } +#endif + else + { + // Landscape unoptimized + Blit16ulandscape(); + } + } + else + { + if (g_gxdp.cbxPitch == 2) + { + // Portrait optimized + Blit16pportrait(); + } +#ifdef ARM + else if(g_bH3800) + { + // Portrait optimized (iPAQ 38xx) + Blit1638portrait(); + } +#endif + else + { + // Portrait unoptimized + Blit16uportrait(); + } + } + } + else if (g_gxdp.cBPP == 4) + { + if (g_bLandscape) + { + Blit4ulandscape(); + } + else + { + Blit4uportrait(); + } + } + } + + return 1; +} +*/ + +extern "C" bool8_32 S9xDeinitUpdate(int _iWidth, int _iHeight, bool8_32 _bSixteenBit) +{ + //LeaveCriticalSection(&g_cWaitForNextFrame); + //EnterCriticalSection(&g_cWaitForNextFrame); + + if (g_gxdp.cBPP == 16) + { + if (g_bLandscape) + { + if (g_bSmoothStretch) + { + if (g_bLandLeft) + Blit16uStretchedLeft(); + else + Blit16uStretchedRight(); + } + else if (g_gxdp.cbyPitch == -2) + { + // Landscape optimized + if (g_bLandLeft) + Blit16mLandscapeLeft(); + else + Blit16uLandscapeRight(); + } +#ifdef ARM + else if (g_bH3800) + { + // Landscape optimized (iPAQ 38xx) + if(g_bLandLeft) + Blit1638landscape(); + else + Blit1638right(); + } +#endif + else + { + // Landscape unoptimized + if (g_bLandLeft) + { + Blit16uLandscapeLeft(); + } + else + { + Blit16uLandscapeRight(); + } + } + } + else + { + if (g_gxdp.cbxPitch == 2) + { + // Portrait optimized + Blit16pPortrait(); + } +#ifdef ARM + else if(g_bH3800) + { + // Portrait optimized (iPAQ 38xx) + Blit1638portrait(); + } +#endif + else + { + // Portrait unoptimized + Blit16uPortrait(); + } + } + } + else if (g_gxdp.cBPP == 4) + { + if (g_bLandscape) + { + Blit4ulandscape(); + } + else + { + Blit4uportrait(); + } + } + return (TRUE); +} + +extern "C" void S9xTextMode() +{ +} + +extern "C" void S9xGraphicsMode() +{ +} + +extern "C" void S9xExit() +{ +} + +extern "C" void S9xSetPalette() +{ +} + +extern "C" void S9xMessage(int, int, const char *_pszMessage) +{ + DEBUGMSG(TRUE, (L"%S\n",_pszMessage)); +} + +extern "C" bool8_32 S9xReadMousePosition(int _iWhich, int &_iX, int &_iY, uint32 &_dwButtons) +{ + return 0; +} + +extern "C" bool8_32 S9xReadSuperScopePosition(int &_iX, int &_iY, uint32 &_dwButtons) +{ + return 0; +} + +uint32 g_iJoypadState; + +extern "C" uint32 S9xReadJoypad(int _iWhich) +{ + if (_iWhich == 0) + { + return g_iJoypadState | 0x80000000; + } + + return 0; +} + +extern "C" bool8_32 S9xOpenSnapshotFile(const char *_pszFilename, bool8_32 _bReadOnly, STREAM *_File) +{ + if (_bReadOnly) + { + if ((*_File = OPEN_STREAM(_pszFilename, "rb"))) + return (TRUE); + } + else + { + if ((*_File = OPEN_STREAM(_pszFilename, "wb"))) + return (TRUE); + } + + return 0; +} + +extern "C" void S9xCloseSnapshotFile(STREAM file) +{ + CLOSE_STREAM(file); +} + +void S9xAutoSaveSRAM() +{ + Memory.SaveSRAM(S9xGetSRAMFilename()); +} + +extern "C" const char *S9xBasename(const char *_pszF) +{ + return ""; +} + +extern "C" void S9xExtraUsage() +{ +} + +extern "C" void S9xParseArg(char **argv, int &i, int argc) +{ +} + +const char *S9xGetSRAMFilename() +{ + static char filename [PATH_MAX]; + char drive [_MAX_DRIVE]; + char dir [_MAX_DIR]; + char fname [_MAX_FNAME]; + char ext [_MAX_EXT]; + + _splitpath (Memory.ROMFilename, drive, dir, fname, ext); + strcpy (filename, fname); + strcat (filename, ".srm"); + + return (filename); +} + +BYTE ScreenBuffer [256*239*2]; +BYTE SubScreenBuffer [256*239*2]; +BYTE ZBuffer [256*239]; +BYTE SubZBuffer [256*239]; + +void S9xInitDisplay() +{ + GFX.SubScreen = SubScreenBuffer; + GFX.ZBuffer = ZBuffer; + GFX.SubZBuffer = SubZBuffer; + + GFX.RealPitch = GFX.Pitch = 256 * 2; + GFX.Screen = ScreenBuffer; + GFX.Delta = (GFX.SubScreen - GFX.Screen) >> 1; + + if (Settings.SixteenBit) + { + GFX.PPL = GFX.Pitch >> 1; + GFX.PPLx2 = GFX.Pitch; + } + else + { + GFX.PPL = GFX.Pitch; + GFX.PPLx2 = GFX.Pitch * 2; + } +} + +void S9xSetTitle(const char *_szTitle) +{ + wsprintf(g_szTitle, TEXT("%S"), _szTitle); +} + + +#define MAX_LOADSTRING 100 + +unsigned short *g_pKeypad = NULL; +HBITMAP hbmTemp = NULL; +HDC hMemoryDC; + +bool LoadKeypad() +{ + unsigned short *pvBits = NULL; + + if (!hbmTemp) + { + HDC hDC = GetDC(g_hWnd); + + hMemoryDC = CreateCompatibleDC(hDC); + + BMIWrapper bmInfo; + + memset(&bmInfo, 0, sizeof(BMIWrapper)); + bmInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmInfo.bmiHeader.biWidth = 240; + bmInfo.bmiHeader.biHeight = 192; + bmInfo.bmiHeader.biPlanes = 1; + bmInfo.bmiHeader.biBitCount = 16; + bmInfo.bmiHeader.biCompression = BI_BITFIELDS; + bmInfo.bmiColors[0] = 0xf800; + bmInfo.bmiColors[1] = 0x07e0; + bmInfo.bmiColors[2] = 0x001f; + + hbmTemp = CreateDIBSection(hMemoryDC, (BITMAPINFO *) &bmInfo, DIB_RGB_COLORS, (void **) &pvBits, NULL, 0); + + ReleaseDC(g_hWnd, hDC); + } + + if (hbmTemp) + { + SelectObject(hMemoryDC, hbmTemp); + + BitBlt(hMemoryDC, 0, 0, 240, 192, g_hSkinDC, 0, 0, SRCCOPY); + + if (!g_pKeypad) + g_pKeypad = pvBits; + } + + return (g_pKeypad != NULL); +} + +void DrawKeypad() +{ + if (g_gxdp.cBPP == 16) + { + Initialize16(); + } + else if (g_gxdp.cBPP == 4) + { + Initialize4(); + } +} + +bool InitializeEmulation(int _iTransparency, int _iSoundEnabled, int _iSixteenBitSound) +{ + ZeroMemory(&Settings, sizeof(Settings)); + + LoadOptions(); + + Settings.JoystickEnabled = FALSE; + //Settings.Stereo = FALSE; + Settings.SoundBufferSize = 0; + Settings.CyclesPercentage = g_iCycles; + //Settings.DisableSoundEcho = TRUE; + Settings.APUEnabled = _iSoundEnabled; + Settings.NextAPUEnabled = Settings.APUEnabled; + Settings.SixteenBitSound = _iSixteenBitSound; + Settings.H_Max = (SNES_CYCLES_PER_SCANLINE * Settings.CyclesPercentage) / 100; + Settings.SkipFrames = AUTO_FRAMERATE; + Settings.Shutdown = Settings.ShutdownMaster = TRUE; + Settings.FrameTimePAL = 20000; + Settings.FrameTimeNTSC = 16667; + Settings.FrameTime = Settings.FrameTimeNTSC; + Settings.DisableSampleCaching = !(_iSoundEnabled); + Settings.DisableMasterVolume = !(_iSoundEnabled); + Settings.Mouse = FALSE; + Settings.SuperScope = FALSE; + Settings.MultiPlayer5 = FALSE; + Settings.ControllerOption = SNES_MULTIPLAYER5; + Settings.Transparency = _iTransparency; + Settings.SixteenBit = TRUE; + Settings.SupportHiRes = FALSE; + Settings.SoundSync = _iSoundEnabled; + Settings.ThreadSound = FALSE; + Settings.Mute = !_iSoundEnabled; + //Settings.DisplayFrameRate = TRUE; + + Settings.HBlankStart = (256 * Settings.H_Max) / SNES_HCOUNTER_MAX; + + if (!Memory.Init() || !S9xInitAPU()) + { + return false; + } + + S9xInitDisplay(); + // S9xInitInputDevices(); + +#ifdef GFX_MULTI_FORMAT + S9xSetRenderPixelFormat(RGB565); +#endif + + return true; +} + +bool LoadROM() +{ + // Load ROM + LRESULT lResult = TRUE; + TCHAR szFile[MAX_PATH] = TEXT("\0"); + OPENFILENAME ofn; + char szRom[MAX_PATH]; + + memset(&ofn, 0, sizeof(ofn)); + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = g_hWnd; + ofn.lpstrFile = szFile; + ofn.nMaxFile = MAX_PATH; + ofn.lpstrFilter = TEXT("All (*.smc,*.fig,*.zip)\0*.smc,*.fig,*.zip\0"); + ofn.lpstrTitle = TEXT("Open ROM"); + ofn.Flags = OFN_EXPLORER; + + if (GetOpenFileName(&ofn)) + { + sprintf(szRom, "%S", ofn.lpstrFile); + if (Memory.LoadROM(szRom)) + { + Memory.LoadSRAM(S9xGetSRAMFilename()); + } + else + { + S9xReset(); + } + } + else + { + return false; + } + + return true; +} + +bool8_32 LoadSlot(int slot) +{ + LRESULT lResult = TRUE; + static char filename [_MAX_PATH + 1]; + char drive [_MAX_DRIVE + 1]; + char dir [_MAX_DIR + 1]; + char fname [_MAX_FNAME + 1]; + char ext [_MAX_EXT + 1]; + + if(g_emMode != emStopped) + { + //if (freezefiledir exists) + //{ + // _splitpath(Memory::ROMFilename, drive, dir, filename, ext); + // sprintf (ext, ".%03d", savenumber); + // _makepath (szState, dir, freezefiledir, filename, ext); + //} + //else + { + _splitpath(Memory.ROMFilename, drive, dir, fname, ext); + sprintf (ext, "%03d", slot); + _makepath (filename, drive, dir, fname, ext); + } + + if (!S9xUnfreezeGame(filename)) + { + return false; + } + + if(g_bResumeAfterLoadState) + StartEmulation(g_hWnd, g_hWndCB); + + return true; + } + else + { + return false; + } +} + + +bool LoadState() +{ + // load state + LRESULT lResult = TRUE; + TCHAR szFile[MAX_PATH] = TEXT("\0"); + OPENFILENAME ofn; + char szState[MAX_PATH]; + + memset(&ofn, 0, sizeof(ofn)); + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = g_hWnd; + ofn.lpstrFile = szFile; + ofn.nMaxFile = MAX_PATH; + ofn.lpstrFilter = TEXT("All (*.pss)\0*.pss\0"); + ofn.lpstrTitle = TEXT("Load State"); + ofn.Flags = OFN_EXPLORER; + + if (GetOpenFileName(&ofn)) + { + sprintf(szState, "%S", ofn.lpstrFile); + if (!S9xUnfreezeGame(szState)) + { + return false; + } + } + else + { + return false; + } + + return true; +} + +bool SaveState() +{ + // Save state + LRESULT lResult = TRUE; + TCHAR szFile[MAX_PATH] = TEXT("\0"); + OPENFILENAME ofn; + char szState[MAX_PATH]; + + memset(&ofn, 0, sizeof(ofn)); + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = g_hWnd; + ofn.lpstrFile = szFile; + ofn.nMaxFile = MAX_PATH; + ofn.lpstrFilter = TEXT("All (*.pss)\0*.pss\0"); + ofn.lpstrTitle = TEXT("Save State"); + ofn.Flags = OFN_EXPLORER; + + if (GetSaveFileName(&ofn)) + { + sprintf(szState, "%S", ofn.lpstrFile); + if (!S9xFreezeGame(szState)) + { + return false; + } + } + else + { + return false; + } + + return true; +} + +bool8_32 SaveSlot(int slot) +{ + LRESULT lResult = TRUE; + + static char filename [_MAX_PATH + 1]; + char drive [_MAX_DRIVE + 1]; + char dir [_MAX_DIR + 1]; + char fname [_MAX_FNAME + 1]; + char ext [_MAX_EXT + 1]; + + if(g_emMode != emStopped) + { + //if (freezefiledir exists) + //{ + // _splitpath(Memory::ROMFilename, drive, dir, filename, ext); + // sprintf (ext, ".%03d", savenumber); + // _makepath (szState, dir, freezefiledir, filename, ext); + //} + //else + { + _splitpath(Memory.ROMFilename, drive, dir, fname, ext); + sprintf (ext, "%03d", slot); + _makepath (filename, drive, dir, fname, ext); + } + + if (!S9xFreezeGame(filename)) + { + return false; + }; + + if(g_bResumeAfterSaveState) + StartEmulation(g_hWnd, g_hWndCB); + return true; + } + else + { + return false; + } + +} + + +bool StartEmulation(HWND hWnd, HWND hWndCB) +{ + + ShowWindow(hWndCB, SW_HIDE); + + RECT rc; + GetWindowRect(hWnd, &rc); + rc.top = 0; + rc.bottom = 320; + SetWindowPos(hWnd, HWND_TOP, rc.left, rc.top, rc.right, rc.bottom, 0); + + if (SHFullScreen(hWnd, SHFS_HIDESIPBUTTON|SHFS_HIDETASKBAR|SHFS_HIDESTARTICON)) + { + SHSipPreference(hWnd, SIP_FORCEDOWN); + } + else + { + return false; + } + + SetForegroundWindow(hWnd); + + // Try opening the Display for Fullscreen access + if (GXOpenDisplay(hWnd, GX_FULLSCREEN) == 0) + { + return false; + } + + if (GXSetViewport(0, 320, 0, 0) == 0) + { + return false; + } + + // Initialize the Hardware Buttons + GXOpenInput(); + + // Get the Display properties + g_gxdp = GXGetDisplayProperties(); + g_bGXBuffered = (GXIsDisplayDRAMBuffer() == TRUE); + + // Check for upgraded Aero and fix properties + if (g_gxdp.cbxPitch == 0xf000) + { + g_gxdp.cbxPitch = 640; + } + + // Check PDA model for device-specific fixes/optimizations + unsigned short szTemp[64]; + + SystemParametersInfo(SPI_GETOEMINFO, sizeof(szTemp), szTemp, 0); + + if (!_wcsicmp(szTemp, _T("Compaq iPAQ H3800"))) //iPAQ 38xx + { + g_bH3800 = true; + g_pBuffer = (unsigned short *) 0xac0755a0; + g_gxdp.ffFormat = 168; + g_gxdp.cxWidth = 240; + g_gxdp.cyHeight = 320; + g_gxdp.cBPP = 16; + g_gxdp.cbyPitch = 2; + g_gxdp.cbxPitch = -640; + g_bGXBuffered = false; + } + else if (!_wcsicmp(szTemp, _T("Pocket PC J710"))) //Casio E-200 + { + //nothing yet :( + } + + // Get information about the Hardware Keys + g_gxkl = GXGetDefaultKeys(GX_NORMALKEYS); + + if (Settings.APUEnabled) + { + Settings.NextAPUEnabled = Settings.APUEnabled; + S9xInitSound(Settings.SoundPlaybackRate, Settings.Stereo, Settings.SoundBufferSize); + } + + if (!S9xGraphicsInit()) + { + return false; + } + + S9xTextMode(); + S9xGraphicsMode(); + + if (!g_bH3800) + g_pBuffer = (unsigned short *) GXBeginDraw(); + + DrawKeypad(); + S9xSetSoundMute(!Settings.APUEnabled); + + S9xSetTitle(Memory.ROMName); + + //Get the processor performance counter frequency + QueryPerformanceFrequency(&g_liFreq); + + //Start drawing thread + //InitializeCriticalSection(&g_cWaitForNextFrame); + //EnterCriticalSection(&g_cWaitForNextFrame); + //g_hDrawThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)DrawThread, NULL, 0, NULL); + //CeSetThreadQuantum(g_hDrawThread, 10); + +#ifdef THREADCPU + g_hS9xMainLoopThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)S9xMainLoopThread, NULL, 0, NULL); + CeSetThreadQuantum(g_hS9xMainLoopThread, THREADCPUQUANTUM); + SetThreadPriority(g_hS9xMainLoopThread, THREAD_PRIORITY_NORMAL); +#endif + + g_emMode = emRunning; + + return true; +} + +HBITMAP g_bmPausedBitmap; +HBITMAP g_hbmPausedDIB; +HDC g_hPausedDC; + + +bool PauseEmulation(HWND hWnd, HWND hWndCB) +{ + if(!g_bH3800) GXEndDraw(); +#ifdef THREADCPU + SuspendThread(g_hS9xMainLoopThread); +#endif + GXCloseDisplay(); + GXCloseInput(); + + HDC hDC = GetDC(hWnd); + + g_hPausedDC = CreateCompatibleDC(hDC); + + typedef struct BMIWrapper + { + BITMAPINFOHEADER bmiHeader; + DWORD bmiColors[3]; + } BMIWrapper; + + BMIWrapper bmInfo; + unsigned short *pvBits = NULL; + + memset(&bmInfo, 0, sizeof(BMIWrapper)); + bmInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmInfo.bmiHeader.biWidth = 240; + bmInfo.bmiHeader.biHeight = 224; + bmInfo.bmiHeader.biPlanes = 1; + bmInfo.bmiHeader.biBitCount = 16; + bmInfo.bmiHeader.biCompression = BI_BITFIELDS; + bmInfo.bmiColors[0] = 0xf800; + bmInfo.bmiColors[1] = 0x07e0; + bmInfo.bmiColors[2] = 0x001f; + + g_hbmPausedDIB = CreateDIBSection(g_hPausedDC, (BITMAPINFO *) &bmInfo, DIB_RGB_COLORS, (void **) &pvBits, NULL, 0); + + if (g_hbmPausedDIB) + { + SelectObject(g_hPausedDC, g_hbmPausedDIB); + + static int iXOffset = (256 - g_gxdp.cxWidth) / 2; + int iGFXPitch2 = GFX.Pitch / 2; + int iYGFXPitch = iGFXPitch2 * 224; + unsigned short iValue; + + for (int y = 0; y < 224; y++) + { + for (int x = 0; x < (int) g_gxdp.cxWidth; x++) + { + iValue = *((unsigned short *) GFX.Screen + (x + iXOffset) + iYGFXPitch); + + *pvBits = iValue; + pvBits++; + } + + iYGFXPitch -= iGFXPitch2; + } + } + + ReleaseDC(hWnd, hDC); + + RECT rc; + GetWindowRect(hWnd, &rc); + rc.top = 26; + rc.bottom = 320 - 26; + MoveWindow(hWnd, rc.left, rc.top, rc.right, rc.bottom, TRUE); + + if (!SHFullScreen(hWnd, SHFS_HIDESIPBUTTON|SHFS_SHOWTASKBAR|SHFS_SHOWSTARTICON)) + { + return false; + } + + ShowWindow(hWndCB, SW_SHOW); + + Memory.SaveSRAM(S9xGetSRAMFilename()); + S9xSetSoundMute(TRUE); + + g_emMode = emPaused; + + return true; +} + +bool ResumeEmulation(HWND hWnd, HWND hWndCB) +{ + DeleteObject(g_bmPausedBitmap); + DeleteObject(g_hPausedDC); + + GXOpenInput(); + + RECT rc; + GetWindowRect(hWnd, &rc); + rc.top = 0; + rc.bottom = 320; + SetWindowPos(hWnd, HWND_TOP, rc.left, rc.top, rc.right, rc.bottom, 0); + + if (SHFullScreen(hWnd, SHFS_HIDESIPBUTTON|SHFS_HIDETASKBAR|SHFS_HIDESTARTICON)) + { + SHSipPreference(hWnd, SIP_FORCEDOWN); + } + else + { + return false; + } + + ShowWindow(hWndCB, SW_HIDE); + + // Try opening the Display for Fullscreen access + if (GXOpenDisplay(hWnd, GX_FULLSCREEN) == 0) + { + return false; + } + + if (!g_bH3800) + g_pBuffer = (unsigned short *) GXBeginDraw(); +#ifdef THREADCPU + ResumeThread(g_hS9xMainLoopThread); +#endif + + DrawKeypad(); + S9xSetSoundMute(FALSE); + + g_emMode = emRunning; + + return true; +} + +bool StopEmulation(HWND hWnd, HWND hWndCB) +{ + //Stop drawing thread + //CloseHandle(g_hDrawThread); + //DeleteCriticalSection(&g_cWaitForNextFrame); +#ifdef THREADCPU + CloseHandle(g_hS9xMainLoopThread); +#endif + + if ((g_emMode == emRunning) || (g_emMode == emPaused)) + { + Memory.SaveSRAM(S9xGetSRAMFilename()); + CloseSoundDevice(); + } + + if (g_emMode == emRunning) + { + GXCloseDisplay(); + + RECT rc; + GetWindowRect(hWnd, &rc); + rc.top = 0; + rc.bottom = 320 - 26; + SetWindowPos(hWnd, HWND_TOP, rc.left, rc.top, rc.right, rc.bottom, 0); + + if (!SHFullScreen(hWnd, SHFS_HIDESIPBUTTON|SHFS_SHOWTASKBAR|SHFS_SHOWSTARTICON)) + { + return false; + } + + ShowWindow(hWndCB, SW_SHOW); + } + + g_emMode = emStopped; + + return true; +} + + +const char *S9xGetFilename (const char *ex) +{ + static char filename [PATH_MAX + 1]; + char drive [_MAX_DRIVE + 1]; + char dir [_MAX_DIR + 1]; + char fname [_MAX_FNAME + 1]; + char ext [_MAX_EXT + 1]; + + _splitpath (Memory.ROMFilename, drive, dir, fname, ext); + strcpy (filename, fname); + strcat (filename, ex); + + return (filename); +} + +void S9xLoadSDD1Data () +{ +} + +void _makepath (char *path, const char *drive, const char *dir, + const char *fname, const char *ext) +{ + if (drive && *drive) + { + *path = *drive; + *(path + 1) = ':'; + *(path + 2) = 0; + } + else + *path = 0; + + if (dir && *dir) + { + strcat (path, dir); + if (strlen (dir) != 1 || *dir != '\\') + strcat (path, SLASH_STR); + } + + strcat (path, fname); + if (ext && *ext) + { + strcat (path, "."); + strcat (path, ext); + } +} + +void _splitpath (const char *path, char *drive, char *dir, char *fname, + char *ext) +{ + if (*path && *(path + 1) == ':') + { + *drive = toupper (*path); + path += 2; + } + else + *drive = 0; + + char *slash = strrchr (path, SLASH_CHAR); + if (!slash) + slash = strrchr (path, '/'); + char *dot = strrchr (path, '.'); + if (dot && slash && dot < slash) + dot = NULL; + + if (!slash) + { + if (*drive) + strcpy (dir, "\\"); + else + strcpy (dir, ""); + strcpy (fname, path); + if (dot) + { + *(fname + (dot - path)) = 0; + strcpy (ext, dot + 1); + } + else + strcpy (ext, ""); + } + else + { + if (*drive && *path != '\\') + { + strcpy (dir, "\\"); + strcat (dir, path); + *(dir + (slash - path) + 1) = 0; + } + else + { + strcpy (dir, path); + if (slash - path == 0) + *(dir + 1) = 0; + else + *(dir + (slash - path)) = 0; + } + + strcpy (fname, slash + 1); + if (dot) + { + *(fname + (dot - slash) - 1) = 0; + strcpy (ext, dot + 1); + } + else + strcpy (ext, ""); + } +} + +#ifdef THREADCPU +long WINAPI S9xMainLoopThread() +{ + struct SICPU * icpu = &ICPU; + struct SCPUState * cpu = &CPU; + struct SRegisters * reg = &Registers; + for(;;) + { + while (!(CPU.Flags & FRAME_ADVANCE_FLAG)) + { + S9xMainLoop(reg, icpu, cpu); + } + Sleep(0); + } + return 0; +} +#endif \ No newline at end of file diff --git a/src/snes4iphone_src/pocketpc.h b/src/snes4iphone_src/pocketpc.h new file mode 100755 index 0000000..aa171a3 --- /dev/null +++ b/src/snes4iphone_src/pocketpc.h @@ -0,0 +1,30 @@ +enum EmulationMode { emStopped, emRunning, emPaused }; + +extern EmulationMode g_emMode; +extern HBITMAP g_hbmPausedDIB; +extern HDC g_hPausedDC; +extern HINSTANCE g_hInstance; +extern uint32 g_iJoypadState; +extern uint32 g_iCycles; +extern bool g_bLandscape; +extern bool g_bLandLeft; +extern bool g_bCompat; +extern bool g_bAutoSkip; +extern bool g_bSmoothStretch; +extern HBITMAP g_hbmSkin; +extern HDC g_hSkinDC; +extern unsigned short *g_pKeypad; +extern uint32 g_iFrameSkip; +extern uint32 g_iSoundQuality; +extern bool g_bUseGameFolders; + +extern void SetKeypad(); +extern bool LoadState(); +extern bool SaveState(); +extern void StopEmulation(); +extern bool StartEmulation(HWND, HWND); +extern bool8_32 SaveSlot(int); +extern bool8_32 LoadSlot(int); +extern bool LoadOptions(); + + diff --git a/src/snes4iphone_src/port.h b/src/snes4iphone_src/port.h new file mode 100755 index 0000000..767bb6a --- /dev/null +++ b/src/snes4iphone_src/port.h @@ -0,0 +1,430 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#ifndef _PORT_H_ +#define _PORT_H_ + +/* +This port.h is really a right-of-passage for anyone trying to port the emulator + to another platform. It must have started out as a set of defines for a + single platform, and instead of using define blocks as new platforms were + added, individual coders simply added exceptions and sprinkled #ifdef and #ifndef + statements throughout the original list. + +I can't take it anymore, it's too convoluted. So I've commented out the entire + section, and preemptively rewritten the first #define segment the way god intended, + with a single define-block for each target platform. +*/ + +/* +** _SNESPPC DEFINES +*/ + +//Title +#define TITLE "Snes9x" + +//Required Includes +#include "pixform.h" +#include //RC +//#include +#include +#include +//Types Defined +typedef unsigned char bool8; +typedef unsigned char uint8; +typedef unsigned short uint16; +typedef unsigned int uint32; +typedef signed char int8; +typedef short int16; +typedef int int32; +typedef long long int64; + +//CSNES Types for conversion to 32 bit +/*typedef unsigned long bool8_32; +typedef unsigned long uint8_32; +typedef unsigned long uint16_32; +typedef long int8_32; +typedef long int16_32;*/ + +//For Debugging Purposes: + +typedef unsigned char bool8_32; +typedef unsigned char uint8_32; +typedef unsigned short uint16_32; +typedef signed char int8_32; +typedef short int16_32; + +//Defines for Extern C +#define EXTERN_C extern "C" +#define START_EXTERN_C extern "C" { +#define END_EXTERN_C } + +#define VOID void + +//Path Defines +#undef _MAX_PATH +#define _MAX_DIR PATH_MAX +#define _MAX_DRIVE 1 +#define _MAX_FNAME PATH_MAX +#define _MAX_EXT PATH_MAX +#define PATH_MAX 1024 +#define _MAX_PATH (1024) + +//True/False Defines +#define TRUE 1 +#define FALSE 0 + +//Slash Char Definitions +#define SLASH_STR "/" +#define SLASH_CHAR '/' + +//Misc Items +EXTERN_C void S9xGenerateSound (); + +//Misc Items +//#define LSB_FIRST +#define STATIC static +#define FASTCALL +#define PIXEL_FORMAT RGB565 +#define CHECK_SOUND() +#define ZeroMemory(a,b) memset((a),0,(b)) +#define PACKING __attribute__ ((packed)) +#define ALIGN_BY_ONE __attribute__ ((aligned (1), packed)) +#undef FAST_LSB_WORD_ACCESS + + +//Additional Items for _SNESPPC port +void _makepath (char *path, const char *drive, const char *dir, + const char *fname, const char *ext); +void _splitpath (const char *path, char *drive, char *dir, char *fname, + char *ext); +#define strcasecmp strcmp +#define strncasecmp strncmp +//#define time(a) (0) + +#ifdef INLINE +#undef INLINE +#define INLINE inline +#endif + +static inline void __memcpy4(void *d, void *s, unsigned long c) +{ + unsigned long *dl=(unsigned long *)d; + unsigned long *sl=(unsigned long *)s; + for (; c; --c) *dl++=*sl++; +} + +static inline void __memcpy4a(void *d, void *s, unsigned long c) +{ + unsigned long *dl=(unsigned long *)d; + unsigned long *sl=(unsigned long *)s; + for (; c; --c) *dl++=*sl++; +} + +static inline void memcpy32(void *d, void *s, unsigned long c) +{ + unsigned long *dl=(unsigned long *)d; + unsigned long *sl=(unsigned long *)s; + for (; c; --c) *dl++=*sl++; +} + +static inline void __memset4(void *d, unsigned long v, unsigned long c) +{ + unsigned long *dl=(unsigned long *)d; + for (; c; --c) *dl++=v; +} + +static inline void memset32(void *d, unsigned long v, unsigned long c) +{ + unsigned long *dl=(unsigned long *)d; + for (; c; --c) *dl++=v; +} + +static inline void memset16(void *d, unsigned short v, unsigned long c) +{ + unsigned short *dl=(unsigned short *)d; + for (; c; --c) *dl++=v; +} + +#endif // _PORT_H_ + +/* +#ifndef _SNESPPC +#define _SNESPPC +#endif + +#ifndef RC_OPTIMIZED +#define RC_OPTIMIZED +#endif + +#ifdef inline +#undef inline +#endif + +#ifdef INLINE +#undef INLINE +#endif + +#define inline __inline +#define INLINE __inline + +#ifdef DEBUG +#ifndef _PROFILE_ +#define _PROFILE_ +#endif +#endif + +#ifndef _SNESPPC +#ifndef STORM +#include +#include +#else +//#include +//#include +#endif + +#include +#else +#include +#endif + +#define PIXEL_FORMAT RGB565 +//#define GFX_MULTI_FORMAT + +#if defined(TARGET_OS_MAC) && TARGET_OS_MAC + +#ifdef _SNESPPC +#include "zlib/zlib.h" //RC +#else +#include "zlib.h" +#endif + +#define ZLIB +#define EXECUTE_SUPERFX_PER_LINE +#define SOUND +#define VAR_CYCLES +#define CPU_SHUTDOWN +#define SPC700_SHUTDOWN +#define PIXEL_FORMAT RGB555 +#define CHECK_SOUND() +#define M_PI 3.14159265359 +#undef _MAX_PATH + +#undef DEBUGGER // Apple Universal Headers sometimes #define DEBUGGER +#undef GFX_MULTI_FORMAT + +int strncasecmp(const char *s1, const char *s2, unsigned n); +int strcasecmp(const char *s1, const char *s2 ); + +#endif + +#ifndef snes9x_types_defined +#define snes9x_types_defined + +//CSNES +#ifdef _SNESPPC +typedef unsigned long bool8; +#else +typedef unsigned char bool8; +#endif + +#ifndef __WIN32__ +typedef unsigned char uint8; +typedef unsigned short uint16; +typedef signed char int8; +typedef short int16; +//typedef long int32; +//typedef unsigned long uint32; +typedef int int32; +typedef unsigned int uint32; +#ifdef _SNESPPC +typedef __int64 int64; +//CSNES +typedef unsigned long uint8_32; +typedef unsigned long uint16_32; +typedef long int8_32; +typedef long int16_32; + +#else +typedef long long int64; +#endif +#else // __WIN32__ + +#ifdef __BORLANDC__ +//#include +#else + +typedef unsigned char uint8; +typedef unsigned short uint16; +typedef signed char int8; +typedef short int16; + +#ifndef WSAAPI +// winsock2.h typedefs int32 as well. +typedef long int32; +#endif + +typedef unsigned int uint32; + +#endif // __BORLANDC__ + +typedef __int64 int64; + +#endif // __WIN32__ +#endif // snes9x_types_defined +#include "pixform.h" + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifdef STORM +#define EXTERN_C +#define START_EXTERN_C +#define END_EXTERN_C +#else +#if defined(__cplusplus) || defined(c_plusplus) +#define EXTERN_C extern "C" +#define START_EXTERN_C extern "C" { +#define END_EXTERN_C } +#else +#define EXTERN_C extern +#define START_EXTERN_C +#define END_EXTERN_C +#endif +#endif + +#ifndef __WIN32__ + +#ifndef PATH_MAX +#define PATH_MAX 1024 +#endif + +#define _MAX_DIR PATH_MAX +#define _MAX_DRIVE 1 +#define _MAX_FNAME PATH_MAX +#define _MAX_EXT PATH_MAX +#ifndef _MAX_PATH +#define _MAX_PATH PATH_MAX +#endif + +#ifdef _SNESPPC +#define strcasecmp strcmp +#define strncasecmp strncmp +#define time(a) (0) +#ifdef _MAX_PATH +#undef _MAX_PATH +#define _MAX_PATH (1024) +#endif +#endif + +#define ZeroMemory(a,b) memset((a),0,(b)) + +void _makepath (char *path, const char *drive, const char *dir, + const char *fname, const char *ext); +void _splitpath (const char *path, char *drive, char *dir, char *fname, + char *ext); +#else // __WIN32__ +#define strcasecmp stricmp +#define strncasecmp strnicmp +#endif + +EXTERN_C void S9xGenerateSound (); + +#ifdef STORM +EXTERN_C int soundsignal; +EXTERN_C void MixSound(void); +//Yes, CHECK_SOUND is getting defined correctly! +#define CHECK_SOUND if (Settings.APUEnabled) if(SetSignalPPC(0L, soundsignal) & soundsignal) MixSound +#else +#define CHECK_SOUND() +#endif + +#ifdef __DJGPP +#define SLASH_STR "\\" +#define SLASH_CHAR '\\' +#else +#define SLASH_STR "/" +#define SLASH_CHAR '/' +#endif + +#ifdef __linux +typedef void (*SignalHandler)(int); +#define SIG_PF SignalHandler +#endif + +#if defined(__i386__) || defined(__i486__) || defined(__i586__) || \ + defined(__WIN32__) || defined(__alpha__) +#define LSB_FIRST +#define FAST_LSB_WORD_ACCESS +#else +#ifdef _SNESPPC +#define LSB_FIRST +//NOPE! #define FAST_LSB_WORD_ACCESS //RC +#else +#define MSB_FIRST +#endif +#endif + +#ifdef __sun +#define TITLE "Snes9X: Solaris" +#endif + +#ifdef __linux +#define TITLE "Snes9X: Linux" +#endif + +#ifndef TITLE +#define TITLE "Snes9x" +#endif + +#ifdef STORM +#define STATIC +#define strncasecmp strnicmp +#else +#define STATIC static +#endif + +#endif +*/ diff --git a/src/snes4iphone_src/ppu.cpp b/src/snes4iphone_src/ppu.cpp new file mode 100755 index 0000000..77bf483 --- /dev/null +++ b/src/snes4iphone_src/ppu.cpp @@ -0,0 +1,2773 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#include "snes9x.h" +#include "memmap.h" +#include "ppu.h" +#include "cpuexec.h" +#include "missing.h" +#include "apu.h" +#include "dma.h" +#include "gfx.h" +#include "display.h" +#include "sa1.h" +#ifndef _SNESPPC +//#include "netplay.h" +#endif +#include "sdd1.h" +#include "srtc.h" + +#include "port.h" + +#ifndef ZSNES_FX +#include "fxemu.h" +#include "fxinst.h" +extern struct FxInit_s SuperFX; +extern struct FxRegs_s GSU; +#else +EXTERN_C void S9xSuperFXWriteReg (uint8, uint32); +EXTERN_C uint8 S9xSuperFXReadReg (uint32); +#endif + +void S9xUpdateHTimer () +{ + if (PPU.HTimerEnabled) + { +#ifdef DEBUGGER + missing.hirq_pos = PPU.IRQHBeamPos; +#endif + PPU.HTimerPosition = PPU.IRQHBeamPos * Settings.H_Max / SNES_HCOUNTER_MAX; + if (PPU.HTimerPosition == Settings.H_Max || + PPU.HTimerPosition == Settings.HBlankStart) + { + PPU.HTimerPosition--; + } + + if (!PPU.VTimerEnabled || CPU.V_Counter == PPU.IRQVBeamPos) + { + if (PPU.HTimerPosition < CPU.Cycles) + { + // Missed the IRQ on this line already + if (CPU.WhichEvent == HBLANK_END_EVENT || + CPU.WhichEvent == HTIMER_AFTER_EVENT) + { + CPU.WhichEvent = HBLANK_END_EVENT; + CPU.NextEvent = Settings.H_Max; + } + else + { + CPU.WhichEvent = HBLANK_START_EVENT; + CPU.NextEvent = Settings.HBlankStart; + } + } + else + { + if (CPU.WhichEvent == HTIMER_BEFORE_EVENT || + CPU.WhichEvent == HBLANK_START_EVENT) + { + if (PPU.HTimerPosition > Settings.HBlankStart) + { + // HTimer was to trigger before h-blank start, + // now triggers after start of h-blank + CPU.NextEvent = Settings.HBlankStart; + CPU.WhichEvent = HBLANK_START_EVENT; + } + else + { + CPU.NextEvent = PPU.HTimerPosition; + CPU.WhichEvent = HTIMER_BEFORE_EVENT; + } + } + else + { + CPU.WhichEvent = HTIMER_AFTER_EVENT; + CPU.NextEvent = PPU.HTimerPosition; + } + } + } + } +} + +void S9xFixColourBrightness () +{ + IPPU.XB = mul_brightness [PPU.Brightness]; +#ifndef _SNESPPC + if (Settings.SixteenBit) +#endif + { + for (int i = 0; i < 256; i++) + { + IPPU.Red [i] = IPPU.XB [PPU.CGDATA [i] & 0x1f]; + IPPU.Green [i] = IPPU.XB [(PPU.CGDATA [i] >> 5) & 0x1f]; + IPPU.Blue [i] = IPPU.XB [(PPU.CGDATA [i] >> 10) & 0x1f]; + IPPU.ScreenColors [i] = BUILD_PIXEL (IPPU.Red [i], IPPU.Green [i], + IPPU.Blue [i]); + } + } +} + +/**********************************************************************************************/ +/* S9xSetPPU() */ +/* This function sets a PPU Register to a specific byte */ +/**********************************************************************************************/ +void S9xSetPPU(uint8 Byte, uint16 Address) +{ + if (Address <= 0x2183) + { + switch (Address) + { + case 0x2100 : + // Brightness and screen blank bit + if (Byte != Memory.FillRAM[0x2100]) + { + FLUSH_REDRAW(); + if (PPU.Brightness != (Byte & 0xF)) + { + IPPU.ColorsChanged = TRUE; + IPPU.DirectColourMapsNeedRebuild = TRUE; + PPU.Brightness = Byte & 0xF; + S9xFixColourBrightness(); + if (PPU.Brightness > IPPU.MaxBrightness) + IPPU.MaxBrightness = PPU.Brightness; + } + if ((Memory.FillRAM[0x2100] & 0x80) != (Byte & 0x80)) + { + IPPU.ColorsChanged = TRUE; + PPU.ForcedBlanking = (Byte >> 7) & 1; + } + } + break; + + case 0x2101 : + // Sprite (OBJ) tile address + if (Byte != Memory.FillRAM[0x2101]) + { + FLUSH_REDRAW(); + PPU.OBJNameBase = (Byte & 3) << 14; + PPU.OBJNameSelect = ((Byte >> 3) & 3) << 13; + PPU.OBJSizeSelect = (Byte >> 5) & 7; + IPPU.OBJChanged = TRUE; + } + break; + + case 0x2102 : + // Sprite write address (low) + PPU.OAMAddr = Byte; + PPU.OAMFlip = 2; + PPU.OAMReadFlip = 0; + PPU.SavedOAMAddr = PPU.OAMAddr; + if (PPU.OAMPriorityRotation) + { + PPU.FirstSprite = PPU.OAMAddr & 0x7f; +#ifdef DEBUGGER + missing.sprite_priority_rotation = 1; +#endif + } + break; + + case 0x2103 : + // Sprite register write address (high), sprite priority rotation + // bit. + if ((PPU.OAMPriorityRotation = (Byte & 0x80) == 0 ? 0 : 1)) + { + PPU.FirstSprite = PPU.OAMAddr & 0x7f; +#ifdef DEBUGGER + missing.sprite_priority_rotation = 1; +#endif + } + // Only update the sprite write address top bit if the low byte has + // been written to first. + if (PPU.OAMFlip & 2) + { + PPU.OAMAddr &= 0x00FF; + PPU.OAMAddr |= (Byte & 1) << 8; + } + PPU.OAMFlip = 0; + PPU.OAMReadFlip = 0; + PPU.SavedOAMAddr = PPU.OAMAddr; + break; + + case 0x2104 : + // Sprite register write + REGISTER_2104(Byte); + + break; + + case 0x2105 : + // Screen mode (0 - 7), background tile sizes and background 3 + // priority + if (Byte != Memory.FillRAM[0x2105]) + { + FLUSH_REDRAW(); + PPU.BG[0].BGSize = (Byte >> 4) & 1; + PPU.BG[1].BGSize = (Byte >> 5) & 1; + PPU.BG[2].BGSize = (Byte >> 6) & 1; + PPU.BG[3].BGSize = (Byte >> 7) & 1; + PPU.BGMode = Byte & 7; + // BJ: BG3Priority only takes effect if BGMode==1 and the bit is set + PPU.BG3Priority = ((Byte & 0x0f) == 0x09); +#ifdef DEBUGGER + missing.modes[PPU.BGMode] = 1; +#endif + } + break; + + case 0x2106 : + // Mosaic pixel size and enable + if (Byte != Memory.FillRAM[0x2106]) + { + FLUSH_REDRAW(); +#ifdef DEBUGGER + if ((Byte & 0xf0) && (Byte & 0x0f)) + missing.mosaic = 1; +#endif + PPU.Mosaic = (Byte >> 4) + 1; + PPU.BGMosaic[0] = (Byte & 1) && PPU.Mosaic > 1; + PPU.BGMosaic[1] = (Byte & 2) && PPU.Mosaic > 1; + PPU.BGMosaic[2] = (Byte & 4) && PPU.Mosaic > 1; + PPU.BGMosaic[3] = (Byte & 8) && PPU.Mosaic > 1; + } + break; + case 0x2107 : // [BG0SC] + if (Byte != Memory.FillRAM[0x2107]) + { + FLUSH_REDRAW(); + PPU.BG[0].SCSize = Byte & 3; + PPU.BG[0].SCBase = (Byte & 0x7c) << 8; + } + break; + + case 0x2108 : // [BG1SC] + if (Byte != Memory.FillRAM[0x2108]) + { + FLUSH_REDRAW(); + PPU.BG[1].SCSize = Byte & 3; + PPU.BG[1].SCBase = (Byte & 0x7c) << 8; + } + break; + + case 0x2109 : // [BG2SC] + if (Byte != Memory.FillRAM[0x2109]) + { + FLUSH_REDRAW(); + PPU.BG[2].SCSize = Byte & 3; + PPU.BG[2].SCBase = (Byte & 0x7c) << 8; + } + break; + + case 0x210A : // [BG3SC] + if (Byte != Memory.FillRAM[0x210a]) + { + FLUSH_REDRAW(); + PPU.BG[3].SCSize = Byte & 3; + PPU.BG[3].SCBase = (Byte & 0x7c) << 8; + } + break; + + case 0x210B : // [BG01NBA] + if (Byte != Memory.FillRAM[0x210b]) + { + FLUSH_REDRAW(); + PPU.BG[0].NameBase = (Byte & 7) << 12; + PPU.BG[1].NameBase = ((Byte >> 4) & 7) << 12; + } + break; + + case 0x210C : // [BG23NBA] + if (Byte != Memory.FillRAM[0x210c]) + { + FLUSH_REDRAW(); + PPU.BG[2].NameBase = (Byte & 7) << 12; + PPU.BG[3].NameBase = ((Byte >> 4) & 7) << 12; + } + break; + + case 0x210D : + PPU.BG[0].HOffset = + ((PPU.BG[0].HOffset >> 8) & 0xff) | ((uint16) Byte << 8); + break; + + case 0x210E : + PPU.BG[0].VOffset = + ((PPU.BG[0].VOffset >> 8) & 0xff) | ((uint16) Byte << 8); + break; + case 0x210F : + PPU.BG[1].HOffset = + ((PPU.BG[1].HOffset >> 8) & 0xff) | ((uint16) Byte << 8); + break; + + case 0x2110 : + PPU.BG[1].VOffset = + ((PPU.BG[1].VOffset >> 8) & 0xff) | ((uint16) Byte << 8); + break; + + case 0x2111 : + PPU.BG[2].HOffset = + ((PPU.BG[2].HOffset >> 8) & 0xff) | ((uint16) Byte << 8); + break; + + case 0x2112 : + PPU.BG[2].VOffset = + ((PPU.BG[2].VOffset >> 8) & 0xff) | ((uint16) Byte << 8); + break; + + case 0x2113 : + PPU.BG[3].HOffset = + ((PPU.BG[3].HOffset >> 8) & 0xff) | ((uint16) Byte << 8); + break; + + case 0x2114 : + PPU.BG[3].VOffset = + ((PPU.BG[3].VOffset >> 8) & 0xff) | ((uint16) Byte << 8); + break; + + case 0x2115 : + // VRAM byte/word access flag and increment + PPU.VMA.High = (Byte & 0x80) == 0 ? FALSE : TRUE; + switch (Byte & 3) + { + case 0 : + PPU.VMA.Increment = 1; + break; + case 1 : + PPU.VMA.Increment = 32; + break; + case 2 : + PPU.VMA.Increment = 128; + break; + case 3 : + PPU.VMA.Increment = 128; + break; + } +#ifdef DEBUGGER + if ((Byte & 3) != 0) + missing.vram_inc = Byte & 3; +#endif + if (Byte & 0x0c) + { + static uint16 IncCount[4] = { 0, 32, 64, 128 }; + static uint16 Shift[4] = { 0, 5, 6, 7 }; +#ifdef DEBUGGER + missing.vram_full_graphic_inc = + (Byte & 0x0c) >> 2; +#endif + PPU.VMA.Increment = 1; + uint8 i = (Byte & 0x0c) >> 2; + PPU.VMA.FullGraphicCount = IncCount[i]; + PPU.VMA.Mask1 = IncCount[i] * 8 - 1; + PPU.VMA.Shift = Shift[i]; + } + else + PPU.VMA.FullGraphicCount = 0; + break; + + case 0x2116 : + // VRAM read/write address (low) + PPU.VMA.Address &= 0xFF00; + PPU.VMA.Address |= Byte; + IPPU.FirstVRAMRead = TRUE; + break; + + case 0x2117 : + // VRAM read/write address (high) + PPU.VMA.Address &= 0x00FF; + PPU.VMA.Address |= Byte << 8; + IPPU.FirstVRAMRead = TRUE; + break; + + case 0x2118 : + // VRAM write data (low) + IPPU.FirstVRAMRead = TRUE; + REGISTER_2118(Byte); + break; + + case 0x2119 : + // VRAM write data (high) + IPPU.FirstVRAMRead = TRUE; + REGISTER_2119(Byte); + break; + + case 0x211a : + // Mode 7 outside rotation area display mode and flipping + if (Byte != Memory.FillRAM[0x211a]) + { + FLUSH_REDRAW(); + PPU.Mode7Repeat = Byte >> 6; + PPU.Mode7VFlip = (Byte & 2) >> 1; + PPU.Mode7HFlip = Byte & 1; + } + break; + case 0x211b : + // Mode 7 matrix A (low & high) + PPU.MatrixA = ((PPU.MatrixA >> 8) & 0xff) | (Byte << 8); + PPU.Need16x8Mulitply = TRUE; + break; + case 0x211c : + // Mode 7 matrix B (low & high) + PPU.MatrixB = ((PPU.MatrixB >> 8) & 0xff) | (Byte << 8); + PPU.Need16x8Mulitply = TRUE; + break; + case 0x211d : + // Mode 7 matrix C (low & high) + PPU.MatrixC = ((PPU.MatrixC >> 8) & 0xff) | (Byte << 8); + break; + case 0x211e : + // Mode 7 matrix D (low & high) + PPU.MatrixD = ((PPU.MatrixD >> 8) & 0xff) | (Byte << 8); + break; + case 0x211f : + // Mode 7 centre of rotation X (low & high) + PPU.CentreX = ((PPU.CentreX >> 8) & 0xff) | (Byte << 8); + break; + case 0x2120 : + // Mode 7 centre of rotation Y (low & high) + PPU.CentreY = ((PPU.CentreY >> 8) & 0xff) | (Byte << 8); + break; + + case 0x2121 : + // CG-RAM address + PPU.CGFLIP = 0; + PPU.CGFLIPRead = 0; + PPU.CGADD = Byte; + break; + + case 0x2122 : + REGISTER_2122(Byte); + break; + + case 0x2123 : + // Window 1 and 2 enable for backgrounds 1 and 2 + if (Byte != Memory.FillRAM[0x2123]) + { + FLUSH_REDRAW(); + + PPU.ClipWindow1Enable[0] = !!(Byte & 0x02); + PPU.ClipWindow1Enable[1] = !!(Byte & 0x20); + PPU.ClipWindow2Enable[0] = !!(Byte & 0x08); + PPU.ClipWindow2Enable[1] = !!(Byte & 0x80); + PPU.ClipWindow1Inside[0] = !(Byte & 0x01); + PPU.ClipWindow1Inside[1] = !(Byte & 0x10); + PPU.ClipWindow2Inside[0] = !(Byte & 0x04); + PPU.ClipWindow2Inside[1] = !(Byte & 0x40); + PPU.RecomputeClipWindows = TRUE; +#ifdef DEBUGGER + if (Byte & 0x80) + missing.window2[1] = 1; + if (Byte & 0x20) + missing.window1[1] = 1; + if (Byte & 0x08) + missing.window2[0] = 1; + if (Byte & 0x02) + missing.window1[0] = 1; +#endif + } + break; + case 0x2124 : + // Window 1 and 2 enable for backgrounds 3 and 4 + if (Byte != Memory.FillRAM[0x2124]) + { + FLUSH_REDRAW(); + + PPU.ClipWindow1Enable[2] = !!(Byte & 0x02); + PPU.ClipWindow1Enable[3] = !!(Byte & 0x20); + PPU.ClipWindow2Enable[2] = !!(Byte & 0x08); + PPU.ClipWindow2Enable[3] = !!(Byte & 0x80); + PPU.ClipWindow1Inside[2] = !(Byte & 0x01); + PPU.ClipWindow1Inside[3] = !(Byte & 0x10); + PPU.ClipWindow2Inside[2] = !(Byte & 0x04); + PPU.ClipWindow2Inside[3] = !(Byte & 0x40); + PPU.RecomputeClipWindows = TRUE; +#ifdef DEBUGGER + if (Byte & 0x80) + missing.window2[3] = 1; + if (Byte & 0x20) + missing.window1[3] = 1; + if (Byte & 0x08) + missing.window2[2] = 1; + if (Byte & 0x02) + missing.window1[2] = 1; +#endif + } + break; + case 0x2125 : + // Window 1 and 2 enable for objects and colour window + if (Byte != Memory.FillRAM[0x2125]) + { + FLUSH_REDRAW(); + + PPU.ClipWindow1Enable[4] = !!(Byte & 0x02); + PPU.ClipWindow1Enable[5] = !!(Byte & 0x20); + PPU.ClipWindow2Enable[4] = !!(Byte & 0x08); + PPU.ClipWindow2Enable[5] = !!(Byte & 0x80); + PPU.ClipWindow1Inside[4] = !(Byte & 0x01); + PPU.ClipWindow1Inside[5] = !(Byte & 0x10); + PPU.ClipWindow2Inside[4] = !(Byte & 0x04); + PPU.ClipWindow2Inside[5] = !(Byte & 0x40); + PPU.RecomputeClipWindows = TRUE; +#ifdef DEBUGGER + if (Byte & 0x80) + missing.window2[5] = 1; + if (Byte & 0x20) + missing.window1[5] = 1; + if (Byte & 0x08) + missing.window2[4] = 1; + if (Byte & 0x02) + missing.window1[4] = 1; +#endif + } + break; + case 0x2126 : + // Window 1 left position + if (Byte != Memory.FillRAM[0x2126]) + { + FLUSH_REDRAW(); + + PPU.Window1Left = Byte; + PPU.RecomputeClipWindows = TRUE; + } + break; + case 0x2127 : + // Window 1 right position + if (Byte != Memory.FillRAM[0x2127]) + { + FLUSH_REDRAW(); + + PPU.Window1Right = Byte; + PPU.RecomputeClipWindows = TRUE; + } + break; + case 0x2128 : + // Window 2 left position + if (Byte != Memory.FillRAM[0x2128]) + { + FLUSH_REDRAW(); + + PPU.Window2Left = Byte; + PPU.RecomputeClipWindows = TRUE; + } + break; + case 0x2129 : + // Window 2 right position + if (Byte != Memory.FillRAM[0x2129]) + { + FLUSH_REDRAW(); + + PPU.Window2Right = Byte; + PPU.RecomputeClipWindows = TRUE; + } + break; + case 0x212a : + // Windows 1 & 2 overlap logic for backgrounds 1 - 4 + if (Byte != Memory.FillRAM[0x212a]) + { + FLUSH_REDRAW(); + + PPU.ClipWindowOverlapLogic[0] = (Byte & 0x03); + PPU.ClipWindowOverlapLogic[1] = (Byte & 0x0c) >> 2; + PPU.ClipWindowOverlapLogic[2] = (Byte & 0x30) >> 4; + PPU.ClipWindowOverlapLogic[3] = (Byte & 0xc0) >> 6; + PPU.RecomputeClipWindows = TRUE; + } + break; + case 0x212b : + // Windows 1 & 2 overlap logic for objects and colour window + if (Byte != Memory.FillRAM[0x212b]) + { + FLUSH_REDRAW(); + + PPU.ClipWindowOverlapLogic[4] = Byte & 0x03; + PPU.ClipWindowOverlapLogic[5] = (Byte & 0x0c) >> 2; + PPU.RecomputeClipWindows = TRUE; + } + break; + case 0x212c : + // Main screen designation (backgrounds 1 - 4 and objects) + if (Byte != Memory.FillRAM[0x212c]) + { + FLUSH_REDRAW(); + + PPU.RecomputeClipWindows = TRUE; + Memory.FillRAM[Address] = Byte; + return; + } + break; + case 0x212d : + // Sub-screen designation (backgrounds 1 - 4 and objects) + if (Byte != Memory.FillRAM[0x212d]) + { + FLUSH_REDRAW(); + +#ifdef DEBUGGER + if (Byte & 0x1f) + missing.subscreen = 1; +#endif + PPU.RecomputeClipWindows = TRUE; + Memory.FillRAM[Address] = Byte; + return; + } + break; + case 0x212e : + // Window mask designation for main screen ? + if (Byte != Memory.FillRAM[0x212e]) + { + FLUSH_REDRAW(); + + PPU.RecomputeClipWindows = TRUE; + } + break; + case 0x212f : + // Window mask designation for sub-screen ? + if (Byte != Memory.FillRAM[0x212f]) + { + FLUSH_REDRAW(); + + PPU.RecomputeClipWindows = TRUE; + } + break; + case 0x2130 : + // Fixed colour addition or screen addition + if (Byte != Memory.FillRAM[0x2130]) + { + FLUSH_REDRAW(); + + PPU.RecomputeClipWindows = TRUE; +#ifdef DEBUGGER + if ((Byte & 1) && (PPU.BGMode == 3 || PPU.BGMode == 4 + || PPU.BGMode == 7)) + missing.direct = 1; +#endif + } + break; + case 0x2131 : + // Colour addition or subtraction select + if (Byte != Memory.FillRAM[0x2131]) + { + FLUSH_REDRAW(); + + // Backgrounds 1 - 4, objects and backdrop colour add/sub enable +#ifdef DEBUGGER + if (Byte & 0x80) + { + // Subtract + if (Memory.FillRAM[0x2130] & 0x02) + missing.subscreen_sub = 1; + else + missing.fixed_colour_sub = 1; + } + else + { + // Addition + if (Memory.FillRAM[0x2130] & 0x02) + missing.subscreen_add = 1; + else + missing.fixed_colour_add = 1; + } +#endif + Memory.FillRAM[0x2131] = Byte; + } + break; + case 0x2132 : + if (Byte != Memory.FillRAM[0x2132]) + { + FLUSH_REDRAW(); + + // Colour data for fixed colour addition/subtraction + if (Byte & 0x80) + PPU.FixedColourBlue = Byte & 0x1f; + if (Byte & 0x40) + PPU.FixedColourGreen = Byte & 0x1f; + if (Byte & 0x20) + PPU.FixedColourRed = Byte & 0x1f; + } + break; + case 0x2133 : + // Screen settings + if (Byte != Memory.FillRAM[0x2133]) + { +#ifdef DEBUGGER + if (Byte & 0x40) + missing.mode7_bgmode = 1; + if (Byte & 0x08) + missing.pseudo_512 = 1; +#endif + if (Byte & 0x04) + { + PPU.ScreenHeight = SNES_HEIGHT_EXTENDED; +#ifdef DEBUGGER + missing.lines_239 = 1; +#endif + } + else + PPU.ScreenHeight = SNES_HEIGHT; +#ifdef DEBUGGER + if (Byte & 0x02) + missing.sprite_double_height = 1; + + if (Byte & 1) + missing.interlace = 1; +#endif + } + break; + case 0x2134 : + case 0x2135 : + case 0x2136 : + // Matrix 16bit x 8bit multiply result (read-only) + return; + + case 0x2137 : + // Software latch for horizontal and vertical timers (read-only) + return; + case 0x2138 : + // OAM read data (read-only) + return; + case 0x2139 : + case 0x213a : + // VRAM read data (read-only) + return; + case 0x213b : + // CG-RAM read data (read-only) + return; + case 0x213c : + case 0x213d : + // Horizontal and vertical (low/high) read counter (read-only) + return; + case 0x213e : + // PPU status (time over and range over) + return; + case 0x213f : + // NTSC/PAL select and field (read-only) + return; + case 0x2140 : + case 0x2141 : + case 0x2142 : + case 0x2143 : + case 0x2144 : + case 0x2145 : + case 0x2146 : + case 0x2147 : + case 0x2148 : + case 0x2149 : + case 0x214a : + case 0x214b : + case 0x214c : + case 0x214d : + case 0x214e : + case 0x214f : + case 0x2150 : + case 0x2151 : + case 0x2152 : + case 0x2153 : + case 0x2154 : + case 0x2155 : + case 0x2156 : + case 0x2157 : + case 0x2158 : + case 0x2159 : + case 0x215a : + case 0x215b : + case 0x215c : + case 0x215d : + case 0x215e : + case 0x215f : + case 0x2160 : + case 0x2161 : + case 0x2162 : + case 0x2163 : + case 0x2164 : + case 0x2165 : + case 0x2166 : + case 0x2167 : + case 0x2168 : + case 0x2169 : + case 0x216a : + case 0x216b : + case 0x216c : + case 0x216d : + case 0x216e : + case 0x216f : + case 0x2170 : + case 0x2171 : + case 0x2172 : + case 0x2173 : + case 0x2174 : + case 0x2175 : + case 0x2176 : + case 0x2177 : + case 0x2178 : + case 0x2179 : + case 0x217a : + case 0x217b : + case 0x217c : + case 0x217d : + case 0x217e : + case 0x217f : +#ifdef SPCTOOL + _SPCInPB(Address & 3, Byte); +#else + // CPU.Flags |= DEBUG_MODE_FLAG; + Memory.FillRAM[Address] = Byte; + IAPU.RAM[(Address & 3) + 0xf4] = Byte; + #ifdef SPC700_SHUTDOWN + CPU.APU_APUExecuting = Settings.APUEnabled; + IAPU.WaitCounter++; + #endif +#endif // SPCTOOL + break; + case 0x2180 : + REGISTER_2180(Byte); + break; + case 0x2181 : + PPU.WRAM &= 0x1FF00; + PPU.WRAM |= Byte; + break; + case 0x2182 : + PPU.WRAM &= 0x100FF; + PPU.WRAM |= Byte << 8; + break; + case 0x2183 : + PPU.WRAM &= 0x0FFFF; + PPU.WRAM |= Byte << 16; + PPU.WRAM &= 0x1FFFF; + break; + } + } + else + { +#ifdef USE_SA1 + if (Settings.SA1) + { + if (Address >= 0x2200 && Address < 0x23ff) + S9xSetSA1(Byte, Address); + else + Memory.FillRAM[Address] = Byte; + return; + } + else +#endif + // Dai Kaijyu Monogatari II + if (Address == 0x2801 && Settings.SRTC) + S9xSetSRTC(Byte, Address); + else if (Address < 0x3000 || Address >= 0x3000 + 768) + { +#ifdef DEBUGGER + missing.unknownppu_write = Address; + if (Settings.TraceUnknownRegisters) + { + sprintf( + String, + "Unknown register write: $%02X->$%04X\n", + Byte, + Address); + S9xMessage(S9X_TRACE, S9X_PPU_TRACE, String); + } +#endif + } + else + { + if (!Settings.SuperFX) + return; + + switch (Address) + { + case 0x3030 : + if ((Memory.FillRAM[0x3030] ^ Byte) & FLG_G) + { + Memory.FillRAM[Address] = Byte; + // Go flag has been changed + if (Byte & FLG_G) + S9xSuperFXExec(); + else + FxFlushCache(); + } + else + Memory.FillRAM[Address] = Byte; + break; + + case 0x3031 : + Memory.FillRAM[Address] = Byte; + break; + case 0x3033 : + Memory.FillRAM[Address] = Byte; + break; + case 0x3034 : + Memory.FillRAM[Address] = Byte & 0x7f; + break; + case 0x3036 : + Memory.FillRAM[Address] = Byte & 0x7f; + break; + case 0x3037 : + Memory.FillRAM[Address] = Byte; + break; + case 0x3038 : + Memory.FillRAM[Address] = Byte; + break; + case 0x3039 : + Memory.FillRAM[Address] = Byte; + break; + case 0x303a : + Memory.FillRAM[Address] = Byte; + break; + case 0x303b : + break; + case 0x303f : + Memory.FillRAM[Address] = Byte; + break; + case 0x301f : + Memory.FillRAM[Address] = Byte; + Memory.FillRAM[0x3000 + GSU_SFR] |= FLG_G; + S9xSuperFXExec(); + return; + + default : + Memory.FillRAM[Address] = Byte; + if (Address >= 0x3100) + { + FxCacheWriteAccess(Address); + } + break; + } + return; + } + } + Memory.FillRAM[Address] = Byte; +} + +/**********************************************************************************************/ +/* S9xGetPPU() */ +/* This function retrieves a PPU Register */ +/**********************************************************************************************/ +uint8 S9xGetPPU(uint16 Address) +{ + uint8 byte = 0; + + if (Address <= 0x2190) + { + switch (Address) + { + case 0x2100 : + case 0x2101 : + return (Memory.FillRAM[Address]); + case 0x2102 : +#ifdef DEBUGGER + missing.oam_address_read = 1; +#endif + return (uint8) (PPU.OAMAddr); + case 0x2103 : + return (((PPU.OAMAddr >> 8) & 1) | (PPU.OAMPriorityRotation << 7)); + case 0x2104 : + case 0x2105 : + case 0x2106 : + case 0x2107 : + case 0x2108 : + case 0x2109 : + case 0x210a : + case 0x210b : + case 0x210c : + return (Memory.FillRAM[Address]); + case 0x210d : + case 0x210e : + case 0x210f : + case 0x2110 : + case 0x2111 : + case 0x2112 : + case 0x2113 : + case 0x2114 : +#ifdef DEBUGGER + missing.bg_offset_read = 1; +#endif + return (Memory.FillRAM[Address]); + case 0x2115 : + return (Memory.FillRAM[Address]); + case 0x2116 : + return (uint8) (PPU.VMA.Address); + case 0x2117 : + return (PPU.VMA.Address >> 8); + case 0x2118 : + case 0x2119 : + case 0x211a : + return (Memory.FillRAM[Address]); + case 0x211b : + case 0x211c : + case 0x211d : + case 0x211e : + case 0x211f : + case 0x2120 : +#ifdef DEBUGGER + missing.matrix_read = 1; +#endif + return (Memory.FillRAM[Address]); + case 0x2121 : + return (PPU.CGADD); + case 0x2122 : + case 0x2123 : + case 0x2124 : + case 0x2125 : + case 0x2126 : + case 0x2127 : + case 0x2128 : + case 0x2129 : + case 0x212a : + case 0x212b : + case 0x212c : + case 0x212d : + case 0x212e : + case 0x212f : + case 0x2130 : + case 0x2131 : + case 0x2132 : + case 0x2133 : + return (Memory.FillRAM[Address]); + + case 0x2134 : + case 0x2135 : + case 0x2136 : + // 16bit x 8bit multiply read result. + if (PPU.Need16x8Mulitply) + { + int32 r = (int32) PPU.MatrixA * (int32) (PPU.MatrixB >> 8); + + Memory.FillRAM[0x2134] = (uint8) r; + Memory.FillRAM[0x2135] = (uint8) (r >> 8); + Memory.FillRAM[0x2136] = (uint8) (r >> 16); + PPU.Need16x8Mulitply = FALSE; + } +#ifdef DEBUGGER + missing.matrix_multiply = 1; +#endif + return (Memory.FillRAM[Address]); + case 0x2137 : + // Latch h and v counters +#ifdef DEBUGGER + missing.h_v_latch = 1; +#endif +#if 0 + #ifdef CPU_SHUTDOWN + CPU.WaitAddress = CPU.PCAtOpcodeStart; + #endif +#endif + PPU.HVBeamCounterLatched = 1; + PPU.VBeamPosLatched = (uint16) + CPU.V_Counter; + PPU.HBeamPosLatched = (uint16) ((CPU.Cycles * SNES_HCOUNTER_MAX) / Settings.H_Max); + + // Causes screen flicker for Yoshi's Island if uncommented + //CLEAR_IRQ_SOURCE (PPU_V_BEAM_IRQ_SOURCE | PPU_H_BEAM_IRQ_SOURCE); + + if (SNESGameFixes.NeedInit0x2137) + PPU.VBeamFlip = 0; //jyam sword world sfc2 & godzill + return (0); + case 0x2138 : + // Read OAM (sprite) control data + if (!PPU.OAMReadFlip) + { + byte = PPU.OAMData[PPU.OAMAddr << 1]; + } + else + { + byte = PPU.OAMData[(PPU.OAMAddr << 1) + 1]; + if (++PPU.OAMAddr >= 0x110) + PPU.OAMAddr = 0; + } + PPU.OAMReadFlip ^= 1; +#ifdef DEBUGGER + missing.oam_read = 1; +#endif + return (byte); + + case 0x2139 : + // Read vram low byte +#ifdef DEBUGGER + missing.vram_read = 1; +#endif + if (IPPU.FirstVRAMRead) + byte = Memory.VRAM[PPU.VMA.Address << 1]; + else if (PPU.VMA.FullGraphicCount) + { + uint32 addr = PPU.VMA.Address - 1; + uint32 rem = addr & PPU.VMA.Mask1; + uint32 address = + (addr & ~PPU.VMA.Mask1) + + (rem >> PPU.VMA.Shift) + + ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3); + byte = Memory.VRAM[((address << 1) - 2) & 0xFFFF]; + } + else + byte = Memory.VRAM[((PPU.VMA.Address << 1) - 2) & 0xffff]; + + if (!PPU.VMA.High) + { + PPU.VMA.Address += PPU.VMA.Increment; + IPPU.FirstVRAMRead = FALSE; + } + break; + case 0x213A : + // Read vram high byte +#ifdef DEBUGGER + missing.vram_read = 1; +#endif + if (IPPU.FirstVRAMRead) + byte = Memory.VRAM[((PPU.VMA.Address << 1) + 1) & 0xffff]; + else if (PPU.VMA.FullGraphicCount) + { + uint32 addr = PPU.VMA.Address - 1; + uint32 rem = addr & PPU.VMA.Mask1; + uint32 address = + (addr & ~PPU.VMA.Mask1) + + (rem >> PPU.VMA.Shift) + + ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3); + byte = Memory.VRAM[((address << 1) - 1) & 0xFFFF]; + } + else + byte = Memory.VRAM[((PPU.VMA.Address << 1) - 1) & 0xFFFF]; + if (PPU.VMA.High) + { + PPU.VMA.Address += PPU.VMA.Increment; + IPPU.FirstVRAMRead = FALSE; + } + break; + + case 0x213B : + // Read palette data +#ifdef DEBUGGER + missing.cgram_read = 1; +#endif + if (PPU.CGFLIPRead) + byte = PPU.CGDATA[PPU.CGADD++] >> 8; + else + byte = PPU.CGDATA[PPU.CGADD] & 0xff; + + PPU.CGFLIPRead ^= 1; + return (byte); + + case 0x213C : + // Horizontal counter value 0-339 +#ifdef DEBUGGER + missing.h_counter_read = 1; +#endif + if (PPU.HBeamFlip) + byte = PPU.HBeamPosLatched >> 8; + else + byte = (uint8) PPU.HBeamPosLatched; + PPU.HBeamFlip ^= 1; + break; + case 0x213D : + // Vertical counter value 0-262 +#ifdef DEBUGGER + missing.v_counter_read = 1; +#endif + if (PPU.VBeamFlip) + byte = PPU.VBeamPosLatched >> 8; + else + byte = (uint8) PPU.VBeamPosLatched; + PPU.VBeamFlip ^= 1; + break; + case 0x213E : + // PPU time and range over flags + return (SNESGameFixes._0x213E_ReturnValue); + + case 0x213F : + // NTSC/PAL and which field flags + PPU.VBeamFlip = PPU.HBeamFlip = 0; + return ((Settings.PAL ? 0x10 : 0) | (Memory.FillRAM[0x213f] & 0xc0)); + + case 0x2140 : + case 0x2141 : + case 0x2142 : + case 0x2143 : + case 0x2144 : + case 0x2145 : + case 0x2146 : + case 0x2147 : + case 0x2148 : + case 0x2149 : + case 0x214a : + case 0x214b : + case 0x214c : + case 0x214d : + case 0x214e : + case 0x214f : + case 0x2150 : + case 0x2151 : + case 0x2152 : + case 0x2153 : + case 0x2154 : + case 0x2155 : + case 0x2156 : + case 0x2157 : + case 0x2158 : + case 0x2159 : + case 0x215a : + case 0x215b : + case 0x215c : + case 0x215d : + case 0x215e : + case 0x215f : + case 0x2160 : + case 0x2161 : + case 0x2162 : + case 0x2163 : + case 0x2164 : + case 0x2165 : + case 0x2166 : + case 0x2167 : + case 0x2168 : + case 0x2169 : + case 0x216a : + case 0x216b : + case 0x216c : + case 0x216d : + case 0x216e : + case 0x216f : + case 0x2170 : + case 0x2171 : + case 0x2172 : + case 0x2173 : + case 0x2174 : + case 0x2175 : + case 0x2176 : + case 0x2177 : + case 0x2178 : + case 0x2179 : + case 0x217a : + case 0x217b : + case 0x217c : + case 0x217d : + case 0x217e : + case 0x217f : +#ifdef SPCTOOL + return ((uint8) _SPCOutP[Address & 3]); +#else + // CPU.Flags |= DEBUG_MODE_FLAG; + #ifdef SPC700_SHUTDOWN + CPU.APU_APUExecuting = Settings.APUEnabled; + IAPU.WaitCounter++; + #endif + if(Settings.APUEnabled) + { + #ifdef CPU_SHUTDOWN + //CPU.WaitAddress = CPU.PCAtOpcodeStart; + #endif + if(SNESGameFixes.APU_OutPorts_ReturnValueFix + && Address >= 0x2140 + && Address <= 0x2143 + && !CPU.V_Counter) + { + return (uint8) ((Address & 1) ? + ((rand() & 0xff00) >> 8) : (rand() & 0xff)); + } + + return (APU.OutPorts[Address & 3]); + } + + switch (Settings.SoundSkipMethod) + { + case 0 : + case 1 : + CPU.BranchSkip = TRUE; + break; + case 2 : + break; + case 3 : + CPU.BranchSkip = TRUE; + break; + } + if (Address & 3 < 2) + { + int r = rand(); + if (r & 2) + { + if (r & 4) + return (Address & 3 == 1 ? 0xaa : 0xbb); + else + return ((r >> 3) & 0xff); + } + } + else + { + int r = rand(); + if (r & 2) + return ((r >> 3) & 0xff); + } + return (Memory.FillRAM[Address]); +#endif // SPCTOOL + + case 0x2180 : + // Read WRAM +#ifdef DEBUGGER + missing.wram_read = 1; +#endif + byte = Memory.RAM[PPU.WRAM++]; + PPU.WRAM &= 0x1FFFF; + break; + case 0x2181 : + case 0x2182 : + case 0x2183 : + return (Memory.FillRAM[Address]); + case 0x2190 : + return (1); + } + } + else + { +#ifdef USE_SA1 + if (Settings.SA1) + return (S9xGetSA1(Address)); +#endif + if (Address <= 0x2fff || Address >= 0x3000 + 768) + { + switch (Address) + { + case 0x21c2 : + return (0x20); + case 0x21c3 : + return (0); + case 0x2800 : + // For Dai Kaijyu Monogatari II + if (Settings.SRTC) + return (S9xGetSRTC(Address)); + /*FALL*/ + + default : +#ifdef DEBUGGER + missing.unknownppu_read = Address; + if (Settings.TraceUnknownRegisters) + { + sprintf(String, "Unknown register read: $%04X\n", Address); + S9xMessage(S9X_TRACE, S9X_PPU_TRACE, String); + } +#endif + // XXX: + return (0); //Memory.FillRAM[Address]); + } + } + + if (!Settings.SuperFX) + return (0x30); + byte = Memory.FillRAM[Address]; + + //if (Address != 0x3030 && Address != 0x3031) + //printf ("%04x\n", Address); + #ifdef CPU_SHUTDOWN + if (Address == 0x3030) + { + CPU.WaitAddress = CPU.PCAtOpcodeStart; + } + else + #endif + if (Address == 0x3031) + { + CLEAR_IRQ_SOURCE(GSU_IRQ_SOURCE); + Memory.FillRAM[0x3031] = byte & 0x7f; + } + return (byte); + } + + return (byte); +} + +/**********************************************************************************************/ +/* S9xSetCPU() */ +/* This function sets a CPU/DMA Register to a specific byte */ +/**********************************************************************************************/ +void S9xSetCPU(uint8 byte, uint16 Address) +{ + int d; + + if (Address < 0x4200) + { +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + switch (Address) + { + case 0x4016 : + // S9xReset reading of old-style joypads + if ((byte & 1) && !(Memory.FillRAM[Address] & 1)) + { + PPU.Joypad1ButtonReadPos = 0; + PPU.Joypad2ButtonReadPos = 0; + PPU.Joypad3ButtonReadPos = 0; + } + break; + case 0x4017 : + break; + default : +#ifdef DEBUGGER + missing.unknowncpu_write = Address; + if (Settings.TraceUnknownRegisters) + { + sprintf(String, "Unknown register register write: $%02X->$%04X\n", byte, Address); + S9xMessage(S9X_TRACE, S9X_PPU_TRACE, String); + } +#endif + break; + } + } + else + switch (Address) + { + case 0x4200 : + // NMI, V & H IRQ and joypad reading enable flags + if ((byte & 0x20) + && (!SNESGameFixes.umiharakawaseFix || PPU.IRQVBeamPos < 209)) + { + if (!PPU.VTimerEnabled) + { +#ifdef DEBUGGER + missing.virq = 1; + missing.virq_pos = PPU.IRQVBeamPos; +#endif + PPU.VTimerEnabled = TRUE; + if (PPU.HTimerEnabled) + S9xUpdateHTimer(); + else if (PPU.IRQVBeamPos == CPU.V_Counter) + S9xSetIRQ(PPU_V_BEAM_IRQ_SOURCE); + } + } + else + { + PPU.VTimerEnabled = FALSE; +#ifndef RC_OPTIMIZED + if (SNESGameFixes.umiharakawaseFix) + byte &= ~0x20; +#endif + } + + if (byte & 0x10) + { + if (!PPU.HTimerEnabled) + { +#ifdef DEBUGGER + missing.hirq = 1; + missing.hirq_pos = PPU.IRQHBeamPos; +#endif + PPU.HTimerEnabled = TRUE; + S9xUpdateHTimer(); + } + } + else + { + // No need to check for HTimer being disabled as the scanline + // event trigger code won't trigger an H-IRQ unless its enabled. + PPU.HTimerEnabled = FALSE; + PPU.HTimerPosition = Settings.H_Max + 1; + } + +#ifndef RC_OPTIMIZED + if (!Settings.DaffyDuck) + CLEAR_IRQ_SOURCE(PPU_V_BEAM_IRQ_SOURCE | PPU_H_BEAM_IRQ_SOURCE); + + if ((byte & 0x80) + && !(Memory.FillRAM[0x4200] & 0x80) + && CPU.V_Counter >= PPU.ScreenHeight + FIRST_VISIBLE_LINE + && CPU.V_Counter <= PPU.ScreenHeight + (SNESGameFixes.alienVSpredetorFix ? 25 : 15) + && //jyam 15->25 alien vs predetor + // Panic Bomberman clears the NMI pending flag @ scanline 230 before enabling + // NMIs again. The NMI routine crashes the CPU if it is called without the NMI + // pending flag being set... + (Memory.FillRAM[0x4210] & 0x80) && !CPU.NMIActive) + { + CPU.Flags |= NMI_FLAG; + CPU.NMIActive = TRUE; + CPU.NMICycleCount = CPU.NMITriggerPoint; + } +#endif + break; + case 0x4201 : + // I/O port output + case 0x4202 : + // Multiplier (for multply) + break; + case 0x4203 : + { + // Multiplicand + uint32 res = Memory.FillRAM[0x4202] * byte; + + Memory.FillRAM[0x4216] = (uint8) res; + Memory.FillRAM[0x4217] = (uint8) (res >> 8); + break; + } + case 0x4204 : + case 0x4205 : + // Low and high muliplier (for divide) + break; + case 0x4206 : + { + // Divisor + uint16 a = + Memory.FillRAM[0x4204] + (Memory.FillRAM[0x4205] << 8); + uint16 div = byte ? a / byte : 0xffff; + uint16 rem = byte ? a % byte : a; + + Memory.FillRAM[0x4214] = (uint8) div; + Memory.FillRAM[0x4215] = div >> 8; + Memory.FillRAM[0x4216] = (uint8) rem; + Memory.FillRAM[0x4217] = rem >> 8; + break; + } + case 0x4207 : + d = PPU.IRQHBeamPos; + PPU.IRQHBeamPos = (PPU.IRQHBeamPos & 0xFF00) | byte; + + if (PPU.HTimerEnabled && PPU.IRQHBeamPos != d) + S9xUpdateHTimer(); + break; + + case 0x4208 : + d = PPU.IRQHBeamPos; + PPU.IRQHBeamPos = (PPU.IRQHBeamPos & 0xFF) | ((byte & 1) << 8); + + if (PPU.HTimerEnabled && PPU.IRQHBeamPos != d) + S9xUpdateHTimer(); + + break; + + case 0x4209 : + d = PPU.IRQVBeamPos; + PPU.IRQVBeamPos = (PPU.IRQVBeamPos & 0xFF00) | byte; +#ifdef DEBUGGER + missing.virq_pos = PPU.IRQVBeamPos; +#endif + if (PPU.VTimerEnabled && PPU.IRQVBeamPos != d) + { + if (PPU.HTimerEnabled) + S9xUpdateHTimer(); + else + { + if (PPU.IRQVBeamPos == CPU.V_Counter) + S9xSetIRQ(PPU_V_BEAM_IRQ_SOURCE); + } + } + break; + + case 0x420A : + d = PPU.IRQVBeamPos; + PPU.IRQVBeamPos = (PPU.IRQVBeamPos & 0xFF) | ((byte & 1) << 8); +#ifdef DEBUGGER + missing.virq_pos = PPU.IRQVBeamPos; +#endif + if (PPU.VTimerEnabled && PPU.IRQVBeamPos != d) + { + if (PPU.HTimerEnabled) + S9xUpdateHTimer(); + else + { + if (PPU.IRQVBeamPos == CPU.V_Counter) + S9xSetIRQ(PPU_V_BEAM_IRQ_SOURCE); + } + } + break; + + case 0x420B : +#ifdef DEBUGGER + missing.dma_this_frame = byte; + missing.dma_channels = byte; +#endif + if ((byte & 0x01) != 0) + S9xDoDMA(0); + if ((byte & 0x02) != 0) + S9xDoDMA(1); + if ((byte & 0x04) != 0) + S9xDoDMA(2); + if ((byte & 0x08) != 0) + S9xDoDMA(3); + if ((byte & 0x10) != 0) + S9xDoDMA(4); + if ((byte & 0x20) != 0) + S9xDoDMA(5); + if ((byte & 0x40) != 0) + S9xDoDMA(6); + if ((byte & 0x80) != 0) + S9xDoDMA(7); + break; + case 0x420C : +#ifdef DEBUGGER + missing.hdma_this_frame |= byte; + missing.hdma_channels |= byte; +#endif + if (Settings.DisableHDMA) + byte = 0; + Memory.FillRAM[0x420c] = byte; + IPPU.HDMA = byte; + break; + + case 0x420d : + // Cycle speed 0 - 2.68Mhz, 1 - 3.58Mhz (banks 0x80 +) + if ((byte & 1) != (Memory.FillRAM[0x420d] & 1)) + { + if (byte & 1) + { + CPU.FastROMSpeed = ONE_CYCLE; +#ifdef DEBUGGER + missing.fast_rom = 1; +#endif + } + else + CPU.FastROMSpeed = SLOW_ONE_CYCLE; + + Memory.FixROMSpeed(); + } + /* FALL */ + case 0x420e : + case 0x420f : + // --->>> Unknown + break; + case 0x4210 : + // NMI ocurred flag (reset on read or write) + Memory.FillRAM[0x4210] = 0; + return; + case 0x4211 : + // IRQ ocurred flag (reset on read or write) + CLEAR_IRQ_SOURCE(PPU_V_BEAM_IRQ_SOURCE | PPU_H_BEAM_IRQ_SOURCE); + break; + case 0x4212 : + // v-blank, h-blank and joypad being scanned flags (read-only) + case 0x4213 : + // I/O Port (read-only) + case 0x4214 : + case 0x4215 : + // Quotent of divide (read-only) + case 0x4216 : + case 0x4217 : + // Multiply product (read-only) + return; + case 0x4218 : + case 0x4219 : + case 0x421a : + case 0x421b : + case 0x421c : + case 0x421d : + case 0x421e : + case 0x421f : + // Joypad values (read-only) + return; + + case 0x4300 : + case 0x4310 : + case 0x4320 : + case 0x4330 : + case 0x4340 : + case 0x4350 : + case 0x4360 : + case 0x4370 : + d = (Address >> 4) & 0x7; + DMA[d].TransferDirection = (byte & 128) != 0 ? 1 : 0; + DMA[d].HDMAIndirectAddressing = (byte & 64) != 0 ? 1 : 0; + DMA[d].AAddressDecrement = (byte & 16) != 0 ? 1 : 0; + DMA[d].AAddressFixed = (byte & 8) != 0 ? 1 : 0; + DMA[d].TransferMode = (byte & 7); + break; + + case 0x4301 : + case 0x4311 : + case 0x4321 : + case 0x4331 : + case 0x4341 : + case 0x4351 : + case 0x4361 : + case 0x4371 : + DMA[((Address >> 4) & 0x7)].BAddress = byte; + break; + + case 0x4302 : + case 0x4312 : + case 0x4322 : + case 0x4332 : + case 0x4342 : + case 0x4352 : + case 0x4362 : + case 0x4372 : + d = (Address >> 4) & 0x7; + DMA[d].AAddress &= 0xFF00; + DMA[d].AAddress |= byte; + break; + + case 0x4303 : + case 0x4313 : + case 0x4323 : + case 0x4333 : + case 0x4343 : + case 0x4353 : + case 0x4363 : + case 0x4373 : + d = (Address >> 4) & 0x7; + DMA[d].AAddress &= 0xFF; + DMA[d].AAddress |= byte << 8; + break; + + case 0x4304 : + case 0x4314 : + case 0x4324 : + case 0x4334 : + case 0x4344 : + case 0x4354 : + case 0x4364 : + case 0x4374 : + DMA[((Address >> 4) & 0x7)].ABank = byte; + break; + + case 0x4305 : + case 0x4315 : + case 0x4325 : + case 0x4335 : + case 0x4345 : + case 0x4355 : + case 0x4365 : + case 0x4375 : + d = (Address >> 4) & 0x7; + DMA[d].TransferBytes &= 0xFF00; + DMA[d].TransferBytes |= byte; + DMA[d].IndirectAddress &= 0xff00; + DMA[d].IndirectAddress |= byte; + break; + + case 0x4306 : + case 0x4316 : + case 0x4326 : + case 0x4336 : + case 0x4346 : + case 0x4356 : + case 0x4366 : + case 0x4376 : + d = (Address >> 4) & 0x7; + DMA[d].TransferBytes &= 0xFF; + DMA[d].TransferBytes |= byte << 8; + DMA[d].IndirectAddress &= 0xff; + DMA[d].IndirectAddress |= byte << 8; + break; + + case 0x4307 : + case 0x4317 : + case 0x4327 : + case 0x4337 : + case 0x4347 : + case 0x4357 : + case 0x4367 : + case 0x4377 : + DMA[d = ((Address >> 4) & 0x7)].IndirectBank = byte; + break; + + case 0x4308 : + case 0x4318 : + case 0x4328 : + case 0x4338 : + case 0x4348 : + case 0x4358 : + case 0x4368 : + case 0x4378 : + d = (Address >> 4) & 7; + DMA[d].Address &= 0xff00; + DMA[d].Address |= byte; + break; + + case 0x4309 : + case 0x4319 : + case 0x4329 : + case 0x4339 : + case 0x4349 : + case 0x4359 : + case 0x4369 : + case 0x4379 : + d = (Address >> 4) & 0x7; + DMA[d].Address &= 0xff; + DMA[d].Address |= byte << 8; + break; + + case 0x430A : + case 0x431A : + case 0x432A : + case 0x433A : + case 0x434A : + case 0x435A : + case 0x436A : + case 0x437A : + d = (Address >> 4) & 0x7; + DMA[d].LineCount = byte & 0x7f; + DMA[d].Repeat = !(byte & 0x80); + break; + + case 0x4800 : + case 0x4801 : + case 0x4802 : + case 0x4803 : + //printf ("%02x->%04x\n", byte, Address); + break; + + case 0x4804 : + case 0x4805 : + case 0x4806 : + case 0x4807 : + //printf ("%02x->%04x\n", byte, Address); + + S9xSetSDD1MemoryMap(Address - 0x4804, byte & 7); + break; + default : +#ifdef DEBUGGER + missing.unknowncpu_write = Address; + if (Settings.TraceUnknownRegisters) + { + sprintf( + String, + "Unknown register write: $%02X->$%04X\n", + byte, + Address); + S9xMessage(S9X_TRACE, S9X_PPU_TRACE, String); + } +#endif + break; + } + Memory.FillRAM[Address] = byte; +} + +/**********************************************************************************************/ +/* S9xGetCPU() */ +/* This function retrieves a CPU/DMA Register */ +/**********************************************************************************************/ +uint8 S9xGetCPU(uint16 Address) +{ + uint8 byte; + + if (Address < 0x4200) + { +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + switch (Address) + { + // Secret of the Evermore + case 0x4000 : + case 0x4001 : + return (0x40); + + case 0x4016 : + { + if (Memory.FillRAM[0x4016] & 1) + { + if ((!Settings.SwapJoypads + && IPPU.Controller == SNES_MOUSE_SWAPPED) + || (Settings.SwapJoypads + && IPPU.Controller == SNES_MOUSE)) + { + if (++PPU.MouseSpeed[0] > 2) + PPU.MouseSpeed[0] = 0; + } + return (0); + } + + int ind = Settings.SwapJoypads ? 1 : 0; + byte = IPPU.Joypads[ind] >> (PPU.Joypad1ButtonReadPos ^ 15); + PPU.Joypad1ButtonReadPos++; + return (byte & 1); + } + case 0x4017 : + { + if (Memory.FillRAM[0x4016] & 1) + { + // MultiPlayer5 adaptor is only allowed to be plugged into port 2 + switch (IPPU.Controller) + { + case SNES_MULTIPLAYER5 : + return (2); + case SNES_MOUSE_SWAPPED : + if (Settings.SwapJoypads + && ++PPU.MouseSpeed[0] > 2) + PPU.MouseSpeed[0] = 0; + break; + + case SNES_MOUSE : + if (!Settings.SwapJoypads + && ++PPU.MouseSpeed[0] > 2) + PPU.MouseSpeed[0] = 0; + break; + } + return (0x00); + } + + int ind = Settings.SwapJoypads ? 0 : 1; + + if (IPPU.Controller == SNES_MULTIPLAYER5) + { + if (Memory.FillRAM[0x4201] & 0x80) + { + byte = + ((IPPU.Joypads[ind] + >> (PPU.Joypad2ButtonReadPos ^ 15)) + & 1) + | (((IPPU.Joypads[2] + >> (PPU.Joypad2ButtonReadPos ^ 15)) + & 1) + << 1); + PPU.Joypad2ButtonReadPos++; + return (byte); + } + else + { + byte = + ((IPPU.Joypads[3] + >> (PPU.Joypad3ButtonReadPos ^ 15)) + & 1) + | (((IPPU.Joypads[4] + >> (PPU.Joypad3ButtonReadPos ^ 15)) + & 1) + << 1); + PPU.Joypad3ButtonReadPos++; + return (byte); + } + } + return ( + (IPPU.Joypads[ind] + >> (PPU.Joypad2ButtonReadPos++ ^ 15)) + & 1); + } + default : +#ifdef DEBUGGER + missing.unknowncpu_read = Address; + if (Settings.TraceUnknownRegisters) + { + sprintf(String, "Unknown register read: $%04X\n", Address); + S9xMessage(S9X_TRACE, S9X_PPU_TRACE, String); + } +#endif + break; + } + return (Memory.FillRAM[Address]); + } + else + switch (Address) + { + // BS Dynami Tracer! needs to be able to check if NMIs are enabled + // already, otherwise the game locks up. + case 0x4200 : + // NMI, h & v timers and joypad reading enable + if (SNESGameFixes.Old_Read0x4200) + { +#ifdef CPU_SHUTDOWN + CPU.WaitAddress = CPU.PCAtOpcodeStart; +#endif + return (REGISTER_4212()); + } + case 0x4201 : + // I/O port (output - write only?) + case 0x4202 : + case 0x4203 : + // Multiplier and multiplicand (write) + case 0x4204 : + case 0x4205 : + case 0x4206 : + // Divisor and dividend (write) + return (Memory.FillRAM[Address]); + case 0x4207 : + return (uint8) (PPU.IRQHBeamPos); + case 0x4208 : + return (PPU.IRQHBeamPos >> 8); + case 0x4209 : + return (uint8) (PPU.IRQVBeamPos); + case 0x420a : + return (PPU.IRQVBeamPos >> 8); + case 0x420b : + // General purpose DMA enable + // Super Formation Soccer 95 della Serie A UCC Xaqua requires this + // register should not always return zero. + // .. But Aero 2 waits until this register goes zero.. + // Just keep toggling the value for now in the hope that it breaks + // the game out of its wait loop... + Memory.FillRAM[0x420b] = !Memory.FillRAM[0x420b]; + return (Memory.FillRAM[0x420b]); + case 0x420c : + // H-DMA enable + return (IPPU.HDMA); + case 0x420d : + // Cycle speed 0 - 2.68Mhz, 1 - 3.58Mhz (banks 0x80 +) + return (Memory.FillRAM[Address]); + case 0x420e : + case 0x420f : + // --->>> Unknown + return (Memory.FillRAM[Address]); + case 0x4210 : +#ifdef CPU_SHUTDOWN + CPU.WaitAddress = CPU.PCAtOpcodeStart; +#endif + byte = Memory.FillRAM[0x4210]; + Memory.FillRAM[0x4210] = 0; + return (byte); + case 0x4211 : + byte = + (CPU.IRQActive + & (PPU_V_BEAM_IRQ_SOURCE | PPU_H_BEAM_IRQ_SOURCE)) + ? 0x80 + : 0; + // Super Robot Wars Ex ROM bug requires this. + byte |= CPU.Cycles >= Settings.HBlankStart ? 0x40 : 0; + CLEAR_IRQ_SOURCE(PPU_V_BEAM_IRQ_SOURCE | PPU_H_BEAM_IRQ_SOURCE); + return (byte); + case 0x4212 : + // V-blank, h-blank and joypads being read flags (read-only) +#ifdef CPU_SHUTDOWN + CPU.WaitAddress = CPU.PCAtOpcodeStart; +#endif + return (REGISTER_4212()); + case 0x4213 : + // I/O port input + case 0x4214 : + case 0x4215 : + // Quotient of divide result + case 0x4216 : + case 0x4217 : + // Multiplcation result (for multiply) or remainder of + // divison. + return (Memory.FillRAM[Address]); + case 0x4218 : + case 0x4219 : + case 0x421a : + case 0x421b : + case 0x421c : + case 0x421d : + case 0x421e : + case 0x421f : + // Joypads 1-4 button and direction state. + return (Memory.FillRAM[Address]); + + case 0x4300 : + case 0x4310 : + case 0x4320 : + case 0x4330 : + case 0x4340 : + case 0x4350 : + case 0x4360 : + case 0x4370 : + // DMA direction, address type, fixed flag, + return (Memory.FillRAM[Address]); + + case 0x4301 : + case 0x4311 : + case 0x4321 : + case 0x4331 : + case 0x4341 : + case 0x4351 : + case 0x4361 : + case 0x4371 : + return (Memory.FillRAM[Address]); + + case 0x4302 : + case 0x4312 : + case 0x4322 : + case 0x4332 : + case 0x4342 : + case 0x4352 : + case 0x4362 : + case 0x4372 : + return (Memory.FillRAM[Address]); + + case 0x4303 : + case 0x4313 : + case 0x4323 : + case 0x4333 : + case 0x4343 : + case 0x4353 : + case 0x4363 : + case 0x4373 : + return (Memory.FillRAM[Address]); + + case 0x4304 : + case 0x4314 : + case 0x4324 : + case 0x4334 : + case 0x4344 : + case 0x4354 : + case 0x4364 : + case 0x4374 : + return (Memory.FillRAM[Address]); + + case 0x4305 : + case 0x4315 : + case 0x4325 : + case 0x4335 : + case 0x4345 : + case 0x4355 : + case 0x4365 : + case 0x4375 : + return (Memory.FillRAM[Address]); + + case 0x4306 : + case 0x4316 : + case 0x4326 : + case 0x4336 : + case 0x4346 : + case 0x4356 : + case 0x4366 : + case 0x4376 : + return (Memory.FillRAM[Address]); + + case 0x4307 : + case 0x4317 : + case 0x4327 : + case 0x4337 : + case 0x4347 : + case 0x4357 : + case 0x4367 : + case 0x4377 : + return (DMA[(Address >> 4) & 7].IndirectBank); + + case 0x4308 : + case 0x4318 : + case 0x4328 : + case 0x4338 : + case 0x4348 : + case 0x4358 : + case 0x4368 : + case 0x4378 : + return (Memory.FillRAM[Address]); + + case 0x4309 : + case 0x4319 : + case 0x4329 : + case 0x4339 : + case 0x4349 : + case 0x4359 : + case 0x4369 : + case 0x4379 : + return (Memory.FillRAM[Address]); + + case 0x430A : + case 0x431A : + case 0x432A : + case 0x433A : + case 0x434A : + case 0x435A : + case 0x436A : + case 0x437A : + { + int d = (Address & 0x70) >> 4; + if (IPPU.HDMA & (1 << d)) + { + return (DMA[d].LineCount); + } + return (Memory.FillRAM[Address]); + } + default : +#ifdef DEBUGGER + missing.unknowncpu_read = Address; + if (Settings.TraceUnknownRegisters) + { + sprintf(String, "Unknown register read: $%04X\n", Address); + S9xMessage(S9X_TRACE, S9X_PPU_TRACE, String); + } + +#endif + break; + } + return (Memory.FillRAM[Address]); +} + +void S9xResetPPU() +{ + PPU.BGMode = 0; + PPU.BG3Priority = 0; + PPU.Brightness = 0; + PPU.VMA.High = 0; + PPU.VMA.Increment = 1; + PPU.VMA.Address = 0; + PPU.VMA.FullGraphicCount = 0; + PPU.VMA.Shift = 0; + + for (uint8 B = 0; B != 4; B++) + { + PPU.BG[B].SCBase = 0; + PPU.BG[B].VOffset = 0; + PPU.BG[B].HOffset = 0; + PPU.BG[B].BGSize = 0; + PPU.BG[B].NameBase = 0; + PPU.BG[B].SCSize = 0; + + PPU.ClipCounts[B] = 0; + PPU.ClipWindowOverlapLogic[B] = CLIP_OR; + PPU.ClipWindow1Enable[B] = FALSE; + PPU.ClipWindow2Enable[B] = FALSE; + PPU.ClipWindow1Inside[B] = TRUE; + PPU.ClipWindow2Inside[B] = TRUE; + } + + PPU.ClipCounts[4] = 0; + PPU.ClipCounts[5] = 0; + PPU.ClipWindowOverlapLogic[4] = PPU.ClipWindowOverlapLogic[5] = CLIP_OR; + PPU.ClipWindow1Enable[4] = PPU.ClipWindow1Enable[5] = FALSE; + PPU.ClipWindow2Enable[4] = PPU.ClipWindow2Enable[5] = FALSE; + PPU.ClipWindow1Inside[4] = PPU.ClipWindow1Inside[5] = TRUE; + PPU.ClipWindow2Inside[4] = PPU.ClipWindow2Inside[5] = TRUE; + + PPU.CGFLIP = 0; + int c; + for (c = 0; c < 256; c++) + { + IPPU.Red[c] = (c & 7) << 2; + IPPU.Green[c] = ((c >> 3) & 7) << 2; + IPPU.Blue[c] = ((c >> 6) & 2) << 3; + PPU.CGDATA[c] = + IPPU.Red[c] | (IPPU.Green[c] << 5) | (IPPU.Blue[c] << 10); + } + + PPU.FirstSprite = 0; + PPU.LastSprite = 127; + for (int Sprite = 0; Sprite < 128; Sprite++) + { + PPU.OBJ[Sprite].HPos = 0; + PPU.OBJ[Sprite].VPos = 0; + PPU.OBJ[Sprite].VFlip = 0; + PPU.OBJ[Sprite].HFlip = 0; + PPU.OBJ[Sprite].Priority = 0; + PPU.OBJ[Sprite].Palette = 0; + PPU.OBJ[Sprite].Name = 0; + PPU.OBJ[Sprite].Size = 0; + } + PPU.OAMPriorityRotation = 0; + + PPU.OAMFlip = 0; + PPU.OAMTileAddress = 0; + PPU.OAMAddr = 0; + PPU.IRQVBeamPos = 0; + PPU.IRQHBeamPos = 0; + PPU.VBeamPosLatched = 0; + PPU.HBeamPosLatched = 0; + + PPU.HBeamFlip = 0; + PPU.VBeamFlip = 0; + PPU.HVBeamCounterLatched = 0; + + PPU.MatrixA = PPU.MatrixB = PPU.MatrixC = PPU.MatrixD = 0; + PPU.CentreX = PPU.CentreY = 0; + PPU.Joypad1ButtonReadPos = 0; + PPU.Joypad2ButtonReadPos = 0; + PPU.Joypad3ButtonReadPos = 0; + + PPU.CGADD = 0; + PPU.FixedColourRed = PPU.FixedColourGreen = PPU.FixedColourBlue = 0; + PPU.SavedOAMAddr = 0; + PPU.ScreenHeight = SNES_HEIGHT; + PPU.WRAM = 0; + PPU.BG_Forced = 0; + PPU.ForcedBlanking = TRUE; + PPU.OBJThroughMain = FALSE; + PPU.OBJThroughSub = FALSE; + PPU.OBJSizeSelect = 0; + PPU.OBJNameSelect = 0; + PPU.OBJNameBase = 0; + PPU.OBJAddition = FALSE; + PPU.OAMReadFlip = 0; + ZeroMemory(PPU.OAMData, 512 + 32); + + PPU.VTimerEnabled = FALSE; + PPU.HTimerEnabled = FALSE; + PPU.HTimerPosition = Settings.H_Max + 1; + PPU.Mosaic = 0; + PPU.BGMosaic[0] = PPU.BGMosaic[1] = FALSE; + PPU.BGMosaic[2] = PPU.BGMosaic[3] = FALSE; + PPU.Mode7HFlip = FALSE; + PPU.Mode7VFlip = FALSE; + PPU.Mode7Repeat = 0; + PPU.Window1Left = 1; + PPU.Window1Right = 0; + PPU.Window2Left = 1; + PPU.Window2Right = 0; + PPU.RecomputeClipWindows = TRUE; + PPU.CGFLIPRead = 0; + PPU.Need16x8Mulitply = FALSE; + PPU.MouseSpeed[0] = PPU.MouseSpeed[1] = 0; + + IPPU.ColorsChanged = TRUE; + IPPU.HDMA = 0; + IPPU.HDMAStarted = FALSE; + IPPU.MaxBrightness = 0; + IPPU.LatchedBlanking = 0; + IPPU.OBJChanged = TRUE; + IPPU.RenderThisFrame = TRUE; + IPPU.DirectColourMapsNeedRebuild = TRUE; + IPPU.FrameCount = 0; + IPPU.RenderedFramesCount = 0; + IPPU.DisplayedRenderedFrameCount = 0; + IPPU.SkippedFrames = 0; + IPPU.FrameSkip = 0; + ZeroMemory(IPPU.TileCached[TILE_2BIT], MAX_2BIT_TILES); + ZeroMemory(IPPU.TileCached[TILE_4BIT], MAX_4BIT_TILES); + ZeroMemory(IPPU.TileCached[TILE_8BIT], MAX_8BIT_TILES); + IPPU.FirstVRAMRead = FALSE; + IPPU.LatchedInterlace = FALSE; + IPPU.DoubleWidthPixels = FALSE; + IPPU.RenderedScreenWidth = SNES_WIDTH; + IPPU.RenderedScreenHeight = SNES_HEIGHT; + IPPU.XB = NULL; + for (c = 0; c < 256; c++) + IPPU.ScreenColors[c] = c; + S9xFixColourBrightness(); + IPPU.PreviousLine = IPPU.CurrentLine = 0; + IPPU.Joypads[0] = IPPU.Joypads[1] = IPPU.Joypads[2] = 0; + IPPU.Joypads[3] = IPPU.Joypads[4] = 0; + IPPU.SuperScope = 0; + IPPU.Mouse[0] = IPPU.Mouse[1] = 0; + IPPU.PrevMouseX[0] = IPPU.PrevMouseX[1] = 256 / 2; + IPPU.PrevMouseY[0] = IPPU.PrevMouseY[1] = 224 / 2; + + if (Settings.ControllerOption == 0) + IPPU.Controller = SNES_MAX_CONTROLLER_OPTIONS - 1; + else + IPPU.Controller = Settings.ControllerOption - 1; + S9xNextController(); + + for (c = 0; c < 2; c++) + memset(& IPPU.Clip[c], 0, sizeof(struct ClipData)); + + if (Settings.MouseMaster) + { + S9xProcessMouse(0); + S9xProcessMouse(1); + } + for (c = 0; c < 0x8000; c += 0x100) + memset(& Memory.FillRAM[c], c >> 8, 0x100); + + ZeroMemory(& Memory.FillRAM[0x2100], 0x100); + ZeroMemory(& Memory.FillRAM[0x4200], 0x100); + ZeroMemory(& Memory.FillRAM[0x4000], 0x100); + // For BS Suttehakkun 2... + ZeroMemory(& Memory.FillRAM[0x1000], 0x1000); +} + +void S9xProcessMouse(int which1) +{ + int x, y; + uint32 buttons; + + if ((IPPU.Controller == SNES_MOUSE + || IPPU.Controller == SNES_MOUSE_SWAPPED) + && S9xReadMousePosition(which1, x, y, buttons)) + { + int delta_x, delta_y; +#define MOUSE_SIGNATURE 0x1 + IPPU.Mouse[which1] = + MOUSE_SIGNATURE + | (PPU.MouseSpeed[which1] << 4) + | ((buttons & 1) << 6) + | ((buttons & 2) << 6); + + delta_x = x - IPPU.PrevMouseX[which1]; + delta_y = y - IPPU.PrevMouseY[which1]; + + if (delta_x > 63) + { + delta_x = 63; + IPPU.PrevMouseX[which1] += 63; + } + else if (delta_x < -63) + { + delta_x = -63; + IPPU.PrevMouseX[which1] -= 63; + } + else + IPPU.PrevMouseX[which1] = x; + + if (delta_y > 63) + { + delta_y = 63; + IPPU.PrevMouseY[which1] += 63; + } + else if (delta_y < -63) + { + delta_y = -63; + IPPU.PrevMouseY[which1] -= 63; + } + else + IPPU.PrevMouseY[which1] = y; + + if (delta_x < 0) + { + delta_x = -delta_x; + IPPU.Mouse[which1] |= (delta_x | 0x80) << 16; + } + else + IPPU.Mouse[which1] |= delta_x << 16; + + if (delta_y < 0) + { + delta_y = -delta_y; + IPPU.Mouse[which1] |= (delta_y | 0x80) << 24; + } + else + IPPU.Mouse[which1] |= delta_y << 24; + + if (IPPU.Controller == SNES_MOUSE_SWAPPED) + IPPU.Joypads[0] = IPPU.Mouse[which1]; + else + IPPU.Joypads[1] = IPPU.Mouse[which1]; + } +} + +void ProcessSuperScope() +{ + int x, y; + uint32 buttons; + + if (IPPU.Controller == SNES_SUPERSCOPE + && S9xReadSuperScopePosition(x, y, buttons)) + { +#define SUPERSCOPE_SIGNATURE 0x00ff + uint32 scope; + + scope = + SUPERSCOPE_SIGNATURE + | ((buttons & 1) << (7 + 8)) + | ((buttons & 2) << (5 + 8)) + | ((buttons & 4) << (3 + 8)) + | ((buttons & 8) << (1 + 8)); + if (x > 255) + x = 255; + if (x < 0) + x = 0; + if (y > PPU.ScreenHeight - 1) + y = PPU.ScreenHeight - 1; + if (y < 0) + y = 0; + + PPU.VBeamPosLatched = (uint16) (y + 1); + PPU.HBeamPosLatched = (uint16) x; + PPU.HVBeamCounterLatched = TRUE; + Memory.FillRAM[0x213F] |= 0x40; + IPPU.Joypads[1] = scope; + } +} + +void S9xNextController() +{ + switch (IPPU.Controller) + { + case SNES_MULTIPLAYER5 : + IPPU.Controller = SNES_JOYPAD; + break; + case SNES_JOYPAD : + if (Settings.MouseMaster) + { + IPPU.Controller = SNES_MOUSE_SWAPPED; + break; + } + case SNES_MOUSE_SWAPPED : + if (Settings.MouseMaster) + { + IPPU.Controller = SNES_MOUSE; + break; + } + case SNES_MOUSE : + if (Settings.SuperScopeMaster) + { + IPPU.Controller = SNES_SUPERSCOPE; + break; + } + case SNES_SUPERSCOPE : + if (Settings.MultiPlayer5Master) + { + IPPU.Controller = SNES_MULTIPLAYER5; + break; + } + default : + IPPU.Controller = SNES_JOYPAD; + break; + } +} + +void S9xUpdateJoypads() +{ +#ifdef _SNESPPC + int i = 0; +#else + int i; + + for (i = 0; i < 5; i++) +#endif + { + IPPU.Joypads[i] = S9xReadJoypad(i); + if (IPPU.Joypads[i] & SNES_LEFT_MASK) + IPPU.Joypads[i] &= ~SNES_RIGHT_MASK; + if (IPPU.Joypads[i] & SNES_UP_MASK) + IPPU.Joypads[i] &= ~SNES_DOWN_MASK; + } + + //touhaiden controller Fix + if (SNESGameFixes.TouhaidenControllerFix + && (IPPU.Controller == SNES_JOYPAD + || IPPU.Controller == SNES_MULTIPLAYER5)) + { + for (i = 0; i < 5; i++) + { + if (IPPU.Joypads[i]) + IPPU.Joypads[i] |= 0xffff0000; + } + } + + // Read mouse position if enabled + if (Settings.MouseMaster) + { + for (i = 0; i < 2; i++) + S9xProcessMouse(i); + } + + // Read SuperScope if enabled + if (Settings.SuperScopeMaster) + ProcessSuperScope(); + + if (Memory.FillRAM[0x4200] & 1) + { + PPU.Joypad1ButtonReadPos = 16; + if (Memory.FillRAM[0x4201] & 0x80) + { + PPU.Joypad2ButtonReadPos = 16; + PPU.Joypad3ButtonReadPos = 0; + } + else + { + PPU.Joypad2ButtonReadPos = 0; + PPU.Joypad3ButtonReadPos = 16; + } + int ind = Settings.SwapJoypads ? 1 : 0; + + Memory.FillRAM[0x4218] = (uint8) IPPU.Joypads[ind]; + Memory.FillRAM[0x4219] = (uint8) (IPPU.Joypads[ind] >> 8); + Memory.FillRAM[0x421a] = (uint8) IPPU.Joypads[ind ^ 1]; + Memory.FillRAM[0x421b] = (uint8) (IPPU.Joypads[ind ^ 1] >> 8); + if (Memory.FillRAM[0x4201] & 0x80) + { + Memory.FillRAM[0x421c] = (uint8) IPPU.Joypads[ind]; + Memory.FillRAM[0x421d] = (uint8) (IPPU.Joypads[ind] >> 8); + Memory.FillRAM[0x421e] = (uint8) IPPU.Joypads[2]; + Memory.FillRAM[0x421f] = (uint8) (IPPU.Joypads[2] >> 8); + } + else + { + Memory.FillRAM[0x421c] = (uint8) IPPU.Joypads[3]; + Memory.FillRAM[0x421d] = (uint8) (IPPU.Joypads[3] >> 8); + Memory.FillRAM[0x421e] = (uint8) IPPU.Joypads[4]; + Memory.FillRAM[0x421f] = (uint8) (IPPU.Joypads[4] >> 8); + } + } +} + +#ifndef ZSNES_FX +void S9xSuperFXExec() +{ +#if 1 + if (Settings.SuperFX) + { + if ((Memory.FillRAM[0x3000 + GSU_SFR] & FLG_G) + && (Memory.FillRAM[0x3000 + GSU_SCMR] & 0x18) == 0x18) + { + if (!Settings.WinterGold) + FxEmulate(~0); + else FxEmulate((Memory.FillRAM[0x3000 + GSU_CLSR] & 1) ? 700 : 350); + int GSUStatus = Memory.FillRAM[0x3000 + + GSU_SFR] | (Memory.FillRAM[0x3000 + GSU_SFR + 1] << 8); + if ((GSUStatus & (FLG_G | FLG_IRQ)) == FLG_IRQ) + { + // Trigger a GSU IRQ. + S9xSetIRQ(GSU_IRQ_SOURCE); + } + } + } +#else + uint32 tmp = (Memory.FillRAM[0x3034] << 16) + + * (uint16 *) & Memory.FillRAM[0x301e]; + #if 0 + if (tmp == 0x018428) + { + * (uint16 *) + & SRAM[0x0064] = 0xbc00; + * (uint16 *) & SRAM[0x002c] = 0x8000; + } + #endif + if (tmp == -1) //0x018428) //0x01bfc3) //0x09edaf) //-1) //0x57edaf) + { + while (Memory.FillRAM[0x3030] & 0x20) + { + int i; + int32 vError; + uint8 avReg[0x40]; + char tmp[128]; + uint8 vPipe; + uint8 vColr; + uint8 vPor; + + FxPipeString(tmp); + /* Make the string 32 chars long */ + if (strlen(tmp) < 32) + { + memset(& tmp[strlen(tmp)], ' ', 32 - strlen(tmp)); + tmp[32] = 0; + } + + /* Copy registers (so we can see if any changed) */ + vColr = FxGetColorRegister(); + vPor = FxGetPlotOptionRegister(); + memcpy(avReg, SuperFX.pvRegisters, 0x40); + + /* Print the pipe string */ + printf(tmp); + + /* Execute the instruction in the pipe */ + vPipe = FxPipe(); + vError = FxEmulate(1); + + /* Check if any registers changed (and print them if they did) */ + for (i = 0; i < 16; i++) + { + uint32 a = 0; + uint32 r1 = + ((uint32) avReg[i * 2]) + | (((uint32) avReg[(i * 2) + 1]) << 8); + uint32 r2 = + (uint32) (SuperFX.pvRegisters[i * 2]) + | (((uint32) SuperFX.pvRegisters[(i * 2) + 1]) << 8); + if (i == 15) + a = OPCODE_BYTES(vPipe); + if (((r1 + a) & 0xffff) != r2) + printf(" r%d=$%04x", i, r2); + } + { + /* Check SFR */ + uint32 r1 = + ((uint32) avReg[0x30]) | (((uint32) avReg[0x31]) << 8); + uint32 r2 = + (uint32) (SuperFX.pvRegisters[0x30]) + | (((uint32) SuperFX.pvRegisters[0x31]) << 8); + if ((r1 & (1 << 1)) != (r2 & (1 << 1))) + printf(" Z=%d", (uint32) (!!(r2 & (1 << 1)))); + if ((r1 & (1 << 2)) != (r2 & (1 << 2))) + printf(" CY=%d", (uint32) (!!(r2 & (1 << 2)))); + if ((r1 & (1 << 3)) != (r2 & (1 << 3))) + printf(" S=%d", (uint32) (!!(r2 & (1 << 3)))); + if ((r1 & (1 << 4)) != (r2 & (1 << 4))) + printf(" OV=%d", (uint32) (!!(r2 & (1 << 4)))); + if ((r1 & (1 << 5)) != (r2 & (1 << 5))) + printf(" G=%d", (uint32) (!!(r2 & (1 << 5)))); + if ((r1 & (1 << 6)) != (r2 & (1 << 6))) + printf(" R=%d", (uint32) (!!(r2 & (1 << 6)))); + if ((r1 & (1 << 8)) != (r2 & (1 << 8))) + printf(" ALT1=%d", (uint32) (!!(r2 & (1 << 8)))); + if ((r1 & (1 << 9)) != (r2 & (1 << 9))) + printf(" ALT2=%d", (uint32) (!!(r2 & (1 << 9)))); + if ((r1 & (1 << 10)) != (r2 & (1 << 10))) + printf(" IL=%d", (uint32) (!!(r2 & (1 << 10)))); + if ((r1 & (1 << 11)) != (r2 & (1 << 11))) + printf(" IH=%d", (uint32) (!!(r2 & (1 << 11)))); + if ((r1 & (1 << 12)) != (r2 & (1 << 12))) + printf(" B=%d", (uint32) (!!(r2 & (1 << 12)))); + if ((r1 & (1 << 15)) != (r2 & (1 << 15))) + printf(" IRQ=%d", (uint32) (!!(r2 & (1 << 15)))); + } + { + /* Check PBR */ + uint32 r1 = ((uint32) avReg[0x34]); + uint32 r2 = (uint32) (SuperFX.pvRegisters[0x34]); + if (r1 != r2) + printf(" PBR=$%02x", r2); + } + { + /* Check ROMBR */ + uint32 r1 = ((uint32) avReg[0x36]); + uint32 r2 = (uint32) (SuperFX.pvRegisters[0x36]); + if (r1 != r2) + printf(" ROMBR=$%02x", r2); + } + { + /* Check RAMBR */ + uint32 r1 = ((uint32) avReg[0x3c]); + uint32 r2 = (uint32) (SuperFX.pvRegisters[0x3c]); + if (r1 != r2) + printf(" RAMBR=$%02x", r2); + } + { + /* Check CBR */ + uint32 r1 = + ((uint32) avReg[0x3e]) | (((uint32) avReg[0x3f]) << 8); + uint32 r2 = + (uint32) (SuperFX.pvRegisters[0x3e]) + | (((uint32) SuperFX.pvRegisters[0x3f]) << 8); + if (r1 != r2) + printf(" CBR=$%04x", r2); + } + { + /* Check COLR */ + if (vColr != FxGetColorRegister()) + printf(" COLR=$%02x", FxGetColorRegister()); + } + { + /* Check POR */ + if (vPor != FxGetPlotOptionRegister()) + printf(" POR=$%02x", FxGetPlotOptionRegister()); + } + printf("\n"); + } + S9xExit(); + } + else + { + uint32 t = + (Memory.FillRAM[0x3034] << 16) + + (Memory.FillRAM[0x301f] << 8) + + (Memory.FillRAM[0x301e] << 0); + + printf("%06x: %d\n", t, FxEmulate(2000000)); + // FxEmulate (2000000); + } + #if 0 + if (!(CPU.Flags & TRACE_FLAG)) + { + static int z = 1; if (z == 0) + { + extern FILE * trace; + CPU.Flags |= TRACE_FLAG; + trace = fopen("trace.log", "wb"); + } + else + z--; + } + #endif + Memory.FillRAM[0x3030] &= ~0x20; + if (Memory.FillRAM[0x3031] & 0x80) + { + S9xSetIRQ(GSU_IRQ_SOURCE); + } + #endif +} +#endif + diff --git a/src/snes4iphone_src/ppu.h b/src/snes4iphone_src/ppu.h new file mode 100755 index 0000000..c91bfb9 --- /dev/null +++ b/src/snes4iphone_src/ppu.h @@ -0,0 +1,540 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#ifndef _PPU_H_ +#define _PPU_H_ + +#define FIRST_VISIBLE_LINE 1 + +extern uint8 GetBank; +extern uint16 SignExtend [2]; + +#define TILE_2BIT 0 +#define TILE_4BIT 1 +#define TILE_8BIT 2 + +#define MAX_2BIT_TILES 4096 +#define MAX_4BIT_TILES 2048 +#define MAX_8BIT_TILES 1024 + +#define PPU_H_BEAM_IRQ_SOURCE (1 << 0) +#define PPU_V_BEAM_IRQ_SOURCE (1 << 1) +#define GSU_IRQ_SOURCE (1 << 2) +#define SA1_IRQ_SOURCE (1 << 7) +#define SA1_DMA_IRQ_SOURCE (1 << 5) + +struct ClipData { + uint32 Count [6]; + uint32 Left [6][6]; + uint32 Right [6][6]; +}; + +struct InternalPPU { + bool8_32 ColorsChanged; + uint8 HDMA; + bool8_32 HDMAStarted; + uint8 MaxBrightness; + bool8_32 LatchedBlanking; + bool8_32 OBJChanged; + bool8_32 RenderThisFrame; + bool8_32 DirectColourMapsNeedRebuild; + uint32 FrameCount; + uint32 RenderedFramesCount; + uint32 DisplayedRenderedFrameCount; + uint32 SkippedFrames; + uint32 FrameSkip; + uint8 *TileCache [3]; + uint8 *TileCached [3]; + bool8_32 FirstVRAMRead; + bool8_32 LatchedInterlace; + bool8_32 DoubleWidthPixels; + int RenderedScreenHeight; + int RenderedScreenWidth; + uint32 Red [256]; + uint32 Green [256]; + uint32 Blue [256]; + uint8 *XB; + uint16 ScreenColors [256]; + int PreviousLine; + int CurrentLine; + int Controller; + uint32 Joypads[5]; + uint32 SuperScope; + uint32 Mouse[2]; + int PrevMouseX[2]; + int PrevMouseY[2]; + struct ClipData Clip [2]; +}; + +struct SOBJ +{ + short HPos; + uint16 VPos; + uint16 Name; + uint8 VFlip; + uint8 HFlip; + uint8 Priority; + uint8 Palette; + uint8 Size; +}; + +struct SPPU { + uint8 BGMode; + uint8 BG3Priority; + uint8 Brightness; + + struct { + bool8_32 High; + uint8 Increment; + uint16 Address; + uint16 Mask1; + uint16 FullGraphicCount; + uint16 Shift; + } VMA; + + struct { + uint16 SCBase; + uint16 VOffset; + uint16 HOffset; + uint8 BGSize; + uint16 NameBase; + uint16 SCSize; + } BG [4]; + + bool8_32 CGFLIP; + uint16 CGDATA [256]; + uint8 FirstSprite; + uint8 LastSprite; + struct SOBJ OBJ [128]; + uint8 OAMPriorityRotation; + uint16 OAMAddr; + + uint8 OAMFlip; + uint16 OAMTileAddress; + uint16 IRQVBeamPos; + uint16 IRQHBeamPos; + uint16 VBeamPosLatched; + uint16 HBeamPosLatched; + + uint8 HBeamFlip; + uint8 VBeamFlip; + uint8 HVBeamCounterLatched; + + short MatrixA; + short MatrixB; + short MatrixC; + short MatrixD; + short CentreX; + short CentreY; + uint8 Joypad1ButtonReadPos; + uint8 Joypad2ButtonReadPos; + + uint8 CGADD; + uint8 FixedColourRed; + uint8 FixedColourGreen; + uint8 FixedColourBlue; + uint16 SavedOAMAddr; + uint16 ScreenHeight; + uint32 WRAM; + uint8 BG_Forced; + bool8_32 ForcedBlanking; + bool8_32 OBJThroughMain; + bool8_32 OBJThroughSub; + uint8 OBJSizeSelect; + uint16 OBJNameBase; + bool8_32 OBJAddition; + uint8 OAMReadFlip; + uint8 OAMData [512 + 32]; + bool8_32 VTimerEnabled; + bool8_32 HTimerEnabled; + short HTimerPosition; + uint8 Mosaic; + bool8_32 BGMosaic [4]; + bool8_32 Mode7HFlip; + bool8_32 Mode7VFlip; + uint8 Mode7Repeat; + uint8 Window1Left; + uint8 Window1Right; + uint8 Window2Left; + uint8 Window2Right; + uint8 ClipCounts [6]; + uint8 ClipWindowOverlapLogic [6]; + uint8 ClipWindow1Enable [6]; + uint8 ClipWindow2Enable [6]; + bool8_32 ClipWindow1Inside [6]; + bool8_32 ClipWindow2Inside [6]; + bool8_32 RecomputeClipWindows; + uint8 CGFLIPRead; + uint16 OBJNameSelect; + bool8_32 Need16x8Mulitply; + uint8 Joypad3ButtonReadPos; + uint8 MouseSpeed[2]; +}; + +#define CLIP_OR 0 +#define CLIP_AND 1 +#define CLIP_XOR 2 +#define CLIP_XNOR 3 + +struct SDMA { + bool8_32 TransferDirection; + bool8_32 AAddressFixed; + bool8_32 AAddressDecrement; + uint8 TransferMode; + + uint8 ABank; + uint16 AAddress; + uint16 Address; + uint8 BAddress; + + // General DMA only: + uint16 TransferBytes; + + // H-DMA only: + bool8_32 HDMAIndirectAddressing; + uint16 IndirectAddress; + uint8 IndirectBank; + uint8 Repeat; + uint8 LineCount; + uint8 FirstLine; +}; + +START_EXTERN_C +void S9xUpdateScreen (); +void S9xResetPPU (); +void S9xFixColourBrightness (); +void S9xUpdateJoypads (); +void S9xProcessMouse(int which1); +void S9xSuperFXExec (); + +void S9xSetPPU (uint8 Byte, uint16 Address); +uint8 S9xGetPPU (uint16 Address); +void S9xSetCPU (uint8 Byte, uint16 Address); +uint8 S9xGetCPU (uint16 Address); + +void S9xInitC4 (); +void S9xSetC4 (uint8 Byte, uint16 Address); +uint8 S9xGetC4 (uint16 Address); +void S9xSetC4RAM (uint8 Byte, uint16 Address); +uint8 S9xGetC4RAM (uint16 Address); + +extern struct SPPU PPU; +extern struct SDMA DMA [8]; +extern struct InternalPPU IPPU; +END_EXTERN_C + +#include "gfx.h" +#include "memmap.h" + +STATIC INLINE uint8 REGISTER_4212() +{ + GetBank = 0; + if (CPU.V_Counter >= PPU.ScreenHeight + FIRST_VISIBLE_LINE && + CPU.V_Counter < PPU.ScreenHeight + FIRST_VISIBLE_LINE + 3) + GetBank = 1; + + GetBank |= CPU.Cycles >= Settings.HBlankStart ? 0x40 : 0; + if (CPU.V_Counter >= PPU.ScreenHeight + FIRST_VISIBLE_LINE) + GetBank |= 0x80; /* XXX: 0x80 or 0xc0 ? */ + + return (GetBank); +} + +STATIC INLINE void FLUSH_REDRAW () +{ + if (IPPU.PreviousLine != IPPU.CurrentLine) + S9xUpdateScreen (); +} + +STATIC INLINE void REGISTER_2104 (uint8 byte) +{ + if (PPU.OAMAddr >= 0x110) + return; + + int addr = (PPU.OAMAddr << 1) + (PPU.OAMFlip & 1); + + if (byte != PPU.OAMData [addr]) + { + FLUSH_REDRAW (); + PPU.OAMData [addr] = byte; + IPPU.OBJChanged = TRUE; + if (addr & 0x200) + { + // X position high bit, and sprite size (x4) + struct SOBJ *pObj = &PPU.OBJ [(addr & 0x1f) * 4]; + + pObj->HPos = (pObj->HPos & 0xFF) | SignExtend[(byte >> 0) & 1]; + pObj++->Size = byte & 2; + pObj->HPos = (pObj->HPos & 0xFF) | SignExtend[(byte >> 2) & 1]; + pObj++->Size = byte & 8; + pObj->HPos = (pObj->HPos & 0xFF) | SignExtend[(byte >> 4) & 1]; + pObj++->Size = byte & 32; + pObj->HPos = (pObj->HPos & 0xFF) | SignExtend[(byte >> 6) & 1]; + pObj->Size = byte & 128; + } + else + { + if (addr & 1) + { + if (addr & 2) + { + addr = PPU.OAMAddr >> 1; + // Tile within group, priority, h and v flip. + PPU.OBJ[addr].Name &= 0xFF; + PPU.OBJ[addr].Name |= ((uint16) (byte & 1)) << 8; + PPU.OBJ[addr].Palette = (byte >> 1) & 7; + PPU.OBJ[addr].Priority = (byte >> 4) & 3; + PPU.OBJ[addr].HFlip = (byte >> 6) & 1; + PPU.OBJ[addr].VFlip = (byte >> 7) & 1; + } + else + { + // Sprite Y position + PPU.OBJ[PPU.OAMAddr >> 1].VPos = byte; + } + } + else + { + if (addr & 2) + { + // Tile group + + PPU.OBJ[addr = PPU.OAMAddr >> 1].Name &= 0x100; + PPU.OBJ[addr].Name |= byte; + } + else + { + // X position (low) + PPU.OBJ[addr = PPU.OAMAddr >> 1].HPos &= 0xFF00; + PPU.OBJ[addr].HPos |= byte; + } + } + } + } + PPU.OAMFlip ^= 1; + if (!(PPU.OAMFlip & 1)) + PPU.OAMAddr++; + + Memory.FillRAM [0x2104] = byte; +} + +STATIC INLINE void REGISTER_2118 (uint8 Byte) +{ + uint32 address; + if (PPU.VMA.FullGraphicCount) + { + uint32 rem = PPU.VMA.Address & PPU.VMA.Mask1; + address = (((PPU.VMA.Address & ~PPU.VMA.Mask1) + + (rem >> PPU.VMA.Shift) + + ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3)) << 1) & 0xffff; + Memory.VRAM [address] = Byte; + } + else + { + Memory.VRAM[address = (PPU.VMA.Address << 1) & 0xFFFF] = Byte; + } + IPPU.TileCached [TILE_2BIT][address >> 4] = FALSE; + IPPU.TileCached [TILE_4BIT][address >> 5] = FALSE; + IPPU.TileCached [TILE_8BIT][address >> 6] = FALSE; + if (!PPU.VMA.High) + { +#ifdef DEBUGGER + if (Settings.TraceVRAM && !CPU.InDMA) + { + printf ("VRAM write byte: $%04X (%d,%d)\n", PPU.VMA.Address, + Memory.FillRAM[0x2115] & 3, + (Memory.FillRAM [0x2115] & 0x0c) >> 2); + } +#endif + PPU.VMA.Address += PPU.VMA.Increment; + } +// Memory.FillRAM [0x2118] = Byte; +} + +STATIC INLINE void REGISTER_2118_tile (uint8 Byte) +{ + uint32 address; + uint32 rem = PPU.VMA.Address & PPU.VMA.Mask1; + address = (((PPU.VMA.Address & ~PPU.VMA.Mask1) + + (rem >> PPU.VMA.Shift) + + ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3)) << 1) & 0xffff; + Memory.VRAM [address] = Byte; + IPPU.TileCached [TILE_2BIT][address >> 4] = FALSE; + IPPU.TileCached [TILE_4BIT][address >> 5] = FALSE; + IPPU.TileCached [TILE_8BIT][address >> 6] = FALSE; + if (!PPU.VMA.High) + PPU.VMA.Address += PPU.VMA.Increment; +// Memory.FillRAM [0x2118] = Byte; +} + +STATIC INLINE void REGISTER_2118_linear (uint8 Byte) +{ + uint32 address; + Memory.VRAM[address = (PPU.VMA.Address << 1) & 0xFFFF] = Byte; + IPPU.TileCached [TILE_2BIT][address >> 4] = FALSE; + IPPU.TileCached [TILE_4BIT][address >> 5] = FALSE; + IPPU.TileCached [TILE_8BIT][address >> 6] = FALSE; + if (!PPU.VMA.High) + PPU.VMA.Address += PPU.VMA.Increment; +// Memory.FillRAM [0x2118] = Byte; +} + +STATIC INLINE void REGISTER_2119 (uint8 Byte) +{ + uint32 address; + if (PPU.VMA.FullGraphicCount) + { + uint32 rem = PPU.VMA.Address & PPU.VMA.Mask1; + address = ((((PPU.VMA.Address & ~PPU.VMA.Mask1) + + (rem >> PPU.VMA.Shift) + + ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3)) << 1) + 1) & 0xFFFF; + Memory.VRAM [address] = Byte; + } + else + { + Memory.VRAM[address = ((PPU.VMA.Address << 1) + 1) & 0xFFFF] = Byte; + } + IPPU.TileCached [TILE_2BIT][address >> 4] = FALSE; + IPPU.TileCached [TILE_4BIT][address >> 5] = FALSE; + IPPU.TileCached [TILE_8BIT][address >> 6] = FALSE; + if (PPU.VMA.High) + { +#ifdef DEBUGGER + if (Settings.TraceVRAM && !CPU.InDMA) + { + printf ("VRAM write word: $%04X (%d,%d)\n", PPU.VMA.Address, + Memory.FillRAM[0x2115] & 3, + (Memory.FillRAM [0x2115] & 0x0c) >> 2); + } +#endif + PPU.VMA.Address += PPU.VMA.Increment; + } +// Memory.FillRAM [0x2119] = Byte; +} + +STATIC INLINE void REGISTER_2119_tile (uint8 Byte) +{ + uint32 rem = PPU.VMA.Address & PPU.VMA.Mask1; + uint32 address = ((((PPU.VMA.Address & ~PPU.VMA.Mask1) + + (rem >> PPU.VMA.Shift) + + ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3)) << 1) + 1) & 0xFFFF; + Memory.VRAM [address] = Byte; + IPPU.TileCached [TILE_2BIT][address >> 4] = FALSE; + IPPU.TileCached [TILE_4BIT][address >> 5] = FALSE; + IPPU.TileCached [TILE_8BIT][address >> 6] = FALSE; + if (PPU.VMA.High) + PPU.VMA.Address += PPU.VMA.Increment; +// Memory.FillRAM [0x2119] = Byte; +} + +STATIC INLINE void REGISTER_2119_linear (uint8 Byte) +{ + uint32 address; + Memory.VRAM[address = ((PPU.VMA.Address << 1) + 1) & 0xFFFF] = Byte; + IPPU.TileCached [TILE_2BIT][address >> 4] = FALSE; + IPPU.TileCached [TILE_4BIT][address >> 5] = FALSE; + IPPU.TileCached [TILE_8BIT][address >> 6] = FALSE; + if (PPU.VMA.High) + PPU.VMA.Address += PPU.VMA.Increment; +// Memory.FillRAM [0x2119] = Byte; +} + +STATIC INLINE void REGISTER_2122(uint8 Byte) +{ + // CG-RAM (palette) write + + if (PPU.CGFLIP) + { + if ((Byte & 0x7f) != (PPU.CGDATA[PPU.CGADD] >> 8)) + { +#ifndef _SNESPPC + if (Settings.SixteenBit) +#endif + FLUSH_REDRAW (); + PPU.CGDATA[PPU.CGADD] &= 0x00FF; + PPU.CGDATA[PPU.CGADD] |= (Byte & 0x7f) << 8; + IPPU.ColorsChanged = TRUE; +#ifndef _SNESPPC + if (Settings.SixteenBit) +#endif + { + IPPU.Blue [PPU.CGADD] = IPPU.XB [(Byte >> 2) & 0x1f]; + IPPU.Green [PPU.CGADD] = IPPU.XB [(PPU.CGDATA[PPU.CGADD] >> 5) & 0x1f]; + IPPU.ScreenColors [PPU.CGADD] = (uint16) BUILD_PIXEL (IPPU.Red [PPU.CGADD], + IPPU.Green [PPU.CGADD], + IPPU.Blue [PPU.CGADD]); + } + } + PPU.CGADD++; + } + else + { + if (Byte != (uint8) (PPU.CGDATA[PPU.CGADD] & 0xff)) + { +#ifndef _SNESPPC + if (Settings.SixteenBit) +#endif + FLUSH_REDRAW (); + PPU.CGDATA[PPU.CGADD] &= 0x7F00; + PPU.CGDATA[PPU.CGADD] |= Byte; + IPPU.ColorsChanged = TRUE; +#ifndef _SNESPPC + if (Settings.SixteenBit) +#endif + { + IPPU.Red [PPU.CGADD] = IPPU.XB [Byte & 0x1f]; + IPPU.Green [PPU.CGADD] = IPPU.XB [(PPU.CGDATA[PPU.CGADD] >> 5) & 0x1f]; + IPPU.ScreenColors [PPU.CGADD] = (uint16) BUILD_PIXEL (IPPU.Red [PPU.CGADD], + IPPU.Green [PPU.CGADD], + IPPU.Blue [PPU.CGADD]); + } + } + } + PPU.CGFLIP ^= 1; +// Memory.FillRAM [0x2122] = Byte; +} + +STATIC INLINE void REGISTER_2180(uint8 Byte) +{ + Memory.RAM[PPU.WRAM++] = Byte; + PPU.WRAM &= 0x1FFFF; + Memory.FillRAM [0x2180] = Byte; +} +#endif diff --git a/src/snes4iphone_src/ppu_.cpp b/src/snes4iphone_src/ppu_.cpp new file mode 100755 index 0000000..1cdfa0b --- /dev/null +++ b/src/snes4iphone_src/ppu_.cpp @@ -0,0 +1,2644 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#include "snes9x.h" +#include "memmap.h" +#include "ppu.h" +#include "cpuexec.h" +#include "missing.h" +#include "apu.h" +#include "dma.h" +#include "gfx.h" +#include "display.h" +#include "sa1.h" +#ifndef _SNESPPC +//#include "netplay.h" +#endif +#include "sdd1.h" +#include "srtc.h" + + +#ifndef ZSNES_FX +#include "fxemu.h" +#include "fxinst.h" +extern struct FxInit_s SuperFX; +extern struct FxRegs_s GSU; +#else +EXTERN_C void S9xSuperFXWriteReg (uint8, uint32); +EXTERN_C uint8 S9xSuperFXReadReg (uint32); +#endif + +void S9xUpdateHTimer () +{ + if (PPU.HTimerEnabled) + { +#ifdef DEBUGGER + missing.hirq_pos = PPU.IRQHBeamPos; +#endif + PPU.HTimerPosition = PPU.IRQHBeamPos * Settings.H_Max / SNES_HCOUNTER_MAX; + if (PPU.HTimerPosition == Settings.H_Max || + PPU.HTimerPosition == Settings.HBlankStart) + { + PPU.HTimerPosition--; + } + + if (!PPU.VTimerEnabled || CPU.V_Counter == PPU.IRQVBeamPos) + { + if (PPU.HTimerPosition < CPU.Cycles) + { + // Missed the IRQ on this line already + if (CPU.WhichEvent == HBLANK_END_EVENT || + CPU.WhichEvent == HTIMER_AFTER_EVENT) + { + CPU.WhichEvent = HBLANK_END_EVENT; + CPU.NextEvent = Settings.H_Max; + } + else + { + CPU.WhichEvent = HBLANK_START_EVENT; + CPU.NextEvent = Settings.HBlankStart; + } + } + else + { + if (CPU.WhichEvent == HTIMER_BEFORE_EVENT || + CPU.WhichEvent == HBLANK_START_EVENT) + { + if (PPU.HTimerPosition > Settings.HBlankStart) + { + // HTimer was to trigger before h-blank start, + // now triggers after start of h-blank + CPU.NextEvent = Settings.HBlankStart; + CPU.WhichEvent = HBLANK_START_EVENT; + } + else + { + CPU.NextEvent = PPU.HTimerPosition; + CPU.WhichEvent = HTIMER_BEFORE_EVENT; + } + } + else + { + CPU.WhichEvent = HTIMER_AFTER_EVENT; + CPU.NextEvent = PPU.HTimerPosition; + } + } + } + } +} + +void S9xFixColourBrightness () +{ + IPPU.XB = mul_brightness [PPU.Brightness]; +#ifndef _SNESPPC + if (Settings.SixteenBit) +#endif + { + for (int i = 0; i < 256; i++) + { + IPPU.Red [i] = IPPU.XB [PPU.CGDATA [i] & 0x1f]; + IPPU.Green [i] = IPPU.XB [(PPU.CGDATA [i] >> 5) & 0x1f]; + IPPU.Blue [i] = IPPU.XB [(PPU.CGDATA [i] >> 10) & 0x1f]; + IPPU.ScreenColors [i] = BUILD_PIXEL (IPPU.Red [i], IPPU.Green [i], + IPPU.Blue [i]); + } + } +} + +/**********************************************************************************************/ +/* S9xSetPPU() */ +/* This function sets a PPU Register to a specific byte */ +/**********************************************************************************************/ +void S9xSetPPU (uint8 Byte, uint16 Address) +{ + if (Address <= 0x2183) + { + switch (Address) + { + case 0x2100: + // Brightness and screen blank bit + if (Byte != Memory.FillRAM [0x2100]) + { + FLUSH_REDRAW (); + if (PPU.Brightness != (Byte & 0xF)) + { + IPPU.ColorsChanged = TRUE; + IPPU.DirectColourMapsNeedRebuild = TRUE; + PPU.Brightness = Byte & 0xF; + S9xFixColourBrightness (); + if (PPU.Brightness > IPPU.MaxBrightness) + IPPU.MaxBrightness = PPU.Brightness; + } + if ((Memory.FillRAM[0x2100] & 0x80) != (Byte & 0x80)) + { + IPPU.ColorsChanged = TRUE; + PPU.ForcedBlanking = (Byte >> 7) & 1; + } + } + break; + + case 0x2101: + // Sprite (OBJ) tile address + if (Byte != Memory.FillRAM [0x2101]) + { + FLUSH_REDRAW (); + PPU.OBJNameBase = (Byte & 3) << 14; + PPU.OBJNameSelect = ((Byte >> 3) & 3) << 13; + PPU.OBJSizeSelect = (Byte >> 5) & 7; + IPPU.OBJChanged = TRUE; + } + break; + + case 0x2102: + // Sprite write address (low) + PPU.OAMAddr = Byte; + PPU.OAMFlip = 2; + PPU.OAMReadFlip = 0; + PPU.SavedOAMAddr = PPU.OAMAddr; + if (PPU.OAMPriorityRotation) + { + PPU.FirstSprite = PPU.OAMAddr & 0x7f; +#ifdef DEBUGGER + missing.sprite_priority_rotation = 1; +#endif + } + break; + + case 0x2103: + // Sprite register write address (high), sprite priority rotation + // bit. + if ((PPU.OAMPriorityRotation = (Byte & 0x80) == 0 ? 0 : 1)) + { + PPU.FirstSprite = PPU.OAMAddr & 0x7f; +#ifdef DEBUGGER + missing.sprite_priority_rotation = 1; +#endif + } + // Only update the sprite write address top bit if the low byte has + // been written to first. + if (PPU.OAMFlip & 2) + { + PPU.OAMAddr &= 0x00FF; + PPU.OAMAddr |= (Byte & 1) << 8; + } + PPU.OAMFlip = 0; + PPU.OAMReadFlip = 0; + PPU.SavedOAMAddr = PPU.OAMAddr; + break; + + case 0x2104: + // Sprite register write + REGISTER_2104(Byte, &Memory, &IPPU, &PPU); + + break; + + case 0x2105: + // Screen mode (0 - 7), background tile sizes and background 3 + // priority + if (Byte != Memory.FillRAM [0x2105]) + { + FLUSH_REDRAW (); + PPU.BG3Priority = (Byte >> 3) & 1; + PPU.BG[0].BGSize = (Byte >> 4) & 1; + PPU.BG[1].BGSize = (Byte >> 5) & 1; + PPU.BG[2].BGSize = (Byte >> 6) & 1; + PPU.BG[3].BGSize = (Byte >> 7) & 1; + PPU.BGMode = Byte & 7; +#ifdef DEBUGGER + missing.modes[PPU.BGMode] = 1; +#endif + } + break; + + case 0x2106: + // Mosaic pixel size and enable + if (Byte != Memory.FillRAM [0x2106]) + { + FLUSH_REDRAW (); +#ifdef DEBUGGER + if ((Byte & 0xf0) && (Byte & 0x0f)) + missing.mosaic = 1; +#endif + PPU.Mosaic = (Byte >> 4) + 1; + PPU.BGMosaic [0] = (Byte & 1) && PPU.Mosaic > 1; + PPU.BGMosaic [1] = (Byte & 2) && PPU.Mosaic > 1; + PPU.BGMosaic [2] = (Byte & 4) && PPU.Mosaic > 1; + PPU.BGMosaic [3] = (Byte & 8) && PPU.Mosaic > 1; + } + break; + case 0x2107: // [BG0SC] + if (Byte != Memory.FillRAM [0x2107]) + { + FLUSH_REDRAW (); + PPU.BG[0].SCSize = Byte & 3; + PPU.BG[0].SCBase = (Byte & 0x7c) << 8; + } + break; + + case 0x2108: // [BG1SC] + if (Byte != Memory.FillRAM [0x2108]) + { + FLUSH_REDRAW (); + PPU.BG[1].SCSize = Byte & 3; + PPU.BG[1].SCBase = (Byte & 0x7c) << 8; + } + break; + + case 0x2109: // [BG2SC] + if (Byte != Memory.FillRAM [0x2109]) + { + FLUSH_REDRAW (); + PPU.BG[2].SCSize = Byte & 3; + PPU.BG[2].SCBase = (Byte & 0x7c) << 8; + } + break; + + case 0x210A: // [BG3SC] + if (Byte != Memory.FillRAM [0x210a]) + { + FLUSH_REDRAW (); + PPU.BG[3].SCSize = Byte & 3; + PPU.BG[3].SCBase = (Byte & 0x7c) << 8; + } + break; + + case 0x210B: // [BG01NBA] + if (Byte != Memory.FillRAM [0x210b]) + { + FLUSH_REDRAW (); + PPU.BG[0].NameBase = (Byte & 7) << 12; + PPU.BG[1].NameBase = ((Byte >> 4) & 7) << 12; + } + break; + + case 0x210C: // [BG23NBA] + if (Byte != Memory.FillRAM [0x210c]) + { + FLUSH_REDRAW (); + PPU.BG[2].NameBase = (Byte & 7) << 12; + PPU.BG[3].NameBase = ((Byte >> 4) & 7) << 12; + } + break; + + case 0x210D: + PPU.BG[0].HOffset = ((PPU.BG[0].HOffset >> 8) & 0xff) | + ((uint16) Byte << 8); + break; + + case 0x210E: + PPU.BG[0].VOffset = ((PPU.BG[0].VOffset >> 8) & 0xff) | + ((uint16) Byte << 8); + break; + case 0x210F: + PPU.BG[1].HOffset = ((PPU.BG[1].HOffset >> 8) & 0xff) | + ((uint16) Byte << 8); + break; + + case 0x2110: + PPU.BG[1].VOffset = ((PPU.BG[1].VOffset >> 8) & 0xff) | + ((uint16) Byte << 8); + break; + + case 0x2111: + PPU.BG[2].HOffset = ((PPU.BG[2].HOffset >> 8) & 0xff) | + ((uint16) Byte << 8); + break; + + case 0x2112: + PPU.BG[2].VOffset = ((PPU.BG[2].VOffset >> 8) & 0xff) | + ((uint16) Byte << 8); + break; + + case 0x2113: + PPU.BG[3].HOffset = ((PPU.BG[3].HOffset >> 8) & 0xff) | + ((uint16) Byte << 8); + break; + + case 0x2114: + PPU.BG[3].VOffset = ((PPU.BG[3].VOffset >> 8) & 0xff) | + ((uint16) Byte << 8); + break; + + case 0x2115: + // VRAM byte/word access flag and increment + PPU.VMA.High = (Byte & 0x80) == 0 ? FALSE : TRUE; + switch (Byte & 3) + { + case 0: + PPU.VMA.Increment = 1; + break; + case 1: + PPU.VMA.Increment = 32; + break; + case 2: + PPU.VMA.Increment = 128; + break; + case 3: + PPU.VMA.Increment = 128; + break; + } +#ifdef DEBUGGER + if ((Byte & 3) != 0) + missing.vram_inc = Byte & 3; +#endif + if (Byte & 0x0c) + { + static uint16 IncCount [4] = { 0, 32, 64, 128 }; + static uint16 Shift [4] = { 0, 5, 6, 7 }; +#ifdef DEBUGGER + missing.vram_full_graphic_inc = (Byte & 0x0c) >> 2; +#endif + PPU.VMA.Increment = 1; + uint8 i = (Byte & 0x0c) >> 2; + PPU.VMA.FullGraphicCount = IncCount [i]; + PPU.VMA.Mask1 = IncCount [i] * 8 - 1; + PPU.VMA.Shift = Shift [i]; + } + else + PPU.VMA.FullGraphicCount = 0; + break; + + case 0x2116: + // VRAM read/write address (low) + PPU.VMA.Address &= 0xFF00; + PPU.VMA.Address |= Byte; + IPPU.FirstVRAMRead = TRUE; + break; + + case 0x2117: + // VRAM read/write address (high) + PPU.VMA.Address &= 0x00FF; + PPU.VMA.Address |= Byte << 8; + IPPU.FirstVRAMRead = TRUE; + break; + + case 0x2118: + // VRAM write data (low) + IPPU.FirstVRAMRead = TRUE; + REGISTER_2118(Byte, &Memory, &IPPU, &PPU); + break; + + case 0x2119: + // VRAM write data (high) + IPPU.FirstVRAMRead = TRUE; + REGISTER_2119(Byte, &Memory, &IPPU, &PPU); + break; + + case 0x211a: + // Mode 7 outside rotation area display mode and flipping + if (Byte != Memory.FillRAM [0x211a]) + { + FLUSH_REDRAW (); + PPU.Mode7Repeat = Byte >> 6; + PPU.Mode7VFlip = (Byte & 2) >> 1; + PPU.Mode7HFlip = Byte & 1; + } + break; + case 0x211b: + // Mode 7 matrix A (low & high) + PPU.MatrixA = ((PPU.MatrixA >> 8) & 0xff) | (Byte << 8); + PPU.Need16x8Mulitply = TRUE; + break; + case 0x211c: + // Mode 7 matrix B (low & high) + PPU.MatrixB = ((PPU.MatrixB >> 8) & 0xff) | (Byte << 8); + PPU.Need16x8Mulitply = TRUE; + break; + case 0x211d: + // Mode 7 matrix C (low & high) + PPU.MatrixC = ((PPU.MatrixC >> 8) & 0xff) | (Byte << 8); + break; + case 0x211e: + // Mode 7 matrix D (low & high) + PPU.MatrixD = ((PPU.MatrixD >> 8) & 0xff) | (Byte << 8); + break; + case 0x211f: + // Mode 7 centre of rotation X (low & high) + PPU.CentreX = ((PPU.CentreX >> 8) & 0xff) | (Byte << 8); + break; + case 0x2120: + // Mode 7 centre of rotation Y (low & high) + PPU.CentreY = ((PPU.CentreY >> 8) & 0xff) | (Byte << 8); + break; + + case 0x2121: + // CG-RAM address + PPU.CGFLIP = 0; + PPU.CGFLIPRead = 0; + PPU.CGADD = Byte; + break; + + case 0x2122: + REGISTER_2122(Byte, &Memory, &IPPU, &PPU); + break; + + case 0x2123: + // Window 1 and 2 enable for backgrounds 1 and 2 + if (Byte != Memory.FillRAM [0x2123]) + { + FLUSH_REDRAW (); + + PPU.ClipWindow1Enable [0] = !!(Byte & 0x02); + PPU.ClipWindow1Enable [1] = !!(Byte & 0x20); + PPU.ClipWindow2Enable [0] = !!(Byte & 0x08); + PPU.ClipWindow2Enable [1] = !!(Byte & 0x80); + PPU.ClipWindow1Inside [0] = !(Byte & 0x01); + PPU.ClipWindow1Inside [1] = !(Byte & 0x10); + PPU.ClipWindow2Inside [0] = !(Byte & 0x04); + PPU.ClipWindow2Inside [1] = !(Byte & 0x40); + PPU.RecomputeClipWindows = TRUE; +#ifdef DEBUGGER + if (Byte & 0x80) + missing.window2[1] = 1; + if (Byte & 0x20) + missing.window1[1] = 1; + if (Byte & 0x08) + missing.window2[0] = 1; + if (Byte & 0x02) + missing.window1[0] = 1; +#endif + } + break; + case 0x2124: + // Window 1 and 2 enable for backgrounds 3 and 4 + if (Byte != Memory.FillRAM [0x2124]) + { + FLUSH_REDRAW (); + + PPU.ClipWindow1Enable [2] = !!(Byte & 0x02); + PPU.ClipWindow1Enable [3] = !!(Byte & 0x20); + PPU.ClipWindow2Enable [2] = !!(Byte & 0x08); + PPU.ClipWindow2Enable [3] = !!(Byte & 0x80); + PPU.ClipWindow1Inside [2] = !(Byte & 0x01); + PPU.ClipWindow1Inside [3] = !(Byte & 0x10); + PPU.ClipWindow2Inside [2] = !(Byte & 0x04); + PPU.ClipWindow2Inside [3] = !(Byte & 0x40); + PPU.RecomputeClipWindows = TRUE; +#ifdef DEBUGGER + if (Byte & 0x80) + missing.window2[3] = 1; + if (Byte & 0x20) + missing.window1[3] = 1; + if (Byte & 0x08) + missing.window2[2] = 1; + if (Byte & 0x02) + missing.window1[2] = 1; +#endif + } + break; + case 0x2125: + // Window 1 and 2 enable for objects and colour window + if (Byte != Memory.FillRAM [0x2125]) + { + FLUSH_REDRAW (); + + PPU.ClipWindow1Enable [4] = !!(Byte & 0x02); + PPU.ClipWindow1Enable [5] = !!(Byte & 0x20); + PPU.ClipWindow2Enable [4] = !!(Byte & 0x08); + PPU.ClipWindow2Enable [5] = !!(Byte & 0x80); + PPU.ClipWindow1Inside [4] = !(Byte & 0x01); + PPU.ClipWindow1Inside [5] = !(Byte & 0x10); + PPU.ClipWindow2Inside [4] = !(Byte & 0x04); + PPU.ClipWindow2Inside [5] = !(Byte & 0x40); + PPU.RecomputeClipWindows = TRUE; +#ifdef DEBUGGER + if (Byte & 0x80) + missing.window2[5] = 1; + if (Byte & 0x20) + missing.window1[5] = 1; + if (Byte & 0x08) + missing.window2[4] = 1; + if (Byte & 0x02) + missing.window1[4] = 1; +#endif + } + break; + case 0x2126: + // Window 1 left position + if (Byte != Memory.FillRAM [0x2126]) + { + FLUSH_REDRAW (); + + PPU.Window1Left = Byte; + PPU.RecomputeClipWindows = TRUE; + } + break; + case 0x2127: + // Window 1 right position + if (Byte != Memory.FillRAM [0x2127]) + { + FLUSH_REDRAW (); + + PPU.Window1Right = Byte; + PPU.RecomputeClipWindows = TRUE; + } + break; + case 0x2128: + // Window 2 left position + if (Byte != Memory.FillRAM [0x2128]) + { + FLUSH_REDRAW (); + + PPU.Window2Left = Byte; + PPU.RecomputeClipWindows = TRUE; + } + break; + case 0x2129: + // Window 2 right position + if (Byte != Memory.FillRAM [0x2129]) + { + FLUSH_REDRAW (); + + PPU.Window2Right = Byte; + PPU.RecomputeClipWindows = TRUE; + } + break; + case 0x212a: + // Windows 1 & 2 overlap logic for backgrounds 1 - 4 + if (Byte != Memory.FillRAM [0x212a]) + { + FLUSH_REDRAW (); + + PPU.ClipWindowOverlapLogic [0] = (Byte & 0x03); + PPU.ClipWindowOverlapLogic [1] = (Byte & 0x0c) >> 2; + PPU.ClipWindowOverlapLogic [2] = (Byte & 0x30) >> 4; + PPU.ClipWindowOverlapLogic [3] = (Byte & 0xc0) >> 6; + PPU.RecomputeClipWindows = TRUE; + } + break; + case 0x212b: + // Windows 1 & 2 overlap logic for objects and colour window + if (Byte != Memory.FillRAM [0x212b]) + { + FLUSH_REDRAW (); + + PPU.ClipWindowOverlapLogic [4] = Byte & 0x03; + PPU.ClipWindowOverlapLogic [5] = (Byte & 0x0c) >> 2; + PPU.RecomputeClipWindows = TRUE; + } + break; + case 0x212c: + // Main screen designation (backgrounds 1 - 4 and objects) + if (Byte != Memory.FillRAM [0x212c]) + { + FLUSH_REDRAW (); + + PPU.RecomputeClipWindows = TRUE; + Memory.FillRAM [Address] = Byte; + return; + } + break; + case 0x212d: + // Sub-screen designation (backgrounds 1 - 4 and objects) + if (Byte != Memory.FillRAM [0x212d]) + { + FLUSH_REDRAW (); + +#ifdef DEBUGGER + if (Byte & 0x1f) + missing.subscreen = 1; +#endif + PPU.RecomputeClipWindows = TRUE; + Memory.FillRAM [Address] = Byte; + return; + } + break; + case 0x212e: + // Window mask designation for main screen ? + if (Byte != Memory.FillRAM [0x212e]) + { + FLUSH_REDRAW (); + + PPU.RecomputeClipWindows = TRUE; + } + break; + case 0x212f: + // Window mask designation for sub-screen ? + if (Byte != Memory.FillRAM [0x212f]) + { + FLUSH_REDRAW (); + + PPU.RecomputeClipWindows = TRUE; + } + break; + case 0x2130: + // Fixed colour addition or screen addition + if (Byte != Memory.FillRAM [0x2130]) + { + FLUSH_REDRAW (); + + PPU.RecomputeClipWindows = TRUE; +#ifdef DEBUGGER + if ((Byte & 1) && (PPU.BGMode == 3 || PPU.BGMode == 4 || PPU.BGMode == 7)) + missing.direct = 1; +#endif + } + break; + case 0x2131: + // Colour addition or subtraction select + if (Byte != Memory.FillRAM[0x2131]) + { + FLUSH_REDRAW (); + + // Backgrounds 1 - 4, objects and backdrop colour add/sub enable +#ifdef DEBUGGER + if (Byte & 0x80) + { + // Subtract + if (Memory.FillRAM[0x2130] & 0x02) + missing.subscreen_sub = 1; + else + missing.fixed_colour_sub = 1; + } + else + { + // Addition + if (Memory.FillRAM[0x2130] & 0x02) + missing.subscreen_add = 1; + else + missing.fixed_colour_add = 1; + } +#endif + Memory.FillRAM[0x2131] = Byte; + } + break; + case 0x2132: + if (Byte != Memory.FillRAM [0x2132]) + { + FLUSH_REDRAW (); + + // Colour data for fixed colour addition/subtraction + if (Byte & 0x80) + PPU.FixedColourBlue = Byte & 0x1f; + if (Byte & 0x40) + PPU.FixedColourGreen = Byte & 0x1f; + if (Byte & 0x20) + PPU.FixedColourRed = Byte & 0x1f; + } + break; + case 0x2133: + // Screen settings + if (Byte != Memory.FillRAM [0x2133]) + { +#ifdef DEBUGGER + if (Byte & 0x40) + missing.mode7_bgmode = 1; + if (Byte & 0x08) + missing.pseudo_512 = 1; +#endif + if (Byte & 0x04) + { + PPU.ScreenHeight = SNES_HEIGHT_EXTENDED; +#ifdef DEBUGGER + missing.lines_239 = 1; +#endif + } + else + PPU.ScreenHeight = SNES_HEIGHT; +#ifdef DEBUGGER + if (Byte & 0x02) + missing.sprite_double_height = 1; + + if (Byte & 1) + missing.interlace = 1; +#endif + } + break; + case 0x2134: + case 0x2135: + case 0x2136: + // Matrix 16bit x 8bit multiply result (read-only) + return; + + case 0x2137: + // Software latch for horizontal and vertical timers (read-only) + return; + case 0x2138: + // OAM read data (read-only) + return; + case 0x2139: + case 0x213a: + // VRAM read data (read-only) + return; + case 0x213b: + // CG-RAM read data (read-only) + return; + case 0x213c: + case 0x213d: + // Horizontal and vertical (low/high) read counter (read-only) + return; + case 0x213e: + // PPU status (time over and range over) + return; + case 0x213f: + // NTSC/PAL select and field (read-only) + return; + case 0x2140: case 0x2141: case 0x2142: case 0x2143: + case 0x2144: case 0x2145: case 0x2146: case 0x2147: + case 0x2148: case 0x2149: case 0x214a: case 0x214b: + case 0x214c: case 0x214d: case 0x214e: case 0x214f: + case 0x2150: case 0x2151: case 0x2152: case 0x2153: + case 0x2154: case 0x2155: case 0x2156: case 0x2157: + case 0x2158: case 0x2159: case 0x215a: case 0x215b: + case 0x215c: case 0x215d: case 0x215e: case 0x215f: + case 0x2160: case 0x2161: case 0x2162: case 0x2163: + case 0x2164: case 0x2165: case 0x2166: case 0x2167: + case 0x2168: case 0x2169: case 0x216a: case 0x216b: + case 0x216c: case 0x216d: case 0x216e: case 0x216f: + case 0x2170: case 0x2171: case 0x2172: case 0x2173: + case 0x2174: case 0x2175: case 0x2176: case 0x2177: + case 0x2178: case 0x2179: case 0x217a: case 0x217b: + case 0x217c: case 0x217d: case 0x217e: case 0x217f: +#ifdef SPCTOOL + _SPCInPB (Address & 3, Byte); +#else +// CPU.Flags |= DEBUG_MODE_FLAG; + Memory.FillRAM [Address] = Byte; + IAPU.RAM [(Address & 3) + 0xf4] = Byte; +#ifdef SPC700_SHUTDOWN + IAPU.APUExecuting = Settings.APUEnabled; + IAPU.WaitCounter++; +#endif +#endif // SPCTOOL + break; + case 0x2180: + REGISTER_2180(Byte, &Memory, &IPPU, &PPU); + break; + case 0x2181: + PPU.WRAM &= 0x1FF00; + PPU.WRAM |= Byte; + break; + case 0x2182: + PPU.WRAM &= 0x100FF; + PPU.WRAM |= Byte << 8; + break; + case 0x2183: + PPU.WRAM &= 0x0FFFF; + PPU.WRAM |= Byte << 16; + PPU.WRAM &= 0x1FFFF; + break; + } + } + else + { + if (Settings.SA1) + { + if (Address >= 0x2200 && Address <0x23ff) + S9xSetSA1 (Byte, Address); + else + Memory.FillRAM [Address] = Byte; + return; + } + else + // Dai Kaijyu Monogatari II + if (Address == 0x2801 && Settings.SRTC) + S9xSetSRTC (Byte, Address); + else + if (Address < 0x3000 || Address >= 0x3000 + 768) + { +#ifdef DEBUGGER + missing.unknownppu_write = Address; + if (Settings.TraceUnknownRegisters) + { + sprintf (String, "Unknown register write: $%02X->$%04X\n", + Byte, Address); + S9xMessage (S9X_TRACE, S9X_PPU_TRACE, String); + } +#endif + } + else + { + if (!Settings.SuperFX) + return; + + #ifdef ZSNES_FX + Memory.FillRAM [Address] = Byte; + if (Address < 0x3040) + S9xSuperFXWriteReg (Byte, Address); + #else + switch (Address) + { + case 0x3030: + if ((Memory.FillRAM [0x3030] ^ Byte) & FLG_G) + { + Memory.FillRAM [Address] = Byte; + // Go flag has been changed + if (Byte & FLG_G) + S9xSuperFXExec (); + else + FxFlushCache (&GSU); + } + else + Memory.FillRAM [Address] = Byte; + break; + + case 0x3031: + Memory.FillRAM [Address] = Byte; + break; + case 0x3033: + Memory.FillRAM [Address] = Byte; + break; + case 0x3034: + Memory.FillRAM [Address] = Byte & 0x7f; + break; + case 0x3036: + Memory.FillRAM [Address] = Byte & 0x7f; + break; + case 0x3037: + Memory.FillRAM [Address] = Byte; + break; + case 0x3038: + Memory.FillRAM [Address] = Byte; + break; + case 0x3039: + Memory.FillRAM [Address] = Byte; + break; + case 0x303a: + Memory.FillRAM [Address] = Byte; + break; + case 0x303b: + break; + case 0x303f: + Memory.FillRAM [Address] = Byte; + break; + case 0x301f: + Memory.FillRAM [Address] = Byte; + Memory.FillRAM [0x3000 + GSU_SFR] |= FLG_G; + S9xSuperFXExec (); + return; + + default: + Memory.FillRAM[Address] = Byte; + if (Address >= 0x3100) + { + FxCacheWriteAccess (Address, &GSU); + } + break; + } + #endif + return; + } + } + Memory.FillRAM[Address] = Byte; +} + +/**********************************************************************************************/ +/* S9xGetPPU() */ +/* This function retrieves a PPU Register */ +/**********************************************************************************************/ +uint8 S9xGetPPU (uint16 Address) +{ + uint8 byte = 0; + + if (Address <= 0x2190) + { + switch (Address) + { + case 0x2100: + case 0x2101: + return (Memory.FillRAM[Address]); + case 0x2102: +#ifdef DEBUGGER + missing.oam_address_read = 1; +#endif + return (uint8)(PPU.OAMAddr); + case 0x2103: + return (((PPU.OAMAddr >> 8) & 1) | (PPU.OAMPriorityRotation << 7)); + case 0x2104: + case 0x2105: + case 0x2106: + case 0x2107: + case 0x2108: + case 0x2109: + case 0x210a: + case 0x210b: + case 0x210c: + return (Memory.FillRAM[Address]); + case 0x210d: + case 0x210e: + case 0x210f: + case 0x2110: + case 0x2111: + case 0x2112: + case 0x2113: + case 0x2114: +#ifdef DEBUGGER + missing.bg_offset_read = 1; +#endif + return (Memory.FillRAM[Address]); + case 0x2115: + return (Memory.FillRAM[Address]); + case 0x2116: + return (uint8)(PPU.VMA.Address); + case 0x2117: + return (PPU.VMA.Address >> 8); + case 0x2118: + case 0x2119: + case 0x211a: + return (Memory.FillRAM[Address]); + case 0x211b: + case 0x211c: + case 0x211d: + case 0x211e: + case 0x211f: + case 0x2120: +#ifdef DEBUGGER + missing.matrix_read = 1; +#endif + return (Memory.FillRAM[Address]); + case 0x2121: + return (PPU.CGADD); + case 0x2122: + case 0x2123: + case 0x2124: + case 0x2125: + case 0x2126: + case 0x2127: + case 0x2128: + case 0x2129: + case 0x212a: + case 0x212b: + case 0x212c: + case 0x212d: + case 0x212e: + case 0x212f: + case 0x2130: + case 0x2131: + case 0x2132: + case 0x2133: + return (Memory.FillRAM[Address]); + + case 0x2134: + case 0x2135: + case 0x2136: + // 16bit x 8bit multiply read result. + if (PPU.Need16x8Mulitply) + { + int32 r = (int32) PPU.MatrixA * (int32) (PPU.MatrixB >> 8); + + Memory.FillRAM[0x2134] = (uint8) r; + Memory.FillRAM[0x2135] = (uint8)(r >> 8); + Memory.FillRAM[0x2136] = (uint8)(r >> 16); + PPU.Need16x8Mulitply = FALSE; + } +#ifdef DEBUGGER + missing.matrix_multiply = 1; +#endif + return (Memory.FillRAM[Address]); + case 0x2137: + // Latch h and v counters +#ifdef DEBUGGER + missing.h_v_latch = 1; +#endif +#if 0 +#ifdef CPU_SHUTDOWN + CPU.WaitAddress = CPU.PCAtOpcodeStart; +#endif +#endif + PPU.HVBeamCounterLatched = 1; + PPU.VBeamPosLatched = (uint16) CPU.V_Counter; + PPU.HBeamPosLatched = (uint16) ((CPU.Cycles * SNES_HCOUNTER_MAX) / Settings.H_Max); + + // Causes screen flicker for Yoshi's Island if uncommented + //CLEAR_IRQ_SOURCE (PPU_V_BEAM_IRQ_SOURCE | PPU_H_BEAM_IRQ_SOURCE); + + if (SNESGameFixes.NeedInit0x2137) + PPU.VBeamFlip = 0; //jyam sword world sfc2 & godzill + return (0); + case 0x2138: + // Read OAM (sprite) control data + if (!PPU.OAMReadFlip) + { + byte = PPU.OAMData [PPU.OAMAddr << 1]; + } + else + { + byte = PPU.OAMData [(PPU.OAMAddr << 1) + 1]; + if (++PPU.OAMAddr >= 0x110) + PPU.OAMAddr = 0; + + } + PPU.OAMReadFlip ^= 1; +#ifdef DEBUGGER + missing.oam_read = 1; +#endif + return (byte); + + case 0x2139: + // Read vram low byte +#ifdef DEBUGGER + missing.vram_read = 1; +#endif + if (IPPU.FirstVRAMRead) + byte = Memory.VRAM[PPU.VMA.Address << 1]; + else + if (PPU.VMA.FullGraphicCount) + { + uint32 addr = PPU.VMA.Address - 1; + uint32 rem = addr & PPU.VMA.Mask1; + uint32 address = (addr & ~PPU.VMA.Mask1) + + (rem >> PPU.VMA.Shift) + + ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3); + byte = Memory.VRAM [((address << 1) - 2) & 0xFFFF]; + } + else + byte = Memory.VRAM[((PPU.VMA.Address << 1) - 2) & 0xffff]; + + if (!PPU.VMA.High) + { + PPU.VMA.Address += PPU.VMA.Increment; + IPPU.FirstVRAMRead = FALSE; + } + break; + case 0x213A: + // Read vram high byte +#ifdef DEBUGGER + missing.vram_read = 1; +#endif + if (IPPU.FirstVRAMRead) + byte = Memory.VRAM[((PPU.VMA.Address << 1) + 1) & 0xffff]; + else + if (PPU.VMA.FullGraphicCount) + { + uint32 addr = PPU.VMA.Address - 1; + uint32 rem = addr & PPU.VMA.Mask1; + uint32 address = (addr & ~PPU.VMA.Mask1) + + (rem >> PPU.VMA.Shift) + + ((rem & (PPU.VMA.FullGraphicCount - 1)) << 3); + byte = Memory.VRAM [((address << 1) - 1) & 0xFFFF]; + } + else + byte = Memory.VRAM[((PPU.VMA.Address << 1) - 1) & 0xFFFF]; + if (PPU.VMA.High) + { + PPU.VMA.Address += PPU.VMA.Increment; + IPPU.FirstVRAMRead = FALSE; + } + break; + + case 0x213B: + // Read palette data +#ifdef DEBUGGER + missing.cgram_read = 1; +#endif + if (PPU.CGFLIPRead) + byte = PPU.CGDATA [PPU.CGADD++] >> 8; + else + byte = PPU.CGDATA [PPU.CGADD] & 0xff; + + PPU.CGFLIPRead ^= 1; + return (byte); + + case 0x213C: + // Horizontal counter value 0-339 +#ifdef DEBUGGER + missing.h_counter_read = 1; +#endif + if (PPU.HBeamFlip) + byte = PPU.HBeamPosLatched >> 8; + else + byte = (uint8)PPU.HBeamPosLatched; + PPU.HBeamFlip ^= 1; + break; + case 0x213D: + // Vertical counter value 0-262 +#ifdef DEBUGGER + missing.v_counter_read = 1; +#endif + if (PPU.VBeamFlip) + byte = PPU.VBeamPosLatched >> 8; + else + byte = (uint8)PPU.VBeamPosLatched; + PPU.VBeamFlip ^= 1; + break; + case 0x213E: + // PPU time and range over flags + return (SNESGameFixes._0x213E_ReturnValue); + + case 0x213F: + // NTSC/PAL and which field flags + PPU.VBeamFlip = PPU.HBeamFlip = 0; + return ((Settings.PAL ? 0x10 : 0) | (Memory.FillRAM[0x213f] & 0xc0)); + + case 0x2140: case 0x2141: case 0x2142: case 0x2143: + case 0x2144: case 0x2145: case 0x2146: case 0x2147: + case 0x2148: case 0x2149: case 0x214a: case 0x214b: + case 0x214c: case 0x214d: case 0x214e: case 0x214f: + case 0x2150: case 0x2151: case 0x2152: case 0x2153: + case 0x2154: case 0x2155: case 0x2156: case 0x2157: + case 0x2158: case 0x2159: case 0x215a: case 0x215b: + case 0x215c: case 0x215d: case 0x215e: case 0x215f: + case 0x2160: case 0x2161: case 0x2162: case 0x2163: + case 0x2164: case 0x2165: case 0x2166: case 0x2167: + case 0x2168: case 0x2169: case 0x216a: case 0x216b: + case 0x216c: case 0x216d: case 0x216e: case 0x216f: + case 0x2170: case 0x2171: case 0x2172: case 0x2173: + case 0x2174: case 0x2175: case 0x2176: case 0x2177: + case 0x2178: case 0x2179: case 0x217a: case 0x217b: + case 0x217c: case 0x217d: case 0x217e: case 0x217f: +#ifdef SPCTOOL + return ((uint8) _SPCOutP [Address & 3]); +#else + // CPU.Flags |= DEBUG_MODE_FLAG; +#ifdef SPC700_SHUTDOWN + IAPU.APUExecuting = Settings.APUEnabled; + IAPU.WaitCounter++; +#endif + if (Settings.APUEnabled) + { +#ifdef CPU_SHUTDOWN +// CPU.WaitAddress = CPU.PCAtOpcodeStart; +#endif + if (SNESGameFixes.APU_OutPorts_ReturnValueFix && + Address >= 0x2140 && Address <= 0x2143 && !CPU.V_Counter) + { + return (uint8)((Address & 1) ? ((rand() & 0xff00) >> 8) : + (rand() & 0xff)); + } + + return (APU.OutPorts [Address & 3]); + } + + switch (Settings.SoundSkipMethod) + { + case 0: + case 1: + CPU.BranchSkip = TRUE; + break; + case 2: + break; + case 3: + CPU.BranchSkip = TRUE; + break; + } + if (Address & 3 < 2) + { + int r = rand (); + if (r & 2) + { + if (r & 4) + return (Address & 3 == 1 ? 0xaa : 0xbb); + else + return ((r >> 3) & 0xff); + } + } + else + { + int r = rand (); + if (r & 2) + return ((r >> 3) & 0xff); + } + return (Memory.FillRAM[Address]); +#endif // SPCTOOL + + case 0x2180: + // Read WRAM +#ifdef DEBUGGER + missing.wram_read = 1; +#endif + byte = Memory.RAM [PPU.WRAM++]; + PPU.WRAM &= 0x1FFFF; + break; + case 0x2181: + case 0x2182: + case 0x2183: + return (Memory.FillRAM [Address]); + case 0x2190: + return (1); + } + } + else + { + if (Settings.SA1) + return (S9xGetSA1 (Address)); + + if (Address <= 0x2fff || Address >= 0x3000 + 768) + { + switch (Address) + { + case 0x21c2: + return (0x20); + case 0x21c3: + return (0); + case 0x2800: + // For Dai Kaijyu Monogatari II + if (Settings.SRTC) + return (S9xGetSRTC (Address)); + /*FALL*/ + + default: +#ifdef DEBUGGER + missing.unknownppu_read = Address; + if (Settings.TraceUnknownRegisters) + { + sprintf (String, "Unknown register read: $%04X\n", Address); + S9xMessage (S9X_TRACE, S9X_PPU_TRACE, String); + } +#endif + // XXX: + return (0); //Memory.FillRAM[Address]); + } + } + + if (!Settings.SuperFX) + return (0x30); +#ifdef ZSNES_FX + if (Address < 0x3040) + byte = S9xSuperFXReadReg (Address); + else + byte = Memory.FillRAM [Address]; + +#ifdef CPU_SHUTDOWN + if (Address == 0x3030) + CPU.WaitAddress = CPU.PCAtOpcodeStart; +#endif + if (Address == 0x3031) + CLEAR_IRQ_SOURCE (GSU_IRQ_SOURCE); +#else + byte = Memory.FillRAM [Address]; + +//if (Address != 0x3030 && Address != 0x3031) +//printf ("%04x\n", Address); +#ifdef CPU_SHUTDOWN + if (Address == 0x3030) + { + CPU.WaitAddress = CPU.PCAtOpcodeStart; + } + else +#endif + if (Address == 0x3031) + { + CLEAR_IRQ_SOURCE (GSU_IRQ_SOURCE); + Memory.FillRAM [0x3031] = byte & 0x7f; + } + return (byte); +#endif + } + + return (byte); +} + +/**********************************************************************************************/ +/* S9xSetCPU() */ +/* This function sets a CPU/DMA Register to a specific byte */ +/**********************************************************************************************/ +void S9xSetCPU (uint8 byte, uint16 Address) +{ + int d; + + if (Address < 0x4200) + { +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + switch (Address) + { + case 0x4016: + // S9xReset reading of old-style joypads + if ((byte & 1) && !(Memory.FillRAM [Address] & 1)) + { + PPU.Joypad1ButtonReadPos = 0; + PPU.Joypad2ButtonReadPos = 0; + PPU.Joypad3ButtonReadPos = 0; + } + break; + case 0x4017: + break; + default: +#ifdef DEBUGGER + missing.unknowncpu_write = Address; + if (Settings.TraceUnknownRegisters) + { + sprintf (String, "Unknown register register write: $%02X->$%04X\n", + byte, Address); + S9xMessage (S9X_TRACE, S9X_PPU_TRACE, String); + } +#endif + break; + } + } + else + switch (Address) + { + case 0x4200: + // NMI, V & H IRQ and joypad reading enable flags + if ((byte & 0x20) && + (!SNESGameFixes.umiharakawaseFix || PPU.IRQVBeamPos < 209)) + { + if (!PPU.VTimerEnabled) + { +#ifdef DEBUGGER + missing.virq = 1; + missing.virq_pos = PPU.IRQVBeamPos; +#endif + PPU.VTimerEnabled = TRUE; + if (PPU.HTimerEnabled) + S9xUpdateHTimer (); + else + if (PPU.IRQVBeamPos == CPU.V_Counter) + S9xSetIRQ (PPU_V_BEAM_IRQ_SOURCE); + } + } + else + { + PPU.VTimerEnabled = FALSE; +#ifndef RC_OPTIMIZED + if (SNESGameFixes.umiharakawaseFix) + byte &= ~0x20; +#endif + } + + if (byte & 0x10) + { + if (!PPU.HTimerEnabled) + { +#ifdef DEBUGGER + missing.hirq = 1; + missing.hirq_pos = PPU.IRQHBeamPos; +#endif + PPU.HTimerEnabled = TRUE; + S9xUpdateHTimer (); + } + } + else + { + // No need to check for HTimer being disabled as the scanline + // event trigger code won't trigger an H-IRQ unless its enabled. + PPU.HTimerEnabled = FALSE; + PPU.HTimerPosition = Settings.H_Max + 1; + } + +#ifndef RC_OPTIMIZED + if (!Settings.DaffyDuck) + CLEAR_IRQ_SOURCE (PPU_V_BEAM_IRQ_SOURCE | PPU_H_BEAM_IRQ_SOURCE); + + if ((byte & 0x80) && + !(Memory.FillRAM [0x4200] & 0x80) && + CPU.V_Counter >= PPU.ScreenHeight + FIRST_VISIBLE_LINE && + CPU.V_Counter <= PPU.ScreenHeight + + (SNESGameFixes.alienVSpredetorFix ? 25 : 15) && //jyam 15->25 alien vs predetor +// Panic Bomberman clears the NMI pending flag @ scanline 230 before enabling +// NMIs again. The NMI routine crashes the CPU if it is called without the NMI +// pending flag being set... + (Memory.FillRAM [0x4210] & 0x80) && + !CPU.NMIActive) + { + CPU.Flags |= NMI_FLAG; + CPU.NMIActive = TRUE; + CPU.NMICycleCount = CPU.NMITriggerPoint; + } +#endif + break; + case 0x4201: + // I/O port output + case 0x4202: + // Multiplier (for multply) + break; + case 0x4203: + { + // Multiplicand + uint32 res = Memory.FillRAM[0x4202] * byte; + + Memory.FillRAM[0x4216] = (uint8) res; + Memory.FillRAM[0x4217] = (uint8) (res >> 8); + break; + } + case 0x4204: + case 0x4205: + // Low and high muliplier (for divide) + break; + case 0x4206: + { + // Divisor + uint16 a = Memory.FillRAM[0x4204] + (Memory.FillRAM[0x4205] << 8); + uint16 div = byte ? a / byte : 0xffff; + uint16 rem = byte ? a % byte : a; + + Memory.FillRAM[0x4214] = (uint8)div; + Memory.FillRAM[0x4215] = div >> 8; + Memory.FillRAM[0x4216] = (uint8)rem; + Memory.FillRAM[0x4217] = rem >> 8; + break; + } + case 0x4207: + d = PPU.IRQHBeamPos; + PPU.IRQHBeamPos = (PPU.IRQHBeamPos & 0xFF00) | byte; + + if (PPU.HTimerEnabled && PPU.IRQHBeamPos != d) + S9xUpdateHTimer (); + break; + + case 0x4208: + d = PPU.IRQHBeamPos; + PPU.IRQHBeamPos = (PPU.IRQHBeamPos & 0xFF) | ((byte & 1) << 8); + + if (PPU.HTimerEnabled && PPU.IRQHBeamPos != d) + S9xUpdateHTimer (); + + break; + + case 0x4209: + d = PPU.IRQVBeamPos; + PPU.IRQVBeamPos = (PPU.IRQVBeamPos & 0xFF00) | byte; +#ifdef DEBUGGER + missing.virq_pos = PPU.IRQVBeamPos; +#endif + if (PPU.VTimerEnabled && PPU.IRQVBeamPos != d) + { + if (PPU.HTimerEnabled) + S9xUpdateHTimer (); + else + { + if (PPU.IRQVBeamPos == CPU.V_Counter) + S9xSetIRQ (PPU_V_BEAM_IRQ_SOURCE); + } + } + break; + + case 0x420A: + d = PPU.IRQVBeamPos; + PPU.IRQVBeamPos = (PPU.IRQVBeamPos & 0xFF) | ((byte & 1) << 8); +#ifdef DEBUGGER + missing.virq_pos = PPU.IRQVBeamPos; +#endif + if (PPU.VTimerEnabled && PPU.IRQVBeamPos != d) + { + if (PPU.HTimerEnabled) + S9xUpdateHTimer (); + else + { + if (PPU.IRQVBeamPos == CPU.V_Counter) + S9xSetIRQ (PPU_V_BEAM_IRQ_SOURCE); + } + } + break; + + case 0x420B: +#ifdef DEBUGGER + missing.dma_this_frame = byte; + missing.dma_channels = byte; +#endif + if ((byte & 0x01) != 0) + S9xDoDMA (0); + if ((byte & 0x02) != 0) + S9xDoDMA (1); + if ((byte & 0x04) != 0) + S9xDoDMA (2); + if ((byte & 0x08) != 0) + S9xDoDMA (3); + if ((byte & 0x10) != 0) + S9xDoDMA (4); + if ((byte & 0x20) != 0) + S9xDoDMA (5); + if ((byte & 0x40) != 0) + S9xDoDMA (6); + if ((byte & 0x80) != 0) + S9xDoDMA (7); + break; + case 0x420C: +#ifdef DEBUGGER + missing.hdma_this_frame |= byte; + missing.hdma_channels |= byte; +#endif + if (Settings.DisableHDMA) + byte = 0; + Memory.FillRAM[0x420c] = byte; + IPPU.HDMA = byte; + break; + + case 0x420d: + // Cycle speed 0 - 2.68Mhz, 1 - 3.58Mhz (banks 0x80 +) + if ((byte & 1) != (Memory.FillRAM [0x420d] & 1)) + { + if (byte & 1) + { + CPU.FastROMSpeed = ONE_CYCLE; +#ifdef DEBUGGER + missing.fast_rom = 1; +#endif + } + else + CPU.FastROMSpeed = SLOW_ONE_CYCLE; + + Memory.FixROMSpeed (); + } + /* FALL */ + case 0x420e: + case 0x420f: + // --->>> Unknown + break; + case 0x4210: + // NMI ocurred flag (reset on read or write) + Memory.FillRAM[0x4210] = 0; + return; + case 0x4211: + // IRQ ocurred flag (reset on read or write) + CLEAR_IRQ_SOURCE (PPU_V_BEAM_IRQ_SOURCE | PPU_H_BEAM_IRQ_SOURCE); + break; + case 0x4212: + // v-blank, h-blank and joypad being scanned flags (read-only) + case 0x4213: + // I/O Port (read-only) + case 0x4214: + case 0x4215: + // Quotent of divide (read-only) + case 0x4216: + case 0x4217: + // Multiply product (read-only) + return; + case 0x4218: + case 0x4219: + case 0x421a: + case 0x421b: + case 0x421c: + case 0x421d: + case 0x421e: + case 0x421f: + // Joypad values (read-only) + return; + + case 0x4300: + case 0x4310: + case 0x4320: + case 0x4330: + case 0x4340: + case 0x4350: + case 0x4360: + case 0x4370: + d = (Address >> 4) & 0x7; + DMA[d].TransferDirection = (byte & 128) != 0 ? 1 : 0; + DMA[d].HDMAIndirectAddressing = (byte & 64) != 0 ? 1 : 0; + DMA[d].AAddressDecrement = (byte & 16) != 0 ? 1 : 0; + DMA[d].AAddressFixed = (byte & 8) != 0 ? 1 : 0; + DMA[d].TransferMode = (byte & 7); + break; + + case 0x4301: + case 0x4311: + case 0x4321: + case 0x4331: + case 0x4341: + case 0x4351: + case 0x4361: + case 0x4371: + DMA[((Address >> 4) & 0x7)].BAddress = byte; + break; + + case 0x4302: + case 0x4312: + case 0x4322: + case 0x4332: + case 0x4342: + case 0x4352: + case 0x4362: + case 0x4372: + d = (Address >> 4) & 0x7; + DMA[d].AAddress &= 0xFF00; + DMA[d].AAddress |= byte; + break; + + case 0x4303: + case 0x4313: + case 0x4323: + case 0x4333: + case 0x4343: + case 0x4353: + case 0x4363: + case 0x4373: + d = (Address >> 4) & 0x7; + DMA[d].AAddress &= 0xFF; + DMA[d].AAddress |= byte << 8; + break; + + case 0x4304: + case 0x4314: + case 0x4324: + case 0x4334: + case 0x4344: + case 0x4354: + case 0x4364: + case 0x4374: + DMA[((Address >> 4) & 0x7)].ABank = byte; + break; + + case 0x4305: + case 0x4315: + case 0x4325: + case 0x4335: + case 0x4345: + case 0x4355: + case 0x4365: + case 0x4375: + d = (Address >> 4) & 0x7; + DMA[d].TransferBytes &= 0xFF00; + DMA[d].TransferBytes |= byte; + DMA[d].IndirectAddress &= 0xff00; + DMA[d].IndirectAddress |= byte; + break; + + case 0x4306: + case 0x4316: + case 0x4326: + case 0x4336: + case 0x4346: + case 0x4356: + case 0x4366: + case 0x4376: + d = (Address >> 4) & 0x7; + DMA[d].TransferBytes &= 0xFF; + DMA[d].TransferBytes |= byte << 8; + DMA[d].IndirectAddress &= 0xff; + DMA[d].IndirectAddress |= byte << 8; + break; + + case 0x4307: + case 0x4317: + case 0x4327: + case 0x4337: + case 0x4347: + case 0x4357: + case 0x4367: + case 0x4377: + DMA[d = ((Address >> 4) & 0x7)].IndirectBank = byte; + break; + + case 0x4308: + case 0x4318: + case 0x4328: + case 0x4338: + case 0x4348: + case 0x4358: + case 0x4368: + case 0x4378: + d = (Address >> 4) & 7; + DMA[d].Address &= 0xff00; + DMA[d].Address |= byte; + break; + + case 0x4309: + case 0x4319: + case 0x4329: + case 0x4339: + case 0x4349: + case 0x4359: + case 0x4369: + case 0x4379: + d = (Address >> 4) & 0x7; + DMA[d].Address &= 0xff; + DMA[d].Address |= byte << 8; + break; + + case 0x430A: + case 0x431A: + case 0x432A: + case 0x433A: + case 0x434A: + case 0x435A: + case 0x436A: + case 0x437A: + d = (Address >> 4) & 0x7; + DMA[d].LineCount = byte & 0x7f; + DMA[d].Repeat = !(byte & 0x80); + break; + + case 0x4800: + case 0x4801: + case 0x4802: + case 0x4803: +//printf ("%02x->%04x\n", byte, Address); + break; + + case 0x4804: + case 0x4805: + case 0x4806: + case 0x4807: +//printf ("%02x->%04x\n", byte, Address); + + S9xSetSDD1MemoryMap (Address - 0x4804, byte & 7); + break; + default: +#ifdef DEBUGGER + missing.unknowncpu_write = Address; + if (Settings.TraceUnknownRegisters) + { + sprintf (String, "Unknown register write: $%02X->$%04X\n", + byte, Address); + S9xMessage (S9X_TRACE, S9X_PPU_TRACE, String); + } +#endif + break; + } + Memory.FillRAM [Address] = byte; +} + +/**********************************************************************************************/ +/* S9xGetCPU() */ +/* This function retrieves a CPU/DMA Register */ +/**********************************************************************************************/ +uint8 S9xGetCPU (uint16 Address) +{ + uint8 byte; + + if (Address < 0x4200) + { +#ifdef VAR_CYCLES + CPU.Cycles += ONE_CYCLE; +#endif + switch (Address) + { + // Secret of the Evermore + case 0x4000: + case 0x4001: + return (0x40); + + case 0x4016: + { + if (Memory.FillRAM [0x4016] & 1) + { + if ((!Settings.SwapJoypads && + IPPU.Controller == SNES_MOUSE_SWAPPED) || + (Settings.SwapJoypads && + IPPU.Controller == SNES_MOUSE)) + { + if (++PPU.MouseSpeed [0] > 2) + PPU.MouseSpeed [0] = 0; + } + return (0); + } + + int ind = Settings.SwapJoypads ? 1 : 0; + byte = IPPU.Joypads[ind] >> (PPU.Joypad1ButtonReadPos ^ 15); + PPU.Joypad1ButtonReadPos++; + return (byte & 1); + } + case 0x4017: + { + if (Memory.FillRAM [0x4016] & 1) + { + // MultiPlayer5 adaptor is only allowed to be plugged into port 2 + switch (IPPU.Controller) + { + case SNES_MULTIPLAYER5: + return (2); + case SNES_MOUSE_SWAPPED: + if (Settings.SwapJoypads && ++PPU.MouseSpeed [0] > 2) + PPU.MouseSpeed [0] = 0; + break; + + case SNES_MOUSE: + if (!Settings.SwapJoypads && ++PPU.MouseSpeed [0] > 2) + PPU.MouseSpeed [0] = 0; + break; + } + return (0x00); + } + + int ind = Settings.SwapJoypads ? 0 : 1; + + if (IPPU.Controller == SNES_MULTIPLAYER5) + { + if (Memory.FillRAM [0x4201] & 0x80) + { + byte = ((IPPU.Joypads[ind] >> (PPU.Joypad2ButtonReadPos ^ 15)) & 1) | + (((IPPU.Joypads[2] >> (PPU.Joypad2ButtonReadPos ^ 15)) & 1) << 1); + PPU.Joypad2ButtonReadPos++; + return (byte); + } + else + { + byte = ((IPPU.Joypads[3] >> (PPU.Joypad3ButtonReadPos ^ 15)) & 1) | + (((IPPU.Joypads[4] >> (PPU.Joypad3ButtonReadPos ^ 15)) & 1) << 1); + PPU.Joypad3ButtonReadPos++; + return (byte); + } + } + return ((IPPU.Joypads[ind] >> (PPU.Joypad2ButtonReadPos++ ^ 15)) & 1); + } + default: +#ifdef DEBUGGER + missing.unknowncpu_read = Address; + if (Settings.TraceUnknownRegisters) + { + sprintf (String, "Unknown register read: $%04X\n", Address); + S9xMessage (S9X_TRACE, S9X_PPU_TRACE, String); + } +#endif + break; + } + return (Memory.FillRAM [Address]); + } + else + switch (Address) + { + // BS Dynami Tracer! needs to be able to check if NMIs are enabled + // already, otherwise the game locks up. + case 0x4200: + // NMI, h & v timers and joypad reading enable + if (SNESGameFixes.Old_Read0x4200) + { +#ifdef CPU_SHUTDOWN + CPU.WaitAddress = CPU.PCAtOpcodeStart; +#endif + return (REGISTER_4212()); + } + case 0x4201: + // I/O port (output - write only?) + case 0x4202: + case 0x4203: + // Multiplier and multiplicand (write) + case 0x4204: + case 0x4205: + case 0x4206: + // Divisor and dividend (write) + return (Memory.FillRAM[Address]); + case 0x4207: + return (uint8)(PPU.IRQHBeamPos); + case 0x4208: + return (PPU.IRQHBeamPos >> 8); + case 0x4209: + return (uint8)(PPU.IRQVBeamPos); + case 0x420a: + return (PPU.IRQVBeamPos >> 8); + case 0x420b: + // General purpose DMA enable + // Super Formation Soccer 95 della Serie A UCC Xaqua requires this + // register should not always return zero. + // .. But Aero 2 waits until this register goes zero.. + // Just keep toggling the value for now in the hope that it breaks + // the game out of its wait loop... + Memory.FillRAM [0x420b] = !Memory.FillRAM [0x420b]; + return (Memory.FillRAM [0x420b]); + case 0x420c: + // H-DMA enable + return (IPPU.HDMA); + case 0x420d: + // Cycle speed 0 - 2.68Mhz, 1 - 3.58Mhz (banks 0x80 +) + return (Memory.FillRAM[Address]); + case 0x420e: + case 0x420f: + // --->>> Unknown + return (Memory.FillRAM[Address]); + case 0x4210: +#ifdef CPU_SHUTDOWN + CPU.WaitAddress = CPU.PCAtOpcodeStart; +#endif + byte = Memory.FillRAM[0x4210]; + Memory.FillRAM[0x4210] = 0; + return (byte); + case 0x4211: + byte = (CPU.IRQActive & (PPU_V_BEAM_IRQ_SOURCE | PPU_H_BEAM_IRQ_SOURCE)) ? 0x80 : 0; + // Super Robot Wars Ex ROM bug requires this. + byte |= CPU.Cycles >= Settings.HBlankStart ? 0x40 : 0; + CLEAR_IRQ_SOURCE (PPU_V_BEAM_IRQ_SOURCE | PPU_H_BEAM_IRQ_SOURCE); + return (byte); + case 0x4212: + // V-blank, h-blank and joypads being read flags (read-only) +#ifdef CPU_SHUTDOWN + CPU.WaitAddress = CPU.PCAtOpcodeStart; +#endif + return (REGISTER_4212()); + case 0x4213: + // I/O port input + case 0x4214: + case 0x4215: + // Quotient of divide result + case 0x4216: + case 0x4217: + // Multiplcation result (for multiply) or remainder of + // divison. + return (Memory.FillRAM[Address]); + case 0x4218: + case 0x4219: + case 0x421a: + case 0x421b: + case 0x421c: + case 0x421d: + case 0x421e: + case 0x421f: + // Joypads 1-4 button and direction state. + return (Memory.FillRAM [Address]); + + case 0x4300: + case 0x4310: + case 0x4320: + case 0x4330: + case 0x4340: + case 0x4350: + case 0x4360: + case 0x4370: + // DMA direction, address type, fixed flag, + return (Memory.FillRAM[Address]); + + case 0x4301: + case 0x4311: + case 0x4321: + case 0x4331: + case 0x4341: + case 0x4351: + case 0x4361: + case 0x4371: + return (Memory.FillRAM[Address]); + + case 0x4302: + case 0x4312: + case 0x4322: + case 0x4332: + case 0x4342: + case 0x4352: + case 0x4362: + case 0x4372: + return (Memory.FillRAM[Address]); + + case 0x4303: + case 0x4313: + case 0x4323: + case 0x4333: + case 0x4343: + case 0x4353: + case 0x4363: + case 0x4373: + return (Memory.FillRAM[Address]); + + case 0x4304: + case 0x4314: + case 0x4324: + case 0x4334: + case 0x4344: + case 0x4354: + case 0x4364: + case 0x4374: + return (Memory.FillRAM[Address]); + + case 0x4305: + case 0x4315: + case 0x4325: + case 0x4335: + case 0x4345: + case 0x4355: + case 0x4365: + case 0x4375: + return (Memory.FillRAM[Address]); + + case 0x4306: + case 0x4316: + case 0x4326: + case 0x4336: + case 0x4346: + case 0x4356: + case 0x4366: + case 0x4376: + return (Memory.FillRAM[Address]); + + case 0x4307: + case 0x4317: + case 0x4327: + case 0x4337: + case 0x4347: + case 0x4357: + case 0x4367: + case 0x4377: + return (DMA[(Address >> 4) & 7].IndirectBank); + + case 0x4308: + case 0x4318: + case 0x4328: + case 0x4338: + case 0x4348: + case 0x4358: + case 0x4368: + case 0x4378: + return (Memory.FillRAM[Address]); + + case 0x4309: + case 0x4319: + case 0x4329: + case 0x4339: + case 0x4349: + case 0x4359: + case 0x4369: + case 0x4379: + return (Memory.FillRAM[Address]); + + case 0x430A: + case 0x431A: + case 0x432A: + case 0x433A: + case 0x434A: + case 0x435A: + case 0x436A: + case 0x437A: + { + int d = (Address & 0x70) >> 4; + if (IPPU.HDMA & (1 << d)) + { + return (DMA[d].LineCount); + } + return (Memory.FillRAM[Address]); + } + default: +#ifdef DEBUGGER + missing.unknowncpu_read = Address; + if (Settings.TraceUnknownRegisters) + { + sprintf (String, "Unknown register read: $%04X\n", Address); + S9xMessage (S9X_TRACE, S9X_PPU_TRACE, String); + } + +#endif + break; + } + return (Memory.FillRAM[Address]); +} + +void S9xResetPPU () +{ + PPU.BGMode = 0; + PPU.BG3Priority = 0; + PPU.Brightness = 0; + PPU.VMA.High = 0; + PPU.VMA.Increment = 1; + PPU.VMA.Address = 0; + PPU.VMA.FullGraphicCount = 0; + PPU.VMA.Shift = 0; + + for (uint8 B = 0; B != 4; B++) + { + PPU.BG[B].SCBase = 0; + PPU.BG[B].VOffset = 0; + PPU.BG[B].HOffset = 0; + PPU.BG[B].BGSize = 0; + PPU.BG[B].NameBase = 0; + PPU.BG[B].SCSize = 0; + + PPU.ClipCounts[B] = 0; + PPU.ClipWindowOverlapLogic [B] = CLIP_OR; + PPU.ClipWindow1Enable[B] = FALSE; + PPU.ClipWindow2Enable[B] = FALSE; + PPU.ClipWindow1Inside[B] = TRUE; + PPU.ClipWindow2Inside[B] = TRUE; + } + + PPU.ClipCounts[4] = 0; + PPU.ClipCounts[5] = 0; + PPU.ClipWindowOverlapLogic[4] = PPU.ClipWindowOverlapLogic[5] = CLIP_OR; + PPU.ClipWindow1Enable[4] = PPU.ClipWindow1Enable[5] = FALSE; + PPU.ClipWindow2Enable[4] = PPU.ClipWindow2Enable[5] = FALSE; + PPU.ClipWindow1Inside[4] = PPU.ClipWindow1Inside[5] = TRUE; + PPU.ClipWindow2Inside[4] = PPU.ClipWindow2Inside[5] = TRUE; + + PPU.CGFLIP = 0; + int c; + for (c = 0; c < 256; c++) + { + IPPU.Red [c] = (c & 7) << 2; + IPPU.Green [c] = ((c >> 3) & 7) << 2; + IPPU.Blue [c] = ((c >> 6) & 2) << 3; + PPU.CGDATA [c] = IPPU.Red [c] | (IPPU.Green [c] << 5) | + (IPPU.Blue [c] << 10); + } + + PPU.FirstSprite = 0; + PPU.LastSprite = 127; + for (int Sprite = 0; Sprite < 128; Sprite++) + { + PPU.OBJ[Sprite].HPos = 0; + PPU.OBJ[Sprite].VPos = 0; + PPU.OBJ[Sprite].VFlip = 0; + PPU.OBJ[Sprite].HFlip = 0; + PPU.OBJ[Sprite].Priority = 0; + PPU.OBJ[Sprite].Palette = 0; + PPU.OBJ[Sprite].Name = 0; + PPU.OBJ[Sprite].Size = 0; + } + PPU.OAMPriorityRotation = 0; + + PPU.OAMFlip = 0; + PPU.OAMTileAddress = 0; + PPU.OAMAddr = 0; + PPU.IRQVBeamPos = 0; + PPU.IRQHBeamPos = 0; + PPU.VBeamPosLatched = 0; + PPU.HBeamPosLatched = 0; + + PPU.HBeamFlip = 0; + PPU.VBeamFlip = 0; + PPU.HVBeamCounterLatched = 0; + + PPU.MatrixA = PPU.MatrixB = PPU.MatrixC = PPU.MatrixD = 0; + PPU.CentreX = PPU.CentreY = 0; + PPU.Joypad1ButtonReadPos = 0; + PPU.Joypad2ButtonReadPos = 0; + PPU.Joypad3ButtonReadPos = 0; + + PPU.CGADD = 0; + PPU.FixedColourRed = PPU.FixedColourGreen = PPU.FixedColourBlue = 0; + PPU.SavedOAMAddr = 0; + PPU.ScreenHeight = SNES_HEIGHT; + PPU.WRAM = 0; + PPU.BG_Forced = 0; + PPU.ForcedBlanking = TRUE; + PPU.OBJThroughMain = FALSE; + PPU.OBJThroughSub = FALSE; + PPU.OBJSizeSelect = 0; + PPU.OBJNameSelect = 0; + PPU.OBJNameBase = 0; + PPU.OBJAddition = FALSE; + PPU.OAMReadFlip = 0; + ZeroMemory (PPU.OAMData, 512 + 32); + + PPU.VTimerEnabled = FALSE; + PPU.HTimerEnabled = FALSE; + PPU.HTimerPosition = Settings.H_Max + 1; + PPU.Mosaic = 0; + PPU.BGMosaic [0] = PPU.BGMosaic [1] = FALSE; + PPU.BGMosaic [2] = PPU.BGMosaic [3] = FALSE; + PPU.Mode7HFlip = FALSE; + PPU.Mode7VFlip = FALSE; + PPU.Mode7Repeat = 0; + PPU.Window1Left = 1; + PPU.Window1Right = 0; + PPU.Window2Left = 1; + PPU.Window2Right = 0; + PPU.RecomputeClipWindows = TRUE; + PPU.CGFLIPRead = 0; + PPU.Need16x8Mulitply = FALSE; + PPU.MouseSpeed[0] = PPU.MouseSpeed[1] = 0; + + IPPU.ColorsChanged = TRUE; + IPPU.HDMA = 0; + IPPU.HDMAStarted = FALSE; + IPPU.MaxBrightness = 0; + IPPU.LatchedBlanking = 0; + IPPU.OBJChanged = TRUE; + IPPU.RenderThisFrame = TRUE; + IPPU.DirectColourMapsNeedRebuild = TRUE; + IPPU.FrameCount = 0; + IPPU.RenderedFramesCount = 0; + IPPU.DisplayedRenderedFrameCount = 0; + IPPU.SkippedFrames = 0; + IPPU.FrameSkip = 0; + ZeroMemory (IPPU.TileCached [TILE_2BIT], MAX_2BIT_TILES); + ZeroMemory (IPPU.TileCached [TILE_4BIT], MAX_4BIT_TILES); + ZeroMemory (IPPU.TileCached [TILE_8BIT], MAX_8BIT_TILES); + IPPU.FirstVRAMRead = FALSE; + IPPU.LatchedInterlace = FALSE; + IPPU.DoubleWidthPixels = FALSE; + IPPU.RenderedScreenWidth = SNES_WIDTH; + IPPU.RenderedScreenHeight = SNES_HEIGHT; + IPPU.XB = NULL; + for (c = 0; c < 256; c++) + IPPU.ScreenColors [c] = c; + S9xFixColourBrightness (); + IPPU.PreviousLine = IPPU.CurrentLine = 0; + IPPU.Joypads[0] = IPPU.Joypads[1] = IPPU.Joypads[2] = 0; + IPPU.Joypads[3] = IPPU.Joypads[4] = 0; + IPPU.SuperScope = 0; + IPPU.Mouse[0] = IPPU.Mouse[1] = 0; + IPPU.PrevMouseX[0] = IPPU.PrevMouseX[1] = 256 / 2; + IPPU.PrevMouseY[0] = IPPU.PrevMouseY[1] = 224 / 2; + + if (Settings.ControllerOption == 0) + IPPU.Controller = SNES_MAX_CONTROLLER_OPTIONS - 1; + else + IPPU.Controller = Settings.ControllerOption - 1; + S9xNextController (); + + for (c = 0; c < 2; c++) + memset (&IPPU.Clip [c], 0, sizeof (struct ClipData)); + + if (Settings.MouseMaster) + { + S9xProcessMouse (0); + S9xProcessMouse (1); + } + for (c = 0; c < 0x8000; c += 0x100) + memset (&Memory.FillRAM [c], c >> 8, 0x100); + + ZeroMemory (&Memory.FillRAM [0x2100], 0x100); + ZeroMemory (&Memory.FillRAM [0x4200], 0x100); + ZeroMemory (&Memory.FillRAM [0x4000], 0x100); + // For BS Suttehakkun 2... + ZeroMemory (&Memory.FillRAM [0x1000], 0x1000); +} + +void S9xProcessMouse (int which1) +{ + int x, y; + uint32 buttons; + + if ((IPPU.Controller == SNES_MOUSE || IPPU.Controller == SNES_MOUSE_SWAPPED) && + S9xReadMousePosition (which1, x, y, buttons)) + { + int delta_x, delta_y; +#define MOUSE_SIGNATURE 0x1 + IPPU.Mouse [which1] = MOUSE_SIGNATURE | + (PPU.MouseSpeed [which1] << 4) | + ((buttons & 1) << 6) | ((buttons & 2) << 6); + + delta_x = x - IPPU.PrevMouseX[which1]; + delta_y = y - IPPU.PrevMouseY[which1]; + + if (delta_x > 63) + { + delta_x = 63; + IPPU.PrevMouseX[which1] += 63; + } + else + if (delta_x < -63) + { + delta_x = -63; + IPPU.PrevMouseX[which1] -= 63; + } + else + IPPU.PrevMouseX[which1] = x; + + if (delta_y > 63) + { + delta_y = 63; + IPPU.PrevMouseY[which1] += 63; + } + else + if (delta_y < -63) + { + delta_y = -63; + IPPU.PrevMouseY[which1] -= 63; + } + else + IPPU.PrevMouseY[which1] = y; + + if (delta_x < 0) + { + delta_x = -delta_x; + IPPU.Mouse [which1] |= (delta_x | 0x80) << 16; + } + else + IPPU.Mouse [which1] |= delta_x << 16; + + if (delta_y < 0) + { + delta_y = -delta_y; + IPPU.Mouse [which1] |= (delta_y | 0x80) << 24; + } + else + IPPU.Mouse [which1] |= delta_y << 24; + + if (IPPU.Controller == SNES_MOUSE_SWAPPED) + IPPU.Joypads [0] = IPPU.Mouse [which1]; + else + IPPU.Joypads [1] = IPPU.Mouse [which1]; + } +} + +void ProcessSuperScope () +{ + int x, y; + uint32 buttons; + + if (IPPU.Controller == SNES_SUPERSCOPE && + S9xReadSuperScopePosition (x, y, buttons)) + { +#define SUPERSCOPE_SIGNATURE 0x00ff + uint32 scope; + + scope = SUPERSCOPE_SIGNATURE | ((buttons & 1) << (7 + 8)) | + ((buttons & 2) << (5 + 8)) | ((buttons & 4) << (3 + 8)) | + ((buttons & 8) << (1 + 8)); + if (x > 255) + x = 255; + if (x < 0) + x = 0; + if (y > PPU.ScreenHeight - 1) + y = PPU.ScreenHeight - 1; + if (y < 0) + y = 0; + + PPU.VBeamPosLatched = (uint16) (y + 1); + PPU.HBeamPosLatched = (uint16) x; + PPU.HVBeamCounterLatched = TRUE; + Memory.FillRAM [0x213F] |= 0x40; + IPPU.Joypads [1] = scope; + } +} + +void S9xNextController () +{ + switch (IPPU.Controller) + { + case SNES_MULTIPLAYER5: + IPPU.Controller = SNES_JOYPAD; + break; + case SNES_JOYPAD: + if (Settings.MouseMaster) + { + IPPU.Controller = SNES_MOUSE_SWAPPED; + break; + } + case SNES_MOUSE_SWAPPED: + if (Settings.MouseMaster) + { + IPPU.Controller = SNES_MOUSE; + break; + } + case SNES_MOUSE: + if (Settings.SuperScopeMaster) + { + IPPU.Controller = SNES_SUPERSCOPE; + break; + } + case SNES_SUPERSCOPE: + if (Settings.MultiPlayer5Master) + { + IPPU.Controller = SNES_MULTIPLAYER5; + break; + } + default: + IPPU.Controller = SNES_JOYPAD; + break; + } +} + +void S9xUpdateJoypads () +{ +#ifdef _SNESPPC + int i = 0; +#else + int i; + + for (i = 0; i < 5; i++) +#endif + { + IPPU.Joypads [i] = S9xReadJoypad (i); + if (IPPU.Joypads [i] & SNES_LEFT_MASK) + IPPU.Joypads [i] &= ~SNES_RIGHT_MASK; + if (IPPU.Joypads [i] & SNES_UP_MASK) + IPPU.Joypads [i] &= ~SNES_DOWN_MASK; + } + + //touhaiden controller Fix + if (SNESGameFixes.TouhaidenControllerFix && + (IPPU.Controller == SNES_JOYPAD || IPPU.Controller == SNES_MULTIPLAYER5)) + { + for (i = 0; i < 5; i++) + { + if (IPPU.Joypads [i]) + IPPU.Joypads [i] |= 0xffff0000; + } + } + + // Read mouse position if enabled + if (Settings.MouseMaster) + { + for (i = 0; i < 2; i++) + S9xProcessMouse (i); + } + + // Read SuperScope if enabled + if (Settings.SuperScopeMaster) + ProcessSuperScope (); + + if (Memory.FillRAM [0x4200] & 1) + { + PPU.Joypad1ButtonReadPos = 16; + if (Memory.FillRAM [0x4201] & 0x80) + { + PPU.Joypad2ButtonReadPos = 16; + PPU.Joypad3ButtonReadPos = 0; + } + else + { + PPU.Joypad2ButtonReadPos = 0; + PPU.Joypad3ButtonReadPos = 16; + } + int ind = Settings.SwapJoypads ? 1 : 0; + + Memory.FillRAM [0x4218] = (uint8) IPPU.Joypads [ind]; + Memory.FillRAM [0x4219] = (uint8) (IPPU.Joypads [ind] >> 8); + Memory.FillRAM [0x421a] = (uint8) IPPU.Joypads [ind ^ 1]; + Memory.FillRAM [0x421b] = (uint8) (IPPU.Joypads [ind ^ 1] >> 8); + if (Memory.FillRAM [0x4201] & 0x80) + { + Memory.FillRAM [0x421c] = (uint8) IPPU.Joypads [ind]; + Memory.FillRAM [0x421d] = (uint8) (IPPU.Joypads [ind] >> 8); + Memory.FillRAM [0x421e] = (uint8) IPPU.Joypads [2]; + Memory.FillRAM [0x421f] = (uint8) (IPPU.Joypads [2] >> 8); + } + else + { + Memory.FillRAM [0x421c] = (uint8) IPPU.Joypads [3]; + Memory.FillRAM [0x421d] = (uint8) (IPPU.Joypads [3] >> 8); + Memory.FillRAM [0x421e] = (uint8) IPPU.Joypads [4]; + Memory.FillRAM [0x421f] = (uint8) (IPPU.Joypads [4] >> 8); + } + } +} + +#ifndef ZSNES_FX +void S9xSuperFXExec () +{ +#if 1 + if (Settings.SuperFX) + { + if ((Memory.FillRAM [0x3000 + GSU_SFR] & FLG_G) && + (Memory.FillRAM [0x3000 + GSU_SCMR] & 0x18) == 0x18) + { + if (!Settings.WinterGold) + FxEmulate (~0); + else + FxEmulate ((Memory.FillRAM [0x3000 + GSU_CLSR] & 1) ? 700 : 350); + int GSUStatus = Memory.FillRAM [0x3000 + GSU_SFR] | + (Memory.FillRAM [0x3000 + GSU_SFR + 1] << 8); + if ((GSUStatus & (FLG_G | FLG_IRQ)) == FLG_IRQ) + { + // Trigger a GSU IRQ. + S9xSetIRQ (GSU_IRQ_SOURCE); + } + } + } +#else + uint32 tmp = (Memory.FillRAM[0x3034] << 16) + *(uint16 *) &Memory.FillRAM [0x301e]; + +#if 0 + if (tmp == 0x018428) + { + *(uint16 *) &SRAM [0x0064] = 0xbc00; + *(uint16 *) &SRAM [0x002c] = 0x8000; + } +#endif + if (tmp == -1)//0x018428) //0x01bfc3) //0x09edaf) //-1) //0x57edaf) + { + while (Memory.FillRAM [0x3030] & 0x20) + { + int i; + int32 vError; + uint8 avReg[0x40]; + char tmp[128]; + uint8 vPipe; + uint8 vColr; + uint8 vPor; + + FxPipeString (tmp); + /* Make the string 32 chars long */ + if(strlen(tmp) < 32) { memset(&tmp[strlen(tmp)],' ',32-strlen(tmp)); tmp[32] = 0; } + + /* Copy registers (so we can see if any changed) */ + vColr = FxGetColorRegister(); + vPor = FxGetPlotOptionRegister(); + memcpy(avReg,SuperFX.pvRegisters,0x40); + + /* Print the pipe string */ + printf(tmp); + + /* Execute the instruction in the pipe */ + vPipe = FxPipe(); + vError = FxEmulate(1); + + /* Check if any registers changed (and print them if they did) */ + for(i=0; i<16; i++) + { + uint32 a = 0; + uint32 r1 = ((uint32)avReg[i*2]) | (((uint32)avReg[(i*2)+1])<<8); + uint32 r2 = (uint32)(SuperFX.pvRegisters[i*2]) | (((uint32)SuperFX.pvRegisters[(i*2)+1])<<8); + if(i==15) + a = OPCODE_BYTES(vPipe); + if(((r1+a)&0xffff) != r2) + printf(" r%d=$%04x",i,r2); + } + { + /* Check SFR */ + uint32 r1 = ((uint32)avReg[0x30]) | (((uint32)avReg[0x31])<<8); + uint32 r2 = (uint32)(SuperFX.pvRegisters[0x30]) | (((uint32)SuperFX.pvRegisters[0x31])<<8); + if((r1&(1<<1)) != (r2&(1<<1))) + printf(" Z=%d",(uint32)(!!(r2&(1<<1)))); + if((r1&(1<<2)) != (r2&(1<<2))) + printf(" CY=%d",(uint32)(!!(r2&(1<<2)))); + if((r1&(1<<3)) != (r2&(1<<3))) + printf(" S=%d",(uint32)(!!(r2&(1<<3)))); + if((r1&(1<<4)) != (r2&(1<<4))) + printf(" OV=%d",(uint32)(!!(r2&(1<<4)))); + if((r1&(1<<5)) != (r2&(1<<5))) + printf(" G=%d",(uint32)(!!(r2&(1<<5)))); + if((r1&(1<<6)) != (r2&(1<<6))) + printf(" R=%d",(uint32)(!!(r2&(1<<6)))); + if((r1&(1<<8)) != (r2&(1<<8))) + printf(" ALT1=%d",(uint32)(!!(r2&(1<<8)))); + if((r1&(1<<9)) != (r2&(1<<9))) + printf(" ALT2=%d",(uint32)(!!(r2&(1<<9)))); + if((r1&(1<<10)) != (r2&(1<<10))) + printf(" IL=%d",(uint32)(!!(r2&(1<<10)))); + if((r1&(1<<11)) != (r2&(1<<11))) + printf(" IH=%d",(uint32)(!!(r2&(1<<11)))); + if((r1&(1<<12)) != (r2&(1<<12))) + printf(" B=%d",(uint32)(!!(r2&(1<<12)))); + if((r1&(1<<15)) != (r2&(1<<15))) + printf(" IRQ=%d",(uint32)(!!(r2&(1<<15)))); + } + { + /* Check PBR */ + uint32 r1 = ((uint32)avReg[0x34]); + uint32 r2 = (uint32)(SuperFX.pvRegisters[0x34]); + if(r1 != r2) + printf(" PBR=$%02x",r2); + } + { + /* Check ROMBR */ + uint32 r1 = ((uint32)avReg[0x36]); + uint32 r2 = (uint32)(SuperFX.pvRegisters[0x36]); + if(r1 != r2) + printf(" ROMBR=$%02x",r2); + } + { + /* Check RAMBR */ + uint32 r1 = ((uint32)avReg[0x3c]); + uint32 r2 = (uint32)(SuperFX.pvRegisters[0x3c]); + if(r1 != r2) + printf(" RAMBR=$%02x",r2); + } + { + /* Check CBR */ + uint32 r1 = ((uint32)avReg[0x3e]) | (((uint32)avReg[0x3f])<<8); + uint32 r2 = (uint32)(SuperFX.pvRegisters[0x3e]) | (((uint32)SuperFX.pvRegisters[0x3f])<<8); + if(r1 != r2) + printf(" CBR=$%04x",r2); + } + { + /* Check COLR */ + if(vColr != FxGetColorRegister()) + printf(" COLR=$%02x",FxGetColorRegister()); + } + { + /* Check POR */ + if(vPor != FxGetPlotOptionRegister()) + printf(" POR=$%02x",FxGetPlotOptionRegister()); + } + printf ("\n"); + } + S9xExit (); + } + else + { + uint32 t = (Memory.FillRAM [0x3034] << 16) + + (Memory.FillRAM [0x301f] << 8) + + (Memory.FillRAM [0x301e] << 0); + +printf ("%06x: %d\n", t, FxEmulate (2000000)); +// FxEmulate (2000000); + } +#if 0 + if (!(CPU.Flags & TRACE_FLAG)) + { + static int z = 1; + if (z == 0) + { + extern FILE *trace; + CPU.Flags |= TRACE_FLAG; + trace = fopen ("trace.log", "wb"); + } + else + z--; + } +#endif + Memory.FillRAM [0x3030] &= ~0x20; + if (Memory.FillRAM [0x3031] & 0x80) + { + S9xSetIRQ (GSU_IRQ_SOURCE); + } +#endif +} +#endif diff --git a/src/snes4iphone_src/readme.txt b/src/snes4iphone_src/readme.txt new file mode 100755 index 0000000..8fe6f95 --- /dev/null +++ b/src/snes4iphone_src/readme.txt @@ -0,0 +1,10 @@ +3.71 +--files were errorenously getting _logXX.log names instead of _logXX.txt. Fixed +3.7 +what's new: +--new feature: per thread indent in the log files +--new options: STLOG_MULTITHREADING (turns on/off multithreading features), STLOG_USE_PERFORMANCE_CONTER (you can turn off usage of GetPerformanceCounter() function) +--fixed bug with stack overflow in GetLogFileName() function (thanks to Alexander Shargin) +--fixed bug with unclosed handle when used from DLL (thanks to Rene Heijndijk). +--fixed bug with ___DoNothing() function for the cases when the STLOG_DEBUG macro is undefined +--new functions: STLOG_WRITE_IID, STLOG_WRITE_GUID, STLOG_WRITE_CLSID diff --git a/src/snes4iphone_src/render8 orr.S b/src/snes4iphone_src/render8 orr.S new file mode 100755 index 0000000..aaff045 --- /dev/null +++ b/src/snes4iphone_src/render8 orr.S @@ -0,0 +1,218 @@ + .global asmDrawTile8_noflip + .global asmDrawTile8_hflip + .global asmDrawTile8_hvflip + .global asmDrawTile8_vflip + .global asmDrawTile8T_noflip + .global asmDrawTile8T_hflip + .global asmDrawTile8T_hvflip + .global asmDrawTile8T_vflip + + ;@ ############################### + .macro DRAWTILE_NOFLIP + ;@ ############################### + ldr r3,[r0],#4 + + ands r12,r3,#0x0000000F + orrne r12,r1,r12 + strneb r12,[r2,#0] + + ands r12,r3,#0x000000F0 + orrne r12,r1,r12,lsr#4 + strneb r12,[r2,#1] + + ands r12,r3,#0x00000F00 + orrne r12,r1,r12,lsr#8 + strneb r12,[r2,#2] + + ands r12,r3,#0x0000F000 + orrne r12,r1,r12,lsr#12 + strneb r12,[r2,#3] + + ands r12,r3,#0x000F0000 + orrne r12,r1,r12,lsr#16 + strneb r12,[r2,#4] + + ands r12,r3,#0x00F00000 + orrne r12,r1,r12,lsr#20 + strneb r12,[r2,#5] + + ands r12,r3,#0x0F000000 + orrne r12,r1,r12,lsr#24 + strneb r12,[r2,#6] + + ands r12,r3,#0xF0000000 + orrne r12,r1,r12,lsr#28 + strneb r12,[r2,#7] + + add r2,r2,#320 + .endm + + ;@ ############################### + .macro DRAWTILE_HFLIP + ;@ ############################### + ldr r3,[r0],#4 + + ands r12,r3,#0x0000000F + orrne r12,r1,r12 + strneb r12,[r2,#7] + + ands r12,r3,#0x000000F0 + orrne r12,r1,r12,lsr#4 + strneb r12,[r2,#6] + + ands r12,r3,#0x00000F00 + orrne r12,r1,r12,lsr#8 + strneb r12,[r2,#5] + + ands r12,r3,#0x0000F000 + orrne r12,r1,r12,lsr#12 + strneb r12,[r2,#4] + + ands r12,r3,#0x000F0000 + orrne r12,r1,r12,lsr#16 + strneb r12,[r2,#3] + + ands r12,r3,#0x00F00000 + orrne r12,r1,r12,lsr#20 + strneb r12,[r2,#2] + + ands r12,r3,#0x0F000000 + orrne r12,r1,r12,lsr#24 + strneb r12,[r2,#1] + + ands r12,r3,#0xF0000000 + orrne r12,r1,r12,lsr#28 + strneb r12,[r2,#0] + + add r2,r2,#320 + .endm + + ;@ ############################### + .macro DRAWTILE_HVFLIP + ;@ ############################### + ldr r3,[r0],#4 + + ands r12,r3,#0x0000000F + orrne r12,r1,r12 + strneb r12,[r2,#7] + + ands r12,r3,#0x000000F0 + orrne r12,r1,r12,lsr#4 + strneb r12,[r2,#6] + + ands r12,r3,#0x00000F00 + orrne r12,r1,r12,lsr#8 + strneb r12,[r2,#5] + + ands r12,r3,#0x0000F000 + orrne r12,r1,r12,lsr#12 + strneb r12,[r2,#4] + + ands r12,r3,#0x000F0000 + orrne r12,r1,r12,lsr#16 + strneb r12,[r2,#3] + + ands r12,r3,#0x00F00000 + orrne r12,r1,r12,lsr#20 + strneb r12,[r2,#2] + + ands r12,r3,#0x0F000000 + orrne r12,r1,r12,lsr#24 + strneb r12,[r2,#1] + + ands r12,r3,#0xF0000000 + orrne r12,r1,r12,lsr#28 + strneb r12,[r2,#0] + + sub r2,r2,#320 + .endm + + ;@ ############################### + .macro DRAWTILE_VFLIP + ;@ ############################### + ldr r3,[r0],#4 + + ands r12,r3,#0x0000000F + orrne r12,r1,r12 + strneb r12,[r2,#0] + + ands r12,r3,#0x000000F0 + orrne r12,r1,r12,lsr#4 + strneb r12,[r2,#1] + + ands r12,r3,#0x00000F00 + orrne r12,r1,r12,lsr#8 + strneb r12,[r2,#2] + + ands r12,r3,#0x0000F000 + orrne r12,r1,r12,lsr#12 + strneb r12,[r2,#3] + + ands r12,r3,#0x000F0000 + orrne r12,r1,r12,lsr#16 + strneb r12,[r2,#4] + + ands r12,r3,#0x00F00000 + orrne r12,r1,r12,lsr#20 + strneb r12,[r2,#5] + + ands r12,r3,#0x0F000000 + orrne r12,r1,r12,lsr#24 + strneb r12,[r2,#6] + + ands r12,r3,#0xF0000000 + orrne r12,r1,r12,lsr#28 + strneb r12,[r2,#7] + + sub r2,r2,#320 + .endm + + +asmDrawTile8_noflip: + DRAWTILE_NOFLIP + DRAWTILE_NOFLIP + DRAWTILE_NOFLIP + DRAWTILE_NOFLIP + DRAWTILE_NOFLIP + DRAWTILE_NOFLIP + DRAWTILE_NOFLIP + DRAWTILE_NOFLIP + mov pc,lr + +asmDrawTile8_hflip: + DRAWTILE_HFLIP + DRAWTILE_HFLIP + DRAWTILE_HFLIP + DRAWTILE_HFLIP + DRAWTILE_HFLIP + DRAWTILE_HFLIP + DRAWTILE_HFLIP + DRAWTILE_HFLIP + mov pc,lr + +asmDrawTile8_hvflip: + DRAWTILE_HVFLIP + DRAWTILE_HVFLIP + DRAWTILE_HVFLIP + DRAWTILE_HVFLIP + DRAWTILE_HVFLIP + DRAWTILE_HVFLIP + DRAWTILE_HVFLIP + DRAWTILE_HVFLIP + mov pc,lr + +asmDrawTile8_vflip: + DRAWTILE_VFLIP + DRAWTILE_VFLIP + DRAWTILE_VFLIP + DRAWTILE_VFLIP + DRAWTILE_VFLIP + DRAWTILE_VFLIP + DRAWTILE_VFLIP + DRAWTILE_VFLIP + mov pc,lr + + + + + diff --git a/src/snes4iphone_src/resource.h b/src/snes4iphone_src/resource.h new file mode 100755 index 0000000..34fc53a --- /dev/null +++ b/src/snes4iphone_src/resource.h @@ -0,0 +1,181 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by PocketSNES.rc +// +#define IDS_APP_TITLE 1 +#define IDS_HELLO 2 +#define IDC_POCKETSNES 3 +#define IDS_HELLO2 4 +#define IDS_PAUSED 5 +#define IDS_LINK 6 +#define IDS_CREDITS1 7 +#define IDS_CREDITS2 8 +#define IDS_CREDITS0 9 +#define IDI_POCKETSNES 101 +#define IDM_MENU 102 +#define IDS_HELP 104 +#define IDD_OPTIONS 104 +#define IDB_KEYPAD 105 +#define IDD_SKINS 106 +#define IDD_KEYS 107 +#define IDD_KEYS1 108 +#define IDD_CREDITS 108 +#define IDD_KEYS_NEW 109 +#define IDD_DISPLAY 109 +#define IDD_SOUND 110 +#define IDD_SETTINGS 111 +#define IDD_SYSTEM 111 +#define IDB_POCKETSNES 114 +#define IDB_6BUTTON 115 +#define IDB_4BUTTON 118 +#define IDI_LEFT_ARROW 119 +#define IDI_RIGHT_ARROW 120 +#define IDS_COMMAND1 301 +#define IDC_STATIC_TITLE 444 +#define IDC_STATIC_TITLE2 445 +#define IDC_TRANSPARENCY 1001 +#define IDC_SOUND 1002 +#define IDC_ECHO 1003 +#define IDC_SYNC 1004 +#define IDC_SYNCSOUND 1004 +#define IDC_CUSTOM1 1005 +#define IDC_REVERSE 1005 +#define IDC_REVERSESTEREO 1005 +#define IDC_STEREO 1006 +#define IDC_BUTTON_PREVIOUS 1007 +#define IDC_INTERPOLATE 1007 +#define IDC_INTERPOLATESOUND 1007 +#define IDC_BUTTON_SET 1008 +#define IDC_ALTDECODE 1008 +#define IDC_BUTTON_NEXT 1009 +#define IDC_ENVELOPEHEIGHT 1009 +#define IDC_SMOOTHSTRETCH 1010 +#define IDC_FIXFREQUENCY 1010 +#define IDC_LANDSCAPE 1011 +#define IDC_BUTTON_UP 1028 +#define IDC_BUTTON_DOWN 1029 +#define IDC_BUTTON_LEFT 1030 +#define IDC_BUTTON_RIGHT 1031 +#define IDC_BUTTON_B 1032 +#define IDC_BUTTON_A 1033 +#define IDC_BUTTON_Y 1034 +#define IDC_BUTTON_X 1035 +#define IDC_BUTTON_START 1036 +#define IDC_BUTTON_SELECT 1037 +#define IDC_BUTTON_L 1038 +#define IDC_BUTTON_R 1039 +#define IDC_STATIC_UP 1040 +#define IDC_STATIC_LEFT 1041 +#define IDC_STATIC_B 1042 +#define IDC_STATIC_Y 1043 +#define IDC_STATIC_START 1044 +#define IDC_STATIC_L 1045 +#define IDC_STATIC_DOWN 1046 +#define IDC_STATIC_RIGHT 1047 +#define IDC_STATIC_A 1048 +#define IDC_STATIC_X 1049 +#define IDC_STATIC_SELECT 1050 +#define IDC_STATIC_R 1051 +#define IDC_STATIC_INFO 1052 +#define IDC_FRAMESKIP 1053 +#define IDC_SPIN_FRAMESKIP 1055 +#define IDC_CREDITS 1056 +#define IDC_SIXTEENBIT 1059 +#define IDC_EIGHTBIT 1060 +#define IDC_SOUNDQUALITY 1061 +#define IDC_LEFT 1063 +#define IDC_AUTO 1065 +#define IDC_COMPAT 1066 +#define IDC_CYCLES 1067 +#define IDC_CYCLES_SPIN 1068 +#define IDC_PORTRAIT 1069 +#define IDC_LANDLEFT 1070 +#define IDC_LANDLEFTSTRETCH 1071 +#define IDC_LANDRIGHTSTRETCH 1072 +#define IDC_LANDRIGHT 1073 +#define IDC_SLIDER1 1074 +#define IDC_FRAMESKIP_SLIDER 1074 +#define IDC_SKIP 1075 +#define IDC_EDIT1 1076 +#define IDC_BROWSE 1077 +#define IDC_STARTLOADSTATE 1078 +#define IDC_RESUMEAFTERLOADSTATE 1078 +#define IDC_STARTSAVESTATE 1079 +#define IDC_RESUMEAFTERSAVESTATE 1079 +#define IDC_DISPLAYFRAMERATE 1080 +#define IDC_SOUNDQUALITYTEXTBOX 1081 +#define IDC_USEFOLDER 1081 +#define IDM_MAIN_COMMAND1 40001 +#define IDM_HELP_ABOUT 40003 +#define IDM_FILE_LOAD 40004 +#define IDM_TOOLS_LOAD 40004 +#define ID_HELP 40005 +#define IDS_CAP_HELP 40007 +#define IDM_TOOLS_EXIT 40008 +#define IDS_CAP_OPTIONS 40008 +#define IDM_TOOLS_OPTIONS 40009 +#define IDM_OPTIONS_SETTINGS 40009 +#define IDM_TOOLS_SKINS 40010 +#define ID_OPTIONS 40011 +#define IDM_OPTIONS_KEYS 40013 +#define IDM_TOOLS_CREDITS 40014 +#define IDM_TOOLS_LOADSTATE 40015 +#define IDM_TOOLS_SAVESTATE 40016 +#define IDM_OPTIONS_DISPLAY 40017 +#define IDM_OPTIONS_SOUND 40018 +#define IDM_BLANK 40020 +#define IDM_OPTIONS_RESET 40022 +#define IDM_TOOLS_RESET 40022 +#define IDM_LOAD1 40023 +#define IDM_TOOLS_LOAD1 40023 +#define IDM_LOAD2 40024 +#define IDM_TOOLS_LOAD2 40024 +#define IDM_LOAD3 40025 +#define IDM_TOOLS_LOAD3 40025 +#define IDM_LOAD4 40026 +#define IDM_TOOLS_LOAD4 40026 +#define IDM_LOAD5 40027 +#define IDM_TOOLS_LOAD5 40027 +#define IDM_HELP 40029 +#define IDM_SAVE1 40031 +#define IDM_TOOLS_SAVE1 40031 +#define IDM_SAVE2 40032 +#define IDM_TOOLS_SAVE2 40032 +#define IDM_SAVE3 40033 +#define IDM_TOOLS_SAVE3 40033 +#define IDM_SAVE4 40034 +#define IDM_LOAD6 40035 +#define IDM_TOOLS_LOAD6 40035 +#define IDM_LOAD7 40036 +#define IDM_TOOLS_LOAD7 40036 +#define IDM_LOAD8 40037 +#define IDM_SAVE6 40038 +#define IDM_TOOLS_SAVE6 40038 +#define IDM_SAVE7 40039 +#define IDM_TOOLS_SAVE7 40039 +#define IDM_SAVE8 40040 +#define IDM_TOOLS_SAVE8 40040 +#define IDM_SAVE9 40041 +#define IDM_TOOLS_SAVE9 40041 +#define IDM_TOOLS_SAVE4 40042 +#define IDM_TOOLS_SAVE5 40043 +#define IDM_TOOLS_RECENT1 40044 +#define IDM_TOOLS_LOAD8 40045 +#define IDM_TOOLS_LOAD9 40046 +#define ID_OPTIONS_SYSTEM 40049 +#define IDM_OPTIONS_SYSTEM 40049 +#define IDM_CHEAT 40050 +#define IDS_CAP_CHEAT 40052 +#define IDM_NETPLAY 40053 +#define IDS_CAP_NETPLAY 40055 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 143 +#define _APS_NEXT_COMMAND_VALUE 40056 +#define _APS_NEXT_CONTROL_VALUE 1082 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/src/snes4iphone_src/sa1.cpp b/src/snes4iphone_src/sa1.cpp new file mode 100755 index 0000000..b39c714 --- /dev/null +++ b/src/snes4iphone_src/sa1.cpp @@ -0,0 +1,892 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#include "snes9x.h" +#include "ppu.h" +#include "cpuexec.h" + +#include "sa1.h" + +static void S9xSA1CharConv2 (); +static void S9xSA1DMA (); +static void S9xSA1ReadVariableLengthData (bool8 inc, bool8 no_shift); + +void S9xSA1Init () +{ + SA1.NMIActive = FALSE; + SA1.IRQActive = FALSE; + SA1.WaitingForInterrupt = FALSE; + SA1.Waiting = FALSE; + SA1.Flags = 0; + SA1.Executing = FALSE; + memset (&Memory.FillRAM [0x2200], 0, 0x200); + Memory.FillRAM [0x2200] = 0x20; + Memory.FillRAM [0x2220] = 0x00; + Memory.FillRAM [0x2221] = 0x01; + Memory.FillRAM [0x2222] = 0x02; + Memory.FillRAM [0x2223] = 0x03; + Memory.FillRAM [0x2228] = 0xff; + SA1.op1 = 0; + SA1.op2 = 0; + SA1.arithmetic_op = 0; + SA1.sum = 0; + SA1.overflow = FALSE; +} + +void S9xSA1Reset () +{ + SA1Registers.PB = 0; + SA1Registers.PC = Memory.FillRAM [0x2203] | + (Memory.FillRAM [0x2204] << 8); + SA1Registers.D.W = 0; + SA1Registers.DB = 0; + SA1Registers.SH = 1; + SA1Registers.SL = 0xFF; + SA1Registers.XH = 0; + SA1Registers.YH = 0; + SA1Registers.P.W = 0; + + SA1.ShiftedPB = 0; + SA1.ShiftedDB = 0; + SA1SetFlags (MemoryFlag | IndexFlag | IRQ | Emulation); + SA1ClearFlags (Decimal); + + SA1.WaitingForInterrupt = FALSE; + SA1.PC = NULL; + SA1.PCBase = NULL; + S9xSA1SetPCBase (SA1Registers.PC); + //SA1.S9xOpcodes = S9xSA1OpcodesM1X1; // unused + + S9xSA1UnpackStatus(); + //S9xSA1FixCycles (); // unused + SA1.Executing = TRUE; + SA1.BWRAM = Memory.SRAM; + Memory.FillRAM [0x2225] = 0; +} + +void S9xSA1SetBWRAMMemMap (uint8 val) +{ + int c; + + if (val & 0x80) + { + for (c = 0; c < 0x400; c += 16) + { + SA1.Map [c + 6] = SA1.Map [c + 0x806] = (uint8 *) CMemory::MAP_BWRAM_BITMAP2; + SA1.Map [c + 7] = SA1.Map [c + 0x807] = (uint8 *) CMemory::MAP_BWRAM_BITMAP2; + SA1.WriteMap [c + 6] = SA1.WriteMap [c + 0x806] = (uint8 *) CMemory::MAP_BWRAM_BITMAP2; + SA1.WriteMap [c + 7] = SA1.WriteMap [c + 0x807] = (uint8 *) CMemory::MAP_BWRAM_BITMAP2; + } + SA1.BWRAM = Memory.SRAM + (val & 0x7f) * 0x2000 / 4; + } + else + { + for (c = 0; c < 0x400; c += 16) + { + SA1.Map [c + 6] = SA1.Map [c + 0x806] = (uint8 *) CMemory::MAP_BWRAM; + SA1.Map [c + 7] = SA1.Map [c + 0x807] = (uint8 *) CMemory::MAP_BWRAM; + SA1.WriteMap [c + 6] = SA1.WriteMap [c + 0x806] = (uint8 *) CMemory::MAP_BWRAM; + SA1.WriteMap [c + 7] = SA1.WriteMap [c + 0x807] = (uint8 *) CMemory::MAP_BWRAM; + } + SA1.BWRAM = Memory.SRAM + (val & 7) * 0x2000; + } +} + +void S9xFixSA1AfterSnapshotLoad () +{ + SA1.ShiftedPB = (uint32) SA1Registers.PB << 16; + SA1.ShiftedDB = (uint32) SA1Registers.DB << 16; + + S9xSA1SetPCBase (SA1.ShiftedPB + SA1Registers.PC); + S9xSA1UnpackStatus (); + //S9xSA1FixCycles (); // unused + SA1.VirtualBitmapFormat = (Memory.FillRAM [0x223f] & 0x80) ? 2 : 4; + Memory.BWRAM = Memory.SRAM + (Memory.FillRAM [0x2224] & 7) * 0x2000; + S9xSA1SetBWRAMMemMap (Memory.FillRAM [0x2225]); + + SA1.Waiting = (Memory.FillRAM [0x2200] & 0x60) != 0; + SA1.Executing = !SA1.Waiting; +} + +uint8 S9xSA1GetByte (uint32 address) +{ + uint8 *GetAddress = SA1.Map [(address >> MEMMAP_SHIFT) & MEMMAP_MASK]; + if (GetAddress >= (uint8 *) CMemory::MAP_LAST) + return (*(GetAddress + (address & 0xffff))); + + switch ((int) GetAddress) + { + case CMemory::MAP_PPU: + return (S9xGetSA1 (address & 0xffff)); + case CMemory::MAP_LOROM_SRAM: + case CMemory::MAP_SA1RAM: + return (*(Memory.SRAM + (address & 0xffff))); + case CMemory::MAP_BWRAM: + return (*(SA1.BWRAM + ((address & 0x7fff) - 0x6000))); + case CMemory::MAP_BWRAM_BITMAP: + address -= 0x600000; + if (SA1.VirtualBitmapFormat == 2) + return ((Memory.SRAM [(address >> 2) & 0xffff] >> ((address & 3) << 1)) & 3); + else + return ((Memory.SRAM [(address >> 1) & 0xffff] >> ((address & 1) << 2)) & 15); + case CMemory::MAP_BWRAM_BITMAP2: + address = (address & 0xffff) - 0x6000; + if (SA1.VirtualBitmapFormat == 2) + return ((SA1.BWRAM [(address >> 2) & 0xffff] >> ((address & 3) << 1)) & 3); + else + return ((SA1.BWRAM [(address >> 1) & 0xffff] >> ((address & 1) << 2)) & 15); + + case CMemory::MAP_DEBUG: + default: +#ifdef DEBUGGER +// printf ("R(B) %06x\n", address); +#endif + + return (0); + } +} + +uint16 S9xSA1GetWord (uint32 address) +{ + return (S9xSA1GetByte (address) | (S9xSA1GetByte (address + 1) << 8)); +} + +void S9xSA1SetByte (uint8 byte, uint32 address) +{ + uint8 *Setaddress = SA1.WriteMap [(address >> MEMMAP_SHIFT) & MEMMAP_MASK]; + + if (Setaddress >= (uint8 *) CMemory::MAP_LAST) + { + *(Setaddress + (address & 0xffff)) = byte; + return; + } + + switch ((int) Setaddress) + { + case CMemory::MAP_PPU: + S9xSetSA1 (byte, address & 0xffff); + return; + case CMemory::MAP_SA1RAM: + case CMemory::MAP_LOROM_SRAM: + *(Memory.SRAM + (address & 0xffff)) = byte; + return; + case CMemory::MAP_BWRAM: + *(SA1.BWRAM + ((address & 0x7fff) - 0x6000)) = byte; + return; + case CMemory::MAP_BWRAM_BITMAP: + address -= 0x600000; + if (SA1.VirtualBitmapFormat == 2) + { + uint8 *ptr = &Memory.SRAM [(address >> 2) & 0xffff]; + *ptr &= ~(3 << ((address & 3) << 1)); + *ptr |= (byte & 3) << ((address & 3) << 1); + } + else + { + uint8 *ptr = &Memory.SRAM [(address >> 1) & 0xffff]; + *ptr &= ~(15 << ((address & 1) << 2)); + *ptr |= (byte & 15) << ((address & 1) << 2); + } + break; + case CMemory::MAP_BWRAM_BITMAP2: + address = (address & 0xffff) - 0x6000; + if (SA1.VirtualBitmapFormat == 2) + { + uint8 *ptr = &SA1.BWRAM [(address >> 2) & 0xffff]; + *ptr &= ~(3 << ((address & 3) << 1)); + *ptr |= (byte & 3) << ((address & 3) << 1); + } + else + { + uint8 *ptr = &SA1.BWRAM [(address >> 1) & 0xffff]; + *ptr &= ~(15 << ((address & 1) << 2)); + *ptr |= (byte & 15) << ((address & 1) << 2); + } + default: + return; + } +} + +void S9xSA1SetWord (uint16 Word, uint32 address) +{ + S9xSA1SetByte ((uint8) Word, address); + S9xSA1SetByte ((uint8) (Word >> 8), address + 1); +} + +void S9xSA1SetPCBase (uint32 address) +{ + uint8 *GetAddress = SA1.Map [(address >> MEMMAP_SHIFT) & MEMMAP_MASK]; + if (GetAddress >= (uint8 *) CMemory::MAP_LAST) + { + SA1.PCBase = GetAddress; + SA1.PC = GetAddress + (address & 0xffff); + return; + } + + switch ((int) GetAddress) + { + case CMemory::MAP_PPU: + SA1.PCBase = Memory.FillRAM - 0x2000; + SA1.PC = SA1.PCBase + (address & 0xffff); + return; + + case CMemory::MAP_CPU: + SA1.PCBase = Memory.FillRAM - 0x4000; + SA1.PC = SA1.PCBase + (address & 0xffff); + return; + + case CMemory::MAP_DSP: + SA1.PCBase = Memory.FillRAM - 0x6000; + SA1.PC = SA1.PCBase + (address & 0xffff); + return; + + case CMemory::MAP_SA1RAM: + case CMemory::MAP_LOROM_SRAM: + SA1.PCBase = Memory.SRAM; + SA1.PC = SA1.PCBase + (address & 0xffff); + return; + + case CMemory::MAP_BWRAM: + SA1.PCBase = SA1.BWRAM - 0x6000; + SA1.PC = SA1.PCBase + (address & 0xffff); + return; + case CMemory::MAP_HIROM_SRAM: + SA1.PCBase = Memory.SRAM - 0x6000; + SA1.PC = SA1.PCBase + (address & 0xffff); + return; + + case CMemory::MAP_DEBUG: +#ifdef DEBUGGER + printf ("SBP %06x\n", address); +#endif + + default: + case CMemory::MAP_NONE: + SA1.PCBase = Memory.RAM; + SA1.PC = Memory.RAM + (address & 0xffff); + return; + } +} + +void S9xSA1ExecuteDuringSleep () +{ +#if 0 + if (SA1.Executing) + { + while (CPU.Cycles < CPU.NextEvent) + { + S9xSA1MainLoop (); + CPU.Cycles += TWO_CYCLES * 2; + } + } +#endif +} + +void S9xSetSA1MemMap (uint32 which1, uint8 map) +{ + int c; + int start = which1 * 0x100 + 0xc00; + int start2 = which1 * 0x200; + + if (which1 >= 2) + start2 += 0x400; + + for (c = 0; c < 0x100; c += 16) + { + uint8 *block = &Memory.ROM [(map & 7) * 0x100000 + (c << 12)]; + int i; + + for (i = c; i < c + 16; i++) + Memory.Map [start + i] = SA1.Map [start + i] = block; + } + + for (c = 0; c < 0x200; c += 16) + { + uint8 *block = &Memory.ROM [(map & 7) * 0x100000 + (c << 11) - 0x8000]; + int i; + + for (i = c + 8; i < c + 16; i++) + Memory.Map [start2 + i] = SA1.Map [start2 + i] = block; + } +} + +uint8 S9xGetSA1 (uint32 address) +{ +// printf ("R: %04x\n", address); + switch (address) + { + case 0x2300: + return ((uint8) ((Memory.FillRAM [0x2209] & 0x5f) | + (CPU.IRQActive & (SA1_IRQ_SOURCE | SA1_DMA_IRQ_SOURCE)))); + case 0x2301: + return ((Memory.FillRAM [0x2200] & 0xf) | + (Memory.FillRAM [0x2301] & 0xf0)); + case 0x2306: + return ((uint8) SA1.sum); + case 0x2307: + return ((uint8) (SA1.sum >> 8)); + case 0x2308: + return ((uint8) (SA1.sum >> 16)); + case 0x2309: + return ((uint8) (SA1.sum >> 24)); + case 0x230a: + return ((uint8) (SA1.sum >> 32)); + case 0x230c: + return (Memory.FillRAM [0x230c]); + case 0x230d: + { + uint8 byte = Memory.FillRAM [0x230d]; + + if (Memory.FillRAM [0x2258] & 0x80) + { + S9xSA1ReadVariableLengthData (TRUE, FALSE); + } + return (byte); + } + default: +// printf ("R: %04x\n", address); + break; + } + return (Memory.FillRAM [address]); +} + +void S9xSetSA1 (uint8 byte, uint32 address) +{ +//printf ("W: %02x -> %04x\n", byte, address); + switch (address) + { + case 0x2200: + SA1.Waiting = (byte & 0x60) != 0; +// SA1.Executing = !SA1.Waiting && SA1.S9xOpcodes; + + if (!(byte & 0x20) && (Memory.FillRAM [0x2200] & 0x20)) + { + S9xSA1Reset (); + } + if (byte & 0x80) + { + Memory.FillRAM [0x2301] |= 0x80; + if (Memory.FillRAM [0x220a] & 0x80) + { + SA1.Flags |= IRQ_PENDING_FLAG; + SA1.IRQActive |= SNES_IRQ_SOURCE; + SA1.Executing = !SA1.Waiting;// && SA1.S9xOpcodes; // unused + } + } + if (byte & 0x10) + { + Memory.FillRAM [0x2301] |= 0x10; +#ifdef DEBUGGER + printf ("###SA1 NMI\n"); +#endif + if (Memory.FillRAM [0x220a] & 0x10) + { + } + } + break; + + case 0x2201: + if (((byte ^ Memory.FillRAM [0x2201]) & 0x80) && + (Memory.FillRAM [0x2300] & byte & 0x80)) + { + S9xSetIRQ (SA1_IRQ_SOURCE); + } + if (((byte ^ Memory.FillRAM [0x2201]) & 0x20) && + (Memory.FillRAM [0x2300] & byte & 0x20)) + { + S9xSetIRQ (SA1_DMA_IRQ_SOURCE); + } + break; + case 0x2202: + if (byte & 0x80) + { + Memory.FillRAM [0x2300] &= ~0x80; + S9xClearIRQ (SA1_IRQ_SOURCE); + } + if (byte & 0x20) + { + Memory.FillRAM [0x2300] &= ~0x20; + S9xClearIRQ (SA1_DMA_IRQ_SOURCE); + } + break; + case 0x2203: +// printf ("SA1 reset vector: %04x\n", byte | (Memory.FillRAM [0x2204] << 8)); + break; + case 0x2204: +// printf ("SA1 reset vector: %04x\n", (byte << 8) | Memory.FillRAM [0x2203]); + break; + + case 0x2205: +// printf ("SA1 NMI vector: %04x\n", byte | (Memory.FillRAM [0x2206] << 8)); + break; + case 0x2206: +// printf ("SA1 NMI vector: %04x\n", (byte << 8) | Memory.FillRAM [0x2205]); + break; + + case 0x2207: +// printf ("SA1 IRQ vector: %04x\n", byte | (Memory.FillRAM [0x2208] << 8)); + break; + case 0x2208: +// printf ("SA1 IRQ vector: %04x\n", (byte << 8) | Memory.FillRAM [0x2207]); + break; + + case 0x2209: + Memory.FillRAM [0x2209] = byte; + if (byte & 0x80) + Memory.FillRAM [0x2300] |= 0x80; + + if (byte & Memory.FillRAM [0x2201] & 0x80) + { + S9xSetIRQ (SA1_IRQ_SOURCE); + } + break; + case 0x220a: + if (((byte ^ Memory.FillRAM [0x220a]) & 0x80) && + (Memory.FillRAM [0x2301] & byte & 0x80)) + { + SA1.Flags |= IRQ_PENDING_FLAG; + SA1.IRQActive |= SNES_IRQ_SOURCE; +// SA1.Executing = !SA1.Waiting; + } + if (((byte ^ Memory.FillRAM [0x220a]) & 0x40) && + (Memory.FillRAM [0x2301] & byte & 0x40)) + { + SA1.Flags |= IRQ_PENDING_FLAG; + SA1.IRQActive |= TIMER_IRQ_SOURCE; +// SA1.Executing = !SA1.Waiting; + } + if (((byte ^ Memory.FillRAM [0x220a]) & 0x20) && + (Memory.FillRAM [0x2301] & byte & 0x20)) + { + SA1.Flags |= IRQ_PENDING_FLAG; + SA1.IRQActive |= DMA_IRQ_SOURCE; +// SA1.Executing = !SA1.Waiting; + } + if (((byte ^ Memory.FillRAM [0x220a]) & 0x10) && + (Memory.FillRAM [0x2301] & byte & 0x10)) + { +#ifdef DEBUGGER + printf ("###SA1 NMI\n"); +#endif + } + break; + case 0x220b: + if (byte & 0x80) + { + SA1.IRQActive &= ~SNES_IRQ_SOURCE; + Memory.FillRAM [0x2301] &= ~0x80; + } + if (byte & 0x40) + { + SA1.IRQActive &= ~TIMER_IRQ_SOURCE; + Memory.FillRAM [0x2301] &= ~0x40; + } + if (byte & 0x20) + { + SA1.IRQActive &= ~DMA_IRQ_SOURCE; + Memory.FillRAM [0x2301] &= ~0x20; + } + if (byte & 0x10) + { + // Clear NMI + Memory.FillRAM [0x2301] &= ~0x10; + } + if (!SA1.IRQActive) + SA1.Flags &= ~IRQ_PENDING_FLAG; + break; + case 0x220c: +// printf ("SNES NMI vector: %04x\n", byte | (Memory.FillRAM [0x220d] << 8)); + break; + case 0x220d: +// printf ("SNES NMI vector: %04x\n", (byte << 8) | Memory.FillRAM [0x220c]); + break; + + case 0x220e: +// printf ("SNES IRQ vector: %04x\n", byte | (Memory.FillRAM [0x220f] << 8)); + break; + case 0x220f: +// printf ("SNES IRQ vector: %04x\n", (byte << 8) | Memory.FillRAM [0x220e]); + break; + + case 0x2210: +#if 0 + printf ("Timer %s\n", (byte & 0x80) ? "linear" : "HV"); + printf ("Timer H-IRQ %s\n", (byte & 1) ? "enabled" : "disabled"); + printf ("Timer V-IRQ %s\n", (byte & 2) ? "enabled" : "disabled"); +#endif + break; + case 0x2211: +// printf ("Timer reset\n"); + break; + case 0x2212: +// printf ("H-Timer %04x\n", byte | (FillRAM [0x2213] << 8)); + break; + case 0x2213: +// printf ("H-Timer %04x\n", (byte << 8) | FillRAM [0x2212]); + break; + case 0x2214: +// printf ("V-Timer %04x\n", byte | (FillRAM [0x2215] << 8)); + break; + case 0x2215: +// printf ("V-Timer %04x\n", (byte << 8) | FillRAM [0x2214]); + break; + case 0x2220: + case 0x2221: + case 0x2222: + case 0x2223: + S9xSetSA1MemMap (address - 0x2220, byte); +// printf ("MMC: %02x\n", byte); + break; + case 0x2224: +// printf ("BWRAM image SNES %02x -> 0x6000\n", byte); + Memory.BWRAM = Memory.SRAM + (byte & 7) * 0x2000; + break; + case 0x2225: +// printf ("BWRAM image SA1 %02x -> 0x6000 (%02x)\n", byte, Memory.FillRAM [address]); + if (byte != Memory.FillRAM [address]) + S9xSA1SetBWRAMMemMap (byte); + break; + case 0x2226: +// printf ("BW-RAM SNES write %s\n", (byte & 0x80) ? "enabled" : "disabled"); + break; + case 0x2227: +// printf ("BW-RAM SA1 write %s\n", (byte & 0x80) ? "enabled" : "disabled"); + break; + + case 0x2228: +// printf ("BW-RAM write protect area %02x\n", byte); + break; + case 0x2229: +// printf ("I-RAM SNES write protect area %02x\n", byte); + break; + case 0x222a: +// printf ("I-RAM SA1 write protect area %02x\n", byte); + break; + case 0x2230: +#if 0 + printf ("SA1 DMA %s\n", (byte & 0x80) ? "enabled" : "disabled"); + printf ("DMA priority %s\n", (byte & 0x40) ? "DMA" : "SA1"); + printf ("DMA %s\n", (byte & 0x20) ? "char conv" : "normal"); + printf ("DMA type %s\n", (byte & 0x10) ? "BW-RAM -> I-RAM" : "SA1 -> I-RAM"); + printf ("DMA distination %s\n", (byte & 4) ? "BW-RAM" : "I-RAM"); + printf ("DMA source %s\n", DMAsource [byte & 3]); +#endif + break; + case 0x2231: + if (byte & 0x80) + SA1.in_char_dma = FALSE; +#if 0 + printf ("CHDEND %s\n", (byte & 0x80) ? "complete" : "incomplete"); + printf ("DMA colour mode %d\n", byte & 3); + printf ("virtual VRAM width %d\n", (byte >> 2) & 7); +#endif + break; + case 0x2232: + case 0x2233: + case 0x2234: + Memory.FillRAM [address] = byte; +#if 0 + printf ("DMA source start %06x\n", + Memory.FillRAM [0x2232] | (Memory.FillRAM [0x2233] << 8) | + (Memory.FillRAM [0x2234] << 16)); +#endif + break; + case 0x2235: + Memory.FillRAM [address] = byte; + break; + case 0x2236: + Memory.FillRAM [address] = byte; + if ((Memory.FillRAM [0x2230] & 0xa4) == 0x80) + { + // Normal DMA to I-RAM + S9xSA1DMA (); + } + else + if ((Memory.FillRAM [0x2230] & 0xb0) == 0xb0) + { + Memory.FillRAM [0x2300] |= 0x20; + if (Memory.FillRAM [0x2201] & 0x20) + S9xSetIRQ (SA1_DMA_IRQ_SOURCE); + SA1.in_char_dma = TRUE; + } + break; + case 0x2237: + Memory.FillRAM [address] = byte; + if ((Memory.FillRAM [0x2230] & 0xa4) == 0x84) + { + // Normal DMA to BW-RAM + S9xSA1DMA (); + } +#if 0 + printf ("DMA dest address %06x\n", + Memory.FillRAM [0x2235] | (Memory.FillRAM [0x2236] << 8) | + (Memory.FillRAM [0x2237] << 16)); +#endif + break; + case 0x2238: + case 0x2239: + Memory.FillRAM [address] = byte; +#if 0 + printf ("DMA length %04x\n", + Memory.FillRAM [0x2238] | (Memory.FillRAM [0x2239] << 8)); +#endif + break; + case 0x223f: + SA1.VirtualBitmapFormat = (byte & 0x80) ? 2 : 4; + //printf ("virtual VRAM depth %d\n", (byte & 0x80) ? 2 : 4); + break; + + case 0x2240: case 0x2241: case 0x2242: case 0x2243: + case 0x2244: case 0x2245: case 0x2246: case 0x2247: + case 0x2248: case 0x2249: case 0x224a: case 0x224b: + case 0x224c: case 0x224d: case 0x224e: +#if 0 + if (!(SA1.Flags & TRACE_FLAG)) + { + TraceSA1 (); + Trace (); + } +#endif + Memory.FillRAM [address] = byte; + break; + + case 0x224f: + Memory.FillRAM [address] = byte; + if ((Memory.FillRAM [0x2230] & 0xb0) == 0xa0) + { + // Char conversion 2 DMA enabled + memmove (&Memory.ROM [CMemory::MAX_ROM_SIZE - 0x10000] + SA1.in_char_dma * 16, + &Memory.FillRAM [0x2240], 16); + SA1.in_char_dma = (SA1.in_char_dma + 1) & 7; + if ((SA1.in_char_dma & 3) == 0) + { + S9xSA1CharConv2 (); + } + } + break; + case 0x2250: + if (byte & 2) + SA1.sum = 0; + SA1.arithmetic_op = byte & 3; + break; + + case 0x2251: + SA1.op1 = (SA1.op1 & 0xff00) | byte; + break; + case 0x2252: + SA1.op1 = (SA1.op1 & 0xff) | (byte << 8); + break; + case 0x2253: + SA1.op2 = (SA1.op2 & 0xff00) | byte; + break; + case 0x2254: + SA1.op2 = (SA1.op2 & 0xff) | (byte << 8); + switch (SA1.arithmetic_op) + { + case 0: // multiply + SA1.sum = SA1.op1 * SA1.op2; + break; + case 1: // divide + if (SA1.op2 == 0) + SA1.sum = SA1.op1 << 16; + else + { + SA1.sum = (SA1.op1 / (int) ((uint16) SA1.op2)) | + ((SA1.op1 % (int) ((uint16) SA1.op2)) << 16); + } + break; + case 2: + default: // cumulative sum + SA1.sum += SA1.op1 * SA1.op2; + if (SA1.sum & ((int64) 0xffffff << 32)) + SA1.overflow = TRUE; + break; + } + break; + case 0x2258: // Variable bit-field length/auto inc/start. + Memory.FillRAM [0x2258] = byte; + S9xSA1ReadVariableLengthData (TRUE, FALSE); + return; + case 0x2259: + case 0x225a: + case 0x225b: // Variable bit-field start address + Memory.FillRAM [address] = byte; + // XXX: ??? + SA1.variable_bit_pos = 0; + S9xSA1ReadVariableLengthData (FALSE, TRUE); + return; + default: +// printf ("W: %02x->%04x\n", byte, address); + break; + } + if (address >= 0x2200 && address <= 0x22ff) + Memory.FillRAM [address] = byte; +} + +static void S9xSA1CharConv2 () +{ + uint32 dest = Memory.FillRAM [0x2235] | (Memory.FillRAM [0x2236] << 8); + uint32 offset = (SA1.in_char_dma & 7) ? 0 : 1; + int depth = (Memory.FillRAM [0x2231] & 3) == 0 ? 8 : + (Memory.FillRAM [0x2231] & 3) == 1 ? 4 : 2; + int bytes_per_char = 8 * depth; + uint8 *p = &Memory.FillRAM [0x3000] + dest + offset * bytes_per_char; + uint8 *q = &Memory.ROM [CMemory::MAX_ROM_SIZE - 0x10000] + offset * 64; + + switch (depth) + { + case 2: + break; + case 4: + break; + case 8: + for (int l = 0; l < 8; l++, q += 8) + { + for (int b = 0; b < 8; b++) + { + uint8 r = *(q + b); + *(p + 0) = (*(p + 0) << 1) | ((r >> 0) & 1); + *(p + 1) = (*(p + 1) << 1) | ((r >> 1) & 1); + *(p + 16) = (*(p + 16) << 1) | ((r >> 2) & 1); + *(p + 17) = (*(p + 17) << 1) | ((r >> 3) & 1); + *(p + 32) = (*(p + 32) << 1) | ((r >> 4) & 1); + *(p + 33) = (*(p + 33) << 1) | ((r >> 5) & 1); + *(p + 48) = (*(p + 48) << 1) | ((r >> 6) & 1); + *(p + 49) = (*(p + 49) << 1) | ((r >> 7) & 1); + } + p += 2; + } + break; + } +} + +static void S9xSA1DMA () +{ + uint32 src = Memory.FillRAM [0x2232] | + (Memory.FillRAM [0x2233] << 8) | + (Memory.FillRAM [0x2234] << 16); + uint32 dst = Memory.FillRAM [0x2235] | + (Memory.FillRAM [0x2236] << 8) | + (Memory.FillRAM [0x2237] << 16); + uint32 len = Memory.FillRAM [0x2238] | + (Memory.FillRAM [0x2239] << 8); + + uint8 *s; + uint8 *d; + + switch (Memory.FillRAM [0x2230] & 3) + { + case 0: // ROM + s = SA1.Map [(src >> MEMMAP_SHIFT) & MEMMAP_MASK]; + if (s >= (uint8 *) CMemory::MAP_LAST) + s += (src & 0xffff); + else + s = Memory.ROM + (src & 0xffff); + break; + case 1: // BW-RAM + src &= CPU.Memory_SRAMMask; + len &= CPU.Memory_SRAMMask; + s = Memory.SRAM + src; + break; + default: + case 2: + src &= 0x3ff; + len &= 0x3ff; + s = &Memory.FillRAM [0x3000] + src; + break; + } + + if (Memory.FillRAM [0x2230] & 4) + { + dst &= CPU.Memory_SRAMMask; + len &= CPU.Memory_SRAMMask; + d = Memory.SRAM + dst; + } + else + { + dst &= 0x3ff; + len &= 0x3ff; + d = &Memory.FillRAM [0x3000] + dst; + } + memmove (d, s, len); + Memory.FillRAM [0x2301] |= 0x20; + + if (Memory.FillRAM [0x220a] & 0x20) + { + SA1.Flags |= IRQ_PENDING_FLAG; + SA1.IRQActive |= DMA_IRQ_SOURCE; +// SA1.Executing = !SA1.Waiting; + } +} + +void S9xSA1ReadVariableLengthData (bool8 inc, bool8 no_shift) +{ + uint32 addr = Memory.FillRAM [0x2259] | + (Memory.FillRAM [0x225a] << 8) | + (Memory.FillRAM [0x225b] << 16); + uint8 shift = Memory.FillRAM [0x2258] & 15; + + if (no_shift) + shift = 0; + else + if (shift == 0) + shift = 16; + + uint8 s = shift + SA1.variable_bit_pos; + + if (s >= 16) + { + addr += (s >> 4) << 1; + s &= 15; + } + uint32 data = S9xSA1GetWord (addr) | + (S9xSA1GetWord (addr + 2) << 16); + + data >>= s; + Memory.FillRAM [0x230c] = (uint8) data; + Memory.FillRAM [0x230d] = (uint8) (data >> 8); + if (inc) + { + SA1.variable_bit_pos = (SA1.variable_bit_pos + shift) & 15; + Memory.FillRAM [0x2259] = (uint8) addr; + Memory.FillRAM [0x225a] = (uint8) (addr >> 8); + Memory.FillRAM [0x225b] = (uint8) (addr >> 16); + } +} diff --git a/src/snes4iphone_src/sa1.h b/src/snes4iphone_src/sa1.h new file mode 100755 index 0000000..0a2e837 --- /dev/null +++ b/src/snes4iphone_src/sa1.h @@ -0,0 +1,179 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#ifndef _sa1_h_ +#define _sa1_h_ + +#include "memmap.h" + +START_EXTERN_C +struct SSA1Registers { + uint8 PB; + uint8 DB; + pair P; + pair A; + pair D; + pair S; + pair X; + pair Y; + uint16 PC; +}; + +struct SSA1 { + struct SOpcodes *S9xOpcodes; + uint8 _Carry; + uint8 _Zero; + uint8 _Negative; + uint8 _Overflow; + bool8 CPUExecuting; + uint32 ShiftedPB; + uint32 ShiftedDB; + uint32 Flags; + bool8 Executing; + bool8 NMIActive; + bool8 IRQActive; + bool8 WaitingForInterrupt; + bool8 Waiting; +// uint8 WhichEvent; + uint8 *PC; + uint8 *PCBase; + uint8 *BWRAM; + uint8 *PCAtOpcodeStart; + uint8 *WaitAddress; + uint32 WaitCounter; + uint8 *WaitByteAddress1; + uint8 *WaitByteAddress2; +// long Cycles; +// long NextEvent; +// long V_Counter; + uint8 *Map [MEMMAP_NUM_BLOCKS]; + uint8 *WriteMap [MEMMAP_NUM_BLOCKS]; + int16 op1; + int16 op2; + int arithmetic_op; + int64 sum; + bool8 overflow; + uint8 VirtualBitmapFormat; + bool8 in_char_dma; + uint8 variable_bit_pos; +}; + +extern struct SSA1Registers SA1Registers; +extern struct SSA1 SA1; + +#ifdef USE_SA1 + +#define SA1CheckZero() (SA1._Zero == 0) +#define SA1CheckCarry() (SA1._Carry) +#define SA1CheckIRQ() (SA1Registers.PL & IRQ) +#define SA1CheckDecimal() (SA1Registers.PL & Decimal) +#define SA1CheckIndex() (SA1Registers.PL & IndexFlag) +#define SA1CheckMemory() (SA1Registers.PL & MemoryFlag) +#define SA1CheckOverflow() (SA1._Overflow) +#define SA1CheckNegative() (SA1._Negative & 0x80) +#define SA1CheckEmulation() (SA1Registers.P.W & Emulation) + +#define SA1ClearFlags(f) (SA1Registers.P.W &= ~(f)) +#define SA1SetFlags(f) (SA1Registers.P.W |= (f)) +#define SA1CheckFlag(f) (SA1Registers.PL & (f)) + + +uint8 S9xSA1GetByte (uint32); +uint16 S9xSA1GetWord (uint32); +void S9xSA1SetByte (uint8, uint32); +void S9xSA1SetWord (uint16, uint32); +void S9xSA1SetPCBase (uint32); +uint8 S9xGetSA1 (uint32); +void S9xSetSA1 (uint8, uint32); + +extern struct SOpcodes S9xSA1OpcodesM1X1 [256]; +extern struct SOpcodes S9xSA1OpcodesM1X0 [256]; +extern struct SOpcodes S9xSA1OpcodesM0X1 [256]; +extern struct SOpcodes S9xSA1OpcodesM0X0 [256]; + +void S9xSA1MainLoop (); +void S9xSA1Init (); +void S9xFixSA1AfterSnapshotLoad (); +void S9xSA1ExecuteDuringSleep (); +END_EXTERN_C + +#define SNES_IRQ_SOURCE (1 << 7) +#define TIMER_IRQ_SOURCE (1 << 6) +#define DMA_IRQ_SOURCE (1 << 5) + +STATIC inline void S9xSA1UnpackStatus() +{ + SA1._Zero = (SA1Registers.PL & Zero) == 0; + SA1._Negative = (SA1Registers.PL & Negative); + SA1._Carry = (SA1Registers.PL & Carry); + SA1._Overflow = (SA1Registers.PL & Overflow) >> 6; +} + +STATIC inline void S9xSA1PackStatus() +{ + SA1Registers.PL &= ~(Zero | Negative | Carry | Overflow); + SA1Registers.PL |= SA1._Carry | ((SA1._Zero == 0) << 1) | + (SA1._Negative & 0x80) | (SA1._Overflow << 6); +} + +STATIC inline void S9xSA1FixCycles () +{ + if (SA1CheckEmulation ()) + SA1.S9xOpcodes = S9xSA1OpcodesM1X1; + else + if (SA1CheckMemory ()) + { + if (SA1CheckIndex ()) + SA1.S9xOpcodes = S9xSA1OpcodesM1X1; + else + SA1.S9xOpcodes = S9xSA1OpcodesM1X0; + } + else + { + if (SA1CheckIndex ()) + SA1.S9xOpcodes = S9xSA1OpcodesM0X1; + else + SA1.S9xOpcodes = S9xSA1OpcodesM0X0; + } +} + +#endif // USE_SA1 + +#endif diff --git a/src/snes4iphone_src/sa1cpu.cpp b/src/snes4iphone_src/sa1cpu.cpp new file mode 100755 index 0000000..99975bb --- /dev/null +++ b/src/snes4iphone_src/sa1cpu.cpp @@ -0,0 +1,151 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#include "snes9x.h" +#include "memmap.h" +#include "ppu.h" +#include "cpuexec.h" + +#include "sa1.h" +#define CPU SA1 +#define ICPU SA1 + +#undef Registers + +#define Registers SA1Registers +#define S9xGetByte S9xSA1GetByte +#define S9xGetWord S9xSA1GetWord +#define S9xSetByte S9xSA1SetByte +#define S9xSetWord S9xSA1SetWord +#define S9xSetPCBase S9xSA1SetPCBase +#define S9xOpcodesM1X1 S9xSA1OpcodesM1X1 +#define S9xOpcodesM1X0 S9xSA1OpcodesM1X0 +#define S9xOpcodesM0X1 S9xSA1OpcodesM0X1 +#define S9xOpcodesM0X0 S9xSA1OpcodesM0X0 +#define S9xOpcode_IRQ S9xSA1Opcode_IRQ +#define S9xOpcode_NMI S9xSA1Opcode_NMI +#define S9xUnpackStatus S9xSA1UnpackStatus +#define S9xPackStatus S9xSA1PackStatus +#define S9xFixCycles S9xSA1FixCycles +//CSNES Not even used +/* +#define Immediate8 SA1Immediate8 +#define Immediate16 SA1Immediate16 +#define Relative SA1Relative +#define RelativeLong SA1RelativeLong +#define AbsoluteIndexedIndirect SA1AbsoluteIndexedIndirect +#define AbsoluteIndirectLong SA1AbsoluteIndirectLong +#define AbsoluteIndirect SA1AbsoluteIndirect +#define Absolute SA1Absolute +#define AbsoluteLong SA1AbsoluteLong +#define Direct SA1Direct +#define DirectIndirectIndexed SA1DirectIndirectIndexed +#define DirectIndirectIndexedLong SA1DirectIndirectIndexedLong +#define DirectIndexedIndirect SA1DirectIndexedIndirect +#define DirectIndexedX SA1DirectIndexedX +#define DirectIndexedY SA1DirectIndexedY +#define AbsoluteIndexedX SA1AbsoluteIndexedX +#define AbsoluteIndexedY SA1AbsoluteIndexedY +#define AbsoluteLongIndexedX SA1AbsoluteLongIndexedX +#define DirectIndirect SA1DirectIndirect +#define DirectIndirectLong SA1DirectIndirectLong +#define StackRelative SA1StackRelative +#define StackRelativeIndirectIndexed SA1StackRelativeIndirectIndexed +*/ + +//#undef CPU_SHUTDOWN +#undef VAR_CYCLES +#define SA1_OPCODES + +#include "cpuops.cpp" + +void S9xSA1MainLoop () +{ + int i; + +#if 0 + if (SA1.Flags & NMI_FLAG) + { + SA1.Flags &= ~NMI_FLAG; + if (SA1.WaitingForInterrupt) + { + SA1.WaitingForInterrupt = FALSE; + SA1.PC++; + } + S9xSA1Opcode_NMI (); + } +#endif + if (SA1.Flags & IRQ_PENDING_FLAG) + { + if (SA1.IRQActive) + { + if (SA1.WaitingForInterrupt) + { + SA1.WaitingForInterrupt = FALSE; + SA1.PC++; + } + if (!SA1CheckFlag (IRQ)) + S9xSA1Opcode_IRQ (); + } + else + SA1.Flags &= ~IRQ_PENDING_FLAG; + } +#ifdef DEBUGGER + if (SA1.Flags & TRACE_FLAG) + { + for (i = 0; i < 3 && SA1.Executing; i++) + { + S9xSA1Trace (); +#ifdef CPU_SHUTDOWN + SA1.PCAtOpcodeStart = SA1.PC; +#endif + (*SA1.S9xOpcodes [*SA1.PC++].S9xOpcode) (); + } + } + else +#endif + for (i = 0; i < 3 && SA1.Executing; i++) + { +#ifdef CPU_SHUTDOWN + SA1.PCAtOpcodeStart = SA1.PC; +#endif + (*SA1.S9xOpcodes [*SA1.PC++].S9xOpcode) (); + } +} diff --git a/src/snes4iphone_src/sar.h b/src/snes4iphone_src/sar.h new file mode 100755 index 0000000..c58dbb9 --- /dev/null +++ b/src/snes4iphone_src/sar.h @@ -0,0 +1,131 @@ +/******************************************************************************* + Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + + (c) Copyright 1996 - 2003 Gary Henderson (gary.henderson@ntlworld.com) and + Jerremy Koot (jkoot@snes9x.com) + + (c) Copyright 2002 - 2003 Matthew Kendora and + Brad Jorsch (anomie@users.sourceforge.net) + + + + C4 x86 assembler and some C emulation code + (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com), + _Demo_ (_demo_@zsnes.com), and + Nach (n-a-c-h@users.sourceforge.net) + + C4 C++ code + (c) Copyright 2003 Brad Jorsch + + DSP-1 emulator code + (c) Copyright 1998 - 2003 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson, + John Weidman (jweidman@slip.net), + neviksti (neviksti@hotmail.com), and + Kris Bleakley (stinkfish@bigpond.com) + + DSP-2 emulator code + (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and + Lord Nightmare (lord_nightmare@users.sourceforge.net + + OBC1 emulator code + (c) Copyright 2001 - 2003 zsKnight, pagefault (pagefault@zsnes.com) + Ported from x86 assembler to C by sanmaiwashi + + SPC7110 and RTC C++ emulator code + (c) Copyright 2002 Matthew Kendora with research by + zsKnight, John Weidman, and Dark Force + + S-RTC C emulator code + (c) Copyright 2001 John Weidman + + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + + Super FX C emulator code + (c) Copyright 1997 - 1999 Ivar and Gary Henderson. + + + + + Specific ports contains the works of other authors. See headers in + individual files. + + Snes9x homepage: http://www.snes9x.com + + Permission to use, copy, modify and distribute Snes9x in both binary and + source form, for non-commercial purposes, is hereby granted without fee, + providing that this license information and copyright notice appear with + all copies and any derived work. + + This software is provided 'as-is', without any express or implied + warranty. In no event shall the authors be held liable for any damages + arising from the use of this software. + + Snes9x is freeware for PERSONAL USE only. Commercial users should + seek permission of the copyright holders first. Commercial use includes + charging money for Snes9x or software derived from Snes9x. + + The copyright holders request that bug fixes and improvements to the code + should be forwarded to them so everyone can benefit from the modifications + in future versions. + + Super NES and Super Nintendo Entertainment System are trademarks of + Nintendo Co., Limited and its subsidiary companies. +*******************************************************************************/ + +#ifndef _SAR_H_ +#define _SAR_H_ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include "port.h" + +#ifndef snes9x_types_defined +#define snes9x_types_defined + +typedef unsigned char uint8; +typedef unsigned short uint16; +typedef unsigned int uint32; +typedef unsigned char bool8; +typedef signed char int8; +typedef short int16; +typedef int int32; +#endif + +#ifdef RIGHTSHIFT_IS_SAR +#define SAR(b, n) ((b)>>(n)) +#else + +static inline int8 SAR(const int8 b, const int n){ +#ifndef RIGHTSHIFT_INT8_IS_SAR + if(b<0) return (b>>n)|(-1<<(8-n)); +#endif + return b>>n; +} + +static inline int16 SAR(const int16 b, const int n){ +#ifndef RIGHTSHIFT_INT16_IS_SAR + if(b<0) return (b>>n)|(-1<<(16-n)); +#endif + return b>>n; +} + +static inline int32 SAR(const int32 b, const int n){ +#ifndef RIGHTSHIFT_INT32_IS_SAR + if(b<0) return (b>>n)|(-1<<(32-n)); +#endif + return b>>n; +} + +static inline int64 SAR(const int64 b, const int n){ +#ifndef RIGHTSHIFT_INT64_IS_SAR + if(b<0) return (b>>n)|(-1<<(64-n)); +#endif + return b>>n; +} + +#endif + +#endif diff --git a/src/snes4iphone_src/screenshot.cpp b/src/snes4iphone_src/screenshot.cpp new file mode 100755 index 0000000..3203dd5 --- /dev/null +++ b/src/snes4iphone_src/screenshot.cpp @@ -0,0 +1,235 @@ +/******************************************************************************* + Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and + Jerremy Koot (jkoot@snes9x.com) + + (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net) + + (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net), + funkyass (funkyass@spam.shaw.ca), + Joel Yliluoma (http://iki.fi/bisqwit/) + Kris Bleakley (codeviolation@hotmail.com), + Matthew Kendora, + Nach (n-a-c-h@users.sourceforge.net), + Peter Bortas (peter@bortas.org) and + zones (kasumitokoduck@yahoo.com) + + C4 x86 assembler and some C emulation code + (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com), + _Demo_ (_demo_@zsnes.com), and Nach + + C4 C++ code + (c) Copyright 2003 Brad Jorsch + + DSP-1 emulator code + (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson, + John Weidman, neviksti (neviksti@hotmail.com), + Kris Bleakley, Andreas Naive + + DSP-2 emulator code + (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and + Lord Nightmare (lord_nightmare@users.sourceforge.net + + OBC1 emulator code + (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and + Kris Bleakley + Ported from x86 assembler to C by sanmaiwashi + + SPC7110 and RTC C++ emulator code + (c) Copyright 2002 Matthew Kendora with research by + zsKnight, John Weidman, and Dark Force + + S-DD1 C emulator code + (c) Copyright 2003 Brad Jorsch with research by + Andreas Naive and John Weidman + + S-RTC C emulator code + (c) Copyright 2001 John Weidman + + ST010 C++ emulator code + (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora + + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + + Super FX C emulator code + (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman + + + SH assembler code partly based on x86 assembler code + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + + + Specific ports contains the works of other authors. See headers in + individual files. + + Snes9x homepage: http://www.snes9x.com + + Permission to use, copy, modify and distribute Snes9x in both binary and + source form, for non-commercial purposes, is hereby granted without fee, + providing that this license information and copyright notice appear with + all copies and any derived work. + + This software is provided 'as-is', without any express or implied + warranty. In no event shall the authors be held liable for any damages + arising from the use of this software. + + Snes9x is freeware for PERSONAL USE only. Commercial users should + seek permission of the copyright holders first. Commercial use includes + charging money for Snes9x or software derived from Snes9x. + + The copyright holders request that bug fixes and improvements to the code + should be forwarded to them so everyone can benefit from the modifications + in future versions. + + Super NES and Super Nintendo Entertainment System are trademarks of + Nintendo Co., Limited and its subsidiary companies. +*******************************************************************************/ + + +#ifdef HAVE_CONFIG_H + #include +#endif +#include + +#ifndef __WIN32__ +#include +#else +#include +#endif +#include +#include + +#ifdef HAVE_LIBPNG +#include +#endif + +#include "snes9x.h" +#include "memmap.h" +#include "display.h" +#include "gfx.h" +#include "ppu.h" +#include "screenshot.h" + +bool8 S9xDoScreenshot(int width, int height){ +#ifdef HAVE_LIBPNG + FILE *fp; + png_structp png_ptr; + png_infop info_ptr; + png_color_8 sig_bit; + png_color pngpal[256]; + int imgwidth; + int imgheight; + const char *fname=S9xGetFilenameInc(".png"); + + Settings.TakeScreenshot=FALSE; + + if((fp=fopen(fname, "wb"))==NULL){ + perror("Screenshot failed"); + return FALSE; + } + + png_ptr=png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if(!png_ptr){ + fclose(fp); + unlink(fname); + return FALSE; + } + info_ptr=png_create_info_struct(png_ptr); + if(!info_ptr){ + png_destroy_write_struct(&png_ptr, (png_infopp)NULL); + fclose(fp); + unlink(fname); + return FALSE; + } + + if(setjmp(png_jmpbuf(png_ptr))){ + perror("Screenshot: setjmp"); + png_destroy_write_struct(&png_ptr, &info_ptr); + fclose(fp); + unlink(fname); + return FALSE; + } + + imgwidth=width; + imgheight=height; + if(Settings.StretchScreenshots==1){ + if(width<=256 && height>SNES_HEIGHT_EXTENDED) imgwidth=width<<1; + if(width>256 && height<=SNES_HEIGHT_EXTENDED) imgheight=height<<1; + } else if(Settings.StretchScreenshots==2){ + if(width<=256) imgwidth=width<<1; + if(height<=SNES_HEIGHT_EXTENDED) imgheight=height<<1; + } + + png_init_io(png_ptr, fp); + if(!Settings.SixteenBit){ + // BJ: credit sanmaiwashi for the idea to do palettized pngs, and to + // S9xSetPalette in x11.cpp for how to calculate the RGB values + int b=IPPU.MaxBrightness*140; + for(int i=0; i<256; i++){ + pngpal[i].red = (PPU.CGDATA[i] & 0x1f)*b>>8; + pngpal[i].green = ((PPU.CGDATA[i] >> 5) & 0x1f)*b>>8; + pngpal[i].blue = ((PPU.CGDATA[i] >> 10) & 0x1f)*b>>8; + } + png_set_PLTE(png_ptr, info_ptr, pngpal, 256); + } + png_set_IHDR(png_ptr, info_ptr, imgwidth, imgheight, 8, + (Settings.SixteenBit?PNG_COLOR_TYPE_RGB:PNG_COLOR_TYPE_PALETTE), + PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, + PNG_FILTER_TYPE_DEFAULT); + + if(Settings.SixteenBit){ + /* 5 bits per color */ + sig_bit.red=5; + sig_bit.green=5; + sig_bit.blue=5; + png_set_sBIT(png_ptr, info_ptr, &sig_bit); + png_set_shift(png_ptr, &sig_bit); + } + + png_write_info(png_ptr, info_ptr); + + png_set_packing(png_ptr); + + png_byte *row_pointer=new png_byte [png_get_rowbytes(png_ptr, info_ptr)]; + uint8 *screen=GFX.Screen; + for(int y=0; y +#endif + +void S9xSetSDD1MemoryMap (uint32 bank, uint32 value) +{ + bank = 0xc00 + bank * 0x100; + value = value * 1024 * 1024; + + int c; + + for (c = 0; c < 0x100; c += 16) + { + uint8 *block = &Memory.ROM [value + (c << 12)]; + int i; + + for (i = c; i < c + 16; i++) + Memory.Map [i + bank] = block; + } +} + +void S9xResetSDD1 () +{ + memset (&Memory.FillRAM [0x4800], 0, 4); + for (int i = 0; i < 4; i++) + { + Memory.FillRAM [0x4804 + i] = i; + S9xSetSDD1MemoryMap (i, i); + } +} + +void S9xSDD1PostLoadState () +{ + for (int i = 0; i < 4; i++) + S9xSetSDD1MemoryMap (i, Memory.FillRAM [0x4804 + i]); +} + +#if !defined(_SNESPPC) || defined(__IPHONE__) +static int S9xCompareSDD1LoggedDataEntries (const void *p1, const void *p2) +#else +static int _cdecl S9xCompareSDD1LoggedDataEntries (const void *p1, const void *p2) +#endif +{ + uint8 *b1 = (uint8 *) p1; + uint8 *b2 = (uint8 *) p2; + uint32 a1 = (*b1 << 16) + (*(b1 + 1) << 8) + *(b1 + 2); + uint32 a2 = (*b2 << 16) + (*(b2 + 1) << 8) + *(b2 + 2); + + return (a1 - a2); +} + +void S9xSDD1SaveLoggedData () +{ + if (Memory.SDD1LoggedDataCount != Memory.SDD1LoggedDataCountPrev) + { + qsort (Memory.SDD1LoggedData, Memory.SDD1LoggedDataCount, 8, + S9xCompareSDD1LoggedDataEntries); + + FILE *fs = fopen (S9xGetFilename (".dat"), "wb"); + + if (fs) + { + fwrite (Memory.SDD1LoggedData, 8, + Memory.SDD1LoggedDataCount, fs); + fclose (fs); +#if defined(__linux) + chown (S9xGetFilename (".dat"), getuid (), getgid ()); +#endif + } + Memory.SDD1LoggedDataCountPrev = Memory.SDD1LoggedDataCount; + } +} + +void S9xSDD1LoadLoggedData () +{ + FILE *fs = fopen (S9xGetFilename (".dat"), "rb"); + + Memory.SDD1LoggedDataCount = Memory.SDD1LoggedDataCountPrev = 0; + + if (fs) + { + int c = fread (Memory.SDD1LoggedData, 8, + MEMMAP_MAX_SDD1_LOGGED_ENTRIES, fs); + + if (c != EOF) + Memory.SDD1LoggedDataCount = Memory.SDD1LoggedDataCountPrev = c; + fclose (fs); + } +} diff --git a/src/snes4iphone_src/sdd1.h b/src/snes4iphone_src/sdd1.h new file mode 100755 index 0000000..1320889 --- /dev/null +++ b/src/snes4iphone_src/sdd1.h @@ -0,0 +1,48 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#ifndef _SDD1_H_ +#define _SDD1_H_ +void S9xSetSDD1MemoryMap (uint32 bank, uint32 value); +void S9xResetSDD1 (); +void S9xSDD1PostLoadState (); +void S9xSDD1SaveLoggedData (); +void S9xSDD1LoadLoggedData (); +#endif diff --git a/src/snes4iphone_src/sdd1emu.cpp b/src/snes4iphone_src/sdd1emu.cpp new file mode 100755 index 0000000..3f97ee2 --- /dev/null +++ b/src/snes4iphone_src/sdd1emu.cpp @@ -0,0 +1,414 @@ +/******************************************************************************* + Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and + Jerremy Koot (jkoot@snes9x.com) + + (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net) + + (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net), + funkyass (funkyass@spam.shaw.ca), + Joel Yliluoma (http://iki.fi/bisqwit/) + Kris Bleakley (codeviolation@hotmail.com), + Matthew Kendora, + Nach (n-a-c-h@users.sourceforge.net), + Peter Bortas (peter@bortas.org) and + zones (kasumitokoduck@yahoo.com) + + C4 x86 assembler and some C emulation code + (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com), + _Demo_ (_demo_@zsnes.com), and Nach + + C4 C++ code + (c) Copyright 2003 Brad Jorsch + + DSP-1 emulator code + (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson, + John Weidman, neviksti (neviksti@hotmail.com), + Kris Bleakley, Andreas Naive + + DSP-2 emulator code + (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and + Lord Nightmare (lord_nightmare@users.sourceforge.net + + OBC1 emulator code + (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and + Kris Bleakley + Ported from x86 assembler to C by sanmaiwashi + + SPC7110 and RTC C++ emulator code + (c) Copyright 2002 Matthew Kendora with research by + zsKnight, John Weidman, and Dark Force + + S-DD1 C emulator code + (c) Copyright 2003 Brad Jorsch with research by + Andreas Naive and John Weidman + + S-RTC C emulator code + (c) Copyright 2001 John Weidman + + ST010 C++ emulator code + (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora + + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + + Super FX C emulator code + (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman + + + SH assembler code partly based on x86 assembler code + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + + + Specific ports contains the works of other authors. See headers in + individual files. + + Snes9x homepage: http://www.snes9x.com + + Permission to use, copy, modify and distribute Snes9x in both binary and + source form, for non-commercial purposes, is hereby granted without fee, + providing that this license information and copyright notice appear with + all copies and any derived work. + + This software is provided 'as-is', without any express or implied + warranty. In no event shall the authors be held liable for any damages + arising from the use of this software. + + Snes9x is freeware for PERSONAL USE only. Commercial users should + seek permission of the copyright holders first. Commercial use includes + charging money for Snes9x or software derived from Snes9x. + + The copyright holders request that bug fixes and improvements to the code + should be forwarded to them so everyone can benefit from the modifications + in future versions. + + Super NES and Super Nintendo Entertainment System are trademarks of + Nintendo Co., Limited and its subsidiary companies. +*******************************************************************************/ +/* S-DD1 decompressor + * + * Based on code and documentation by Andreas Naive, who deserves a great deal + * of thanks and credit for figuring this out. + * + * Andreas says: + * The author is greatly indebted with The Dumper, without whose help and + * patience providing him with real S-DD1 data the research had never been + * possible. He also wish to note that in the very beggining of his research, + * Neviksti had done some steps in the right direction. By last, the author is + * indirectly indebted to all the people that worked and contributed in the + * S-DD1 issue in the past. + */ + +#include +#include "port.h" +#include "sdd1emu.h" + +static int valid_bits; +static uint16 in_stream; +static uint8 *in_buf; +static uint8 bit_ctr[8]; +static uint8 context_states[32]; +static int context_MPS[32]; +static int bitplane_type; +static int high_context_bits; +static int low_context_bits; +static int prev_bits[8]; + +static struct { + uint8 code_size; + uint8 MPS_next; + uint8 LPS_next; +} evolution_table[] = { + /* 0 */ { 0,25,25}, + /* 1 */ { 0, 2, 1}, + /* 2 */ { 0, 3, 1}, + /* 3 */ { 0, 4, 2}, + /* 4 */ { 0, 5, 3}, + /* 5 */ { 1, 6, 4}, + /* 6 */ { 1, 7, 5}, + /* 7 */ { 1, 8, 6}, + /* 8 */ { 1, 9, 7}, + /* 9 */ { 2,10, 8}, + /* 10 */ { 2,11, 9}, + /* 11 */ { 2,12,10}, + /* 12 */ { 2,13,11}, + /* 13 */ { 3,14,12}, + /* 14 */ { 3,15,13}, + /* 15 */ { 3,16,14}, + /* 16 */ { 3,17,15}, + /* 17 */ { 4,18,16}, + /* 18 */ { 4,19,17}, + /* 19 */ { 5,20,18}, + /* 20 */ { 5,21,19}, + /* 21 */ { 6,22,20}, + /* 22 */ { 6,23,21}, + /* 23 */ { 7,24,22}, + /* 24 */ { 7,24,23}, + /* 25 */ { 0,26, 1}, + /* 26 */ { 1,27, 2}, + /* 27 */ { 2,28, 4}, + /* 28 */ { 3,29, 8}, + /* 29 */ { 4,30,12}, + /* 30 */ { 5,31,16}, + /* 31 */ { 6,32,18}, + /* 32 */ { 7,24,22} +}; + +static uint8 run_table[128] = { + 128, 64, 96, 32, 112, 48, 80, 16, 120, 56, 88, 24, 104, 40, 72, + 8, 124, 60, 92, 28, 108, 44, 76, 12, 116, 52, 84, 20, 100, 36, + 68, 4, 126, 62, 94, 30, 110, 46, 78, 14, 118, 54, 86, 22, 102, + 38, 70, 6, 122, 58, 90, 26, 106, 42, 74, 10, 114, 50, 82, 18, + 98, 34, 66, 2, 127, 63, 95, 31, 111, 47, 79, 15, 119, 55, 87, + 23, 103, 39, 71, 7, 123, 59, 91, 27, 107, 43, 75, 11, 115, 51, + 83, 19, 99, 35, 67, 3, 125, 61, 93, 29, 109, 45, 77, 13, 117, + 53, 85, 21, 101, 37, 69, 5, 121, 57, 89, 25, 105, 41, 73, 9, + 113, 49, 81, 17, 97, 33, 65, 1 +}; + +static inline uint8 GetCodeword(int bits){ + uint8 tmp; + + if(!valid_bits){ + in_stream|=*(in_buf++); + valid_bits=8; + } + in_stream<<=1; + valid_bits--; + in_stream^=0x8000; + if(in_stream&0x8000) return 0x80+(1<>8) | (0x7f>>bits); + in_stream<<=bits; + valid_bits-=bits; + if(valid_bits<0){ + in_stream |= (*(in_buf++))<<(-valid_bits); + valid_bits+=8; + } + return run_table[tmp]; +} + +static inline uint8 GolombGetBit(int code_size){ + if(!bit_ctr[code_size]) bit_ctr[code_size]=GetCodeword(code_size); + bit_ctr[code_size]--; + if(bit_ctr[code_size]==0x80){ + bit_ctr[code_size]=0; + return 2; /* secret code for 'last zero'. ones are always last. */ + } + return (bit_ctr[code_size]==0)?1:0; +} + +static inline uint8 ProbGetBit(uint8 context){ + uint8 state=context_states[context]; + uint8 bit=GolombGetBit(evolution_table[state].code_size); + + if(bit&1){ + context_states[context]=evolution_table[state].LPS_next; + if(state<2){ + context_MPS[context]^=1; + return context_MPS[context]; /* just inverted, so just return it */ + } else{ + return context_MPS[context]^1; /* we know bit is 1, so use a constant */ + } + } else if(bit){ + context_states[context]=evolution_table[state].MPS_next; + /* zero here, zero there, no difference so drop through. */ + } + return context_MPS[context]; /* we know bit is 0, so don't bother xoring */ +} + +static inline uint8 GetBit(uint8 cur_bitplane){ + uint8 bit; + + bit=ProbGetBit(((cur_bitplane&1)<<4) + | ((prev_bits[cur_bitplane]&high_context_bits)>>5) + | (prev_bits[cur_bitplane]&low_context_bits)); + + prev_bits[cur_bitplane] <<= 1; + prev_bits[cur_bitplane] |= bit; + return bit; +} + +void SDD1_decompress(uint8 *out, uint8 *in, int len){ + uint8 bit, i, plane; + uint8 byte1, byte2; + + if(len==0) len=0x10000; + + bitplane_type=in[0]>>6; + + switch(in[0]&0x30){ + case 0x00: + high_context_bits=0x01c0; + low_context_bits =0x0001; + break; + case 0x10: + high_context_bits=0x0180; + low_context_bits =0x0001; + break; + case 0x20: + high_context_bits=0x00c0; + low_context_bits =0x0001; + break; + case 0x30: + high_context_bits=0x0180; + low_context_bits =0x0003; + break; + } + + in_stream=(in[0]<<11) | (in[1]<<3); + valid_bits=5; + in_buf=in+2; + memset(bit_ctr, 0, sizeof(bit_ctr)); + memset(context_states, 0, sizeof(context_states)); + memset(context_MPS, 0, sizeof(context_MPS)); + memset(prev_bits, 0, sizeof(prev_bits)); + + switch(bitplane_type){ + case 0: + while(1) { + for(byte1=byte2=0, bit=0x80; bit; bit>>=1){ + if(GetBit(0)) byte1 |= bit; + if(GetBit(1)) byte2 |= bit; + } + *(out++)=byte1; + if(!--len) return; + *(out++)=byte2; + if(!--len) return; + } + break; + case 1: + i=plane=0; + while(1) { + for(byte1=byte2=0, bit=0x80; bit; bit>>=1){ + if(GetBit(plane)) byte1 |= bit; + if(GetBit(plane+1)) byte2 |= bit; + } + *(out++)=byte1; + if(!--len) return; + *(out++)=byte2; + if(!--len) return; + if(!(i+=32)) plane = (plane+2)&7; + } + break; + case 2: + i=plane=0; + while(1) { + for(byte1=byte2=0, bit=0x80; bit; bit>>=1){ + if(GetBit(plane)) byte1 |= bit; + if(GetBit(plane+1)) byte2 |= bit; + } + *(out++)=byte1; + if(!--len) return; + *(out++)=byte2; + if(!--len) return; + if(!(i+=32)) plane ^= 2; + } + break; + case 3: + do { + for(byte1=plane=0, bit=1; bit; bit<<=1, plane++){ + if(GetBit(plane)) byte1 |= bit; + } + *(out++)=byte1; + } while(--len); + break; + } +} + +static uint8 cur_plane; +static uint8 num_bits; +static uint8 next_byte; + +void SDD1_init(uint8 *in){ + bitplane_type=in[0]>>6; + + switch(in[0]&0x30){ + case 0x00: + high_context_bits=0x01c0; + low_context_bits =0x0001; + break; + case 0x10: + high_context_bits=0x0180; + low_context_bits =0x0001; + break; + case 0x20: + high_context_bits=0x00c0; + low_context_bits =0x0001; + break; + case 0x30: + high_context_bits=0x0180; + low_context_bits =0x0003; + break; + } + + in_stream=(in[0]<<11) | (in[1]<<3); + valid_bits=5; + in_buf=in+2; + memset(bit_ctr, 0, sizeof(bit_ctr)); + memset(context_states, 0, sizeof(context_states)); + memset(context_MPS, 0, sizeof(context_MPS)); + memset(prev_bits, 0, sizeof(prev_bits)); + + cur_plane=0; + num_bits=0; +} + +uint8 SDD1_get_byte(void){ + uint8 bit; + uint8 byte=0; + + switch(bitplane_type){ + case 0: + num_bits+=16; + if(num_bits&16){ + next_byte=0; + for(bit=0x80; bit; bit>>=1){ + if(GetBit(0)) byte |= bit; + if(GetBit(1)) next_byte |= bit; + } + return byte; + } else { + return next_byte; + } + + case 1: + num_bits+=16; + if(num_bits&16){ + next_byte=0; + for(bit=0x80; bit; bit>>=1){ + if(GetBit(cur_plane)) byte |= bit; + if(GetBit(cur_plane+1)) next_byte |= bit; + } + return byte; + } else { + if(!num_bits) cur_plane = (cur_plane+2)&7; + return next_byte; + } + + case 2: + num_bits+=16; + if(num_bits&16){ + next_byte=0; + for(bit=0x80; bit; bit>>=1){ + if(GetBit(cur_plane)) byte |= bit; + if(GetBit(cur_plane+1)) next_byte |= bit; + } + return byte; + } else { + if(!num_bits) cur_plane ^= 2; + return next_byte; + } + + case 3: + for(cur_plane=0, bit=1; bit; bit<<=1, cur_plane++){ + if(GetBit(cur_plane)) byte |= bit; + } + return byte; + + default: + /* should never happen */ + return 0; + } +} + diff --git a/src/snes4iphone_src/sdd1emu.h b/src/snes4iphone_src/sdd1emu.h new file mode 100755 index 0000000..e9d4785 --- /dev/null +++ b/src/snes4iphone_src/sdd1emu.h @@ -0,0 +1,104 @@ +/******************************************************************************* + Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and + Jerremy Koot (jkoot@snes9x.com) + + (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net) + + (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net), + funkyass (funkyass@spam.shaw.ca), + Joel Yliluoma (http://iki.fi/bisqwit/) + Kris Bleakley (codeviolation@hotmail.com), + Matthew Kendora, + Nach (n-a-c-h@users.sourceforge.net), + Peter Bortas (peter@bortas.org) and + zones (kasumitokoduck@yahoo.com) + + C4 x86 assembler and some C emulation code + (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com), + _Demo_ (_demo_@zsnes.com), and Nach + + C4 C++ code + (c) Copyright 2003 Brad Jorsch + + DSP-1 emulator code + (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson, + John Weidman, neviksti (neviksti@hotmail.com), + Kris Bleakley, Andreas Naive + + DSP-2 emulator code + (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and + Lord Nightmare (lord_nightmare@users.sourceforge.net + + OBC1 emulator code + (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and + Kris Bleakley + Ported from x86 assembler to C by sanmaiwashi + + SPC7110 and RTC C++ emulator code + (c) Copyright 2002 Matthew Kendora with research by + zsKnight, John Weidman, and Dark Force + + S-DD1 C emulator code + (c) Copyright 2003 Brad Jorsch with research by + Andreas Naive and John Weidman + + S-RTC C emulator code + (c) Copyright 2001 John Weidman + + ST010 C++ emulator code + (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora + + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + + Super FX C emulator code + (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman + + + SH assembler code partly based on x86 assembler code + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + + + Specific ports contains the works of other authors. See headers in + individual files. + + Snes9x homepage: http://www.snes9x.com + + Permission to use, copy, modify and distribute Snes9x in both binary and + source form, for non-commercial purposes, is hereby granted without fee, + providing that this license information and copyright notice appear with + all copies and any derived work. + + This software is provided 'as-is', without any express or implied + warranty. In no event shall the authors be held liable for any damages + arising from the use of this software. + + Snes9x is freeware for PERSONAL USE only. Commercial users should + seek permission of the copyright holders first. Commercial use includes + charging money for Snes9x or software derived from Snes9x. + + The copyright holders request that bug fixes and improvements to the code + should be forwarded to them so everyone can benefit from the modifications + in future versions. + + Super NES and Super Nintendo Entertainment System are trademarks of + Nintendo Co., Limited and its subsidiary companies. +*******************************************************************************/ +#ifndef SDD1EMU_H +#define SDD1EMU_H + +/* for START_EXTERN_C/END_EXTERN_C */ +#include "port.h" + +extern "C" { + +void SDD1_decompress(uint8 *out, uint8 *in, int output_length); + +void SDD1_init(uint8 *in); +uint8 SDD1_get_byte(void); + +} + +#endif diff --git a/src/snes4iphone_src/seta.cpp b/src/snes4iphone_src/seta.cpp new file mode 100755 index 0000000..0600a07 --- /dev/null +++ b/src/snes4iphone_src/seta.cpp @@ -0,0 +1,107 @@ +/******************************************************************************* + Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and + Jerremy Koot (jkoot@snes9x.com) + + (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net) + + (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net), + funkyass (funkyass@spam.shaw.ca), + Joel Yliluoma (http://iki.fi/bisqwit/) + Kris Bleakley (codeviolation@hotmail.com), + Matthew Kendora, + Nach (n-a-c-h@users.sourceforge.net), + Peter Bortas (peter@bortas.org) and + zones (kasumitokoduck@yahoo.com) + + C4 x86 assembler and some C emulation code + (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com), + _Demo_ (_demo_@zsnes.com), and Nach + + C4 C++ code + (c) Copyright 2003 Brad Jorsch + + DSP-1 emulator code + (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson, + John Weidman, neviksti (neviksti@hotmail.com), + Kris Bleakley, Andreas Naive + + DSP-2 emulator code + (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and + Lord Nightmare (lord_nightmare@users.sourceforge.net + + OBC1 emulator code + (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and + Kris Bleakley + Ported from x86 assembler to C by sanmaiwashi + + SPC7110 and RTC C++ emulator code + (c) Copyright 2002 Matthew Kendora with research by + zsKnight, John Weidman, and Dark Force + + S-DD1 C emulator code + (c) Copyright 2003 Brad Jorsch with research by + Andreas Naive and John Weidman + + S-RTC C emulator code + (c) Copyright 2001 John Weidman + + ST010 C++ emulator code + (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora + + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + + Super FX C emulator code + (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman + + + SH assembler code partly based on x86 assembler code + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + + + Specific ports contains the works of other authors. See headers in + individual files. + + Snes9x homepage: http://www.snes9x.com + + Permission to use, copy, modify and distribute Snes9x in both binary and + source form, for non-commercial purposes, is hereby granted without fee, + providing that this license information and copyright notice appear with + all copies and any derived work. + + This software is provided 'as-is', without any express or implied + warranty. In no event shall the authors be held liable for any damages + arising from the use of this software. + + Snes9x is freeware for PERSONAL USE only. Commercial users should + seek permission of the copyright holders first. Commercial use includes + charging money for Snes9x or software derived from Snes9x. + + The copyright holders request that bug fixes and improvements to the code + should be forwarded to them so everyone can benefit from the modifications + in future versions. + + Super NES and Super Nintendo Entertainment System are trademarks of + Nintendo Co., Limited and its subsidiary companies. +*******************************************************************************/ +#include "port.h" +#include "seta.h" + + +void (*SetSETA)(uint32, uint8)=&S9xSetST010; +uint8 (*GetSETA)(uint32)=&S9xGetST010; + +extern "C"{ +uint8 S9xGetSetaDSP(uint32 Address) +{ + return GetSETA(Address); +} + +void S9xSetSetaDSP(uint8 Byte, uint32 Address) +{ + SetSETA(Address, Byte); +} +} + diff --git a/src/snes4iphone_src/seta.h b/src/snes4iphone_src/seta.h new file mode 100755 index 0000000..f857636 --- /dev/null +++ b/src/snes4iphone_src/seta.h @@ -0,0 +1,156 @@ +/******************************************************************************* + Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and + Jerremy Koot (jkoot@snes9x.com) + + (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net) + + (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net), + funkyass (funkyass@spam.shaw.ca), + Joel Yliluoma (http://iki.fi/bisqwit/) + Kris Bleakley (codeviolation@hotmail.com), + Matthew Kendora, + Nach (n-a-c-h@users.sourceforge.net), + Peter Bortas (peter@bortas.org) and + zones (kasumitokoduck@yahoo.com) + + C4 x86 assembler and some C emulation code + (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com), + _Demo_ (_demo_@zsnes.com), and Nach + + C4 C++ code + (c) Copyright 2003 Brad Jorsch + + DSP-1 emulator code + (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson, + John Weidman, neviksti (neviksti@hotmail.com), + Kris Bleakley, Andreas Naive + + DSP-2 emulator code + (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and + Lord Nightmare (lord_nightmare@users.sourceforge.net + + OBC1 emulator code + (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and + Kris Bleakley + Ported from x86 assembler to C by sanmaiwashi + + SPC7110 and RTC C++ emulator code + (c) Copyright 2002 Matthew Kendora with research by + zsKnight, John Weidman, and Dark Force + + S-DD1 C emulator code + (c) Copyright 2003 Brad Jorsch with research by + Andreas Naive and John Weidman + + S-RTC C emulator code + (c) Copyright 2001 John Weidman + + ST010 C++ emulator code + (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora + + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + + Super FX C emulator code + (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman + + + SH assembler code partly based on x86 assembler code + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + + + Specific ports contains the works of other authors. See headers in + individual files. + + Snes9x homepage: http://www.snes9x.com + + Permission to use, copy, modify and distribute Snes9x in both binary and + source form, for non-commercial purposes, is hereby granted without fee, + providing that this license information and copyright notice appear with + all copies and any derived work. + + This software is provided 'as-is', without any express or implied + warranty. In no event shall the authors be held liable for any damages + arising from the use of this software. + + Snes9x is freeware for PERSONAL USE only. Commercial users should + seek permission of the copyright holders first. Commercial use includes + charging money for Snes9x or software derived from Snes9x. + + The copyright holders request that bug fixes and improvements to the code + should be forwarded to them so everyone can benefit from the modifications + in future versions. + + Super NES and Super Nintendo Entertainment System are trademarks of + Nintendo Co., Limited and its subsidiary companies. +*******************************************************************************/ + +#ifndef NO_SETA +#ifndef _seta_h +#define _seta_h + +#include "port.h" + +#define ST_010 0x01 +#define ST_011 0x02 +#define ST_018 0x03 + + +extern "C" +{ +uint8 S9xGetSetaDSP(uint32 Address); +void S9xSetSetaDSP(uint8 byte,uint32 Address); +uint8 S9xGetST018(uint32 Address); +void S9xSetST018(uint8 Byte, uint32 Address); + +uint8 S9xGetST010(uint32 Address); +void S9xSetST010(uint32 Address, uint8 Byte); +uint8 S9xGetST011(uint32 Address); +void S9xSetST011(uint32 Address, uint8 Byte); +} + +extern void (*SetSETA)(uint32, uint8); +extern uint8 (*GetSETA)(uint32); + +typedef struct SETA_ST010_STRUCT +{ + uint8 input_params[16]; + uint8 output_params[16]; + uint8 op_reg; + uint8 execute; + bool8 control_enable; +} ST010_Regs; + +typedef struct SETA_ST011_STRUCT +{ + bool8 waiting4command; + uint8 status; + uint8 command; + uint32 in_count; + uint32 in_index; + uint32 out_count; + uint32 out_index; + uint8 parameters [512]; + uint8 output [512]; +} ST011_Regs; + +typedef struct SETA_ST018_STRUCT +{ + bool8 waiting4command; + uint8 status; + uint8 part_command; + uint8 pass; + uint32 command; + uint32 in_count; + uint32 in_index; + uint32 out_count; + uint32 out_index; + uint8 parameters [512]; + uint8 output [512]; +} ST018_Regs; + +#endif +#endif + diff --git a/src/snes4iphone_src/seta010.cpp b/src/snes4iphone_src/seta010.cpp new file mode 100755 index 0000000..c6dc266 --- /dev/null +++ b/src/snes4iphone_src/seta010.cpp @@ -0,0 +1,751 @@ +/******************************************************************************* + Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and + Jerremy Koot (jkoot@snes9x.com) + + (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net) + + (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net), + funkyass (funkyass@spam.shaw.ca), + Joel Yliluoma (http://iki.fi/bisqwit/) + Kris Bleakley (codeviolation@hotmail.com), + Matthew Kendora, + Nach (n-a-c-h@users.sourceforge.net), + Peter Bortas (peter@bortas.org) and + zones (kasumitokoduck@yahoo.com) + + C4 x86 assembler and some C emulation code + (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com), + _Demo_ (_demo_@zsnes.com), and Nach + + C4 C++ code + (c) Copyright 2003 Brad Jorsch + + DSP-1 emulator code + (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson, + John Weidman, neviksti (neviksti@hotmail.com), + Kris Bleakley, Andreas Naive + + DSP-2 emulator code + (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and + Lord Nightmare (lord_nightmare@users.sourceforge.net + + OBC1 emulator code + (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and + Kris Bleakley + Ported from x86 assembler to C by sanmaiwashi + + SPC7110 and RTC C++ emulator code + (c) Copyright 2002 Matthew Kendora with research by + zsKnight, John Weidman, and Dark Force + + S-DD1 C emulator code + (c) Copyright 2003 Brad Jorsch with research by + Andreas Naive and John Weidman + + S-RTC C emulator code + (c) Copyright 2001 John Weidman + + ST010 C++ emulator code + (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora + + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + + Super FX C emulator code + (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman + + + SH assembler code partly based on x86 assembler code + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + + + Specific ports contains the works of other authors. See headers in + individual files. + + Snes9x homepage: http://www.snes9x.com + + Permission to use, copy, modify and distribute Snes9x in both binary and + source form, for non-commercial purposes, is hereby granted without fee, + providing that this license information and copyright notice appear with + all copies and any derived work. + + This software is provided 'as-is', without any express or implied + warranty. In no event shall the authors be held liable for any damages + arising from the use of this software. + + Snes9x is freeware for PERSONAL USE only. Commercial users should + seek permission of the copyright holders first. Commercial use includes + charging money for Snes9x or software derived from Snes9x. + + The copyright holders request that bug fixes and improvements to the code + should be forwarded to them so everyone can benefit from the modifications + in future versions. + + Super NES and Super Nintendo Entertainment System are trademarks of + Nintendo Co., Limited and its subsidiary companies. +*******************************************************************************/ +//#include "port.h" +#include "memmap.h" +#include "seta.h" + +// Mode 7 scaling constants for all raster lines +const int16 ST010_M7Scale[176] = { + 0x0380, 0x0325, 0x02da, 0x029c, 0x0268, 0x023b, 0x0215, 0x01f3, + 0x01d5, 0x01bb, 0x01a3, 0x018e, 0x017b, 0x016a, 0x015a, 0x014b, + 0x013e, 0x0132, 0x0126, 0x011c, 0x0112, 0x0109, 0x0100, 0x00f8, + 0x00f0, 0x00e9, 0x00e3, 0x00dc, 0x00d6, 0x00d1, 0x00cb, 0x00c6, + 0x00c1, 0x00bd, 0x00b8, 0x00b4, 0x00b0, 0x00ac, 0x00a8, 0x00a5, + 0x00a2, 0x009e, 0x009b, 0x0098, 0x0095, 0x0093, 0x0090, 0x008d, + 0x008b, 0x0088, 0x0086, 0x0084, 0x0082, 0x0080, 0x007e, 0x007c, + 0x007a, 0x0078, 0x0076, 0x0074, 0x0073, 0x0071, 0x006f, 0x006e, + 0x006c, 0x006b, 0x0069, 0x0068, 0x0067, 0x0065, 0x0064, 0x0063, + 0x0062, 0x0060, 0x005f, 0x005e, 0x005d, 0x005c, 0x005b, 0x005a, + 0x0059, 0x0058, 0x0057, 0x0056, 0x0055, 0x0054, 0x0053, 0x0052, + 0x0051, 0x0051, 0x0050, 0x004f, 0x004e, 0x004d, 0x004d, 0x004c, + 0x004b, 0x004b, 0x004a, 0x0049, 0x0048, 0x0048, 0x0047, 0x0047, + 0x0046, 0x0045, 0x0045, 0x0044, 0x0044, 0x0043, 0x0042, 0x0042, + 0x0041, 0x0041, 0x0040, 0x0040, 0x003f, 0x003f, 0x003e, 0x003e, + 0x003d, 0x003d, 0x003c, 0x003c, 0x003b, 0x003b, 0x003a, 0x003a, + 0x003a, 0x0039, 0x0039, 0x0038, 0x0038, 0x0038, 0x0037, 0x0037, + 0x0036, 0x0036, 0x0036, 0x0035, 0x0035, 0x0035, 0x0034, 0x0034, + 0x0034, 0x0033, 0x0033, 0x0033, 0x0032, 0x0032, 0x0032, 0x0031, + 0x0031, 0x0031, 0x0030, 0x0030, 0x0030, 0x0030, 0x002f, 0x002f, + 0x002f, 0x002e, 0x002e, 0x002e, 0x002e, 0x002d, 0x002d, 0x002d, + 0x002d, 0x002c, 0x002c, 0x002c, 0x002c, 0x002b, 0x002b, 0x002b +}; + +// H-DMA hack +bool seta_hack; + +//temporary Op04 requirement +#include + +#ifndef PI +#define PI 3.1415926535897932384626433832795 +#endif + +ST010_Regs ST010; + +uint8 S9xGetST010(uint32 Address) +{ + if(!(Address&0x80000)) + return 0x80; + + if((Address&0xFFF)==0x20) + return ST010.op_reg; + if ((Address&0xFFF)==0x21) + return ST010.execute; + return Memory.SRAM[Address&CPU.Memory_SRAMMask]; +} + +const int16 ST010_SinTable[256] = { + 0x0000, 0x0324, 0x0648, 0x096a, 0x0c8c, 0x0fab, 0x12c8, 0x15e2, + 0x18f9, 0x1c0b, 0x1f1a, 0x2223, 0x2528, 0x2826, 0x2b1f, 0x2e11, + 0x30fb, 0x33df, 0x36ba, 0x398c, 0x3c56, 0x3f17, 0x41ce, 0x447a, + 0x471c, 0x49b4, 0x4c3f, 0x4ebf, 0x5133, 0x539b, 0x55f5, 0x5842, + 0x5a82, 0x5cb3, 0x5ed7, 0x60eb, 0x62f1, 0x64e8, 0x66cf, 0x68a6, + 0x6a6d, 0x6c23, 0x6dc9, 0x6f5e, 0x70e2, 0x7254, 0x73b5, 0x7504, + 0x7641, 0x776b, 0x7884, 0x7989, 0x7a7c, 0x7b5c, 0x7c29, 0x7ce3, + 0x7d89, 0x7e1d, 0x7e9c, 0x7f09, 0x7f61, 0x7fa6, 0x7fd8, 0x7ff5, + 0x7fff, 0x7ff5, 0x7fd8, 0x7fa6, 0x7f61, 0x7f09, 0x7e9c, 0x7e1d, + 0x7d89, 0x7ce3, 0x7c29, 0x7b5c, 0x7a7c, 0x7989, 0x7884, 0x776b, + 0x7641, 0x7504, 0x73b5, 0x7254, 0x70e2, 0x6f5e, 0x6dc9, 0x6c23, + 0x6a6d, 0x68a6, 0x66cf, 0x64e8, 0x62f1, 0x60eb, 0x5ed7, 0x5cb3, + 0x5a82, 0x5842, 0x55f5, 0x539b, 0x5133, 0x4ebf, 0x4c3f, 0x49b4, + 0x471c, 0x447a, 0x41ce, 0x3f17, 0x3c56, 0x398c, 0x36ba, 0x33df, + 0x30fb, 0x2e11, 0x2b1f, 0x2826, 0x2528, 0x2223, 0x1f1a, 0x1c0b, + 0x18f8, 0x15e2, 0x12c8, 0x0fab, 0x0c8c, 0x096a, 0x0648, 0x0324, + 0x0000, -0x0324, -0x0648, -0x096b, -0x0c8c, -0x0fab, -0x12c8, -0x15e2, + -0x18f9, -0x1c0b, -0x1f1a, -0x2223, -0x2528, -0x2826, -0x2b1f, -0x2e11, + -0x30fb, -0x33df, -0x36ba, -0x398d, -0x3c56, -0x3f17, -0x41ce, -0x447a, + -0x471c, -0x49b4, -0x4c3f, -0x4ebf, -0x5133, -0x539b, -0x55f5, -0x5842, + -0x5a82, -0x5cb3, -0x5ed7, -0x60ec, -0x62f1, -0x64e8, -0x66cf, -0x68a6, + -0x6a6d, -0x6c23, -0x6dc9, -0x6f5e, -0x70e2, -0x7254, -0x73b5, -0x7504, + -0x7641, -0x776b, -0x7884, -0x7989, -0x7a7c, -0x7b5c, -0x7c29, -0x7ce3, + -0x7d89, -0x7e1d, -0x7e9c, -0x7f09, -0x7f61, -0x7fa6, -0x7fd8, -0x7ff5, + -0x7fff, -0x7ff5, -0x7fd8, -0x7fa6, -0x7f61, -0x7f09, -0x7e9c, -0x7e1d, + -0x7d89, -0x7ce3, -0x7c29, -0x7b5c, -0x7a7c, -0x7989, -0x7883, -0x776b, + -0x7641, -0x7504, -0x73b5, -0x7254, -0x70e2, -0x6f5e, -0x6dc9, -0x6c23, + -0x6a6d, -0x68a6, -0x66cf, -0x64e8, -0x62f1, -0x60eb, -0x5ed7, -0x5cb3, + -0x5a82, -0x5842, -0x55f5, -0x539a, -0x5133, -0x4ebf, -0x4c3f, -0x49b3, + -0x471c, -0x447a, -0x41cd, -0x3f17, -0x3c56, -0x398c, -0x36b9, -0x33de, + -0x30fb, -0x2e10, -0x2b1f, -0x2826, -0x2527, -0x2223, -0x1f19, -0x1c0b, + -0x18f8, -0x15e2, -0x12c8, -0x0fab, -0x0c8b, -0x096a, -0x0647, -0x0324}; + +const unsigned char ST010_ArcTan[32][32] = { + { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}, + { 0x80, 0xa0, 0xad, 0xb3, 0xb6, 0xb8, 0xb9, 0xba, 0xbb, 0xbb, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, + 0xbd, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbf, 0xbf, 0xbf, 0xbf}, + { 0x80, 0x93, 0xa0, 0xa8, 0xad, 0xb0, 0xb3, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xbb, + 0xbb, 0xbb, 0xbb, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd}, + { 0x80, 0x8d, 0x98, 0xa0, 0xa6, 0xaa, 0xad, 0xb0, 0xb1, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb7, 0xb8, + 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xba, 0xba, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbc, 0xbc, 0xbc, 0xbc}, + { 0x80, 0x8a, 0x93, 0x9a, 0xa0, 0xa5, 0xa8, 0xab, 0xad, 0xaf, 0xb0, 0xb2, 0xb3, 0xb4, 0xb5, 0xb5, + 0xb6, 0xb7, 0xb7, 0xb8, 0xb8, 0xb8, 0xb9, 0xb9, 0xb9, 0xba, 0xba, 0xba, 0xba, 0xba, 0xbb, 0xbb}, + { 0x80, 0x88, 0x90, 0x96, 0x9b, 0xa0, 0xa4, 0xa7, 0xa9, 0xab, 0xad, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, + 0xb4, 0xb4, 0xb5, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7, 0xb8, 0xb8, 0xb8, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9}, + { 0x80, 0x87, 0x8d, 0x93, 0x98, 0x9c, 0xa0, 0xa3, 0xa6, 0xa8, 0xaa, 0xac, 0xad, 0xae, 0xb0, 0xb0, + 0xb1, 0xb2, 0xb3, 0xb4, 0xb4, 0xb5, 0xb5, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb8, 0xb8, 0xb8}, + { 0x80, 0x86, 0x8b, 0x90, 0x95, 0x99, 0x9d, 0xa0, 0xa3, 0xa5, 0xa7, 0xa9, 0xaa, 0xac, 0xad, 0xae, + 0xaf, 0xb0, 0xb1, 0xb2, 0xb2, 0xb3, 0xb3, 0xb4, 0xb4, 0xb5, 0xb5, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7}, + { 0x80, 0x85, 0x8a, 0x8f, 0x93, 0x97, 0x9a, 0x9d, 0xa0, 0xa2, 0xa5, 0xa6, 0xa8, 0xaa, 0xab, 0xac, + 0xad, 0xae, 0xaf, 0xb0, 0xb0, 0xb1, 0xb2, 0xb2, 0xb3, 0xb3, 0xb4, 0xb4, 0xb5, 0xb5, 0xb5, 0xb5}, + { 0x80, 0x85, 0x89, 0x8d, 0x91, 0x95, 0x98, 0x9b, 0x9e, 0xa0, 0xa0, 0xa4, 0xa6, 0xa7, 0xa9, 0xaa, + 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb0, 0xb1, 0xb1, 0xb2, 0xb2, 0xb3, 0xb3, 0xb4, 0xb4, 0xb4}, + { 0x80, 0x84, 0x88, 0x8c, 0x90, 0x93, 0x96, 0x99, 0x9b, 0x9e, 0xa0, 0xa2, 0xa4, 0xa5, 0xa7, 0xa8, + 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xaf, 0xb0, 0xb0, 0xb1, 0xb2, 0xb2, 0xb2, 0xb3, 0xb3}, + { 0x80, 0x84, 0x87, 0x8b, 0x8e, 0x91, 0x94, 0x97, 0x9a, 0x9c, 0x9e, 0xa0, 0xa2, 0xa3, 0xa5, 0xa6, + 0xa7, 0xa9, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xae, 0xae, 0xaf, 0xb0, 0xb0, 0xb1, 0xb1, 0xb2, 0xb2}, + { 0x80, 0x83, 0x87, 0x8a, 0x8d, 0x90, 0x93, 0x96, 0x98, 0x9a, 0x9c, 0x9e, 0xa0, 0xa2, 0xa3, 0xa5, + 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xae, 0xae, 0xaf, 0xb0, 0xb0, 0xb0, 0xb1}, + { 0x80, 0x83, 0x86, 0x89, 0x8c, 0x8f, 0x92, 0x94, 0x96, 0x99, 0x9b, 0x9d, 0x9e, 0xa0, 0xa2, 0xa3, + 0xa4, 0xa5, 0xa7, 0xa8, 0xa9, 0xa9, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xae, 0xae, 0xaf, 0xaf, 0xb0}, + { 0x80, 0x83, 0x86, 0x89, 0x8b, 0x8e, 0x90, 0x93, 0x95, 0x97, 0x99, 0x9b, 0x9d, 0x9e, 0xa0, 0xa1, + 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xaa, 0xab, 0xac, 0xad, 0xad, 0xae, 0xae, 0xaf}, + { 0x80, 0x83, 0x85, 0x88, 0x8b, 0x8d, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9b, 0x9d, 0x9f, 0xa0, + 0xa1, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa8, 0xa9, 0xaa, 0xab, 0xab, 0xac, 0xad, 0xad, 0xae}, + { 0x80, 0x83, 0x85, 0x88, 0x8a, 0x8c, 0x8f, 0x91, 0x93, 0x95, 0x97, 0x99, 0x9a, 0x9c, 0x9d, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa5, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xaa, 0xab, 0xab, 0xac, 0xad}, + { 0x80, 0x82, 0x85, 0x87, 0x89, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x97, 0x99, 0x9b, 0x9c, 0x9d, + 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa8, 0xa9, 0xaa, 0xaa, 0xab, 0xac}, + { 0x80, 0x82, 0x85, 0x87, 0x89, 0x8b, 0x8d, 0x8f, 0x91, 0x93, 0x95, 0x96, 0x98, 0x99, 0x9b, 0x9c, + 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa7, 0xa8, 0xa9, 0xa9, 0xaa, 0xab}, + { 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x95, 0x97, 0x98, 0x9a, 0x9b, + 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa6, 0xa7, 0xa8, 0xa8, 0xa9, 0xaa}, + { 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x91, 0x93, 0x94, 0x96, 0x97, 0x99, 0x9a, + 0x9b, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa5, 0xa6, 0xa7, 0xa7, 0xa8, 0xa9}, + { 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8b, 0x8d, 0x8f, 0x90, 0x92, 0x94, 0x95, 0x97, 0x98, 0x99, + 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa4, 0xa5, 0xa6, 0xa6, 0xa7, 0xa8}, + { 0x80, 0x82, 0x84, 0x86, 0x87, 0x89, 0x8b, 0x8d, 0x8e, 0x90, 0x91, 0x93, 0x94, 0x96, 0x97, 0x98, + 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa3, 0xa4, 0xa5, 0xa6, 0xa6, 0xa7}, + { 0x80, 0x82, 0x84, 0x85, 0x87, 0x89, 0x8a, 0x8c, 0x8e, 0x8f, 0x91, 0x92, 0x94, 0x95, 0x96, 0x98, + 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa2, 0xa3, 0xa4, 0xa5, 0xa5, 0xa6}, + { 0x80, 0x82, 0x83, 0x85, 0x87, 0x88, 0x8a, 0x8c, 0x8d, 0x8f, 0x90, 0x92, 0x93, 0x94, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa2, 0xa3, 0xa4, 0xa5, 0xa5}, + { 0x80, 0x82, 0x83, 0x85, 0x86, 0x88, 0x8a, 0x8b, 0x8d, 0x8e, 0x90, 0x91, 0x92, 0x94, 0x95, 0x96, + 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa2, 0xa3, 0xa4, 0xa4}, + { 0x80, 0x82, 0x83, 0x85, 0x86, 0x88, 0x89, 0x8b, 0x8c, 0x8e, 0x8f, 0x90, 0x92, 0x93, 0x94, 0x95, + 0x96, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa2, 0xa3, 0xa4}, + { 0x80, 0x82, 0x83, 0x85, 0x86, 0x87, 0x89, 0x8a, 0x8c, 0x8d, 0x8e, 0x90, 0x91, 0x92, 0x93, 0x95, + 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9e, 0x9f, 0xa0, 0xa1, 0xa1, 0xa2, 0xa3}, + { 0x80, 0x81, 0x83, 0x84, 0x86, 0x87, 0x89, 0x8a, 0x8b, 0x8d, 0x8e, 0x8f, 0x90, 0x92, 0x93, 0x94, + 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9e, 0x9f, 0xa0, 0xa1, 0xa1, 0xa2}, + { 0x80, 0x81, 0x83, 0x84, 0x86, 0x87, 0x88, 0x8a, 0x8b, 0x8c, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, + 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0x9f, 0xa0, 0xa1, 0xa1}, + { 0x80, 0x81, 0x83, 0x84, 0x85, 0x87, 0x88, 0x89, 0x8b, 0x8c, 0x8d, 0x8e, 0x90, 0x91, 0x92, 0x93, + 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0x9f, 0xa0, 0xa1}, + { 0x80, 0x81, 0x83, 0x84, 0x85, 0x87, 0x88, 0x89, 0x8a, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, + 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9c, 0x9d, 0x9e, 0x9f, 0x9f, 0xa0}}; + +short ST010_Sin(short Theta) +{ + return ST010_SinTable[(Theta >> 8) & 0xff]; +} + +short ST010_Cos(short Theta) +{ + return ST010_SinTable[((Theta + 0x4000) >> 8) & 0xff]; +} + +void ST010_OP01(short x0, short y0, short &x1, short &y1, short &Quadrant, short &Theta) +{ + if ((x0 < 0) && (y0 < 0)) + { + x1 = -x0; + y1 = -y0; + Quadrant = -0x8000; + } + else if (x0 < 0) + { + x1 = y0; + y1 = -x0; + Quadrant = -0x4000; + } + else if (y0 < 0) + { + x1 = -y0; + y1 = x0; + Quadrant = 0x4000; + } + else + { + x1 = x0; + y1 = y0; + Quadrant = 0x0000; + } + + while ((x1 > 0x1f) || (y1 > 0x1f)) + { + if (x1 > 1) x1 >>= 1; + if (y1 > 1) y1 >>= 1; + } + + if (y1 == 0) Quadrant += 0x4000; + + Theta = (ST010_ArcTan[y1][x1] << 8) ^ Quadrant; +} + +void ST010_Scale(short Multiplier, short X0, short Y0, int &X1, int &Y1) +{ + X1 = X0 * Multiplier << 1; + Y1 = Y0 * Multiplier << 1; +} + +void ST010_Multiply(short Multiplicand, short Multiplier, int &Product) +{ + Product = Multiplicand * Multiplier << 1; +} + +void ST010_Rotate(short Theta, short X0, short Y0, short &X1, short &Y1) +{ + X1 = (Y0 * ST010_Sin(Theta) >> 15) + (X0 * ST010_Cos(Theta) >> 15); + Y1 = (Y0 * ST010_Cos(Theta) >> 15) - (X0 * ST010_Sin(Theta) >> 15); +} + +void SETA_Distance(short Y0, short X0, short &Distance) +{ + if (X0 < 0) X0 = -X0; + if (Y0 < 0) Y0 = -Y0; + Distance = ((X0 * 0x7af0) + 0x4000) >> 15; +} + +void ST010_SortDrivers(uint16 Positions, uint16 Places[32], uint16 Drivers[32]) +{ + bool Sorted; + uint16 Temp; + + if (Positions > 1) + do { + Sorted = true; + for (int i = 0; i < Positions - 1; i++) + if (Places[i] < Places[i + 1]) + { + Temp = Places[i + 1]; + Places[i + 1] = Places[i]; + Places[i] = Temp; + + Temp = Drivers[i + 1]; + Drivers[i + 1] = Drivers[i]; + Drivers[i] = Temp; + + Sorted = false; + } + Positions--; + } while (!Sorted); +} + +#define ST010_WORD(offset) (Memory.SRAM[offset + 1] << 8) | Memory.SRAM[offset] + +void S9xSetST010(uint32 Address, uint8 Byte) +{ + if(!(Address&0x80000)) + { + ST010.control_enable=TRUE; + return; + } + //printf("Write %06X:%02X\n", Address, Byte); + + if((Address &0xFFF) ==0x20 && ST010.control_enable) + ST010.op_reg=Byte; + if((Address &0xFFF) ==0x21 && ST010.control_enable) + ST010.execute=Byte; + else Memory.SRAM[Address&CPU.Memory_SRAMMask]=Byte; + + if(ST010.execute&0x80) + { + switch(ST010.op_reg) + { + // Sorts Driver Placements + // + // Input + // 0x0024-0x0025 : Positions + // 0x0040-0x007f : Places + // 0x0080-0x00ff : Drivers + // Output + // 0x0040-0x007f : Places + // 0x0080-0x00ff : Drivers + // + case 0x02: + { +#ifdef FAST_LSB_WORD_ACCESS + ST010_SortDrivers(*(short*)&SRAM[0x0024], (uint16*) (SRAM + 0x0040), (uint16*) (SRAM + 0x0080)); +#else + uint16 Places[32]; + uint16 Positions = ST010_WORD(0x0024); + int Pos, Offset; + + Offset = 0; + + for (Pos = 0; Pos < Positions; Pos++) + { + Places[Pos] = ST010_WORD(0x0040 + Offset); + Offset += 2; + } + + ST010_SortDrivers(Positions, Places, (uint16*) (SRAM + 0x0080)); + + Offset = 0; + + for (Pos = 0; Pos < Positions; Pos++) + { + SRAM[0x0040 + Offset]=(uint8)(Places[Pos]); + SRAM[0x0041 + Offset]=(uint8)(Places[Pos] >> 8); + Offset += 2; + } +#endif + break; + + } + + // Two Dimensional Coordinate Scale + // + // Input + // 0x0000-0x0001 : X0 (signed) + // 0x0002-0x0003 : Y0 (signed) + // 0x0004-0x0005 : Multiplier (signed) + // Output + // 0x0010-0x0013 : X1 (signed) + // 0x0014-0x0017 : Y1 (signed) + // + case 0x03: + { +#ifdef FAST_LSB_WORD_ACCESS + ST010_Scale(*(short*)&Memory.SRAM[0x0004], *(short*)&Memory.SRAM[0x0000], *(short*)&Memory.SRAM[0x0002], + (int&) Memory.SRAM[0x0010], (int&) Memory.SRAM[0x0014]); +#else + int x1, y1; + + ST010_Scale(ST010_WORD(0x0004), ST010_WORD(0x0000), ST010_WORD(0x0002), x1, y1); + + Memory.SRAM[0x0010]=(uint8)(x1); + Memory.SRAM[0x0011]=(uint8)(x1 >> 8); + Memory.SRAM[0x0012]=(uint8)(x1 >> 16); + Memory.SRAM[0x0013]=(uint8)(x1 >> 24); + Memory.SRAM[0x0014]=(uint8)(y1); + Memory.SRAM[0x0015]=(uint8)(y1 >> 8); + Memory.SRAM[0x0016]=(uint8)(y1 >> 16); + Memory.SRAM[0x0017]=(uint8)(y1 >> 24); +#endif + break; + } + + // 16-bit Multiplication + // + // Input + // 0x0000-0x0001 : Multiplcand (signed) + // 0x0002-0x0003 : Multiplier (signed) + // Output + // 0x0010-0x0013 : Product (signed) + // + case 0x06: + { +#ifdef FAST_LSB_WORD_ACCESS + ST010_Multiply(*(short*)&Memory.SRAM[0x0000], *(short*)&Memory.SRAM[0x0002], (int&) Memory.SRAM[0x0010]); +#else + int Product; + + ST010_Multiply(ST010_WORD(0x0000), ST010_WORD(0x0002), Product); + + Memory.SRAM[0x0010]=(uint8)(Product); + Memory.SRAM[0x0011]=(uint8)(Product >> 8); + Memory.SRAM[0x0012]=(uint8)(Product >> 16); + Memory.SRAM[0x0013]=(uint8)(Product >> 24); +#endif + break; + } + + // Mode 7 Raster Data Calculation + // + // Input + // 0x0000-0x0001 : Angle (signed) + // Output + // 0x00f0-0x024f : Mode 7 Matrix A + // 0x0250-0x03af : Mode 7 Matrix B + // 0x03b0-0x050f : Mode 7 Matrix C + // 0x0510-0x066f : Mode 7 Matrix D + // + case 0x07: + { + int16 data; + int32 offset = 0; + int16 Theta = ST010_WORD(0x0000); + + for (int32 line = 0; line < 176; line++) + { + // Calculate Mode 7 Matrix A/D data + data = ST010_M7Scale[line] * ST010_Cos(Theta) >> 15; + + Memory.SRAM[0x00f0 + offset]=(uint8)(data); + Memory.SRAM[0x00f1 + offset]=(uint8)(data >> 8); + Memory.SRAM[0x0510 + offset]=(uint8)(data); + Memory.SRAM[0x0511 + offset]=(uint8)(data >> 8); + + // Calculate Mode 7 Matrix B/C data + data = ST010_M7Scale[line] * ST010_Sin(Theta) >> 15; + + Memory.SRAM[0x0250 + offset]=(uint8)(data); + Memory.SRAM[0x0251 + offset]=(uint8)(data >> 8); + + if (data) data = ~data; + + Memory.SRAM[0x03b0 + offset]=(uint8)(data); + Memory.SRAM[0x03b1 + offset]=(uint8)(data >> 8); + + offset += 2; + } + + // Shift Angle for use with Lookup table + Memory.SRAM[0x00] = Memory.SRAM[0x01]; + Memory.SRAM[0x01] = 0x00; + + break; + } + + // Two dimensional Coordinate Rotation + // + // Input + // 0x0000-0x0001 : X0 (signed) + // 0x0002-0x0003 : Y0 (signed) + // 0x0004-0x0005 : Angle (signed) + // Output + // 0x0010-0x0011 : X1 (signed) + // 0x0012-0x0013 : Y1 (signed) + // + case 0x08: + { +#ifdef FAST_LSB_WORD_ACCESS + ST010_Rotate(*(short*)&Memory.SRAM[0x0004], *(short*)&Memory.SRAM[0x0000], *(short*)&Memory.SRAM[0x0002], + (short&) Memory.SRAM[0x0010], (short&) Memory.SRAM[0x0012]); +#else + short x1, y1; + + ST010_Rotate(ST010_WORD(0x0004), ST010_WORD(0x0000), ST010_WORD(0x0002), x1, y1); + + Memory.SRAM[0x0010]=(uint8)(x1); + Memory.SRAM[0x0011]=(uint8)(x1 >> 8); + Memory.SRAM[0x0012]=(uint8)(y1); + Memory.SRAM[0x0013]=(uint8)(y1 >> 8); +#endif + break; + } + + // Input + // 0x0000-0x0001 : DX (signed) + // 0x0002-0x0003 : DY (signed) + // Output + // 0x0010-0x0011 : Angle (signed) + // + case 0x01: + { + Memory.SRAM[0x0006] = Memory.SRAM[0x0002]; + Memory.SRAM[0x0007] = Memory.SRAM[0x0003]; + +#ifdef FAST_LSB_WORD_ACCESS + ST010_OP01(*(short*)&Memory.SRAM[0x0000], *(short*)&Memory.SRAM[0x0002], + (short&) Memory.SRAM[0x0000], (short&) Memory.SRAM[0x0002], + (short&) Memory.SRAM[0x0004], (short&) Memory.SRAM[0x0010]); +#else + short x1, y1, Quadrant, Theta; + + ST010_OP01(ST010_WORD(0x0000), ST010_WORD(0x0002), x1, y1, Quadrant, Theta); + + Memory.SRAM[0x0000]=(uint8)(x1); + Memory.SRAM[0x0001]=(uint8)(x1 >> 8); + Memory.SRAM[0x0002]=(uint8)(y1); + Memory.SRAM[0x0003]=(uint8)(y1 >> 8); + Memory.SRAM[0x0004]=(uint8)(Quadrant); + Memory.SRAM[0x0005]=(uint8)(Quadrant >> 8); + Memory.SRAM[0x0010]=(uint8)(Theta); + Memory.SRAM[0x0011]=(uint8)(Theta >> 8); +#endif + break; + } + + // calculate the vector length of (x,y) + case 0x04: + { + int16 square, x,y; +#ifdef FAST_LSB_WORD_ACCESS + x=*((int16*)Memory.SRAM); + y=*((int16*)&Memory.SRAM[2]); +#else + x=Memory.SRAM[0]|(Memory.SRAM[1]<<8); + y=Memory.SRAM[2]|(Memory.SRAM[3]<<8); +#endif + square=(int16)sqrt((double)(y*y+x*x)); + //SETA_Distance( x,y,square ); + +#ifdef FAST_LSB_WORD_ACCESS + *((int16*)&Memory.SRAM[0x10])=square; +#else + Memory.SRAM[0x10]=(uint8)(square); + Memory.SRAM[0x11]=(uint8)(square>>8); +#endif + break; + } + + // calculate AI orientation based on specific guidelines + case 0x05: + { + int dx,dy; + int16 a1,b1,c1; + uint16 o1; + + bool wrap=false; + + // target (x,y) coordinates + int16 ypos_max = ST010_WORD(0x00C0); + int16 xpos_max = ST010_WORD(0x00C2); + + // current coordinates and direction + int32 ypos = SRAM[0xC4]|(SRAM[0xC5]<<8)|(SRAM[0xC6]<<16)|(SRAM[0xC7]<<24); + int32 xpos = SRAM[0xC8]|(SRAM[0xC9]<<8)|(SRAM[0xCA]<<16)|(SRAM[0xCB]<<24); + uint16 rot = SRAM[0xCC]|(SRAM[0xCD]<<8); + + // physics + uint16 speed = ST010_WORD(0x00D4); + uint16 accel = ST010_WORD(0x00D6); + uint16 speed_max = ST010_WORD(0x00D8); + + // special condition acknowledgment + int16 system = ST010_WORD(0x00DA); + int16 flags = ST010_WORD(0x00DC); + + // new target coordinates + int16 ypos_new = ST010_WORD(0x00DE); + int16 xpos_new = ST010_WORD(0x00E0); + + // mask upper bit + xpos_new &= 0x7FFF; + + // get the current distance + dx = xpos_max-(xpos>>16); + dy = ypos_max-(ypos>>16); + + // quirk: clear and move in9 + SRAM[0xD2]=0xFF; + SRAM[0xD3]=0xFF; + SRAM[0xDA]=0; + SRAM[0xDB]=0; + + // grab the target angle + ST010_OP01(dy,dx,a1,b1,c1,(int16 &)o1); + + // check for wrapping + //if((o1<0x6000 && rot>0xA000) || + // (rot<0x6000 && o1>0xA000)) + //if(o10x8000) + { + o1+=0x8000; + rot+=0x8000; + wrap=true; + } + //o1=0x0000; + //rot=0xFF00; + + uint16 old_speed; + + old_speed = speed; + + // special case + if(abs(o1-rot)==0x8000) + { + speed = 0x100; + } + // slow down for sharp curves + else if(abs(o1-rot)>=0x1000) + { + uint32 slow = abs(o1-rot); + slow >>= 4; // scaling + speed -= slow; + } + // otherwise accelerate + else + { + speed += accel; + if(speed > speed_max) + { + // clip speed + speed = speed_max; + } + } + + // prevent negative/positive overflow + if(abs(old_speed-speed)>0x8000) { + if(old_speedrot && (o1-rot)>0x80) || + (o1=0x80) ) + { + if(o1rot) rot+=0x280; + } + + // turn off wrapping + if(wrap) rot-=0x8000; + + // now check the distances (store for later) + dx = (xpos_max<<16)-xpos; + dy = (ypos_max<<16)-ypos; + dx>>=16; + dy>>=16; + + // if we're in so many units of the target, signal it + if( ( system && (dy<=6 && dy>=-8) && (dx<=126 && dx>=-128)) || + (!system && (dx<=6 && dx>=-8) && (dy<=126 && dy>=-128)) ) + { + // announce our new destination and flag it + xpos_max = xpos_new&0x7FFF; + ypos_max = ypos_new; + flags |= 0x08; + } + + // update position + xpos -= (ST010_Cos(rot) * 0x400 >> 15) * (speed >> 8) << 1; + ypos -= (ST010_Sin(rot) * 0x400 >> 15) * (speed >> 8) << 1; + + // quirk: mask upper byte + xpos &= 0x1FFFFFFF; + ypos &= 0x1FFFFFFF; + + SRAM[0x00C0]=(uint8)(ypos_max); + SRAM[0x00C1]=(uint8)(ypos_max >> 8); + SRAM[0x00C2]=(uint8)(xpos_max); + SRAM[0x00C3]=(uint8)(xpos_max >> 8); + SRAM[0x00C4]=(uint8)(ypos); + SRAM[0x00C5]=(uint8)(ypos >> 8); + SRAM[0x00C6]=(uint8)(ypos >> 16); + SRAM[0x00C7]=(uint8)(ypos >> 24); + SRAM[0x00C8]=(uint8)(xpos); + SRAM[0x00C9]=(uint8)(xpos >> 8); + SRAM[0x00CA]=(uint8)(xpos >> 16); + SRAM[0x00CB]=(uint8)(xpos >> 24); + SRAM[0x00CC]=(uint8)(rot); + SRAM[0x00CD]=(uint8)(rot >> 8); + SRAM[0x00D4]=(uint8)(speed); + SRAM[0x00D5]=(uint8)(speed >> 8); + SRAM[0x00DC]=(uint8)(flags); + SRAM[0x00DD]=(uint8)(flags >> 8); + + break; + } + + default: + printf("Unknown Op\n"); + break; + } + + // lower signal: op processed + ST010.op_reg=0; + ST010.execute=0; + } +} + diff --git a/src/snes4iphone_src/seta011.cpp b/src/snes4iphone_src/seta011.cpp new file mode 100755 index 0000000..364e9ef --- /dev/null +++ b/src/snes4iphone_src/seta011.cpp @@ -0,0 +1,233 @@ +/******************************************************************************* + Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and + Jerremy Koot (jkoot@snes9x.com) + + (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net) + + (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net), + funkyass (funkyass@spam.shaw.ca), + Joel Yliluoma (http://iki.fi/bisqwit/) + Kris Bleakley (codeviolation@hotmail.com), + Matthew Kendora, + Nach (n-a-c-h@users.sourceforge.net), + Peter Bortas (peter@bortas.org) and + zones (kasumitokoduck@yahoo.com) + + C4 x86 assembler and some C emulation code + (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com), + _Demo_ (_demo_@zsnes.com), and Nach + + C4 C++ code + (c) Copyright 2003 Brad Jorsch + + DSP-1 emulator code + (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson, + John Weidman, neviksti (neviksti@hotmail.com), + Kris Bleakley, Andreas Naive + + DSP-2 emulator code + (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and + Lord Nightmare (lord_nightmare@users.sourceforge.net + + OBC1 emulator code + (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and + Kris Bleakley + Ported from x86 assembler to C by sanmaiwashi + + SPC7110 and RTC C++ emulator code + (c) Copyright 2002 Matthew Kendora with research by + zsKnight, John Weidman, and Dark Force + + S-DD1 C emulator code + (c) Copyright 2003 Brad Jorsch with research by + Andreas Naive and John Weidman + + S-RTC C emulator code + (c) Copyright 2001 John Weidman + + ST010 C++ emulator code + (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora + + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + + Super FX C emulator code + (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman + + + SH assembler code partly based on x86 assembler code + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + + + Specific ports contains the works of other authors. See headers in + individual files. + + Snes9x homepage: http://www.snes9x.com + + Permission to use, copy, modify and distribute Snes9x in both binary and + source form, for non-commercial purposes, is hereby granted without fee, + providing that this license information and copyright notice appear with + all copies and any derived work. + + This software is provided 'as-is', without any express or implied + warranty. In no event shall the authors be held liable for any damages + arising from the use of this software. + + Snes9x is freeware for PERSONAL USE only. Commercial users should + seek permission of the copyright holders first. Commercial use includes + charging money for Snes9x or software derived from Snes9x. + + The copyright holders request that bug fixes and improvements to the code + should be forwarded to them so everyone can benefit from the modifications + in future versions. + + Super NES and Super Nintendo Entertainment System are trademarks of + Nintendo Co., Limited and its subsidiary companies. +*******************************************************************************/ +#include +#include "port.h" +#include "seta.h" +#include "memmap.h" + +ST011_Regs ST011; + +// shougi playboard +uint8 board[9][9]; + +// debug +static int line = 0; + +uint8 S9xGetST011(uint32 Address) +{ + uint8 t; + uint16 address = (uint16) Address & 0xFFFF; + + // line counter + line++; + + // status check + if (address == 0x01) + { + t = 0xFF; + } + // read directly from s-ram + else + { + t = Memory.SRAM[address]; + } + + // debug +// if(address<0x150) +// printf( "ST011 R: %06X %02X\n", Address, t); + + return t; +} + +void S9xSetST011(uint32 Address, uint8 Byte) +{ + uint16 address = (uint16) Address & 0xFFFF; + static bool reset = false; + + // debug + line++; + + if(!reset) + { + // bootup values + ST011.waiting4command = true; + reset = true; + } + + // debug +// if(address<0x150) +// printf( "ST011 W: %06X %02X\n", Address, Byte ); + + Memory.SRAM[address]=Byte; + + // op commands/data goes through this address + if(address==0x00) + { + // check for new commands + if (ST011.waiting4command) + { + ST011.waiting4command = false; + ST011.command = Byte; + ST011.in_index = 0; + ST011.out_index = 0; + switch(ST011.command) + { + case 0x01: ST011.in_count = 12*10+8; break; + case 0x02: ST011.in_count = 4; break; + case 0x04: ST011.in_count = 0; break; + case 0x05: ST011.in_count = 0; break; + case 0x06: ST011.in_count = 0; break; + case 0x07: ST011.in_count = 0; break; + case 0x0E: ST011.in_count = 0; break; + default: ST011.waiting4command=true; break; + } + } + else + { + ST011.parameters [ST011.in_index] = Byte; + ST011.in_index++; + } + } + + if (ST011.in_count==ST011.in_index) + { + // Actually execute the command + ST011.waiting4command = true; + ST011.out_index = 0; + switch (ST011.command) + { + // unknown: download playboard + case 0x01: + { + // 9x9 board data: top to bottom, left to right + // Values represent piece types and ownership + for( int lcv=0; lcv<9; lcv++ ) + memcpy( board[lcv], ST011.parameters+lcv*10, 9*1 ); + } + break; + + // unknown + case 0x02: break; + + // unknown + case 0x04: + { + // outputs + Memory.SRAM[0x12C] = 0x00; + //Memory.SRAM[0x12D] = 0x00; + Memory.SRAM[0x12E] = 0x00; + } + break; + + // unknown + case 0x05: + { + // outputs + Memory.SRAM[0x12C] = 0x00; + //Memory.SRAM[0x12D] = 0x00; + Memory.SRAM[0x12E] = 0x00; + } + break; + + // unknown + case 0x06: break; + case 0x07: break; + + // unknown + case 0x0E: + { + // outputs + Memory.SRAM[0x12C] = 0x00; + Memory.SRAM[0x12D] = 0x00; + } + break; + } + } +} + diff --git a/src/snes4iphone_src/seta018.cpp b/src/snes4iphone_src/seta018.cpp new file mode 100755 index 0000000..5390a35 --- /dev/null +++ b/src/snes4iphone_src/seta018.cpp @@ -0,0 +1,255 @@ +/******************************************************************************* + Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + + (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com) and + Jerremy Koot (jkoot@snes9x.com) + + (c) Copyright 2001 - 2004 John Weidman (jweidman@slip.net) + + (c) Copyright 2002 - 2004 Brad Jorsch (anomie@users.sourceforge.net), + funkyass (funkyass@spam.shaw.ca), + Joel Yliluoma (http://iki.fi/bisqwit/) + Kris Bleakley (codeviolation@hotmail.com), + Matthew Kendora, + Nach (n-a-c-h@users.sourceforge.net), + Peter Bortas (peter@bortas.org) and + zones (kasumitokoduck@yahoo.com) + + C4 x86 assembler and some C emulation code + (c) Copyright 2000 - 2003 zsKnight (zsknight@zsnes.com), + _Demo_ (_demo_@zsnes.com), and Nach + + C4 C++ code + (c) Copyright 2003 Brad Jorsch + + DSP-1 emulator code + (c) Copyright 1998 - 2004 Ivar (ivar@snes9x.com), _Demo_, Gary Henderson, + John Weidman, neviksti (neviksti@hotmail.com), + Kris Bleakley, Andreas Naive + + DSP-2 emulator code + (c) Copyright 2003 Kris Bleakley, John Weidman, neviksti, Matthew Kendora, and + Lord Nightmare (lord_nightmare@users.sourceforge.net + + OBC1 emulator code + (c) Copyright 2001 - 2004 zsKnight, pagefault (pagefault@zsnes.com) and + Kris Bleakley + Ported from x86 assembler to C by sanmaiwashi + + SPC7110 and RTC C++ emulator code + (c) Copyright 2002 Matthew Kendora with research by + zsKnight, John Weidman, and Dark Force + + S-DD1 C emulator code + (c) Copyright 2003 Brad Jorsch with research by + Andreas Naive and John Weidman + + S-RTC C emulator code + (c) Copyright 2001 John Weidman + + ST010 C++ emulator code + (c) Copyright 2003 Feather, Kris Bleakley, John Weidman and Matthew Kendora + + Super FX x86 assembler emulator code + (c) Copyright 1998 - 2003 zsKnight, _Demo_, and pagefault + + Super FX C emulator code + (c) Copyright 1997 - 1999 Ivar, Gary Henderson and John Weidman + + + SH assembler code partly based on x86 assembler code + (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se) + + + Specific ports contains the works of other authors. See headers in + individual files. + + Snes9x homepage: http://www.snes9x.com + + Permission to use, copy, modify and distribute Snes9x in both binary and + source form, for non-commercial purposes, is hereby granted without fee, + providing that this license information and copyright notice appear with + all copies and any derived work. + + This software is provided 'as-is', without any express or implied + warranty. In no event shall the authors be held liable for any damages + arising from the use of this software. + + Snes9x is freeware for PERSONAL USE only. Commercial users should + seek permission of the copyright holders first. Commercial use includes + charging money for Snes9x or software derived from Snes9x. + + The copyright holders request that bug fixes and improvements to the code + should be forwarded to them so everyone can benefit from the modifications + in future versions. + + Super NES and Super Nintendo Entertainment System are trademarks of + Nintendo Co., Limited and its subsidiary companies. +*******************************************************************************/ +#include "memmap.h" +#include "seta.h" +//#include "port.h" + +ST018_Regs ST018; + +static int line; // line counter + +extern "C"{ +uint8 S9xGetST018(uint32 Address) +{ + uint8 t = 0; + uint16 address = (uint16) Address & 0xFFFF; + + line++; + + // these roles may be flipped + // op output + if (address == 0x3804) + { + if (ST018.out_count) + { + t = (uint8) ST018.output [ST018.out_index]; + ST018.out_index++; + if (ST018.out_count==ST018.out_index) + ST018.out_count=0; + } + else + t = 0x81; + } + // status register + else if (address == 0x3800) + t = ST018.status; + + printf( "ST018 R: %06X %02X\n", Address, t); + + return t; +} + +void S9xSetST018(uint8 Byte, uint32 Address) +{ + uint16 address = (uint16) Address&0xFFFF; + static bool reset = false; + + printf( "ST018 W: %06X %02X\n", Address, Byte ); + + line++; + + if (!reset) + { + // bootup values + ST018.waiting4command = true; + ST018.part_command = 0; + reset = true; + } + + Memory.SRAM[address]=Byte; + + // default status for now + ST018.status = 0x00; + + // op data goes through this address + if (address==0x3804) + { + // check for new commands: 3 bytes length + if(ST018.waiting4command && ST018.part_command==2) + { + ST018.waiting4command = false; + ST018.command <<= 8; + ST018.command |= Byte; + ST018.in_index = 0; + ST018.out_index = 0; + ST018.part_command = 0; // 3-byte commands + ST018.pass = 0; // data streams into the chip + switch(ST018.command & 0xFFFFFF) + { + case 0x0100: ST018.in_count = 0; break; + case 0xFF00: ST018.in_count = 0; break; + default: ST018.waiting4command = true; break; + } + } + else if(ST018.waiting4command) + { + // 3-byte commands + ST018.part_command++; + ST018.command <<= 8; + ST018.command |= Byte; + } + } + // extra parameters + else if (address==0x3802) + { + ST018.parameters[ST018.in_index] = Byte; + ST018.in_index++; + } + + if (ST018.in_count==ST018.in_index) + { + // Actually execute the command + ST018.waiting4command = true; + ST018.in_index = 0; + ST018.out_index = 0; + switch (ST018.command) + { + // hardware check? + case 0x0100: + ST018.waiting4command = false; + ST018.pass++; + if (ST018.pass==1) + { + ST018.in_count = 1; + ST018.out_count = 2; + + // Overload's research + ST018.output[0x00] = 0x81; + ST018.output[0x01] = 0x81; + } + else + { + //ST018.in_count = 1; + ST018.out_count = 3; + + // no reason to change this + //ST018.output[0x00] = 0x81; + //ST018.output[0x01] = 0x81; + ST018.output[0x02] = 0x81; + + // done processing requests + if (ST018.pass==3) + ST018.waiting4command = true; + } + break; + + // unknown: feels like a security detection + // format identical to 0x0100 + case 0xFF00: + ST018.waiting4command = false; + ST018.pass++; + if (ST018.pass==1) + { + ST018.in_count = 1; + ST018.out_count = 2; + + // Overload's research + ST018.output[0x00] = 0x81; + ST018.output[0x01] = 0x81; + } + else + { + //ST018.in_count = 1; + ST018.out_count = 3; + + // no reason to change this + //ST018.output[0x00] = 0x81; + //ST018.output[0x01] = 0x81; + ST018.output[0x02] = 0x81; + + // done processing requests + if (ST018.pass==3) + ST018.waiting4command = true; + } + break; + } + } +} +} + diff --git a/src/snes4iphone_src/snaporig.cpp b/src/snes4iphone_src/snaporig.cpp new file mode 100755 index 0000000..833e1f9 --- /dev/null +++ b/src/snes4iphone_src/snaporig.cpp @@ -0,0 +1,414 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#include +#include +#include + +#if defined(__unix) || defined(__linux) || defined(__sun) || defined(__DJGPP) +//#include +#include +#include +#endif + +#include "snapshot.h" +#include "snaporig.h" +#include "memmap.h" +#include "snes9x.h" +#include "65c816.h" +#include "ppu.h" +#include "cpuexec.h" +#include "display.h" +#include "apu.h" +#include "soundux.h" + +struct SOrigPPU OrigPPU; +struct SOrigDMA OrigDMA [8]; +struct SOrigRegisters OrigRegisters; +struct SOrigCPUState OrigCPU; +struct SOrigAPU OrigAPU; +SOrigSoundData OrigSoundData; +struct SOrigAPURegisters OrigAPURegisters; +char ROMFilename [1025]; + +static int ReadOrigSnapshot (STREAM); + +bool8_32 S9xLoadOrigSnapshot (const char *filename) +{ + STREAM snapshot = NULL; + if (S9xOpenSnapshotFile (filename, TRUE, &snapshot)) + { + int result; + if ((result = ReadOrigSnapshot (snapshot)) != SUCCESS) + { + S9xCloseSnapshotFile (snapshot); + return (FALSE); + } + S9xCloseSnapshotFile (snapshot); + return (TRUE); + } + return (FALSE); +} + +#ifdef _SNESPPC +#pragma warning(disable : 4018) +#endif +static int ReadBlock (const char *key, void *block, int max_len, STREAM snap) +{ + char buffer [20]; + int len = 0; + int rem = 0; + + if (READ_STREAM (buffer, 11, snap) != 11 || + strncmp (buffer, key, 4) != 0 || + (len = atoi (&buffer [4])) == 0) + return (WRONG_FORMAT); + + if (len > max_len) + { + rem = len - max_len; + len = max_len; + } + if (READ_STREAM (block, len, snap) != len) + return (WRONG_FORMAT); + + if (rem) + { + char *junk = new char [rem]; + READ_STREAM (junk, rem, snap); + delete junk; + } + + return (SUCCESS); +} + +static int ReadOrigSnapshot (STREAM snap) +{ + char buffer [_MAX_PATH]; + char rom_filename [_MAX_PATH]; + int result; + int i; + int j; + + int version; + int len = strlen (ORIG_SNAPSHOT_MAGIC) + 1 + 4 + 1; + if (READ_STREAM (buffer, len, snap) != len) + return (WRONG_FORMAT); + if (strncmp (buffer, ORIG_SNAPSHOT_MAGIC, strlen (ORIG_SNAPSHOT_MAGIC)) != 0) + return (WRONG_FORMAT); + if ((version = atoi (&buffer [strlen (SNAPSHOT_MAGIC) + 1])) > ORIG_SNAPSHOT_VERSION) + return (WRONG_VERSION); + + if ((result = ReadBlock ("NAM:", rom_filename, _MAX_PATH, snap)) != SUCCESS) + return (result); + + if ((result = ReadBlock ("HiR:", buffer, 0x41, snap)) != SUCCESS) + return (result); + + if (strcasecmp (rom_filename, Memory.ROMFilename) != 0 && + strcasecmp (S9xBasename (rom_filename), S9xBasename (Memory.ROMFilename)) != 0) + { + S9xMessage (S9X_WARNING, S9X_FREEZE_ROM_NAME, + "Current loaded ROM image doesn't match that required by freeze-game file."); + } + + S9xReset (); + S9xSetSoundMute (TRUE); + if ((result = ReadBlock ("CPU:", &OrigCPU, sizeof (OrigCPU), snap)) != SUCCESS) + return (result); + OrigCPU.FastROMSpeed = OrigCPU.FastROMSpeed_old; + Memory.FixROMSpeed (); + if (version == 3) + { + OrigCPU.Cycles = OrigCPU.Cycles_old; + OrigCPU.NextEvent = OrigCPU.NextEvent_old; + OrigCPU.V_Counter = OrigCPU.V_Counter_old; + OrigCPU.MemSpeed = OrigCPU.MemSpeed_old; + OrigCPU.MemSpeedx2 = OrigCPU.MemSpeedx2_old; + OrigCPU.FastROMSpeed = OrigCPU.FastROMSpeed_old; + } + CPU.Flags = OrigCPU.Flags; + CPU.BranchSkip = OrigCPU.BranchSkip; + CPU.NMIActive = OrigCPU.NMIActive; + CPU.IRQActive = OrigCPU.IRQActive; + CPU.WaitingForInterrupt = OrigCPU.WaitingForInterrupt; + CPU.WhichEvent = OrigCPU.WhichEvent; + CPU.Cycles = OrigCPU.Cycles; + CPU.NextEvent = OrigCPU.NextEvent; + CPU.V_Counter = OrigCPU.V_Counter; + CPU.MemSpeed = OrigCPU.MemSpeed; + CPU.MemSpeedx2 = OrigCPU.MemSpeedx2; + CPU.FastROMSpeed = OrigCPU.FastROMSpeed; + + if ((result = ReadBlock ("REG:", &OrigRegisters, sizeof (OrigRegisters), snap)) != SUCCESS) + return (result); + + Registers = *(struct SRegisters *) &OrigRegisters; + + if ((result = ReadBlock ("PPU:", &OrigPPU, sizeof (OrigPPU), snap)) != SUCCESS) + return (result); + + if (version == 2) + { + OrigPPU.OBJNameSelect = OrigPPU.OBJNameSelect_old << 13; + OrigPPU.OBJNameBase <<= 1; + OrigPPU.OBJNameSelect <<= 13; + } + PPU.BGMode = OrigPPU.BGMode; + PPU.BG3Priority = OrigPPU.BG3Priority; + PPU.Brightness = OrigPPU.Brightness; + + PPU.VMA.High = OrigPPU.VMA.High; + PPU.VMA.Increment = OrigPPU.VMA.Increment; + PPU.VMA.Address = OrigPPU.VMA.Address; + PPU.VMA.Mask1 = OrigPPU.VMA.Mask1; + PPU.VMA.FullGraphicCount = OrigPPU.VMA.FullGraphicCount; + PPU.VMA.Shift = OrigPPU.VMA.Shift; + + for (i = 0; i < 4; i++) + { + PPU.BG[i].SCBase = OrigPPU.BG[i].SCBase; + PPU.BG[i].VOffset = OrigPPU.BG[i].VOffset; + PPU.BG[i].HOffset = OrigPPU.BG[i].HOffset; + PPU.BG[i].BGSize = OrigPPU.BG[i].BGSize; + PPU.BG[i].NameBase = OrigPPU.BG[i].NameBase; + PPU.BG[i].SCSize = OrigPPU.BG[i].SCSize; + } + + PPU.CGFLIP = OrigPPU.CGFLIP; + for (i = 0; i < 256; i++) + PPU.CGDATA [i] = OrigPPU.CGDATA [i]; + PPU.FirstSprite = OrigPPU.FirstSprite; + for (i = 0; i < 128; i++) + { + PPU.OBJ[i].HPos = OrigPPU.OBJ [i].HPos; + PPU.OBJ[i].VPos = OrigPPU.OBJ [i].VPos; + PPU.OBJ[i].Name = OrigPPU.OBJ [i].Name; + PPU.OBJ[i].VFlip = OrigPPU.OBJ [i].VFlip; + PPU.OBJ[i].HFlip = OrigPPU.OBJ [i].HFlip; + PPU.OBJ[i].Priority = OrigPPU.OBJ [i].Priority; + PPU.OBJ[i].Palette = OrigPPU.OBJ [i].Palette; + PPU.OBJ[i].Size = OrigPPU.OBJ [i].Size; + } + PPU.OAMPriorityRotation = OrigPPU.OAMPriorityRotation; + PPU.OAMAddr = OrigPPU.OAMAddr; + + PPU.OAMFlip = OrigPPU.OAMFlip; + PPU.OAMTileAddress = OrigPPU.OAMTileAddress; + PPU.IRQVBeamPos = OrigPPU.IRQVBeamPos; + PPU.IRQHBeamPos = OrigPPU.IRQHBeamPos; + PPU.VBeamPosLatched = OrigPPU.VBeamPosLatched; + PPU.HBeamPosLatched = OrigPPU.HBeamPosLatched; + + PPU.HBeamFlip = OrigPPU.HBeamFlip; + PPU.VBeamFlip = OrigPPU.VBeamFlip; + PPU.HVBeamCounterLatched = OrigPPU.HVBeamCounterLatched; + + PPU.MatrixA = OrigPPU.MatrixA; + PPU.MatrixB = OrigPPU.MatrixB; + PPU.MatrixC = OrigPPU.MatrixC; + PPU.MatrixD = OrigPPU.MatrixD; + PPU.CentreX = OrigPPU.CentreX; + PPU.CentreY = OrigPPU.CentreY; + PPU.Joypad1ButtonReadPos = OrigPPU.Joypad1ButtonReadPos; + PPU.Joypad2ButtonReadPos = OrigPPU.Joypad2ButtonReadPos; + PPU.Joypad3ButtonReadPos = OrigPPU.Joypad3ButtonReadPos; + + PPU.CGADD = OrigPPU.CGADD; + PPU.FixedColourRed = OrigPPU.FixedColourRed; + PPU.FixedColourGreen = OrigPPU.FixedColourGreen; + PPU.FixedColourBlue = OrigPPU.FixedColourBlue; + PPU.SavedOAMAddr = OrigPPU.SavedOAMAddr; + PPU.ScreenHeight = OrigPPU.ScreenHeight; + PPU.WRAM = OrigPPU.WRAM; + PPU.ForcedBlanking = OrigPPU.ForcedBlanking; + PPU.OBJNameSelect = OrigPPU.OBJNameSelect; + PPU.OBJSizeSelect = OrigPPU.OBJSizeSelect; + PPU.OBJNameBase = OrigPPU.OBJNameBase; + PPU.OAMReadFlip = OrigPPU.OAMReadFlip; + memmove (PPU.OAMData, OrigPPU.OAMData, sizeof (PPU.OAMData)); + PPU.VTimerEnabled = OrigPPU.VTimerEnabled; + PPU.HTimerEnabled = OrigPPU.HTimerEnabled; + PPU.HTimerPosition = OrigPPU.HTimerPosition; + PPU.Mosaic = OrigPPU.Mosaic; + memmove (PPU.BGMosaic, OrigPPU.BGMosaic, sizeof (PPU.BGMosaic)); + PPU.Mode7HFlip = OrigPPU.Mode7HFlip; + PPU.Mode7VFlip = OrigPPU.Mode7VFlip; + PPU.Mode7Repeat = OrigPPU.Mode7Repeat; + PPU.Window1Left = OrigPPU.Window1Left; + PPU.Window1Right = OrigPPU.Window1Right; + PPU.Window2Left = OrigPPU.Window2Left; + PPU.Window2Right = OrigPPU.Window2Right; + for (i = 0; i < 6; i++) + { + PPU.ClipWindowOverlapLogic [i] = OrigPPU.ClipWindowOverlapLogic [i]; + PPU.ClipWindow1Enable [i] = OrigPPU.ClipWindow1Enable [i]; + PPU.ClipWindow2Enable [i] = OrigPPU.ClipWindow2Enable [i]; + PPU.ClipWindow1Inside [i] = OrigPPU.ClipWindow1Inside [i]; + PPU.ClipWindow2Inside [i] = OrigPPU.ClipWindow2Inside [i]; + } + PPU.CGFLIPRead = OrigPPU.CGFLIPRead; + PPU.Need16x8Mulitply = OrigPPU.Need16x8Mulitply; + + IPPU.ColorsChanged = TRUE; + IPPU.OBJChanged = TRUE; + S9xFixColourBrightness (); + IPPU.RenderThisFrame = FALSE; + + if ((result = ReadBlock ("DMA:", OrigDMA, sizeof (OrigDMA), snap)) != SUCCESS) + return (result); + + for (i = 0; i < 8; i++) + { + DMA[i].TransferDirection = OrigDMA[i].TransferDirection; + DMA[i].AAddressFixed = OrigDMA[i].AAddressFixed; + DMA[i].AAddressDecrement = OrigDMA[i].AAddressDecrement; + DMA[i].TransferMode = OrigDMA[i].TransferMode; + DMA[i].ABank = OrigDMA[i].ABank; + DMA[i].AAddress = OrigDMA[i].AAddress; + DMA[i].Address = OrigDMA[i].Address; + DMA[i].BAddress = OrigDMA[i].BAddress; + DMA[i].TransferBytes = OrigDMA[i].TransferBytes; + DMA[i].HDMAIndirectAddressing = OrigDMA[i].HDMAIndirectAddressing; + DMA[i].IndirectAddress = OrigDMA[i].IndirectAddress; + DMA[i].IndirectBank = OrigDMA[i].IndirectBank; + DMA[i].Repeat = OrigDMA[i].Repeat; + DMA[i].LineCount = OrigDMA[i].LineCount; + DMA[i].FirstLine = OrigDMA[i].FirstLine; + } + + if ((result = ReadBlock ("VRA:", Memory.VRAM, 0x10000, snap)) != SUCCESS) + return (result); + if ((result = ReadBlock ("RAM:", Memory.RAM, 0x20000, snap)) != SUCCESS) + return (result); + if ((result = ReadBlock ("SRA:", ::SRAM, 0x10000, snap)) != SUCCESS) + return (result); + if ((result = ReadBlock ("FIL:", Memory.FillRAM, 0x8000, snap)) != SUCCESS) + return (result); + if (ReadBlock ("APU:", &OrigAPU, sizeof (OrigAPU), snap) == SUCCESS) + { + APU = *(struct SAPU *) &OrigAPU; + + if ((result = ReadBlock ("ARE:", &OrigAPURegisters, + sizeof (OrigAPURegisters), snap)) != SUCCESS) + return (result); + APURegisters = *(struct SAPURegisters *) &OrigAPURegisters; + if ((result = ReadBlock ("ARA:", IAPU.RAM, 0x10000, snap)) != SUCCESS) + return (result); + if ((result = ReadBlock ("SOU:", &OrigSoundData, + sizeof (SOrigSoundData), snap)) != SUCCESS) + return (result); + + SoundData.master_volume_left = OrigSoundData.master_volume_left; + SoundData.master_volume_right = OrigSoundData.master_volume_right; + SoundData.echo_volume_left = OrigSoundData.echo_volume_left; + SoundData.echo_volume_right = OrigSoundData.echo_volume_right; + SoundData.echo_enable = OrigSoundData.echo_enable; + SoundData.echo_feedback = OrigSoundData.echo_feedback; + SoundData.echo_ptr = OrigSoundData.echo_ptr; + SoundData.echo_buffer_size = OrigSoundData.echo_buffer_size; + SoundData.echo_write_enabled = OrigSoundData.echo_write_enabled; + SoundData.echo_channel_enable = OrigSoundData.echo_channel_enable; + SoundData.pitch_mod = OrigSoundData.pitch_mod; + + for (i = 0; i < 3; i++) + SoundData.dummy [i] = OrigSoundData.dummy [i]; + for (i = 0; i < NUM_CHANNELS; i++) + { + SoundData.channels [i].state = OrigSoundData.channels [i].state; + SoundData.channels [i].type = OrigSoundData.channels [i].type; + SoundData.channels [i].volume_left = OrigSoundData.channels [i].volume_left; + SoundData.channels [i].volume_right = OrigSoundData.channels [i].volume_right; + SoundData.channels [i].hertz = OrigSoundData.channels [i].frequency; + SoundData.channels [i].count = OrigSoundData.channels [i].count; + SoundData.channels [i].loop = OrigSoundData.channels [i].loop; + SoundData.channels [i].envx = OrigSoundData.channels [i].envx; + SoundData.channels [i].left_vol_level = OrigSoundData.channels [i].left_vol_level; + SoundData.channels [i].right_vol_level = OrigSoundData.channels [i].right_vol_level; + SoundData.channels [i].envx_target = OrigSoundData.channels [i].envx_target; + SoundData.channels [i].env_error = OrigSoundData.channels [i].env_error; + SoundData.channels [i].erate = OrigSoundData.channels [i].erate; + SoundData.channels [i].direction = OrigSoundData.channels [i].direction; + SoundData.channels [i].attack_rate = OrigSoundData.channels [i].attack_rate; + SoundData.channels [i].decay_rate = OrigSoundData.channels [i].decay_rate; + SoundData.channels [i].sustain_rate = OrigSoundData.channels [i].sustain_rate; + SoundData.channels [i].release_rate = OrigSoundData.channels [i].release_rate; + SoundData.channels [i].sustain_level = OrigSoundData.channels [i].sustain_level; + SoundData.channels [i].sample = OrigSoundData.channels [i].sample; + for (j = 0; j < 16; j++) + SoundData.channels [i].decoded [j] = OrigSoundData.channels [i].decoded [j]; + + for (j = 0; j < 2; j++) + SoundData.channels [i].previous [j] = OrigSoundData.channels [i].previous [j]; + + SoundData.channels [i].sample_number = OrigSoundData.channels [i].sample_number; + SoundData.channels [i].last_block = OrigSoundData.channels [i].last_block; + SoundData.channels [i].needs_decode = OrigSoundData.channels [i].needs_decode; + SoundData.channels [i].block_pointer = OrigSoundData.channels [i].block_pointer; + SoundData.channels [i].sample_pointer = OrigSoundData.channels [i].sample_pointer; + SoundData.channels [i].mode = OrigSoundData.channels [i].mode; + } + + S9xSetSoundMute (FALSE); + IAPU.PC = IAPU.RAM + IAPU.PC; + S9xAPUUnpackStatus (); + if (APUCheckDirectPage ()) + IAPU.DirectPage = IAPU.RAM + 0x100; + else + IAPU.DirectPage = IAPU.RAM; + Settings.APUEnabled = TRUE; + CPU.APU_APUExecuting = TRUE; + } + else + { + Settings.APUEnabled = FALSE; + CPU.APU_APUExecuting = FALSE; + S9xSetSoundMute (TRUE); + } + S9xFixSoundAfterSnapshotLoad (); + ICPU.ShiftedPB = Registers.PB << 16; + ICPU.ShiftedDB = Registers.DB << 16; + S9xSetPCBase (ICPU.ShiftedPB + Registers.PC, &CPU); + S9xUnpackStatus (); + S9xFixCycles (&Registers, &ICPU); + S9xReschedule (); + + return (SUCCESS); +} diff --git a/src/snes4iphone_src/snaporig.h b/src/snes4iphone_src/snaporig.h new file mode 100755 index 0000000..b83a71f --- /dev/null +++ b/src/snes4iphone_src/snaporig.h @@ -0,0 +1,330 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#ifndef _SNAPORIG_H_ +#define _SNAPORIG_H_ + +#define ORIG_SNAPSHOT_MAGIC "#!snes96" +#define ORIG_SNAPSHOT_VERSION 4 + +EXTERN_C bool8_32 S9xLoadOrigSnapshot (const char *filename); + +struct SOrigCPUState{ + uint32 Flags; + short Cycles_old; + short NextEvent_old; + uint8 CurrentFrame; + uint8 FastROMSpeed_old_old; + uint16 V_Counter_old; + bool8_32 BranchSkip; + bool8_32 NMIActive; + bool8_32 IRQActive; + bool8_32 WaitingForInterrupt; + bool8_32 InDMA; + uint8 WhichEvent; + uint8 *PC; + uint8 *PCBase; + uint16 MemSpeed_old; + uint16 MemSpeedx2_old; + uint16 FastROMSpeed_old; + bool8_32 FastDP; + uint8 *PCAtOpcodeStart; + uint8 *WaitAddress; + uint32 WaitCounter; + long Cycles; + long NextEvent; + long V_Counter; + long MemSpeed; + long MemSpeedx2; + long FastROMSpeed; +}; + +struct SOrigAPU +{ + uint32 Cycles; + bool8_32 ShowROM; + uint8 Flags; + uint8 KeyedChannels; + uint8 OutPorts [4]; + uint8 DSP [0x80]; + uint8 ExtraRAM [64]; + uint16 Timer [3]; + uint16 TimerTarget [3]; + bool8_32 TimerEnabled [3]; + bool8_32 TimerValueWritten [3]; +}; + +typedef union +{ +#ifdef LSB_FIRST + struct { uint8 A, Y; } B; +#else + struct { uint8 Y, A; } B; +#endif + uint16 W; +} OrigYAndA; + +struct SOrigAPURegisters{ + uint8 P; + OrigYAndA YA; + uint8 X; + uint8 S; + uint16 PC; +}; + +#define ORIG_MAX_BUFFER_SIZE (1024 * 4) +#define NUM_CHANNELS 8 + +typedef struct { + int state; + int type; + short volume_left; + short volume_right; + int frequency; + int count; + signed short wave [ORIG_MAX_BUFFER_SIZE]; + bool8_32 loop; + int envx; + short left_vol_level; + short right_vol_level; + short envx_target; + unsigned long int env_error; + unsigned long erate; + int direction; + unsigned long attack_rate; + unsigned long decay_rate; + unsigned long sustain_rate; + unsigned long release_rate; + unsigned long sustain_level; + signed short sample; + signed short decoded [16]; + signed short previous [2]; + uint16 sample_number; + bool8_32 last_block; + bool8_32 needs_decode; + uint32 block_pointer; + uint32 sample_pointer; + int *echo_buf_ptr; + int mode; + uint32 dummy [8]; +} OrigChannel; + +typedef struct +{ + short master_volume_left; + short master_volume_right; + short echo_volume_left; + short echo_volume_right; + int echo_enable; + int echo_feedback; + int echo_ptr; + int echo_buffer_size; + int echo_write_enabled; + int echo_channel_enable; + int pitch_mod; + // Just incase they are needed in the future, for snapshot compatibility. + uint32 dummy [3]; + OrigChannel channels [NUM_CHANNELS]; +} SOrigSoundData; + +struct SOrigOBJ +{ + short HPos; + uint16 VPos; + uint16 Name; + uint8 VFlip; + uint8 HFlip; + uint8 Priority; + uint8 Palette; + uint8 Size; + uint8 Prev; + uint8 Next; +}; + +struct SOrigPPU { + uint8 BGMode; + uint8 BG3Priority; + uint8 Brightness; + + struct { + bool8_32 High; + uint8 Increment; + uint16 Address; + uint16 Mask1; + uint16 FullGraphicCount; + uint16 Shift; + } VMA; + + struct { + uint8 TileSize; + uint16 TileAddress; + uint8 Width; + uint8 Height; + uint16 SCBase; + uint16 VOffset; + uint16 HOffset; + bool8_32 ThroughMain; + bool8_32 ThroughSub; + uint8 BGSize; + uint16 NameBase; + uint16 SCSize; + bool8_32 Addition; + } BG [4]; + + bool8_32 CGFLIP; + uint16 CGDATA [256]; + uint8 FirstSprite; + uint8 LastSprite; + struct SOrigOBJ OBJ [129]; + uint8 OAMPriorityRotation; + uint16 OAMAddr; + + uint8 OAMFlip; + uint16 OAMTileAddress; + uint16 IRQVBeamPos; + uint16 IRQHBeamPos; + uint16 VBeamPosLatched; + uint16 HBeamPosLatched; + + uint8 HBeamFlip; + uint8 VBeamFlip; + uint8 HVBeamCounterLatched; + + short MatrixA; + short MatrixB; + short MatrixC; + short MatrixD; + short CentreX; + short CentreY; + uint8 Joypad1ButtonReadPos; + uint8 Joypad2ButtonReadPos; + + uint8 CGADD; + uint8 FixedColourRed; + uint8 FixedColourGreen; + uint8 FixedColourBlue; + uint16 SavedOAMAddr; + uint16 ScreenHeight; + uint32 WRAM; + uint8 BG_Forced; + bool8_32 ForcedBlanking; + bool8_32 OBJThroughMain; + bool8_32 OBJThroughSub; + uint8 OBJSizeSelect; + uint8 OBJNameSelect_old; + uint16 OBJNameBase; + bool8_32 OBJAddition; + uint8 OAMReadFlip; + uint8 OAMData [512 + 32]; + bool8_32 VTimerEnabled; + bool8_32 HTimerEnabled; + short HTimerPosition; + uint8 Mosaic; + bool8_32 BGMosaic [4]; + bool8_32 Mode7HFlip; + bool8_32 Mode7VFlip; + uint8 Mode7Repeat; + uint8 Window1Left; + uint8 Window1Right; + uint8 Window2Left; + uint8 Window2Right; + uint8 ClipCounts [6]; + uint8 ClipLeftEdges [3][6]; + uint8 ClipRightEdges [3][6]; + uint8 ClipWindowOverlapLogic [6]; + uint8 ClipWindow1Enable [6]; + uint8 ClipWindow2Enable [6]; + bool8_32 ClipWindow1Inside [6]; + bool8_32 ClipWindow2Inside [6]; + bool8_32 RecomputeClipWindows; + uint8 CGFLIPRead; + uint16 OBJNameSelect; + bool8_32 Need16x8Mulitply; + uint8 Joypad3ButtonReadPos; + uint8 MouseSpeed[2]; +}; + +struct SOrigDMA { + bool8_32 TransferDirection; + bool8_32 AAddressFixed; + bool8_32 AAddressDecrement; + uint8 TransferMode; + + uint8 ABank; + uint16 AAddress; + uint16 Address; + uint8 BAddress; + + // General DMA only: + uint16 TransferBytes; + + // H-DMA only: + bool8_32 HDMAIndirectAddressing; + uint16 IndirectAddress; + uint8 IndirectBank; + uint8 Repeat; + uint8 LineCount; + uint8 FirstLine; + bool8_32 JustStarted; +}; + +typedef union +{ +#ifdef LSB_FIRST + struct { uint8 l,h; } B; +#else + struct { uint8 h,l; } B; +#endif + uint16 W; +} OrigPair; + +struct SOrigRegisters{ + uint8 PB; + uint8 DB; + OrigPair P; + OrigPair A; + OrigPair D; + OrigPair S; + OrigPair X; + OrigPair Y; + uint16 PC; +}; + +#endif diff --git a/src/snes4iphone_src/snapshot.cpp b/src/snes4iphone_src/snapshot.cpp new file mode 100755 index 0000000..00a4669 --- /dev/null +++ b/src/snes4iphone_src/snapshot.cpp @@ -0,0 +1,929 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ + +#ifndef __GP32__ +#include +#include +#include +#endif +#if defined(__unix) || defined(__linux) || defined(__sun) || defined(__DJGPP) +#include +#include +#include +#endif + +#include "snapshot.h" +//#include "snaporig.h" +#include "memmap.h" +#include "snes9x.h" +#include "65c816.h" +#include "ppu.h" +#include "cpuexec.h" +#include "display.h" +#include "apu.h" +#include "soundux.h" +#ifdef USE_SA1 +#include "sa1.h" +#endif +#include "srtc.h" +#include "sdd1.h" + + +// notaz: file i/o function pointers for states, +// changing funcs will allow to enable/disable gzipped saves +extern int (*statef_open)(const char *fname, const char *mode); +extern int (*statef_read)(void *p, int l); +extern int (*statef_write)(void *p, int l); +extern void (*statef_close)(); + +extern uint8 *SRAM; + +#ifdef ZSNES_FX +START_EXTERN_C +void S9xSuperFXPreSaveState (); +void S9xSuperFXPostSaveState (); +void S9xSuperFXPostLoadState (); +END_EXTERN_C +#endif + +//bool8 S9xUnfreezeZSNES (const char *filename); + +typedef struct { + int offset; + int size; + int type; +} FreezeData; + +enum { + INT_V, uint8_ARRAY_V, uint16_ARRAY_V, uint32_ARRAY_V +}; + +#define Offset(field,structure) \ + ((int) (((char *) (&(((structure)NULL)->field))) - ((char *) NULL))) + +#define COUNT(ARRAY) (sizeof (ARRAY) / sizeof (ARRAY[0])) + +#undef OFFSET +#define OFFSET(f) Offset(f,struct SCPUState *) + +static FreezeData SnapCPU [] = { + {OFFSET (Flags), 4, INT_V}, + {OFFSET (BranchSkip), 1, INT_V}, + {OFFSET (NMIActive), 1, INT_V}, + {OFFSET (IRQActive), 1, INT_V}, + {OFFSET (WaitingForInterrupt), 1, INT_V}, + {OFFSET (WhichEvent), 1, INT_V}, + {OFFSET (Cycles), 4, INT_V}, + {OFFSET (NextEvent), 4, INT_V}, + {OFFSET (V_Counter), 4, INT_V}, + {OFFSET (MemSpeed), 4, INT_V}, + {OFFSET (MemSpeedx2), 4, INT_V}, + {OFFSET (FastROMSpeed), 4, INT_V} +}; + +#undef OFFSET +#define OFFSET(f) Offset(f,struct SRegisters *) + +static FreezeData SnapRegisters [] = { + {OFFSET (PB), 1, INT_V}, + {OFFSET (DB), 1, INT_V}, + {OFFSET (P.W), 2, INT_V}, + {OFFSET (A.W), 2, INT_V}, + {OFFSET (D.W), 2, INT_V}, + {OFFSET (S.W), 2, INT_V}, + {OFFSET (X.W), 2, INT_V}, + {OFFSET (Y.W), 2, INT_V}, + {OFFSET (PC), 2, INT_V} +}; + +#undef OFFSET +#define OFFSET(f) Offset(f,struct SPPU *) + +static FreezeData SnapPPU [] = { + {OFFSET (BGMode), 1, INT_V}, + {OFFSET (BG3Priority), 1, INT_V}, + {OFFSET (Brightness), 1, INT_V}, + {OFFSET (VMA.High), 1, INT_V}, + {OFFSET (VMA.Increment), 1, INT_V}, + {OFFSET (VMA.Address), 2, INT_V}, + {OFFSET (VMA.Mask1), 2, INT_V}, + {OFFSET (VMA.FullGraphicCount), 2, INT_V}, + {OFFSET (VMA.Shift), 2, INT_V}, + {OFFSET (BG[0].SCBase), 2, INT_V}, + {OFFSET (BG[0].VOffset), 2, INT_V}, + {OFFSET (BG[0].HOffset), 2, INT_V}, + {OFFSET (BG[0].BGSize), 1, INT_V}, + {OFFSET (BG[0].NameBase), 2, INT_V}, + {OFFSET (BG[0].SCSize), 2, INT_V}, + + {OFFSET (BG[1].SCBase), 2, INT_V}, + {OFFSET (BG[1].VOffset), 2, INT_V}, + {OFFSET (BG[1].HOffset), 2, INT_V}, + {OFFSET (BG[1].BGSize), 1, INT_V}, + {OFFSET (BG[1].NameBase), 2, INT_V}, + {OFFSET (BG[1].SCSize), 2, INT_V}, + + {OFFSET (BG[2].SCBase), 2, INT_V}, + {OFFSET (BG[2].VOffset), 2, INT_V}, + {OFFSET (BG[2].HOffset), 2, INT_V}, + {OFFSET (BG[2].BGSize), 1, INT_V}, + {OFFSET (BG[2].NameBase), 2, INT_V}, + {OFFSET (BG[2].SCSize), 2, INT_V}, + + {OFFSET (BG[3].SCBase), 2, INT_V}, + {OFFSET (BG[3].VOffset), 2, INT_V}, + {OFFSET (BG[3].HOffset), 2, INT_V}, + {OFFSET (BG[3].BGSize), 1, INT_V}, + {OFFSET (BG[3].NameBase), 2, INT_V}, + {OFFSET (BG[3].SCSize), 2, INT_V}, + + {OFFSET (CGFLIP), 1, INT_V}, + {OFFSET (CGDATA), 256, uint16_ARRAY_V}, + {OFFSET (FirstSprite), 1, INT_V}, +#define O(N) \ + {OFFSET (OBJ[N].HPos), 2, INT_V}, \ + {OFFSET (OBJ[N].VPos), 2, INT_V}, \ + {OFFSET (OBJ[N].Name), 2, INT_V}, \ + {OFFSET (OBJ[N].VFlip), 1, INT_V}, \ + {OFFSET (OBJ[N].HFlip), 1, INT_V}, \ + {OFFSET (OBJ[N].Priority), 1, INT_V}, \ + {OFFSET (OBJ[N].Palette), 1, INT_V}, \ + {OFFSET (OBJ[N].Size), 1, INT_V} + + O( 0), O( 1), O( 2), O( 3), O( 4), O( 5), O( 6), O( 7), + O( 8), O( 9), O( 10), O( 11), O( 12), O( 13), O( 14), O( 15), + O( 16), O( 17), O( 18), O( 19), O( 20), O( 21), O( 22), O( 23), + O( 24), O( 25), O( 26), O( 27), O( 28), O( 29), O( 30), O( 31), + O( 32), O( 33), O( 34), O( 35), O( 36), O( 37), O( 38), O( 39), + O( 40), O( 41), O( 42), O( 43), O( 44), O( 45), O( 46), O( 47), + O( 48), O( 49), O( 50), O( 51), O( 52), O( 53), O( 54), O( 55), + O( 56), O( 57), O( 58), O( 59), O( 60), O( 61), O( 62), O( 63), + O( 64), O( 65), O( 66), O( 67), O( 68), O( 69), O( 70), O( 71), + O( 72), O( 73), O( 74), O( 75), O( 76), O( 77), O( 78), O( 79), + O( 80), O( 81), O( 82), O( 83), O( 84), O( 85), O( 86), O( 87), + O( 88), O( 89), O( 90), O( 91), O( 92), O( 93), O( 94), O( 95), + O( 96), O( 97), O( 98), O( 99), O(100), O(101), O(102), O(103), + O(104), O(105), O(106), O(107), O(108), O(109), O(110), O(111), + O(112), O(113), O(114), O(115), O(116), O(117), O(118), O(119), + O(120), O(121), O(122), O(123), O(124), O(125), O(126), O(127), +#undef O + {OFFSET (OAMPriorityRotation), 1, INT_V}, + {OFFSET (OAMAddr), 2, INT_V}, + {OFFSET (OAMFlip), 1, INT_V}, + {OFFSET (OAMTileAddress), 2, INT_V}, + {OFFSET (IRQVBeamPos), 2, INT_V}, + {OFFSET (IRQHBeamPos), 2, INT_V}, + {OFFSET (VBeamPosLatched), 2, INT_V}, + {OFFSET (HBeamPosLatched), 2, INT_V}, + {OFFSET (HBeamFlip), 1, INT_V}, + {OFFSET (VBeamFlip), 1, INT_V}, + {OFFSET (HVBeamCounterLatched), 1, INT_V}, + {OFFSET (MatrixA), 2, INT_V}, + {OFFSET (MatrixB), 2, INT_V}, + {OFFSET (MatrixC), 2, INT_V}, + {OFFSET (MatrixD), 2, INT_V}, + {OFFSET (CentreX), 2, INT_V}, + {OFFSET (CentreY), 2, INT_V}, + {OFFSET (Joypad1ButtonReadPos), 1, INT_V}, + {OFFSET (Joypad2ButtonReadPos), 1, INT_V}, + {OFFSET (Joypad3ButtonReadPos), 1, INT_V}, + {OFFSET (CGADD), 1, INT_V}, + {OFFSET (FixedColourRed), 1, INT_V}, + {OFFSET (FixedColourGreen), 1, INT_V}, + {OFFSET (FixedColourBlue), 1, INT_V}, + {OFFSET (SavedOAMAddr), 2, INT_V}, + {OFFSET (ScreenHeight), 2, INT_V}, + {OFFSET (WRAM), 4, INT_V}, + {OFFSET (ForcedBlanking), 1, INT_V}, + {OFFSET (OBJNameSelect), 2, INT_V}, + {OFFSET (OBJSizeSelect), 1, INT_V}, + {OFFSET (OBJNameBase), 2, INT_V}, + {OFFSET (OAMReadFlip), 1, INT_V}, + {OFFSET (VTimerEnabled), 1, INT_V}, + {OFFSET (HTimerEnabled), 1, INT_V}, + {OFFSET (HTimerPosition), 2, INT_V}, + {OFFSET (Mosaic), 1, INT_V}, + {OFFSET (Mode7HFlip), 1, INT_V}, + {OFFSET (Mode7VFlip), 1, INT_V}, + {OFFSET (Mode7Repeat), 1, INT_V}, + {OFFSET (Window1Left), 1, INT_V}, + {OFFSET (Window1Right), 1, INT_V}, + {OFFSET (Window2Left), 1, INT_V}, + {OFFSET (Window2Right), 1, INT_V}, +#define O(N) \ + {OFFSET (ClipWindowOverlapLogic[N]), 1, INT_V}, \ + {OFFSET (ClipWindow1Enable[N]), 1, INT_V}, \ + {OFFSET (ClipWindow2Enable[N]), 1, INT_V}, \ + {OFFSET (ClipWindow1Inside[N]), 1, INT_V}, \ + {OFFSET (ClipWindow2Inside[N]), 1, INT_V} + + O(0), O(1), O(2), O(3), O(4), O(5), + +#undef O + + {OFFSET (CGFLIPRead), 1, INT_V}, + {OFFSET (Need16x8Mulitply), 1, INT_V}, + {OFFSET (BGMosaic), 4, uint8_ARRAY_V}, + {OFFSET (OAMData), 512 + 32, uint8_ARRAY_V}, + {OFFSET (Need16x8Mulitply), 1, INT_V}, + {OFFSET (MouseSpeed), 2, uint8_ARRAY_V} +}; + +#undef OFFSET +#define OFFSET(f) Offset(f,struct SDMA *) + +static FreezeData SnapDMA [] = { +#define O(N) \ + {OFFSET (TransferDirection) + N * sizeof (struct SDMA), 1, INT_V}, \ + {OFFSET (AAddressFixed) + N * sizeof (struct SDMA), 1, INT_V}, \ + {OFFSET (AAddressDecrement) + N * sizeof (struct SDMA), 1, INT_V}, \ + {OFFSET (TransferMode) + N * sizeof (struct SDMA), 1, INT_V}, \ + {OFFSET (ABank) + N * sizeof (struct SDMA), 1, INT_V}, \ + {OFFSET (AAddress) + N * sizeof (struct SDMA), 2, INT_V}, \ + {OFFSET (Address) + N * sizeof (struct SDMA), 2, INT_V}, \ + {OFFSET (BAddress) + N * sizeof (struct SDMA), 1, INT_V}, \ + {OFFSET (TransferBytes) + N * sizeof (struct SDMA), 2, INT_V}, \ + {OFFSET (HDMAIndirectAddressing) + N * sizeof (struct SDMA), 1, INT_V}, \ + {OFFSET (IndirectAddress) + N * sizeof (struct SDMA), 2, INT_V}, \ + {OFFSET (IndirectBank) + N * sizeof (struct SDMA), 1, INT_V}, \ + {OFFSET (Repeat) + N * sizeof (struct SDMA), 1, INT_V}, \ + {OFFSET (LineCount) + N * sizeof (struct SDMA), 1, INT_V}, \ + {OFFSET (FirstLine) + N * sizeof (struct SDMA), 1, INT_V} + + O(0), O(1), O(2), O(3), O(4), O(5), O(6), O(7) +#undef O +}; + +#undef OFFSET +#define OFFSET(f) Offset(f,struct SAPU *) + +static FreezeData SnapAPU [] = { + {OFFSET (Cycles), 4, INT_V}, + {OFFSET (ShowROM), 1, INT_V}, + {OFFSET (Flags), 1, INT_V}, + {OFFSET (KeyedChannels), 1, INT_V}, + {OFFSET (OutPorts), 4, uint8_ARRAY_V}, + {OFFSET (DSP), 0x80, uint8_ARRAY_V}, + {OFFSET (ExtraRAM), 64, uint8_ARRAY_V}, + {OFFSET (Timer), 3, uint16_ARRAY_V}, + {OFFSET (TimerTarget), 3, uint16_ARRAY_V}, + {OFFSET (TimerEnabled), 3, uint8_ARRAY_V}, + {OFFSET (TimerValueWritten), 3, uint8_ARRAY_V} +}; + +#undef OFFSET +#define OFFSET(f) Offset(f,struct SAPURegisters *) + +static FreezeData SnapAPURegisters [] = { + {OFFSET (P) , 1, INT_V}, + {OFFSET (YA.W), 2, INT_V}, + {OFFSET (X) , 1, INT_V}, + {OFFSET (S) , 1, INT_V}, + {OFFSET (PC) , 2, INT_V} +}; + +#undef OFFSET +#undef OFFSET1 +#define OFFSET(f) Offset(f,SSoundData *) + +static FreezeData SnapSoundData [] = { + {OFFSET (master_volume_left), 2, INT_V}, + {OFFSET (master_volume_right), 2, INT_V}, + {OFFSET (echo_volume_left), 2, INT_V}, + {OFFSET (echo_volume_right), 2, INT_V}, + {OFFSET (echo_enable), 4, INT_V}, + {OFFSET (echo_feedback), 4, INT_V}, + {OFFSET (echo_ptr), 4, INT_V}, + {OFFSET (echo_buffer_size), 4, INT_V}, + {OFFSET (echo_write_enabled), 4, INT_V}, + {OFFSET (echo_channel_enable), 4, INT_V}, + {OFFSET (pitch_mod), 4, INT_V}, + {OFFSET (dummy), 3, uint32_ARRAY_V}, +#define O(N) \ + {OFFSET (channels [N].state), 4, INT_V}, \ + {OFFSET (channels [N].type), 4, INT_V}, \ + {OFFSET (channels [N].volume_left), 2, INT_V}, \ + {OFFSET (channels [N].volume_right), 2, INT_V}, \ + {OFFSET (channels [N].hertz), 4, INT_V}, \ + {OFFSET (channels [N].count), 4, INT_V}, \ + {OFFSET (channels [N].loop), 1, INT_V}, \ + {OFFSET (channels [N].envx), 4, INT_V}, \ + {OFFSET (channels [N].left_vol_level), 2, INT_V}, \ + {OFFSET (channels [N].right_vol_level), 2, INT_V}, \ + {OFFSET (channels [N].envx_target), 2, INT_V}, \ + {OFFSET (channels [N].env_error), 4, INT_V}, \ + {OFFSET (channels [N].erate), 4, INT_V}, \ + {OFFSET (channels [N].direction), 4, INT_V}, \ + {OFFSET (channels [N].attack_rate), 4, INT_V}, \ + {OFFSET (channels [N].decay_rate), 4, INT_V}, \ + {OFFSET (channels [N].sustain_rate), 4, INT_V}, \ + {OFFSET (channels [N].release_rate), 4, INT_V}, \ + {OFFSET (channels [N].sustain_level), 4, INT_V}, \ + {OFFSET (channels [N].sample), 2, INT_V}, \ + {OFFSET (channels [N].decoded), 16, uint16_ARRAY_V}, \ + {OFFSET (channels [N].previous16), 2, uint16_ARRAY_V}, \ + {OFFSET (channels [N].sample_number), 2, INT_V}, \ + {OFFSET (channels [N].last_block), 1, INT_V}, \ + {OFFSET (channels [N].needs_decode), 1, INT_V}, \ + {OFFSET (channels [N].block_pointer), 4, INT_V}, \ + {OFFSET (channels [N].sample_pointer), 4, INT_V}, \ + {OFFSET (channels [N].mode), 4, INT_V} + + O(0), O(1), O(2), O(3), O(4), O(5), O(6), O(7) +#undef O +}; + +#ifdef USE_SA1 + +#undef OFFSET +#define OFFSET(f) Offset(f,struct SSA1Registers *) + +static FreezeData SnapSA1Registers [] = { + {OFFSET (PB), 1, INT_V}, + {OFFSET (DB), 1, INT_V}, + {OFFSET (P.W), 2, INT_V}, + {OFFSET (A.W), 2, INT_V}, + {OFFSET (D.W), 2, INT_V}, + {OFFSET (S.W), 2, INT_V}, + {OFFSET (X.W), 2, INT_V}, + {OFFSET (Y.W), 2, INT_V}, + {OFFSET (PC), 2, INT_V} +}; + +#undef OFFSET +#define OFFSET(f) Offset(f,struct SSA1 *) + +static FreezeData SnapSA1 [] = { + {OFFSET (Flags), 4, INT_V}, + {OFFSET (NMIActive), 1, INT_V}, + {OFFSET (IRQActive), 1, INT_V}, + {OFFSET (WaitingForInterrupt), 1, INT_V}, + {OFFSET (op1), 2, INT_V}, + {OFFSET (op2), 2, INT_V}, + {OFFSET (arithmetic_op), 4, INT_V}, + {OFFSET (sum), 8, INT_V}, + {OFFSET (overflow), 1, INT_V} +}; +#endif + +//static char ROMFilename [_MAX_PATH]; +//static char SnapshotFilename [_MAX_PATH]; + +static void Freeze (); +static int Unfreeze (); +void FreezeStruct (char *name, void *base, FreezeData *fields, + int num_fields); +void FreezeBlock (char *name, uint8 *block, int size); + +int UnfreezeStruct (char *name, void *base, FreezeData *fields, + int num_fields); +int UnfreezeBlock (char *name, uint8 *block, int size); + +bool8 Snapshot (const char *filename) +{ + return (S9xFreezeGame (filename)); +} + +bool8 S9xFreezeGame (const char *filename) +{ + if(statef_open(filename, "wb")) + { + Freeze(); + statef_close(); + return (TRUE); + } + return (FALSE); +} + + +bool8 S9xUnfreezeGame (const char *filename) +{ + if(statef_open(filename, "rb")) + { + int result; + if ((result = Unfreeze()) != SUCCESS) + { + switch (result) + { + case WRONG_FORMAT: + S9xMessage (S9X_ERROR, S9X_WRONG_FORMAT, + "File not in Snes9x freeze format"); + S9xReset(); + break; + case WRONG_VERSION: + S9xMessage (S9X_ERROR, S9X_WRONG_VERSION, + "Incompatable Snes9x freeze file format version"); + S9xReset(); + break; + default: + // should never happen + break; + } + statef_close(); + return (FALSE); + } + statef_close(); + return (TRUE); + } + + + return (FALSE); +} + +static void Freeze () +{ + char buffer[1024]; + int i; + + S9xSetSoundMute (TRUE); +#ifdef ZSNES_FX + if (Settings.SuperFX) + S9xSuperFXPreSaveState (); +#endif + + S9xSRTCPreSaveState (); + + for (i = 0; i < 8; i++) + { + SoundData.channels [i].previous16 [0] = (int16) SoundData.channels [i].previous [0]; + SoundData.channels [i].previous16 [1] = (int16) SoundData.channels [i].previous [1]; + } + sprintf (buffer, "%s:%04d\n", SNAPSHOT_MAGIC, SNAPSHOT_VERSION); + statef_write(buffer, strlen (buffer)); + sprintf (buffer, "NAM:%06d:%s%c", strlen (Memory.ROMFilename) + 1, + Memory.ROMFilename, 0); + statef_write(buffer, strlen (buffer) + 1); + FreezeStruct ("CPU", &CPU, SnapCPU, COUNT (SnapCPU)); + FreezeStruct ("REG", &Registers, SnapRegisters, COUNT (SnapRegisters)); + FreezeStruct ("PPU", &PPU, SnapPPU, COUNT (SnapPPU)); + FreezeStruct ("DMA", DMA, SnapDMA, COUNT (SnapDMA)); + +// RAM and VRAM + FreezeBlock ("VRA", Memory.VRAM, 0x10000); + FreezeBlock ("RAM", Memory.RAM, 0x20000); + FreezeBlock ("SRA", ::SRAM, 0x20000); + FreezeBlock ("FIL", Memory.FillRAM, 0x8000); + if (Settings.APUEnabled) + { +// APU + FreezeStruct ("APU", &APU, SnapAPU, COUNT (SnapAPU)); + // copy all SPC700 regs to savestate compatible struct + SAPURegisters spcregs; + spcregs.P = IAPU.P; + spcregs.YA.W = IAPU.YA.W; + spcregs.X = IAPU.X; + spcregs.S = IAPU.S; + spcregs.PC = IAPU.PC - IAPU.RAM; + FreezeStruct ("ARE", &spcregs, SnapAPURegisters, + COUNT (SnapAPURegisters)); + + FreezeBlock ("ARA", IAPU.RAM, 0x10000); + FreezeStruct ("SOU", &SoundData, SnapSoundData, + COUNT (SnapSoundData)); + } +#ifdef USE_SA1 + if (Settings.SA1) + { + SA1Registers.PC = SA1.PC - SA1.PCBase; + S9xSA1PackStatus (); + FreezeStruct ("SA1", &SA1, SnapSA1, COUNT (SnapSA1)); + FreezeStruct ("SAR", &SA1Registers, SnapSA1Registers, + COUNT (SnapSA1Registers)); + } +#endif + S9xSetSoundMute (FALSE); +#ifdef ZSNES_FX + if (Settings.SuperFX) + S9xSuperFXPostSaveState (); +#endif +} + +static int Unfreeze() +{ + // notaz: overflowing the damn Symbian stack again + char buffer [16]; + char rom_filename [512]; + int result; + + int version; + unsigned int len = strlen (SNAPSHOT_MAGIC) + 1 + 4 + 1; + if (statef_read(buffer, len) != (int)len) + { + return (WRONG_FORMAT); + } + if (strncmp (buffer, SNAPSHOT_MAGIC, strlen (SNAPSHOT_MAGIC)) != 0) + { + return (WRONG_FORMAT); + } + if ((version = atoi (&buffer [strlen (SNAPSHOT_MAGIC) + 1])) > SNAPSHOT_VERSION) + return (WRONG_VERSION); + + if ((result = UnfreezeBlock("NAM", (uint8 *) rom_filename, 512)) != SUCCESS) + return (result); + + if (strcasecmp (rom_filename, Memory.ROMFilename) != 0 && + strcasecmp (S9xBasename (rom_filename), S9xBasename (Memory.ROMFilename)) != 0) + { + S9xMessage (S9X_WARNING, S9X_FREEZE_ROM_NAME, + "Current loaded ROM image doesn't match that required by freeze-game file."); + } + + + + uint32 old_flags = CPU.Flags; +#ifdef USE_SA1 + uint32 sa1_old_flags = SA1.Flags; +#endif + S9xReset (); + S9xSetSoundMute (TRUE); + + if ((result = UnfreezeStruct("CPU", &CPU, SnapCPU, + COUNT (SnapCPU))) != SUCCESS) + return (result); + + + Memory.FixROMSpeed (); + CPU.Flags |= old_flags & (DEBUG_MODE_FLAG | TRACE_FLAG | + SINGLE_STEP_FLAG | FRAME_ADVANCE_FLAG); + if ((result = UnfreezeStruct("REG", &Registers, SnapRegisters, COUNT (SnapRegisters))) != SUCCESS) + return (result); + if ((result = UnfreezeStruct("PPU", &PPU, SnapPPU, COUNT (SnapPPU))) != SUCCESS) + return (result); + + + IPPU.ColorsChanged = TRUE; + IPPU.OBJChanged = TRUE; + CPU.InDMA = FALSE; + S9xFixColourBrightness (); + IPPU.RenderThisFrame = FALSE; + + if ((result = UnfreezeStruct ("DMA", DMA, SnapDMA, + COUNT (SnapDMA))) != SUCCESS) + return (result); + + if ((result = UnfreezeBlock ("VRA", Memory.VRAM, 0x10000)) != SUCCESS) + return (result); + + if ((result = UnfreezeBlock ("RAM", Memory.RAM, 0x20000)) != SUCCESS) + return (result); + + if ((result = UnfreezeBlock ("SRA", ::SRAM, 0x20000)) != SUCCESS) + return (result); + + if ((result = UnfreezeBlock ("FIL", Memory.FillRAM, 0x8000)) != SUCCESS) + return (result); + + + if (UnfreezeStruct ("APU", &APU, SnapAPU, COUNT (SnapAPU)) == SUCCESS) + { + SAPURegisters spcregs; + if ((result = UnfreezeStruct ("ARE", &spcregs, SnapAPURegisters, + COUNT (SnapAPURegisters))) != SUCCESS) + return (result); + // reload all SPC700 regs from savestate compatible struct + IAPU.P = spcregs.P; + IAPU.YA.W = spcregs.YA.W; + IAPU.X = spcregs.X; + IAPU.S = spcregs.S; + IAPU.PC = IAPU.RAM + spcregs.PC; + + if ((result = UnfreezeBlock ("ARA", IAPU.RAM, 0x10000)) != SUCCESS) + return (result); + + if ((result = UnfreezeStruct ("SOU", &SoundData, SnapSoundData, + COUNT (SnapSoundData))) != SUCCESS) + return (result); + + // notaz: just to be sure + for(int u=0; u<8; u++) { + SoundData.channels[u].env_ind_attack &= 0xf; + SoundData.channels[u].env_ind_decay &= 0x7; + SoundData.channels[u].env_ind_sustain&= 0x1f; + } + + S9xSetSoundMute (FALSE); + S9xAPUUnpackStatus (); + if (APUCheckDirectPage ()) + IAPU.DirectPage = IAPU.RAM + 0x100; + else + IAPU.DirectPage = IAPU.RAM; + Settings.APUEnabled = TRUE; + /*IAPU.APUExecuting*/CPU.APU_APUExecuting = TRUE; + } + else + { + Settings.APUEnabled = FALSE; + /*IAPU.APUExecuting*/CPU.APU_APUExecuting = FALSE; + S9xSetSoundMute (TRUE); + } +#ifdef USE_SA1 + if ((result = UnfreezeStruct ("SA1", &SA1, SnapSA1, + COUNT(SnapSA1))) == SUCCESS) + { + if ((result = UnfreezeStruct ("SAR", &SA1Registers, + SnapSA1Registers, COUNT (SnapSA1Registers))) != SUCCESS) + return (result); + + S9xFixSA1AfterSnapshotLoad (); + SA1.Flags |= sa1_old_flags & (TRACE_FLAG); + } +#endif + S9xFixSoundAfterSnapshotLoad (); + ICPU.ShiftedPB = Registers.PB << 16; + ICPU.ShiftedDB = Registers.DB << 16; + S9xSetPCBase (ICPU.ShiftedPB + Registers.PC); + + + //S9xUnpackStatus (); // not needed + //S9xFixCycles (); // also not needed? + S9xReschedule (); +#ifdef ZSNES_FX + if (Settings.SuperFX) + S9xSuperFXPostLoadState (); +#endif + + S9xSRTCPostLoadState (); + if (Settings.SDD1) S9xSDD1PostLoadState (); + + return (SUCCESS); +} + +int FreezeSize (int size, int type) +{ + switch (type) + { + case uint16_ARRAY_V: + return (size * 2); + case uint32_ARRAY_V: + return (size * 4); + default: + return (size); + } +} + +void FreezeStruct(char *name, void *base, FreezeData *fields, + int num_fields) +{ + // Work out the size of the required block + int len = 0; + int i; + int j; + + for (i = 0; i < num_fields; i++) + { + if (fields [i].offset + FreezeSize (fields [i].size, + fields [i].type) > len) + len = fields [i].offset + FreezeSize (fields [i].size, + fields [i].type); + } + +// uint8 *block = new uint8 [len]; + uint8 *block = (uint8*)malloc(len); + uint8 *ptr = block; + uint16 word; + uint32 dword; + int64 qword; + + // Build the block ready to be streamed out + for (i = 0; i < num_fields; i++) + { + switch (fields [i].type) + { + case INT_V: + switch (fields [i].size) + { + case 1: + *ptr++ = *((uint8 *) base + fields [i].offset); + break; + case 2: + word = *((uint16 *) ((uint8 *) base + fields [i].offset)); + *ptr++ = (uint8) (word >> 8); + *ptr++ = (uint8) word; + break; + case 4: + dword = *((uint32 *) ((uint8 *) base + fields [i].offset)); + *ptr++ = (uint8) (dword >> 24); + *ptr++ = (uint8) (dword >> 16); + *ptr++ = (uint8) (dword >> 8); + *ptr++ = (uint8) dword; + break; + case 8: + qword = *((int64 *) ((uint8 *) base + fields [i].offset)); + *ptr++ = (uint8) (qword >> 56); + *ptr++ = (uint8) (qword >> 48); + *ptr++ = (uint8) (qword >> 40); + *ptr++ = (uint8) (qword >> 32); + *ptr++ = (uint8) (qword >> 24); + *ptr++ = (uint8) (qword >> 16); + *ptr++ = (uint8) (qword >> 8); + *ptr++ = (uint8) qword; + break; + } + break; + case uint8_ARRAY_V: + memmove (ptr, (uint8 *) base + fields [i].offset, fields [i].size); + ptr += fields [i].size; + break; + case uint16_ARRAY_V: + for (j = 0; j < fields [i].size; j++) + { + word = *((uint16 *) ((uint8 *) base + fields [i].offset + j * 2)); + *ptr++ = (uint8) (word >> 8); + *ptr++ = (uint8) word; + } + break; + case uint32_ARRAY_V: + for (j = 0; j < fields [i].size; j++) + { + dword = *((uint32 *) ((uint8 *) base + fields [i].offset + j * 4)); + *ptr++ = (uint8) (dword >> 24); + *ptr++ = (uint8) (dword >> 16); + *ptr++ = (uint8) (dword >> 8); + *ptr++ = (uint8) dword; + } + break; + } + } + + FreezeBlock (name, block, len); + + free(block); +} + +void FreezeBlock (char *name, uint8 *block, int size) +{ + char buffer [512]; + sprintf (buffer, "%s:%06d:", name, size); + statef_write(buffer, strlen (buffer)); + statef_write(block, size); + +} + +int UnfreezeStruct (char *name, void *base, FreezeData *fields, + int num_fields) +{ + // Work out the size of the required block + int len = 0; + int i; + int j; + + for (i = 0; i < num_fields; i++) + { + if (fields [i].offset + FreezeSize (fields [i].size, + fields [i].type) > len) + len = fields [i].offset + FreezeSize (fields [i].size, + fields [i].type); + } + + uint8 *block = (uint8*)malloc(len); + uint8 *ptr = block; + uint16 word; + uint32 dword; + int64 qword; + int result; + + if ((result = UnfreezeBlock (name, block, len)) != SUCCESS) + { + free(block); + return (result); + } + + // Unpack the block of data into a C structure + for (i = 0; i < num_fields; i++) + { + switch (fields [i].type) + { + case INT_V: + switch (fields [i].size) + { + case 1: + *((uint8 *) base + fields [i].offset) = *ptr++; + break; + case 2: + word = *ptr++ << 8; + word |= *ptr++; + *((uint16 *) ((uint8 *) base + fields [i].offset)) = word; + break; + case 4: + dword = *ptr++ << 24; + dword |= *ptr++ << 16; + dword |= *ptr++ << 8; + dword |= *ptr++; + *((uint32 *) ((uint8 *) base + fields [i].offset)) = dword; + break; + case 8: + qword = (int64) *ptr++ << 56; + qword |= (int64) *ptr++ << 48; + qword |= (int64) *ptr++ << 40; + qword |= (int64) *ptr++ << 32; + qword |= (int64) *ptr++ << 24; + qword |= (int64) *ptr++ << 16; + qword |= (int64) *ptr++ << 8; + qword |= (int64) *ptr++; + *((int64 *) ((uint8 *) base + fields [i].offset)) = qword; + break; + } + break; + case uint8_ARRAY_V: + memmove ((uint8 *) base + fields [i].offset, ptr, fields [i].size); + ptr += fields [i].size; + break; + case uint16_ARRAY_V: + for (j = 0; j < fields [i].size; j++) + { + word = *ptr++ << 8; + word |= *ptr++; + *((uint16 *) ((uint8 *) base + fields [i].offset + j * 2)) = word; + } + break; + case uint32_ARRAY_V: + for (j = 0; j < fields [i].size; j++) + { + dword = *ptr++ << 24; + dword |= *ptr++ << 16; + dword |= *ptr++ << 8; + dword |= *ptr++; + *((uint32 *) ((uint8 *) base + fields [i].offset + j * 4)) = dword; + } + break; + } + } + +// delete block; + free(block); + return (result); +} + +int UnfreezeBlock(char *name, uint8 *block, int size) +{ + char buffer [20]; + int len = 0; + int rem = 0; + + if (statef_read(buffer, 11) != 11 || + strncmp (buffer, name, 3) != 0 || buffer [3] != ':' || + (len = atoi (&buffer [4])) == 0) + { + return (WRONG_FORMAT); + } + + if (len > size) + { + rem = len - size; + len = size; + } + + if (statef_read(block, len) != len) + { + return (WRONG_FORMAT); + } + + if (rem) + { + char *junk = (char*)malloc(rem); + statef_read(junk, rem); + free(junk); + } + + return (SUCCESS); +} + + diff --git a/src/snes4iphone_src/snapshot.h b/src/snes4iphone_src/snapshot.h new file mode 100755 index 0000000..fb23a42 --- /dev/null +++ b/src/snes4iphone_src/snapshot.h @@ -0,0 +1,63 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#ifndef _SNAPSHOT_H_ +#define _SNAPSHOT_H_ + +#include +#include "snes9x.h" + +#define SNAPSHOT_MAGIC "#!snes9x" +#define SNAPSHOT_VERSION 1 + +#define SUCCESS 1 +#define WRONG_FORMAT (-1) +#define WRONG_VERSION (-2) +#define FILE_NOT_FOUND (-3) + +START_EXTERN_C +bool8 S9xFreezeGame (const char *filename); +bool8 S9xUnfreezeGame (const char *filename); +bool8 Snapshot (const char *filename); +bool8 S9xLoadSnapshot (const char *filename); +bool8 S9xSPCDump (const char *filename); +END_EXTERN_C + +#endif diff --git a/src/snes4iphone_src/snes9x.cpp b/src/snes4iphone_src/snes9x.cpp new file mode 100755 index 0000000..36e3f44 --- /dev/null +++ b/src/snes4iphone_src/snes9x.cpp @@ -0,0 +1,655 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#include +#include + +#include "snes9x.h" +#include "memmap.h" +#include "display.h" +#include "cheats.h" + +#ifdef DEBUGGER +extern FILE *trace; +#endif + +void S9xUsage () +{ + S9xMessage (S9X_INFO, S9X_USAGE, "snes9x: S9xUsage: snes9x \n\n"); + S9xMessage (S9X_INFO, S9X_USAGE, "Where can be:\n"); + + S9xMessage (S9X_INFO, S9X_USAGE, "\ +-cycles or -h Percentage of CPU cycles to execute every scan line (default 90)\n"); + S9xMessage (S9X_INFO, S9X_USAGE, "\ +-frameskip or -f Screen update frame skip rate (default 2)\n"); + S9xExtraUsage (); + S9xMessage (S9X_INFO, S9X_USAGE, "\ +-forcehirom or -F or -FH Force Hi-ROM memory map, useful for hacked ROM imagess.\n"); + S9xMessage (S9X_INFO, S9X_USAGE, "\ +-forcelorom or -FL Force Lo-ROM memory map, useful for hacked ROM images.\n"); + S9xMessage (S9X_INFO, S9X_USAGE, "\ +-old or -o Enable old-style SNES joypad emulation\n"); + S9xMessage (S9X_INFO, S9X_USAGE, "\ +-noold or -no Disbale old-style SNES joypad emulation\n"); + S9xMessage (S9X_INFO, S9X_USAGE, "\ +-soundskip or -ss Sound CPU skip-waiting method, 0 - 3 (default 0)\n"); + S9xMessage (S9X_INFO, S9X_USAGE, "\ +-sound or -S Enable digital sound output (default: enabled)\n"); + S9xMessage (S9X_INFO, S9X_USAGE, "\ +-nosound or -NS Disable digital sound output\n"); + S9xMessage (S9X_INFO, S9X_USAGE, "\ +-sound or -S Enable digital sound output (default: off)\n"); + S9xMessage (S9X_INFO, S9X_USAGE, "\ +-soundquality or -r Sound sample playback rate/quality, 0-7 (default 4)\n"); + +#ifdef __sgi +/* BS: changed the sample rate values to match the IRIX options */ + S9xMessage (S9X_INFO, S9X_USAGE, "\ + 0 - off, 1 - 8192, 2 - 11025, 3 - 16000,\n\ + 4 - 22050 (default), 5 - 32000, 6 - 44100,\n\ + 7 - 48000\n"); +#else + S9xMessage (S9X_INFO, S9X_USAGE, "\ + 0 - off, 1 - 8192, 2 - 11025, 3 - 16500,\n\ + 4 - 22050 (default), 5 - 29300, 6 - 36600,\n\ + 7 - 44000\n"); +#endif + + S9xMessage (S9X_INFO, S9X_USAGE, "\ +-stereo Enable stereo sound (default: mono sound)\n"); + S9xMessage (S9X_INFO, S9X_USAGE, "\ +-mono Enable mono sound (default: mono sound)\n"); + S9xMessage (S9X_INFO, S9X_USAGE, "\ +-buffersize or -B Sound playback buffer size (default auto for playback rate)\n"); + S9xMessage (S9X_INFO, S9X_USAGE, "\ +-nospeedhacks or -N Disable some internal speed ups that break a few ROMs\n"); + S9xMessage (S9X_INFO, S9X_USAGE, "\ +-speedhacks or -SH Enable some internal speed ups that break a few ROMs\n"); + S9xMessage (S9X_INFO, S9X_USAGE, "\ +-loadsnapshot or -l \n\ + Load saved game position snapshot file & required ROM\n\ + image.\n"); + S9xMessage (S9X_INFO, S9X_USAGE, "\ +-swapjoypads or -s Swap joypad 1 and 2 around\n"); + S9xMessage (S9X_INFO, S9X_USAGE, "\ +-pal or -p Fool ROM into thinking that this is a PAL SNES system\n"); + S9xMessage (S9X_INFO, S9X_USAGE, "\ +-ntsc or -n Fool ROM into thinking that this is a NTCS SNES system\n"); + S9xMessage (S9X_INFO, S9X_USAGE, "\ +-interleaved or -i ROM image is in interleaved format.\n"); + S9xMessage (S9X_INFO, S9X_USAGE, "\ +-interleaved2 or -i2 ROM image is in interleaved 2 format\n"); + S9xMessage (S9X_INFO, S9X_USAGE, "\ +-nohdma or -H Disable H-DMA emulation (default: enabled)\n"); + S9xMessage (S9X_INFO, S9X_USAGE, "\ +-hdma or -NH Enable H-DMA emulation (default: enabled)\n"); + S9xMessage (S9X_INFO, S9X_USAGE, "\ +-layering or -L Swap some background priority levels - helps some games\n"); + S9xMessage (S9X_INFO, S9X_USAGE, "\ +-graphicwindows Enable graphic window effects (default: enabled)\n"); + S9xMessage (S9X_INFO, S9X_USAGE, "\ +-nographicwindows or -nw Disable graphic window effects (default: enabled)\n"); +#ifdef DEBUGGER + S9xMessage (S9X_INFO, S9X_USAGE, "\ +-noirq or -I Disable processor IRQ (for debugging)\n"); + S9xMessage (S9X_INFO, S9X_USAGE, "\ +-debug or -d Enter debug mode once ROM has loaded\n"); + S9xMessage (S9X_INFO, S9X_USAGE, "\ +-trace or -t Trace CPU instructions to file (WARNING: file gets very large!)\n"); +#endif + +#ifdef JOYSTICK_SUPPORT +#ifdef __linux + S9xMessage (S9X_INFO, S9X_USAGE, "\ +-joydevX /dev/jsY Use joystick device /dev/jsY for emulation of gamepad X\n"); + S9xMessage (S9X_INFO, S9X_USAGE, "\ +-joymapX 0 1 2 3 4 5 6 7 Joystick buttons which should be assigned to gamepad X - A B X Y TL TR Start and Select\n"); +#else + S9xMessage (S9X_INFO, S9X_USAGE, "\ +-four or -4 Single standard PC joystick has four buttons\n"); + S9xMessage (S9X_INFO, S9X_USAGE, "\ +-six or -6 Single standard PC joystick has six buttons\n"); +#endif + S9xMessage (S9X_INFO, S9X_USAGE, "\ +-nojoy or -j Disable joystick support\n"); +#endif + + S9xMessage (S9X_INFO, S9X_USAGE, "\ +\nROM image needs to be in Super MagiCom (*.smc), Super FamiCom (*.sfc),\n\ +*.fig, or split (*.1, *.2, or sf32527a, sf32527b, etc) format and can be\n\ +compressed with gzip or compress.\n"); + + exit (1); +} + +#ifdef STORM +extern int dofps; +extern int hicolor; +extern int secondjoy; +extern int minimal; +int prelude=0; +extern int unit; +#endif + +char *S9xParseArgs (char **argv, int argc) +{ + char *rom_filename = NULL; + + for (int i = 1; i < argc; i++) + { + if (*argv[i] == '-') + { + if (strcasecmp (argv [i], "-so") == 0 || + strcasecmp (argv [i], "-sound") == 0) + { + Settings.NextAPUEnabled = TRUE; + } + else if (strcasecmp (argv [i], "-ns") == 0 || + strcasecmp (argv [i], "-nosound") == 0) + { + Settings.NextAPUEnabled = FALSE; + } + else if (strcasecmp (argv [i], "-soundskip") == 0 || + strcasecmp (argv [i], "-sk") == 0) + { + if (i + 1 < argc) + Settings.SoundSkipMethod = atoi (argv [++i]); + else + S9xUsage (); + } + else if (strcasecmp (argv [i], "-ra") == 0 || + strcasecmp (argv [i], "-ratio") == 0) + { + if (i + 1 < argc) + { + } + else + S9xUsage (); + } + else if (strcasecmp (argv [i], "-h") == 0 || + strcasecmp (argv [i], "-cycles") == 0) + { + if (i + 1 < argc) + { + int p = atoi (argv [++i]); + if (p > 0 && p < 200) + Settings.CyclesPercentage = p; + } + else + S9xUsage (); + } + else if (strcasecmp (argv [i], "-nh") == 0 || + strcasecmp (argv [i], "-nohdma") == 0) + { + Settings.DisableHDMA = TRUE; + } + else if (strcasecmp (argv [i], "-ha") == 0 || + strcasecmp (argv [i], "-hdma") == 0) + { + Settings.DisableHDMA = FALSE; + } + else if (strcasecmp (argv [i], "-n") == 0 || + strcasecmp (argv [i], "-nospeedhacks") == 0) + { + Settings.ShutdownMaster = FALSE; + } + else if (strcasecmp (argv [i], "-sh") == 0 || + strcasecmp (argv [i], "-speedhacks") == 0) + { + Settings.ShutdownMaster = TRUE; + } + else if (strcasecmp (argv [i], "-p") == 0 || + strcasecmp (argv [i], "-pal") == 0) + { + Settings.ForcePAL = TRUE; + } + else if (strcasecmp (argv [i], "-n") == 0 || + strcasecmp (argv [i], "-ntsc") == 0) + { + Settings.ForceNTSC = TRUE; + } + else if (strcasecmp (argv [i], "-f") == 0 || + strcasecmp (argv [i], "-frameskip") == 0) + { + if (i + 1 < argc) + Settings.SkipFrames = atoi (argv [++i]) + 1; + else + S9xUsage (); + } + else if (strcasecmp (argv [i], "-fh") == 0 || + strcasecmp (argv [i], "-hr") == 0 || + strcasecmp (argv [i], "-hirom") == 0) + Settings.ForceHiROM = TRUE; + else if (strcasecmp (argv [i], "-fl") == 0 || + strcasecmp (argv [i], "-lr") == 0 || + strcasecmp (argv [i], "-lorom") == 0) + Settings.ForceLoROM = TRUE; + else if (strcasecmp (argv [i], "-hd") == 0 || + strcasecmp (argv [i], "-header") == 0 || + strcasecmp (argv [i], "-he") == 0) + { + Settings.ForceHeader = TRUE; + } + else if (strcasecmp (argv [i], "-nhd") == 0 || + strcasecmp (argv [i], "-noheader") == 0) + { + Settings.ForceNoHeader = TRUE; + } + else if (strcasecmp (argv [i], "-bs") == 0) + { + Settings.BS = TRUE; + } +#ifdef DEBUGGER + else if (strcasecmp (argv [i], "-d") == 0 || + strcasecmp (argv [i], "-debug") == 0) + { + CPU.Flags |= DEBUG_MODE_FLAG; + } + else if (strcasecmp (argv [i], "-t") == 0 || + strcasecmp (argv [i], "-trace") == 0) + { + trace = fopen ("trace.log", "wb"); + CPU.Flags |= TRACE_FLAG; + } +#endif + else if (strcasecmp (argv [i], "-L") == 0 || + strcasecmp (argv [i], "-layering") == 0) + Settings.BGLayering = TRUE; + else if (strcasecmp (argv [i], "-nl") == 0 || + strcasecmp (argv [i], "-nolayering") == 0) + Settings.BGLayering = FALSE; + else if (strcasecmp (argv [i], "-O") == 0 || + strcasecmp (argv [i], "-tileredraw") == 0) + { + } + else if (strcasecmp (argv [i], "-no") == 0 || + strcasecmp (argv [i], "-lineredraw") == 0) + { + } + else if (strcasecmp (argv [i], "-tr") == 0 || + strcasecmp (argv [i], "-transparency") == 0) + { + Settings.ForceTransparency = TRUE; + Settings.ForceNoTransparency = FALSE; + } + else if (strcasecmp (argv [i], "-nt") == 0 || + strcasecmp (argv [i], "-notransparency") == 0) + { + Settings.ForceNoTransparency = TRUE; + Settings.ForceTransparency = FALSE; + } + else if (strcasecmp (argv [i], "-hi") == 0 || + strcasecmp (argv [i], "-hires") == 0) + { + Settings.SupportHiRes = TRUE; + } + else if (strcasecmp (argv [i], "-16") == 0 || + strcasecmp (argv [i], "-sixteen") == 0) + { + Settings.SixteenBit = TRUE; + } + else if (strcasecmp (argv [i], "-displayframerate") == 0 || + strcasecmp (argv [i], "-dfr") == 0) + { + Settings.DisplayFrameRate = TRUE; + } + else if (strcasecmp (argv [i], "-s") == 0 || + strcasecmp (argv [i], "-swapjoypads") == 0 || + strcasecmp (argv [i], "-sw") == 0) + Settings.SwapJoypads = TRUE; + else if (strcasecmp (argv [i], "-i") == 0 || + strcasecmp (argv [i], "-interleaved") == 0) + Settings.ForceInterleaved = TRUE; + else if (strcasecmp (argv [i], "-i2") == 0 || + strcasecmp (argv [i], "-interleaved2") == 0) + Settings.ForceInterleaved2 = TRUE; + else if (strcasecmp (argv [i], "-ni") == 0 || + strcasecmp (argv [i], "-nointerleave") == 0) + Settings.ForceNotInterleaved = TRUE; + else if (strcasecmp (argv [i], "-noirq") == 0) + Settings.DisableIRQ = TRUE; + else if (strcasecmp (argv [i], "-nw") == 0 || + strcasecmp (argv [i], "-nowindows") == 0) + { + Settings.DisableGraphicWindows = TRUE; + } + else if (strcasecmp (argv [i], "-windows") == 0) + { + Settings.DisableGraphicWindows = FALSE; + } + else if (strcasecmp (argv [i], "-im7") == 0) + { + Settings.Mode7Interpolate = TRUE; + } + else if (strcasecmp (argv [i], "-gg") == 0 || + strcasecmp (argv [i], "-gamegenie") == 0) + { + if (i + 1 < argc) + { + uint32 address; + uint8 byte; + const char *error; + if ((error = S9xGameGenieToRaw (argv [++i], address, byte)) == NULL) + S9xAddCheat (TRUE, FALSE, address, byte); + else + S9xMessage (S9X_ERROR, S9X_GAME_GENIE_CODE_ERROR, + error); + } + else + S9xUsage (); + } + else if (strcasecmp (argv [i], "-ar") == 0 || + strcasecmp (argv [i], "-actionreplay") == 0) + { + if (i + 1 < argc) + { + uint32 address; + uint8 byte; + const char *error; + if ((error = S9xProActionReplayToRaw (argv [++i], address, byte)) == NULL) + S9xAddCheat (TRUE, FALSE, address, byte); + else + S9xMessage (S9X_ERROR, S9X_ACTION_REPLY_CODE_ERROR, + error); + } + else + S9xUsage (); + } + else if (strcasecmp (argv [i], "-gf") == 0 || + strcasecmp (argv [i], "-goldfinger") == 0) + { + if (i + 1 < argc) + { + uint32 address; + uint8 bytes [3]; + bool8 sram; + uint8 num_bytes; + const char *error; + if ((error = S9xGoldFingerToRaw (argv [++i], address, sram, + num_bytes, bytes)) == NULL) + { + for (int c = 0; c < num_bytes; c++) + S9xAddCheat (TRUE, FALSE, address + c, bytes [c]); + } + else + S9xMessage (S9X_ERROR, S9X_GOLD_FINGER_CODE_ERROR, + error); + } + else + S9xUsage (); + } + else if (strcasecmp (argv[i], "-ft") == 0 || + strcasecmp (argv [i], "-frametime") == 0) + { + if (i + 1 < argc) + { + double ft; + if (sscanf (argv [++i], "%lf", &ft) == 1) + { +#ifdef __WIN32__ + Settings.FrameTimePAL = (int32) (ft * 1000); + Settings.FrameTimeNTSC = (int32) (ft * 1000); +#else + Settings.FrameTimePAL = (int32) ft; + Settings.FrameTimeNTSC = (int32) ft; +#endif + + } + } + else + S9xUsage (); + } + else if (strcasecmp (argv [i], "-e") == 0 || + strcasecmp (argv [i], "-echo") == 0) + Settings.DisableSoundEcho = FALSE; + else if (strcasecmp (argv [i], "-ne") == 0 || + strcasecmp (argv [i], "-noecho") == 0) + Settings.DisableSoundEcho = TRUE; + else if (strcasecmp (argv [i], "-r") == 0 || + strcasecmp (argv [i], "-soundquality") == 0 || + strcasecmp (argv [i], "-sq") == 0) + { + if (i + 1 < argc) + Settings.SoundPlaybackRate = atoi (argv [++i]) & 7; + else + S9xUsage (); + } + else if (strcasecmp (argv [i], "-stereo") == 0 || + strcasecmp (argv [i], "-st") == 0) + { + Settings.Stereo = TRUE; + Settings.APUEnabled = TRUE; + Settings.NextAPUEnabled = TRUE; + } + else if (strcasecmp (argv [i], "-mono") == 0) + { + Settings.Stereo = FALSE; + Settings.NextAPUEnabled = TRUE; + } + else if (strcasecmp (argv [i], "-envx") == 0 || + strcasecmp (argv [i], "-ex") == 0) + { + Settings.SoundEnvelopeHeightReading = TRUE; + } + else if (strcasecmp (argv [i], "-nosamplecaching") == 0 || + strcasecmp (argv [i], "-nsc") == 0 || + strcasecmp (argv [i], "-nc") == 0) + { + Settings.DisableSampleCaching = TRUE; + } + else if (strcasecmp (argv [i], "-nomastervolume") == 0 || + strcasecmp (argv [i], "-nmv") == 0) + { + Settings.DisableMasterVolume = TRUE; + } + else if (strcasecmp (argv [i], "-soundsync") == 0 || + strcasecmp (argv [i], "-sy") == 0) + { + Settings.SoundSync = TRUE; + Settings.SoundEnvelopeHeightReading = TRUE; + Settings.InterpolatedSound = TRUE; + } + else if (strcasecmp (argv [i], "-soundsync2") == 0 || + strcasecmp (argv [i], "-sy2") == 0) + { + Settings.SoundSync = 2; + Settings.SoundEnvelopeHeightReading = TRUE; + Settings.InterpolatedSound = TRUE; + } + else if (strcasecmp (argv [i], "-interpolatedsound") == 0 || + strcasecmp (argv [i], "-is") == 0) + { + Settings.InterpolatedSound = TRUE; + } +#ifdef USE_THREADS + else if (strcasecmp (argv [i], "-threadsound") == 0 || + strcasecmp (argv [i], "-ts") == 0) + { + Settings.ThreadSound = TRUE; + } +#endif + else if (strcasecmp (argv [i], "-alt") == 0 || + strcasecmp (argv [i], "-altsampledecode") == 0) + { + Settings.AltSampleDecode = 1; + } + else if (strcasecmp (argv [i], "-fix") == 0) + { + Settings.FixFrequency = 1; + } + else if (strcasecmp (argv [i], "-nosuperfx") == 0 || + strcasecmp (argv [i], "-nosfx") == 0) + Settings.ForceNoSuperFX = TRUE; + else if (strcasecmp (argv [i], "-superfx") == 0 || + strcasecmp (argv [i], "-sfx") == 0) + Settings.ForceSuperFX = TRUE; + else if (strcasecmp (argv [i], "-dsp1") == 0) + Settings.ForceDSP1 = TRUE; + else if (strcasecmp (argv [i], "-nodsp1") == 0) + Settings.ForceNoDSP1 = TRUE; + else if (strcasecmp (argv [i], "-nomultiplayer5") == 0 || + strcasecmp (argv [i], "-nmp") == 0) + Settings.MultiPlayer5 = FALSE; + else if (strcasecmp (argv [i], "-multiplayer5") == 0 || + strcasecmp (argv [i], "-mp") == 0) + { + Settings.MultiPlayer5 = TRUE; + Settings.ControllerOption = SNES_MULTIPLAYER5; + } + else if (strcasecmp (argv [i], "-mouse") == 0 || + strcasecmp (argv [i], "-mo") == 0) + { + Settings.ControllerOption = SNES_MOUSE_SWAPPED; + Settings.Mouse = TRUE; + } + else if (strcasecmp (argv [i], "-nomouse") == 0 || + strcasecmp (argv [i], "-nm") == 0) + { + Settings.Mouse = FALSE; + } + else if (strcasecmp (argv [i], "-superscope") == 0 || + strcasecmp (argv [i], "-ss") == 0) + { + Settings.SuperScope = TRUE; + Settings.ControllerOption = SNES_SUPERSCOPE; + } + else if (strcasecmp (argv [i], "-nosuperscope") == 0 || + strcasecmp (argv [i], "-nss") == 0) + { + Settings.SuperScope = FALSE; + } +#ifdef NETPLAY_SUPPORT + else if (strcasecmp (argv [i], "-port") == 0 || + strcasecmp (argv [i], "-po") == 0) + { + if (i + 1 < argc) + { + Settings.NetPlay = TRUE; + Settings.Port = -atoi (argv [++i]); + } + else + S9xUsage (); + } + else if (strcasecmp (argv [i], "-server") == 0 || + strcasecmp (argv [i], "-srv") == 0) + { + if (i + 1 < argc) + { + Settings.NetPlay = TRUE; + strncpy (Settings.ServerName, argv [++i], 127); + Settings.ServerName [127] = 0; + } + else + S9xUsage (); + } + else if (strcasecmp (argv [i], "-net") == 0) + { + Settings.NetPlay = TRUE; + } +#endif +#ifdef STORM + else if (strcasecmp(argv[i],"-nosecondjoy")==0){secondjoy=0;} + else if (strcasecmp(argv[i],"-showfps")==0){dofps=1;} + else if (strcasecmp(argv[i],"-hicolor")==0){hicolor=1;} + else if (strcasecmp(argv[i],"-minimal")==0){minimal=1;printf("Keyboard with exception of ESC switched off!\n");} + else if (strcasecmp(argv[i],"-ahiunit")==0) + { + if (i+1 +#include + +#ifdef __WIN32__ +#include "..\wsnes9x.h" +#include "..\zlib\zlib.h" +#endif + +#include "port.h" +#include "65c816.h" +#include "messages.h" + +#if defined(USE_GLIDE) && !defined(GFX_MULTI_FORMAT) +#define GFX_MULTI_FORMAT +#endif + +#define ROM_NAME_LEN 23 + +#ifdef ZLIB +//#ifndef __WIN32__ +#include "zlib.h" +//#endif +#define STREAM gzFile +#define READ_STREAM(p,l,s) gzread (s,p,l) +#define WRITE_STREAM(p,l,s) gzwrite (s,p,l) +#define OPEN_STREAM(f,m) gzopen (f,m) +#define CLOSE_STREAM(s) gzclose (s) +#define SEEK_STREAM(p,r,s) gzseek(s,p,r) +#else +#ifdef __GP32__ +#define STREAM long * //F_HANDLE * +#define READ_STREAM(p,l,s) gp32_fread ((unsigned char*)p,(long)l,s) +#define WRITE_STREAM(p,l,s) gp32_fwrite ((unsigned char*)p,(long)l,s) +#define OPEN_STREAM(f,m) gp32_fopen ((char*)f,(char*)m) +#define CLOSE_STREAM(s) gp32_fclose (s) +#define SEEK_STREAM(p,r,s) gp32_fseek(p,r,s) + +#else +#define STREAM FILE * +#define READ_STREAM(p,l,s) fread (p,1,l,s) +#define WRITE_STREAM(p,l,s) fwrite (p,1,l,s) +#define OPEN_STREAM(f,m) fopen (f,m) +#define CLOSE_STREAM(s) fclose (s) +#define SEEK_STREAM(p,r,s) fseek(s,p,r) +#define FROM_CURRENT SEEK_CUR +#endif +#endif + + +/* SNES screen width and height */ +#define SNES_WIDTH 256 +#define SNES_HEIGHT 224 +#define SNES_HEIGHT_EXTENDED 239 +#define IMAGE_WIDTH (Settings.SupportHiRes ? SNES_WIDTH * 2 : SNES_WIDTH) +#define IMAGE_HEIGHT (Settings.SupportHiRes ? SNES_HEIGHT_EXTENDED * 2 : SNES_HEIGHT_EXTENDED) + +#define SNES_MAX_NTSC_VCOUNTER 262 +#define SNES_MAX_PAL_VCOUNTER 312 +#define SNES_HCOUNTER_MAX 342 +#define SPC700_TO_65C816_RATIO 2 +#define AUTO_FRAMERATE 200 + +// NTSC master clock signal 21.47727MHz +// PPU: master clock / 4 +// 1 / PPU clock * 342 -> 63.695us +// 63.695us / (1 / 3.579545MHz) -> 228 cycles per scanline +// From Earth Worm Jim: APU executes an average of 65.14285714 cycles per +// scanline giving an APU clock speed of 1.022731096MHz + +// PAL master clock signal 21.28137MHz +// PPU: master clock / 4 +// 1 / PPU clock * 342 -> 64.281us +// 64.281us / (1 / 3.546895MHz) -> 228 cycles per scanline. + +//#define SNES_SCANLINE_TIME (63.695e-6) +//#define SNES_CLOCK_SPEED (3579545) + +//#define SNES_CLOCK_LEN (1.0 / SNES_CLOCK_SPEED) + +#ifdef VAR_CYCLES +//#define SNES_CYCLES_PER_SCANLINE ((uint32) ((SNES_SCANLINE_TIME / SNES_CLOCK_LEN) * 6 + 0.5)) +#define SNES_CYCLES_PER_SCANLINE ((uint32)(228*6)) +#else +#define SNES_CYCLES_PER_SCANLINE ((uint32) (SNES_SCANLINE_TIME / SNES_CLOCK_LEN + 0.5)) +#endif + +#define SNES_TR_MASK (1 << 4) +#define SNES_TL_MASK (1 << 5) +#define SNES_X_MASK (1 << 6) +#define SNES_A_MASK (1 << 7) +#define SNES_RIGHT_MASK (1 << 8) +#define SNES_LEFT_MASK (1 << 9) +#define SNES_DOWN_MASK (1 << 10) +#define SNES_UP_MASK (1 << 11) +#define SNES_START_MASK (1 << 12) +#define SNES_SELECT_MASK (1 << 13) +#define SNES_Y_MASK (1 << 14) +#define SNES_B_MASK (1 << 15) + +enum { + SNES_MULTIPLAYER5, + SNES_JOYPAD, + SNES_MOUSE_SWAPPED, + SNES_MOUSE, + SNES_SUPERSCOPE, + SNES_JUSTIFIER, + SNES_JUSTIFIER_2, + SNES_MAX_CONTROLLER_OPTIONS +}; + +#define DEBUG_MODE_FLAG (1 << 0) +#define TRACE_FLAG (1 << 1) +#define SINGLE_STEP_FLAG (1 << 2) +#define BREAK_FLAG (1 << 3) +#define SCAN_KEYS_FLAG (1 << 4) +#define SAVE_SNAPSHOT_FLAG (1 << 5) +#define DELAYED_NMI_FLAG (1 << 6) +#define NMI_FLAG (1 << 7) +#define PROCESS_SOUND_FLAG (1 << 8) +#define FRAME_ADVANCE_FLAG (1 << 9) +#define DELAYED_NMI_FLAG2 (1 << 10) +#define IRQ_PENDING_FLAG (1 << 11) + +#ifdef VAR_CYCLES +#define ONE_CYCLE 6 +#define SLOW_ONE_CYCLE 8 +#define TWO_CYCLES 12 +#else +#define ONE_CYCLE 1 +#define SLOW_ONE_CYCLE 1 +#define TWO_CYCLES 2 +#endif + + +#undef MEMMAP_BLOCK_SIZE +#define MEMMAP_BLOCK_SIZE (0x1000) +#undef MEMMAP_NUM_BLOCKS +#define MEMMAP_NUM_BLOCKS (0x1000000 / MEMMAP_BLOCK_SIZE) + +struct SCPUState{ + uint32 Flags; //0 + bool8 BranchSkip; //4 + bool8 NMIActive; //5 + bool8 IRQActive; //6 + bool8 WaitingForInterrupt; //7 + struct SRegisters Regs; //8 + //uint8 PB; //8 + //uint8 DB; //9 + //pair P; //10 + //pair A; //12 + //pair D; //14 + //pair X; //16 + //pair S; //18 + //pair Y; //20 + //uint16 PC; //22 + uint8 *PC; //24 + int32 Cycles; //28 + uint8 *PCBase; //32 + uint8 *PCAtOpcodeStart; //36 + uint8 *WaitAddress; //40 + uint32 WaitCounter; //44 + int32 NextEvent; //48 + int32 V_Counter; //52 + int32 MemSpeed; //56 + int32 MemSpeedx2; //60 + int32 FastROMSpeed; //64 + uint32 AutoSaveTimer; //68 + uint32 NMITriggerPoint; //72 + uint32 NMICycleCount; //76 + uint32 IRQCycleCount; //80 + + bool8 InDMA; //84 + uint8 WhichEvent; //85 + bool8 SRAMModified; //86 + bool8 BRKTriggered; //87 + uint32 _ARM_asm_reserved_1; //88 to stock current jmp table + bool8 TriedInterleavedMode2; //92 + bool8 _ARM_asm_padding1[3]; //93 + + uint8* Memory_Map; //96 + uint8* Memory_WriteMap; //100 + uint8* Memory_MemorySpeed; //104 + uint8* Memory_BlockIsRAM; //108 + uint8* Memory_SRAM; //112 + uint8* Memory_BWRAM; //116 + uint16 Memory_SRAMMask; //120 + bool8 APU_APUExecuting; //122 + bool8 _ARM_asm_padding2; //123 + uint32 _PALMSOS_R9; //124 + uint32 _PALMSOS_R10; //128 + int32 APU_Cycles; //132 notaz + uint32 jump1; //136 + uint32 jump2; //140 + uint32 jump3; //144 + uint32 jump4; //148 +}; + + +#define HBLANK_START_EVENT 0 +#define HBLANK_END_EVENT 1 +#define HTIMER_BEFORE_EVENT 2 +#define HTIMER_AFTER_EVENT 3 +#define NO_EVENT 4 + +struct SSettings{ + // CPU options + bool8 APUEnabled; + bool8 Shutdown; + uint8 SoundSkipMethod; + long H_Max; + long HBlankStart; + long CyclesPercentage; + bool8 DisableIRQ; + bool8 Paused; + bool8 ForcedPause; + bool8 StopEmulation; + + // Tracing options + bool8 TraceDMA; + bool8 TraceHDMA; + bool8 TraceVRAM; + bool8 TraceUnknownRegisters; + bool8 TraceDSP; + + // Joystick options + bool8 SwapJoypads; + bool8 JoystickEnabled; + + // ROM timing options (see also H_Max above) + bool8 ForcePAL; + bool8 ForceNTSC; + bool8 PAL; + uint32 FrameTimePAL; + uint32 FrameTimeNTSC; + uint32 FrameTime; + uint32 SkipFrames; + + // ROM image options + bool8 ForceLoROM; + bool8 ForceHiROM; + bool8 ForceHeader; + bool8 ForceNoHeader; + bool8 ForceInterleaved; + bool8 ForceInterleaved2; + bool8 ForceNotInterleaved; + + // Peripherial options + bool8 ForceSuperFX; + bool8 ForceNoSuperFX; + bool8 ForceDSP1; + bool8 ForceNoDSP1; + bool8 ForceSA1; + bool8 ForceNoSA1; + bool8 ForceC4; + bool8 ForceNoC4; + bool8 ForceSDD1; + bool8 ForceNoSDD1; + bool8 MultiPlayer5; + bool8 Mouse; + bool8 SuperScope; + bool8 SRTC; + uint32 ControllerOption; + + bool8 ShutdownMaster; + bool8 MultiPlayer5Master; + bool8 SuperScopeMaster; + bool8 MouseMaster; + bool8 SuperFX; + bool8 DSP1Master; + bool8 SA1; + bool8 C4; + bool8 SDD1; + + // Sound options + uint32 SoundPlaybackRate; + bool8 TraceSoundDSP; + bool8 Stereo; + bool8 ReverseStereo; + bool8 SixteenBitSound; + int SoundBufferSize; + int SoundMixInterval; + bool8 SoundEnvelopeHeightReading; + bool8 DisableSoundEcho; + bool8 DisableSampleCaching; + bool8 DisableMasterVolume; + bool8 SoundSync; + bool8 InterpolatedSound; + bool8 ThreadSound; + bool8 Mute; +// bool8 NextAPUEnabled; + uint8 AltSampleDecode; + bool8 FixFrequency; + + // Graphics options + bool8 SixteenBit; + bool8 Transparency; + bool8 SupportHiRes; + bool8 Mode7Interpolate; + + // SNES graphics options + bool8 BGLayering; + bool8 DisableGraphicWindows; + bool8 ForceTransparency; + bool8 ForceNoTransparency; + bool8 DisableHDMA; + bool8 DisplayFrameRate; + + // Others + bool8 NetPlay; + bool8 NetPlayServer; + char ServerName [128]; + int Port; + bool8 GlideEnable; + bool8 OpenGLEnable; + int32 AutoSaveDelay; // Time in seconds before S-RAM auto-saved if modified. + bool8 ApplyCheats; + bool8 TurboMode; + uint32 TurboSkipFrames; + uint32 AutoMaxSkipFrames; + +// Fixes for individual games + uint32 StrikeGunnerOffsetHack; + bool8 ChuckRock; + bool8 StarfoxHack; + bool8 WinterGold; + bool8 Dezaemon; + bool8 WrestlemaniaArcade; + bool8 BS; // Japanese Satellite System games. + bool8 DaffyDuck; + uint8 APURAMInitialValue; + bool8 SDD1Pack; + + // notaz + uint32 GfxLayerMask; +#ifdef __WIN32__ + int SoundDriver; +#endif +}; + +struct SSNESGameFixes +{ + uint8 NeedInit0x2137; + uint8 umiharakawaseFix; + uint8 alienVSpredetorFix; + uint8 APU_OutPorts_ReturnValueFix; + uint8 Old_Read0x4200; + uint8 _0x213E_ReturnValue; + uint8 TouhaidenControllerFix; + uint8 SoundEnvelopeHeightReading2; + uint8 SRAMInitialValue; +}; + +START_EXTERN_C +extern struct SSettings Settings; +extern struct SCPUState CPU; +extern struct SSNESGameFixes SNESGameFixes; +extern char String [513]; + +void S9xExit (); +void S9xMessage (int type, int number, const char *message); +void S9xLoadSDD1Data (); +END_EXTERN_C + +enum { + PAUSE_NETPLAY_CONNECT = (1 << 0), + PAUSE_TOGGLE_FULL_SCREEN = (1 << 1), + PAUSE_EXIT = (1 << 2), + PAUSE_MENU = (1 << 3), + PAUSE_INACTIVE_WINDOW = (1 << 4), + PAUSE_WINDOW_ICONISED = (1 << 5), + PAUSE_RESTORE_GUI = (1 << 6), + PAUSE_FREEZE_FILE = (1 << 7) +}; +void S9xSetPause (uint32 mask); +void S9xClearPause (uint32 mask); + +#endif diff --git a/src/snes4iphone_src/soundux.cpp b/src/snes4iphone_src/soundux.cpp new file mode 100755 index 0000000..d692438 --- /dev/null +++ b/src/snes4iphone_src/soundux.cpp @@ -0,0 +1,1259 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#ifdef __DJGPP__ +//#include +#undef TRUE +#endif + +#include +#include +#include +#if !defined(_SNESPPC) || defined(__IPHONE__) +#include +#include +#endif + +#define CLIP16(v) \ +if ((v) < -32768) \ + (v) = -32768; \ +else \ +if ((v) > 32767) \ + (v) = 32767 + +#define CLIP16_latch(v,l) \ +if ((v) < -32768) \ +{ (v) = -32768; (l)++; }\ +else \ +if ((v) > 32767) \ +{ (v) = 32767; (l)++; } + +#define CLIP24(v) \ +if ((v) < -8388608) \ + (v) = -8388608; \ +else \ +if ((v) > 8388607) \ + (v) = 8388607 + +/* +#define CLIP8(v) \ +if ((v) < -128) \ + (v) = -128; \ +else \ +if ((v) > 127) \ + (v) = 127 +*/ + + +#include "snes9x.h" +#include "soundux.h" +#include "apu.h" +#include "memmap.h" +#include "cpuexec.h" + + +static int wave[SOUND_BUFFER_SIZE]; + +//extern int Echo [24000]; +extern int MixBuffer [SOUND_BUFFER_SIZE]; +//extern int EchoBuffer [SOUND_BUFFER_SIZE]; +//extern int FilterTaps [8]; +extern unsigned long Z; +//extern int Loop [16]; + +extern long FilterValues[4][2]; +//extern int NoiseFreq [32]; + + +//#define FIXED_POINT 0x10000UL +#define FIXED_POINT_REMAINDER 0xffffUL +#define FIXED_POINT_SHIFT 16 + +#define VOL_DIV8 0x8000 +#define VOL_DIV16 0x0080 +#define ENVX_SHIFT 24 + +extern "C" void DecodeBlockAsm (int8 *, int16 *, int32 *, int32 *); + +// F is channel's current frequency and M is the 16-bit modulation waveform +// from the previous channel multiplied by the current envelope volume level. +#define PITCH_MOD(F,M) ((F) * ((((unsigned long) (M)) + 0x800000) >> 16) >> 7) +//#define PITCH_MOD(F,M) ((F) * ((((M) & 0x7fffff) >> 14) + 1) >> 8) + +#define LAST_SAMPLE 0xffffff +#define JUST_PLAYED_LAST_SAMPLE(c) ((c)->sample_pointer >= LAST_SAMPLE) + + +static inline void S9xAPUSetEndOfSample (int i, Channel *ch) +{ + ch->state = SOUND_SILENT; + ch->mode = MODE_NONE; + APU.DSP [APU_ENDX] |= 1 << i; + APU.DSP [APU_KON] &= ~(1 << i); + APU.DSP [APU_KOFF] &= ~(1 << i); + APU.KeyedChannels &= ~(1 << i); +} +#ifdef __DJGPP +END_OF_FUNCTION (S9xAPUSetEndOfSample) +#endif + +static inline void S9xAPUSetEndX (int ch) +{ + APU.DSP [APU_ENDX] |= 1 << ch; +} +#ifdef __DJGPP +END_OF_FUNCTION (S9xAPUSetEndX) +#endif + +void S9xSetEchoDelay (int delay) +{ + SoundData.echo_buffer_size = (512 * delay * so.playback_rate) >> 15; // notaz / 32000; + if (so.stereo) + SoundData.echo_buffer_size <<= 1; + if (SoundData.echo_buffer_size) { + while(SoundData.echo_ptr >= SoundData.echo_buffer_size) + SoundData.echo_ptr -= SoundData.echo_buffer_size; + } else + SoundData.echo_ptr = 0; + S9xSetEchoEnable (APU.DSP [APU_EON]); +} + +void S9xSetSoundKeyOff (int channel) +{ + Channel *ch = &SoundData.channels[channel]; + + if (ch->state != SOUND_SILENT) + { + ch->state = SOUND_RELEASE; + ch->mode = MODE_RELEASE; + S9xSetEnvRate (ch, 8, -1, 0, 5<<28); + } +} + +void S9xFixSoundAfterSnapshotLoad () +{ + SoundData.echo_write_enabled = !(APU.DSP [APU_FLG] & 0x20); + SoundData.echo_channel_enable = APU.DSP [APU_EON]; + S9xSetEchoDelay (APU.DSP [APU_EDL] & 0xf); + S9xSetEchoFeedback ((signed char) APU.DSP [APU_EFB]); + + S9xSetFilterCoefficient (0, (signed char) APU.DSP [APU_C0]); + S9xSetFilterCoefficient (1, (signed char) APU.DSP [APU_C1]); + S9xSetFilterCoefficient (2, (signed char) APU.DSP [APU_C2]); + S9xSetFilterCoefficient (3, (signed char) APU.DSP [APU_C3]); + S9xSetFilterCoefficient (4, (signed char) APU.DSP [APU_C4]); + S9xSetFilterCoefficient (5, (signed char) APU.DSP [APU_C5]); + S9xSetFilterCoefficient (6, (signed char) APU.DSP [APU_C6]); + S9xSetFilterCoefficient (7, (signed char) APU.DSP [APU_C7]); + + for (int i = 0; i < 8; i++) + { + SoundData.channels[i].needs_decode = TRUE; + S9xSetSoundFrequency (i, SoundData.channels[i].hertz); + SoundData.channels [i].envxx = SoundData.channels [i].envx << ENVX_SHIFT; + SoundData.channels [i].next_sample = 0; + SoundData.channels [i].interpolate = 0; + SoundData.channels [i].previous [0] = (int32) SoundData.channels [i].previous16 [0]; + SoundData.channels [i].previous [1] = (int32) SoundData.channels [i].previous16 [1]; + } + SoundData.master_volume [0] = SoundData.master_volume_left; + SoundData.master_volume [1] = SoundData.master_volume_right; + SoundData.echo_volume [0] = SoundData.echo_volume_left; + SoundData.echo_volume [1] = SoundData.echo_volume_right; + IAPU.Scanline = 0; +} + +void S9xSetEnvelopeHeight (int channel, int level) +{ + Channel *ch = &SoundData.channels[channel]; + + ch->envx = level; + ch->envxx = level << ENVX_SHIFT; + + ch->left_vol_level = (level * ch->volume_left) / 128; + ch->right_vol_level = (level * ch->volume_right) / 128; + + if (ch->envx == 0 && ch->state != SOUND_SILENT && ch->state != SOUND_GAIN) + { + S9xAPUSetEndOfSample (channel, ch); + } +} + +#if 1 +void S9xSetSoundSample (int, uint16) +{ +} +#else +void S9xSetSoundSample (int channel, uint16 sample_number) +{ + register Channel *ch = &SoundData.channels[channel]; + + if (ch->state != SOUND_SILENT && + sample_number != ch->sample_number) + { + int keep = ch->state; + ch->state = SOUND_SILENT; + ch->sample_number = sample_number; + ch->loop = FALSE; + ch->needs_decode = TRUE; + ch->last_block = FALSE; + ch->previous [0] = ch->previous[1] = 0; + ch->block_pointer = *S9xGetSampleAddress(sample_number); + ch->sample_pointer = 0; + ch->state = keep; + } +} +#endif + +static void DecodeBlock (Channel *ch) +{ + if (ch->block_pointer >= 0x10000 - 9) + { + ch->last_block = TRUE; + ch->loop = FALSE; + ch->block = ch->decoded; + memset32 ((uint32_t *) ch->decoded, 0, 8); + return; + } + signed char *compressed = (signed char *) &IAPU.RAM [ch->block_pointer]; + + unsigned char filter = *compressed; + if ((ch->last_block = filter & 1)) + ch->loop = (filter & 2) != 0; + + int16 *raw = ch->block = ch->decoded; + +#ifdef ARM + DecodeBlockAsm (compressed, raw, &ch->previous [0], &ch->previous [1]); +#else + int32 out; + unsigned char shift; + signed char sample1, sample2; + unsigned int i; + + compressed++; + + int32 prev0 = ch->previous [0]; + int32 prev1 = ch->previous [1]; + shift = filter >> 4; + + switch ((filter >> 2) & 3) + { + case 0: + for (i = 8; i != 0; i--) + { + sample1 = *compressed++; + sample2 = sample1 << 4; + sample2 >>= 4; + sample1 >>= 4; + *raw++ = ((int32) sample1 << shift); + *raw++ = ((int32) sample2 << shift); + } + prev1 = *(raw - 2); + prev0 = *(raw - 1); + break; + case 1: + for (i = 8; i != 0; i--) + { + sample1 = *compressed++; + sample2 = sample1 << 4; + sample2 >>= 4; + sample1 >>= 4; + prev0 = (int16) prev0; + *raw++ = prev1 = ((int32) sample1 << shift) + prev0 - (prev0 >> 4); + prev1 = (int16) prev1; + *raw++ = prev0 = ((int32) sample2 << shift) + prev1 - (prev1 >> 4); + } + break; + case 2: + for (i = 8; i != 0; i--) + { + sample1 = *compressed++; + sample2 = sample1 << 4; + sample2 >>= 4; + sample1 >>= 4; + + out = (sample1 << shift) - prev1 + (prev1 >> 4); + prev1 = (int16) prev0; + prev0 &= ~3; + *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 5) - + (prev0 >> 4); + + out = (sample2 << shift) - prev1 + (prev1 >> 4); + prev1 = (int16) prev0; + prev0 &= ~3; + *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 5) - + (prev0 >> 4); + } + break; + case 3: + for (i = 8; i != 0; i--) + { + sample1 = *compressed++; + sample2 = sample1 << 4; + sample2 >>= 4; + sample1 >>= 4; + out = (sample1 << shift); + + out = out - prev1 + (prev1 >> 3) + (prev1 >> 4); + prev1 = (int16) prev0; + prev0 &= ~3; + *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 3) - + (prev0 >> 4) - (prev1 >> 6); + + out = (sample2 << shift); + out = out - prev1 + (prev1 >> 3) + (prev1 >> 4); + prev1 = (int16) prev0; + prev0 &= ~3; + *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 3) - + (prev0 >> 4) - (prev1 >> 6); + } + break; + } + ch->previous [0] = prev0; + ch->previous [1] = prev1; + +#endif + ch->block_pointer += 9; +} + + +static void MixStereo (int sample_count) +{ + int pitch_mod = SoundData.pitch_mod & (0xFFFFFFFF^APU.DSP[APU_NON]);//~APU.DSP[APU_NON]; + + for (uint32 J = 0; J < NUM_CHANNELS; J++) + { + int32 VL, VR; + Channel *ch = &SoundData.channels[J]; + unsigned long freq0 = ch->frequency; + + if (ch->state == SOUND_SILENT || !(so.sound_switch & (1 << J))) + continue; + +// freq0 = (unsigned long) ((double) freq0 * 0.985);//uncommented by jonathan gevaryahu, as it is necessary for most cards in linux + + bool8 mod = pitch_mod & (1 << J); + + if (ch->needs_decode) + { + DecodeBlock(ch); + ch->needs_decode = FALSE; + ch->sample = ch->block[0]; + ch->sample_pointer = freq0 >> FIXED_POINT_SHIFT; + if (ch->sample_pointer == 0) + ch->sample_pointer = 1; + if (ch->sample_pointer > SOUND_DECODE_LENGTH) + ch->sample_pointer = SOUND_DECODE_LENGTH - 1; + + ch->next_sample = ch->block[ch->sample_pointer]; + ch->interpolate = 0; + + if (Settings.InterpolatedSound && freq0 < FIXED_POINT && !mod) + ch->interpolate = ((ch->next_sample - ch->sample) * + (long) freq0) / (long) FIXED_POINT; + } + VL = (ch->sample * ch-> left_vol_level) / 128; + VR = (ch->sample * ch->right_vol_level) / 128; + + for (uint32 I = 0; I < (uint32) sample_count; I += 2) + { + unsigned long freq = freq0; + + if (mod) + freq = PITCH_MOD(freq, wave [I / 2]); + + ch->env_error += ch->erate; + if (ch->env_error >= FIXED_POINT) + { + uint32 step = ch->env_error >> FIXED_POINT_SHIFT; + + switch (ch->state) + { + case SOUND_ATTACK: + ch->env_error &= FIXED_POINT_REMAINDER; + ch->envx += step << 1; + ch->envxx = ch->envx << ENVX_SHIFT; + + if (ch->envx >= 126) + { + ch->envx = 127; + ch->envxx = 127 << ENVX_SHIFT; + ch->state = SOUND_DECAY; + if (ch->sustain_level != 8) + { + S9xSetEnvRate (ch, ch->decay_rate, -1, + (MAX_ENVELOPE_HEIGHT * ch->sustain_level) >> 3, 1<<28); + break; + } + ch->state = SOUND_SUSTAIN; + S9xSetEnvRate (ch, ch->sustain_rate, -1, 0, 2<<28); + } + break; + + case SOUND_DECAY: + while (ch->env_error >= FIXED_POINT) + { + ch->envxx = (ch->envxx >> 8) * 255; + ch->env_error -= FIXED_POINT; + } + ch->envx = ch->envxx >> ENVX_SHIFT; + if (ch->envx <= ch->envx_target) + { + if (ch->envx <= 0) + { + S9xAPUSetEndOfSample (J, ch); + goto stereo_exit; + } + ch->state = SOUND_SUSTAIN; + S9xSetEnvRate (ch, ch->sustain_rate, -1, 0, 2<<28); + } + break; + + case SOUND_SUSTAIN: + while (ch->env_error >= FIXED_POINT) + { + ch->envxx = (ch->envxx >> 8) * 255; + ch->env_error -= FIXED_POINT; + } + ch->envx = ch->envxx >> ENVX_SHIFT; + if (ch->envx <= 0) + { + S9xAPUSetEndOfSample (J, ch); + goto stereo_exit; + } + break; + + case SOUND_RELEASE: + while (ch->env_error >= FIXED_POINT) + { + ch->envxx -= (MAX_ENVELOPE_HEIGHT << ENVX_SHIFT) / 256; + ch->env_error -= FIXED_POINT; + } + ch->envx = ch->envxx >> ENVX_SHIFT; + if (ch->envx <= 0) + { + S9xAPUSetEndOfSample (J, ch); + goto stereo_exit; + } + break; + + case SOUND_INCREASE_LINEAR: + ch->env_error &= FIXED_POINT_REMAINDER; + ch->envx += step << 1; + ch->envxx = ch->envx << ENVX_SHIFT; + + if (ch->envx >= 126) + { + ch->envx = 127; + ch->envxx = 127 << ENVX_SHIFT; + ch->state = SOUND_GAIN; + ch->mode = MODE_GAIN; + S9xSetEnvRate (ch, 0, -1, 0, 0); + } + break; + + case SOUND_INCREASE_BENT_LINE: + if (ch->envx >= (MAX_ENVELOPE_HEIGHT * 3) / 4) + { + while (ch->env_error >= FIXED_POINT) + { + ch->envxx += (MAX_ENVELOPE_HEIGHT << ENVX_SHIFT) / 256; + ch->env_error -= FIXED_POINT; + } + ch->envx = ch->envxx >> ENVX_SHIFT; + } + else + { + ch->env_error &= FIXED_POINT_REMAINDER; + ch->envx += step << 1; + ch->envxx = ch->envx << ENVX_SHIFT; + } + + if (ch->envx >= 126) + { + ch->envx = 127; + ch->envxx = 127 << ENVX_SHIFT; + ch->state = SOUND_GAIN; + ch->mode = MODE_GAIN; + S9xSetEnvRate (ch, 0, -1, 0, 0); + } + break; + + case SOUND_DECREASE_LINEAR: + ch->env_error &= FIXED_POINT_REMAINDER; + ch->envx -= step << 1; + ch->envxx = ch->envx << ENVX_SHIFT; + if (ch->envx <= 0) + { + S9xAPUSetEndOfSample (J, ch); + goto stereo_exit; + } + break; + + case SOUND_DECREASE_EXPONENTIAL: + while (ch->env_error >= FIXED_POINT) + { + ch->envxx = (ch->envxx >> 8) * 255; + ch->env_error -= FIXED_POINT; + } + ch->envx = ch->envxx >> ENVX_SHIFT; + if (ch->envx <= 0) + { + S9xAPUSetEndOfSample (J, ch); + goto stereo_exit; + } + break; + + case SOUND_GAIN: + S9xSetEnvRate (ch, 0, -1, 0, 0); + break; + } + ch-> left_vol_level = (ch->envx * ch->volume_left) / 128; + ch->right_vol_level = (ch->envx * ch->volume_right) / 128; + VL = (ch->sample * ch-> left_vol_level) / 128; + VR = (ch->sample * ch->right_vol_level) / 128; + } + + ch->count += freq; + if (ch->count >= FIXED_POINT) + { + VL = ch->count >> FIXED_POINT_SHIFT; + ch->sample_pointer += VL; + ch->count &= FIXED_POINT_REMAINDER; + + ch->sample = ch->next_sample; + if (ch->sample_pointer >= SOUND_DECODE_LENGTH) + { + if (JUST_PLAYED_LAST_SAMPLE(ch)) + { + S9xAPUSetEndOfSample (J, ch); + goto stereo_exit; + } + do + { + ch->sample_pointer -= SOUND_DECODE_LENGTH; + if (ch->last_block) + { + if (!ch->loop) + { + ch->sample_pointer = LAST_SAMPLE; + ch->next_sample = ch->sample; + break; + } + else + { + S9xAPUSetEndX (J); + ch->last_block = FALSE; + uint16 *dir = S9xGetSampleAddress (ch->sample_number); + ch->block_pointer = *(dir + 1); + } + } + DecodeBlock (ch); + } while (ch->sample_pointer >= SOUND_DECODE_LENGTH); + if (!JUST_PLAYED_LAST_SAMPLE (ch)) + ch->next_sample = ch->block [ch->sample_pointer]; + } + else + ch->next_sample = ch->block [ch->sample_pointer]; + + if (ch->type == SOUND_SAMPLE) + { + if (Settings.InterpolatedSound && freq < FIXED_POINT && !mod) + { + ch->interpolate = ((ch->next_sample - ch->sample) * + (long) freq) / (long) FIXED_POINT; + ch->sample = (int16) (ch->sample + (((ch->next_sample - ch->sample) * + (long) (ch->count)) / (long) FIXED_POINT)); + } + else + ch->interpolate = 0; + } + else + { + for (;VL > 0; VL--) + if ((so.noise_gen <<= 1) & 0x80000000L) + so.noise_gen ^= 0x0040001L; + ch->sample = (so.noise_gen << 17) >> 17; + ch->interpolate = 0; + } + + VL = (ch->sample * ch-> left_vol_level) / 128; + VR = (ch->sample * ch->right_vol_level) / 128; + } + else + { + if (ch->interpolate) + { + int32 s = (int32) ch->sample + ch->interpolate; + + CLIP16(s); + ch->sample = (int16) s; + VL = (ch->sample * ch-> left_vol_level) / 128; + VR = (ch->sample * ch->right_vol_level) / 128; + } + } + + if (pitch_mod & (1 << (J + 1))) + wave [I / 2] = ch->sample * ch->envx; + + MixBuffer [I] += VL; + MixBuffer [I+1] += VR; + if (ch->echo_buf_ptr) + { + ch->echo_buf_ptr [I] += VL; + ch->echo_buf_ptr [I+1] += VR; + } + } +stereo_exit: ; + } +} + +static void MixMono (int sample_count) +{ + int pitch_mod = SoundData.pitch_mod & (0xFFFFFFFF^APU.DSP[APU_NON]); + + for (uint32 J = 0; J < NUM_CHANNELS; J++) + { + Channel *ch = &SoundData.channels[J]; + unsigned long freq0 = ch->frequency; + + if (ch->state == SOUND_SILENT || !(so.sound_switch & (1 << J))) + continue; + +// freq0 = (unsigned long) ((double) freq0 * 0.985); + + bool8 mod = pitch_mod & (1 << J); + + if (ch->needs_decode) + { + DecodeBlock(ch); + ch->needs_decode = FALSE; + ch->sample = ch->block[0]; + ch->sample_pointer = freq0 >> FIXED_POINT_SHIFT; + if (ch->sample_pointer == 0) + ch->sample_pointer = 1; + if (ch->sample_pointer > SOUND_DECODE_LENGTH) + ch->sample_pointer = SOUND_DECODE_LENGTH - 1; + ch->next_sample = ch->block[ch->sample_pointer]; + ch->interpolate = 0; + + if (Settings.InterpolatedSound && freq0 < FIXED_POINT && !mod) + ch->interpolate = ((ch->next_sample - ch->sample) * + (long) freq0) / (long) FIXED_POINT; + } + int32 V = (ch->sample * ch->left_vol_level) / 128; + + for (uint32 I = 0; I < (uint32) sample_count; I++) + { + unsigned long freq = freq0; + + if (mod) + freq = PITCH_MOD(freq, wave [I]); + + ch->env_error += ch->erate; + if (ch->env_error >= FIXED_POINT) + { + uint32 step = ch->env_error >> FIXED_POINT_SHIFT; + + switch (ch->state) + { + case SOUND_ATTACK: + ch->env_error &= FIXED_POINT_REMAINDER; + ch->envx += step << 1; + ch->envxx = ch->envx << ENVX_SHIFT; + + if (ch->envx >= 126) + { + ch->envx = 127; + ch->envxx = 127 << ENVX_SHIFT; + ch->state = SOUND_DECAY; + if (ch->sustain_level != 8) + { + S9xSetEnvRate (ch, ch->decay_rate, -1, + (MAX_ENVELOPE_HEIGHT * ch->sustain_level) >> 3, 1<<28); + break; + } + ch->state = SOUND_SUSTAIN; + S9xSetEnvRate (ch, ch->sustain_rate, -1, 0, 2<<28); + } + break; + + case SOUND_DECAY: + while (ch->env_error >= FIXED_POINT) + { + ch->envxx = (ch->envxx >> 8) * 255; + ch->env_error -= FIXED_POINT; + } + ch->envx = ch->envxx >> ENVX_SHIFT; + if (ch->envx <= ch->envx_target) + { + if (ch->envx <= 0) + { + S9xAPUSetEndOfSample (J, ch); + goto mono_exit; + } + ch->state = SOUND_SUSTAIN; + S9xSetEnvRate (ch, ch->sustain_rate, -1, 0, 2<<28); + } + break; + + case SOUND_SUSTAIN: + while (ch->env_error >= FIXED_POINT) + { + ch->envxx = (ch->envxx >> 8) * 255; + ch->env_error -= FIXED_POINT; + } + ch->envx = ch->envxx >> ENVX_SHIFT; + if (ch->envx <= 0) + { + S9xAPUSetEndOfSample (J, ch); + goto mono_exit; + } + break; + + case SOUND_RELEASE: + while (ch->env_error >= FIXED_POINT) + { + ch->envxx -= (MAX_ENVELOPE_HEIGHT << ENVX_SHIFT) / 256; + ch->env_error -= FIXED_POINT; + } + ch->envx = ch->envxx >> ENVX_SHIFT; + if (ch->envx <= 0) + { + S9xAPUSetEndOfSample (J, ch); + goto mono_exit; + } + break; + + case SOUND_INCREASE_LINEAR: + ch->env_error &= FIXED_POINT_REMAINDER; + ch->envx += step << 1; + ch->envxx = ch->envx << ENVX_SHIFT; + + if (ch->envx >= 126) + { + ch->envx = 127; + ch->envxx = 127 << ENVX_SHIFT; + ch->state = SOUND_GAIN; + ch->mode = MODE_GAIN; + S9xSetEnvRate (ch, 0, -1, 0, 0); + } + break; + + case SOUND_INCREASE_BENT_LINE: + if (ch->envx >= (MAX_ENVELOPE_HEIGHT * 3) / 4) + { + while (ch->env_error >= FIXED_POINT) + { + ch->envxx += (MAX_ENVELOPE_HEIGHT << ENVX_SHIFT) / 256; + ch->env_error -= FIXED_POINT; + } + ch->envx = ch->envxx >> ENVX_SHIFT; + } + else + { + ch->env_error &= FIXED_POINT_REMAINDER; + ch->envx += step << 1; + ch->envxx = ch->envx << ENVX_SHIFT; + } + + if (ch->envx >= 126) + { + ch->envx = 127; + ch->envxx = 127 << ENVX_SHIFT; + ch->state = SOUND_GAIN; + ch->mode = MODE_GAIN; + S9xSetEnvRate (ch, 0, -1, 0, 0); + } + break; + + case SOUND_DECREASE_LINEAR: + ch->env_error &= FIXED_POINT_REMAINDER; + ch->envx -= step << 1; + ch->envxx = ch->envx << ENVX_SHIFT; + if (ch->envx <= 0) + { + S9xAPUSetEndOfSample (J, ch); + goto mono_exit; + } + break; + + case SOUND_DECREASE_EXPONENTIAL: + while (ch->env_error >= FIXED_POINT) + { + ch->envxx = (ch->envxx >> 8) * 255; + ch->env_error -= FIXED_POINT; + } + ch->envx = ch->envxx >> ENVX_SHIFT; + if (ch->envx <= 0) + { + S9xAPUSetEndOfSample (J, ch); + goto mono_exit; + } + break; + + case SOUND_GAIN: + S9xSetEnvRate (ch, 0, -1, 0, 0); + break; + } + ch->left_vol_level = (ch->envx * ch->volume_left) / 128; + V = (ch->sample * ch->left_vol_level) / 128; + } + + ch->count += freq; + if (ch->count >= FIXED_POINT) + { + V = ch->count >> FIXED_POINT_SHIFT; + ch->sample_pointer += V; + ch->count &= FIXED_POINT_REMAINDER; + + ch->sample = ch->next_sample; + if (ch->sample_pointer >= SOUND_DECODE_LENGTH) + { + if (JUST_PLAYED_LAST_SAMPLE(ch)) + { + S9xAPUSetEndOfSample (J, ch); + goto mono_exit; + } + do + { + ch->sample_pointer -= SOUND_DECODE_LENGTH; + if (ch->last_block) + { + if (!ch->loop) + { + ch->sample_pointer = LAST_SAMPLE; + ch->next_sample = ch->sample; + break; + } + else + { + ch->last_block = FALSE; + uint16 *dir = S9xGetSampleAddress (ch->sample_number); + ch->block_pointer = *(dir + 1); + S9xAPUSetEndX (J); + } + } + DecodeBlock (ch); + } while (ch->sample_pointer >= SOUND_DECODE_LENGTH); + if (!JUST_PLAYED_LAST_SAMPLE (ch)) + ch->next_sample = ch->block [ch->sample_pointer]; + } + else + ch->next_sample = ch->block [ch->sample_pointer]; + + if (ch->type == SOUND_SAMPLE) + { + if (Settings.InterpolatedSound && freq < FIXED_POINT && !mod) + { + ch->interpolate = ((ch->next_sample - ch->sample) * + (long) freq) / (long) FIXED_POINT; + ch->sample = (int16) (ch->sample + (((ch->next_sample - ch->sample) * + (long) (ch->count)) / (long) FIXED_POINT)); + } + else + ch->interpolate = 0; + } + else + { + for (;V > 0; V--) + if ((so.noise_gen <<= 1) & 0x80000000L) + so.noise_gen ^= 0x0040001L; + ch->sample = (so.noise_gen << 17) >> 17; + ch->interpolate = 0; + } + V = (ch->sample * ch-> left_vol_level) / 128; + } + else + { + if (ch->interpolate) + { + int32 s = (int32) ch->sample + ch->interpolate; + + CLIP16(s); + ch->sample = (int16) s; + V = (ch->sample * ch-> left_vol_level) / 128; + } + } + + MixBuffer [I] += V; + if (ch->echo_buf_ptr) + ch->echo_buf_ptr [I] += V; + + if (pitch_mod & (1 << (J + 1))) + wave [I] = ch->sample * ch->envx; + } +mono_exit: ; + } +} + + +// For backwards compatibility with older port specific code +void S9xMixSamples (signed short *buffer, int sample_count) +{ + S9xMixSamplesO (buffer, sample_count, 0); +} + + +void S9xMixSamplesO (signed short *buffer, int sample_count, int sample_offset) +{ + // 16-bit sound only + int J; + + buffer += sample_offset; +/* + if (so.mute_sound) + { + memset16((uint16_t*)buffer, 0, sample_count); + return; + } +*/ + memset32 ((uint32_t*)MixBuffer, 0, sample_count); + if (SoundData.echo_enable) + memset32 ((uint32_t*)EchoBuffer, 0, sample_count); + + if (so.stereo) + MixStereo (sample_count); + else + MixMono (sample_count); + + /* Mix and convert waveforms */ + if (SoundData.echo_enable && SoundData.echo_buffer_size) + { + if (so.stereo) + { + int l, r; + int master_vol_l = SoundData.master_volume[0]; + int master_vol_r = SoundData.master_volume[1]; + int echo_vol_l = SoundData.echo_volume[0]; + int echo_vol_r = SoundData.echo_volume[1]; + + // 16-bit stereo sound with echo enabled ... + if (SoundData.no_filter) + { + // ... but no filter defined. + for (J = 0; J < sample_count; J+=2) + { + int E = Echo [SoundData.echo_ptr]; + + Echo[SoundData.echo_ptr++] = (E * SoundData.echo_feedback) / 128 + EchoBuffer[J]; + Echo[SoundData.echo_ptr++] = (E * SoundData.echo_feedback) / 128 + EchoBuffer[J+1]; + + if (SoundData.echo_ptr >= SoundData.echo_buffer_size) + SoundData.echo_ptr = 0; + + l = (MixBuffer[J] * master_vol_l + E * echo_vol_l) / VOL_DIV16; + r = (MixBuffer[J+1] * master_vol_r + E * echo_vol_r) / VOL_DIV16; + + CLIP16(l); + CLIP16(r); + buffer[J] = l; + buffer[J+1] = r; + } + } + else + { + // ... with filter defined. + for (J = 0; J < sample_count; J+=2) + { + register int E = Echo [SoundData.echo_ptr]; + + Loop [(Z - 0) & 15] = E; + E = E * FilterTaps [0]; + E += Loop [(Z - 2) & 15] * FilterTaps [1]; + E += Loop [(Z - 4) & 15] * FilterTaps [2]; + E += Loop [(Z - 6) & 15] * FilterTaps [3]; + E += Loop [(Z - 8) & 15] * FilterTaps [4]; + E += Loop [(Z - 10) & 15] * FilterTaps [5]; + E += Loop [(Z - 12) & 15] * FilterTaps [6]; + E += Loop [(Z - 14) & 15] * FilterTaps [7]; + E /= 128; + Z++; + + Echo[SoundData.echo_ptr++] = (E * SoundData.echo_feedback) / 128 + EchoBuffer[J]; + Echo[SoundData.echo_ptr++] = (E * SoundData.echo_feedback) / 128 + EchoBuffer[J+1]; + + if (SoundData.echo_ptr >= SoundData.echo_buffer_size) + SoundData.echo_ptr = 0; + + l = (MixBuffer[J] * master_vol_l + E * echo_vol_l) / VOL_DIV16; + r = (MixBuffer[J+1] * master_vol_r + E * echo_vol_r) / VOL_DIV16; + + CLIP16(l); + CLIP16(r); + buffer[J] = l; + buffer[J+1] = r; + } + } + } + else + { + int I; + int master_vol_l = SoundData.master_volume[0]; + int echo_vol_l = SoundData.echo_volume[0]; + + // 16-bit mono sound with echo enabled... + if (SoundData.no_filter) + { + // ... no filter defined + for (J = 0; J < sample_count; J++) + { + int E = Echo [SoundData.echo_ptr]; + + Echo[SoundData.echo_ptr++] = (E * SoundData.echo_feedback) / 128 + EchoBuffer[J]; + + if (SoundData.echo_ptr >= SoundData.echo_buffer_size) + SoundData.echo_ptr = 0; + + I = (MixBuffer[J] * master_vol_l + E * echo_vol_l) / VOL_DIV16; + CLIP16(I); + buffer[J] = I; + } + } + else + { + // ... with filter defined + for (J = 0; J < sample_count; J++) + { + register int E = Echo [SoundData.echo_ptr]; + + Loop [(Z - 0) & 7] = E; + E = E * FilterTaps [0]; + E += Loop [(Z - 1) & 7] * FilterTaps [1]; + E += Loop [(Z - 2) & 7] * FilterTaps [2]; + E += Loop [(Z - 3) & 7] * FilterTaps [3]; + E += Loop [(Z - 4) & 7] * FilterTaps [4]; + E += Loop [(Z - 5) & 7] * FilterTaps [5]; + E += Loop [(Z - 6) & 7] * FilterTaps [6]; + E += Loop [(Z - 7) & 7] * FilterTaps [7]; + E /= 128; + Z++; + + Echo[SoundData.echo_ptr++] = (E * SoundData.echo_feedback) / 128 + EchoBuffer[J]; + + if (SoundData.echo_ptr >= SoundData.echo_buffer_size) + SoundData.echo_ptr = 0; + + I = (MixBuffer[J] * master_vol_l + E * echo_vol_l) / VOL_DIV16; + CLIP16(I); + buffer[J] = I; + } + } + } + } + else + { + int l, master_vol_l = SoundData.master_volume[0]; + + if (so.stereo) + { + int r, master_vol_r = SoundData.master_volume[1]; + + // 16-bit stereo sound, no echo + for (J = 0; J < sample_count; J+=2) + { + l = (MixBuffer[J] * master_vol_l) / VOL_DIV16; + r = (MixBuffer[J+1] * master_vol_r) / VOL_DIV16; + + CLIP16(l); + CLIP16(r); + buffer[J] = l; + buffer[J+1] = r; + } + } + else + { + // 16-bit mono sound, no echo + for (J = 0; J < sample_count; J++) + { + l = (MixBuffer[J] * master_vol_l) / VOL_DIV16; + + CLIP16(l); + buffer[J] = l; + } + } + } +} + +#ifdef __DJGPP +END_OF_FUNCTION(S9xMixSamplesO); +#endif + +void S9xResetSound (bool8 full) +{ + for (int i = 0; i < 8; i++) + { + SoundData.channels[i].state = SOUND_SILENT; + SoundData.channels[i].mode = MODE_NONE; + SoundData.channels[i].type = SOUND_SAMPLE; + SoundData.channels[i].volume_left = 0; + SoundData.channels[i].volume_right = 0; + SoundData.channels[i].hertz = 0; + SoundData.channels[i].count = 0; + SoundData.channels[i].loop = FALSE; + SoundData.channels[i].envx_target = 0; + SoundData.channels[i].env_error = 0; + SoundData.channels[i].erate = 0; + SoundData.channels[i].envx = 0; + SoundData.channels[i].envxx = 0; + SoundData.channels[i].left_vol_level = 0; + SoundData.channels[i].right_vol_level = 0; + SoundData.channels[i].direction = 0; + SoundData.channels[i].attack_rate = 0; + SoundData.channels[i].decay_rate = 0; + SoundData.channels[i].sustain_rate = 0; + SoundData.channels[i].release_rate = 0; + SoundData.channels[i].sustain_level = 0; + // notaz + SoundData.channels[i].env_ind_attack = 0; + SoundData.channels[i].env_ind_decay = 0; + SoundData.channels[i].env_ind_sustain = 0; + SoundData.echo_ptr = 0; + SoundData.echo_feedback = 0; + SoundData.echo_buffer_size = 1; + } + FilterTaps [0] = 127; + FilterTaps [1] = 0; + FilterTaps [2] = 0; + FilterTaps [3] = 0; + FilterTaps [4] = 0; + FilterTaps [5] = 0; + FilterTaps [6] = 0; + FilterTaps [7] = 0; + so.mute_sound = FALSE; + so.noise_gen = 1; + so.sound_switch = 255; + + if (full) + { + SoundData.master_volume_left = 0; + SoundData.master_volume_right = 0; + SoundData.echo_volume_left = 0; + SoundData.echo_volume_right = 0; + SoundData.echo_enable = 0; + SoundData.echo_write_enabled = 0; + SoundData.echo_channel_enable = 0; + SoundData.pitch_mod = 0; + SoundData.dummy[0] = 0; + SoundData.dummy[1] = 0; + SoundData.dummy[2] = 0; + SoundData.master_volume[0] = 0; + SoundData.master_volume[1] = 0; + SoundData.echo_volume[0] = 0; + SoundData.echo_volume[1] = 0; + SoundData.noise_hertz = 0; + } + + SoundData.master_volume_left = 127; + SoundData.master_volume_right = 127; + SoundData.master_volume [0] = SoundData.master_volume [1] = 127; + SoundData.no_filter = TRUE; +} + + + +extern unsigned long AttackRate [16]; +extern unsigned long DecayRate [8]; +extern unsigned long SustainRate [32]; +extern unsigned long IncreaseRate [32]; +extern unsigned long DecreaseRateExp [32]; + + +void S9xSetPlaybackRate (uint32 playback_rate) +{ + so.playback_rate = playback_rate; + + if(playback_rate) { + // notaz: calclulate a value (let's call it freqbase) to simplify channel freq calculations later. + so.freqbase = (FIXED_POINT<<11) / playback_rate; + // now precalculate env rates for S9xSetEnvRate + static int steps [] = + { + //0, 64, 1238, 1238, 256, 1, 64, 109, 64, 1238 + 0, 64, 619, 619, 128, 1, 64, 55, 64, 619 + }; + int i, u; + for(i=0; i < 16; i++) + for(u=0; u < 10; u++) + AttackERate[i][u] = (unsigned long) (((int64) FIXED_POINT * 1000 * steps[u]) / + (AttackRate[i] * playback_rate)); + for(i=0; i < 8; i++) + for(u=0; u < 10; u++) + DecayERate[i][u] = (unsigned long) (((int64) FIXED_POINT * 1000 * steps[u]) / + (DecayRate[i] * playback_rate)); + + for(i=0; i < 32; i++) + for(u=0; u < 10; u++) + SustainERate[i][u]= (unsigned long) (((int64) FIXED_POINT * 1000 * steps[u]) / + (SustainRate[i] * playback_rate)); + + for(i=0; i < 32; i++) + for(u=0; u < 10; u++) + IncreaseERate[i][u]=(unsigned long) (((int64) FIXED_POINT * 1000 * steps[u]) / + (IncreaseRate[i] * playback_rate)); + + for(i=0; i < 32; i++) + for(u=0; u < 10; u++) + DecreaseERateExp[i][u] = (unsigned long) (((int64) FIXED_POINT * 1000 * steps[u]) / + (DecreaseRateExp[i] / 2 * playback_rate)); + + for(u=0; u < 10; u++) + KeyOffERate[u] = (unsigned long) (((int64) FIXED_POINT * 1000 * steps[u]) / + (8 * playback_rate)); + } + + S9xSetEchoDelay (APU.DSP [APU_EDL] & 0xf); + for (int i = 0; i < 8; i++) + S9xSetSoundFrequency (i, SoundData.channels [i].hertz); +} + +bool8 S9xInitSound (void) +{ + so.playback_rate = 22050; + so.stereo = 0; + so.sound_switch = 255; + + S9xResetSound (TRUE); + S9xSetSoundMute (TRUE); + + return (1); +} + diff --git a/src/snes4iphone_src/soundux.h b/src/snes4iphone_src/soundux.h new file mode 100755 index 0000000..f24d6ab --- /dev/null +++ b/src/snes4iphone_src/soundux.h @@ -0,0 +1,336 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#ifndef _SOUND_H_ +#define _SOUND_H_ + +enum { SOUND_SAMPLE = 0, SOUND_NOISE, SOUND_EXTRA_NOISE, SOUND_MUTE }; +enum { SOUND_SILENT, SOUND_ATTACK, SOUND_DECAY, SOUND_SUSTAIN, + SOUND_RELEASE, SOUND_GAIN, SOUND_INCREASE_LINEAR, + SOUND_INCREASE_BENT_LINE, SOUND_DECREASE_LINEAR, + SOUND_DECREASE_EXPONENTIAL}; + +enum { MODE_NONE = SOUND_SILENT, MODE_ADSR, MODE_RELEASE = SOUND_RELEASE, + MODE_GAIN, MODE_INCREASE_LINEAR, MODE_INCREASE_BENT_LINE, + MODE_DECREASE_LINEAR, MODE_DECREASE_EXPONENTIAL}; + +#define MAX_ENVELOPE_HEIGHT 127 +#define ENVELOPE_SHIFT 7 +#define MAX_VOLUME 127 +#define VOLUME_SHIFT 7 +#define VOL_DIV 128 +#define SOUND_DECODE_LENGTH 16 + +#define NUM_CHANNELS 8 +#define SOUND_BUFFER_SIZE (1024*64) +//(2*44100/50) +#define MAX_BUFFER_SIZE SOUND_BUFFER_SIZE + +#define SOUND_BUFS 4 + +typedef struct { + int playback_rate; + bool8 stereo; + bool8 mute_sound; + uint8 sound_switch; + int noise_gen; + uint32 freqbase; // notaz +} SoundStatus; + +EXTERN_C SoundStatus so; + +typedef struct { + int state; + int type; + short volume_left; + short volume_right; + uint32 hertz; + uint32 frequency; + uint32 count; + bool8 loop; + int envx; + short left_vol_level; + short right_vol_level; + short envx_target; + unsigned long int env_error; + unsigned long erate; + int direction; + unsigned long attack_rate; + unsigned long decay_rate; + unsigned long sustain_rate; + unsigned long release_rate; + unsigned long sustain_level; + signed short sample; + signed short decoded [16]; + signed short previous16 [2]; + signed short *block; + uint16 sample_number; + bool8 last_block; + bool8 needs_decode; + uint32 block_pointer; + uint32 sample_pointer; + int *echo_buf_ptr; + int mode; + int32 envxx; + signed short next_sample; + int32 interpolate; + int32 previous [2]; + // notaz + uint8 env_ind_attack; + uint8 env_ind_decay; + uint8 env_ind_sustain; + uint8 dummy1; + // Just incase they are needed in the future, for snapshot compatibility. + uint32 dummy [7]; + //I'll use Fatl's recovery on savestates. + short gaussian[8]; + int g_index; + unsigned short last_valid_header; +} Channel; + +typedef struct +{ + short master_volume_left; + short master_volume_right; + short echo_volume_left; + short echo_volume_right; + int echo_enable; + int echo_feedback; + int echo_ptr; + int echo_buffer_size; + int echo_write_enabled; + int echo_channel_enable; + int pitch_mod; + // Just incase they are needed in the future, for snapshot compatibility. + uint32 dummy [3]; + Channel channels [NUM_CHANNELS]; + bool8 no_filter; + int master_volume [2]; + int echo_volume [2]; + int noise_hertz; +} SSoundData; + +EXTERN_C SSoundData SoundData; + +void S9xSetEnvelopeHeight (int channel, int height); +void S9xSetSoundKeyOff (int channel); +void S9xSetSoundDecayMode (int channel); +void S9xSetSoundAttachMode (int channel); +void S9xSoundStartEnvelope (Channel *); +void S9xSetSoundSample (int channel, uint16 sample_number); +void S9xSetEchoDelay (int byte); +void S9xResetSound (bool8 full); +void S9xFixSoundAfterSnapshotLoad (); +void S9xPlaybackSoundSetting (int channel); +void S9xFixEnvelope (int channel, uint8 gain, uint8 adsr1, uint8 adsr2); +void S9xStartSample (int channel); + +EXTERN_C void S9xMixSamples (signed short *buffer, int sample_count); +EXTERN_C void S9xMixSamplesO(signed short *buffer, int sample_count, int sample_offset); +void S9xSetPlaybackRate (uint32 rate); +bool8 S9xInitSound (void); +#endif + + + +// notaz: some stuff from soundux.cpp to enable their inlining +#include "apu.h" +//#define DEBUG +//#include + +extern int Echo [24000]; +extern int Loop [16]; +extern int FilterTaps [8]; +extern int EchoBuffer [SOUND_BUFFER_SIZE]; +extern int NoiseFreq [32]; + +// precalculated env rates for S9xSetEnvRate +extern unsigned long AttackERate [16][10]; +extern unsigned long DecayERate [8][10]; +extern unsigned long SustainERate [32][10]; +extern unsigned long IncreaseERate [32][10]; +extern unsigned long DecreaseERateExp[32][10]; +extern unsigned long KeyOffERate[10]; + + +#define FIXED_POINT 0x10000UL +#define CLIP8(v) \ +if ((v) < -128) \ + (v) = -128; \ +else \ +if ((v) > 127) \ + (v) = 127 + +static inline void S9xSetSoundMute (bool8 mute) +{ + //bool8 old = so.mute_sound; + so.mute_sound = mute; + //return (old); +} + +static inline void S9xSetEnvRate (Channel *ch, unsigned long rate, int direction, int target, unsigned int mode) +{ + ch->envx_target = target; + + if (rate == ~0UL) + { + ch->direction = 0; + rate = 0; + } + else + ch->direction = direction; + + + if (rate == 0 || so.playback_rate == 0) + ch->erate = 0; + else + { + switch(mode >> 28) { + case 0: // attack + ch->erate = AttackERate[ch->env_ind_attack][ch->state]; + break; + + case 1: // Decay + ch->erate = DecayERate[ch->env_ind_decay][ch->state]; + break; + + case 2: // Sustain + ch->erate = SustainERate[ch->env_ind_sustain][ch->state]; + break; + + case 3: // Increase + ch->erate = IncreaseERate[mode&0x1f][ch->state]; + break; + + case 4: // DecreaseExp + ch->erate = DecreaseERateExp[mode&0x1f][ch->state]; + break; + + case 5: // KeyOff + ch->erate = KeyOffERate[ch->state]; + break; + } + } + +#if 0 + static int steps [] = + { +// 0, 64, 1238, 1238, 256, 1, 64, 109, 64, 1238 + 0, 64, 619, 619, 128, 1, 64, 55, 64, 619 + }; + + if (rate == 0 || so.playback_rate == 0) + ch->erate = 0; + else + { + ch->erate = (unsigned long) + (((int64) FIXED_POINT * 1000 * steps [ch->state]) / + (rate * so.playback_rate)); + } +#endif +} + +static inline void S9xSetEchoEnable (uint8 byte) +{ + SoundData.echo_channel_enable = byte; + if (!SoundData.echo_write_enabled || Settings.DisableSoundEcho) + byte = 0; + if (byte && !SoundData.echo_enable) + { + memset (Echo, 0, sizeof (Echo)); + memset (Loop, 0, sizeof (Loop)); + } + + SoundData.echo_enable = byte; + for (int i = 0; i < 8; i++) + { + if (byte & (1 << i)) + SoundData.channels [i].echo_buf_ptr = EchoBuffer; + else + SoundData.channels [i].echo_buf_ptr = 0; + } +} + +static inline void S9xSetEchoFeedback (int feedback) +{ + CLIP8(feedback); + SoundData.echo_feedback = feedback; +} + +static inline void S9xSetFilterCoefficient (int tap, int value) +{ + FilterTaps [tap & 7] = value; + SoundData.no_filter = (FilterTaps [0] == 127 || FilterTaps [0] == 0) && + FilterTaps [1] == 0 && + FilterTaps [2] == 0 && + FilterTaps [3] == 0 && + FilterTaps [4] == 0 && + FilterTaps [5] == 0 && + FilterTaps [6] == 0 && + FilterTaps [7] == 0; +} + +static inline uint16 *S9xGetSampleAddress (int sample_number) +{ + uint32 addr = (((APU.DSP[APU_DIR] << 8) + (sample_number << 2)) & 0xffff); + return (uint16 *)(IAPU.RAM + addr); +} + +static inline void S9xSetSoundFrequency (int channel, int hertz) // hertz [0~64K<<1] +{ + if (so.playback_rate) + { + if (SoundData.channels[channel].type == SOUND_NOISE) + hertz = NoiseFreq [APU.DSP [APU_FLG] & 0x1f]; +#if 0 // notaz: this compiles to something awful + SoundData.channels[channel].frequency = (int) + (((int64) hertz * FIXED_POINT) / so.playback_rate); +#else + SoundData.channels[channel].frequency = (hertz * so.freqbase) >> 11; +#endif + + /* if (Settings.FixFrequency) + { + SoundData.channels[channel].frequency = + (unsigned long) ((double) SoundData.channels[channel].frequency * 0.980); + }*/ + } +} + diff --git a/src/snes4iphone_src/sounduxnew.cpp b/src/snes4iphone_src/sounduxnew.cpp new file mode 100755 index 0000000..e1a3175 --- /dev/null +++ b/src/snes4iphone_src/sounduxnew.cpp @@ -0,0 +1,2105 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#ifdef __DJGPP__ +//#include +#undef TRUE +#endif + +#include +#include +#include +#ifndef _SNESPPC +#include +#include +#endif + +#define CLIP16(v) \ +if ((v) < -32768) \ + (v) = -32768; \ +else \ +if ((v) > 32767) \ + (v) = 32767 + +#define CLIP16_latch(v,l) \ +if ((v) < -32768) \ +{ (v) = -32768; (l)++; }\ +else \ +if ((v) > 32767) \ +{ (v) = 32767; (l)++; } + +#define CLIP24(v) \ +if ((v) < -8388608) \ + (v) = -8388608; \ +else \ +if ((v) > 8388607) \ + (v) = 8388607 + +#define CLIP8(v) \ +if ((v) < -128) \ + (v) = -128; \ +else \ +if ((v) > 127) \ + (v) = 127 + +#include "snes9x.h" +#include "soundux.h" +#include "apu.h" +#include "memmap.h" +#include "cpuexec.h" + + +extern int Echo [24000]; +extern int DummyEchoBuffer [SOUND_BUFFER_SIZE]; +extern int MixBuffer [SOUND_BUFFER_SIZE]; +extern int EchoBuffer [SOUND_BUFFER_SIZE]; +extern int FilterTaps [8]; +extern unsigned long Z; +extern int Loop [16]; + +extern long FilterValues[4][2]; +extern int NoiseFreq [32]; + +#undef ABS +#define ABS(a) ((a) < 0 ? -(a) : (a)) + +#define FIXED_POINT 0x10000UL +#define FIXED_POINT_REMAINDER 0xffffUL +#define FIXED_POINT_SHIFT 16 + +#define VOL_DIV8 0x8000 +#define VOL_DIV16 0x0080 +#define ENVX_SHIFT 24 + +extern "C" void DecodeBlockAsm (int8 *, int16 *, int32 *, int32 *); +extern "C" void DecodeBlockAsm2 (int8 *, int16 *, int32 *, int32 *); + +// F is channel's current frequency and M is the 16-bit modulation waveform +// from the previous channel multiplied by the current envelope volume level. +#define PITCH_MOD(F,M) ((F) * ((((unsigned long) (M)) + 0x800000) >> 16) >> 7) +//#define PITCH_MOD(F,M) ((F) * ((((M) & 0x7fffff) >> 14) + 1) >> 8) + +#define LAST_SAMPLE 0xffffff +#define JUST_PLAYED_LAST_SAMPLE(c) ((c)->sample_pointer >= LAST_SAMPLE) + +STATIC INLINE uint8 *S9xGetSampleAddress (int sample_number) +{ + uint32 addr = (((APU.DSP[APU_DIR] << 8) + (sample_number << 2)) & 0xffff); + return (IAPU.RAM + addr); +} + +void S9xAPUSetEndOfSample (int i, Channel *ch) +{ + ch->state = SOUND_SILENT; + ch->mode = MODE_NONE; + APU.DSP [APU_ENDX] |= 1 << i; + APU.DSP [APU_KON] &= ~(1 << i); + APU.DSP [APU_KOFF] &= ~(1 << i); + APU.KeyedChannels &= ~(1 << i); +} +#ifdef __DJGPP +END_OF_FUNCTION (S9xAPUSetEndOfSample) +#endif + +void S9xAPUSetEndX (int ch) +{ + APU.DSP [APU_ENDX] |= 1 << ch; +} +#ifdef __DJGPP +END_OF_FUNCTION (S9xAPUSetEndX) +#endif + +void S9xSetEnvRate (Channel *ch, unsigned long rate, int direction, int target) +{ + ch->envx_target = target; + + if (rate == ~0UL) + { + ch->direction = 0; + rate = 0; + } + else + ch->direction = direction; + + static int steps [] = + { +// 0, 64, 1238, 1238, 256, 1, 64, 109, 64, 1238 + 0, 64, 619, 619, 128, 1, 64, 55, 64, 619 + }; + + if (rate == 0 || so.playback_rate == 0) + ch->erate = 0; + else + { + ch->erate = (unsigned long) + (((int64) FIXED_POINT * 1000 * steps [ch->state]) / + (rate * so.playback_rate)); + } +} + +#ifdef __DJGPP +END_OF_FUNCTION(S9xSetEnvRate); +#endif + +void S9xSetEnvelopeRate (int channel, unsigned long rate, int direction, + int target) +{ + S9xSetEnvRate (&SoundData.channels [channel], rate, direction, target); +} + +#ifdef __DJGPP +END_OF_FUNCTION(S9xSetEnvelopeRate); +#endif + +void S9xSetSoundVolume (int channel, short volume_left, short volume_right) +{ + Channel *ch = &SoundData.channels[channel]; + if (!so.stereo) + volume_left = (ABS(volume_right) + ABS(volume_left)) / 2; + + ch->volume_left = volume_left; + ch->volume_right = volume_right; + ch-> left_vol_level = (ch->envx * volume_left) / 128; + ch->right_vol_level = (ch->envx * volume_right) / 128; +} + +void S9xSetMasterVolume (short volume_left, short volume_right) +{ + if (Settings.DisableMasterVolume) + { + SoundData.master_volume_left = 127; + SoundData.master_volume_right = 127; + SoundData.master_volume [0] = SoundData.master_volume [1] = 127; + } + else + { + if (!so.stereo) + volume_left = (ABS (volume_right) + ABS (volume_left)) / 2; + SoundData.master_volume_left = volume_left; + SoundData.master_volume_right = volume_right; + SoundData.master_volume [Settings.ReverseStereo] = volume_left; + SoundData.master_volume [1 ^ Settings.ReverseStereo] = volume_right; + } +} + +void S9xSetEchoVolume (short volume_left, short volume_right) +{ + if (!so.stereo) + volume_left = (ABS (volume_right) + ABS (volume_left)) / 2; + SoundData.echo_volume_left = volume_left; + SoundData.echo_volume_right = volume_right; + SoundData.echo_volume [Settings.ReverseStereo] = volume_left; + SoundData.echo_volume [1 ^ Settings.ReverseStereo] = volume_right; +} + +void S9xSetEchoEnable (uint8 byte) +{ + SoundData.echo_channel_enable = byte; + if (!SoundData.echo_write_enabled || Settings.DisableSoundEcho) + byte = 0; + if (byte && !SoundData.echo_enable) + { + memset (Echo, 0, sizeof (Echo)); + memset (Loop, 0, sizeof (Loop)); + } + + SoundData.echo_enable = byte; + for (int i = 0; i < 8; i++) + { + if (byte & (1 << i)) + SoundData.channels [i].echo_buf_ptr = EchoBuffer; + else + SoundData.channels [i].echo_buf_ptr = DummyEchoBuffer; + } +} + +void S9xSetEchoFeedback (int feedback) +{ + CLIP8(feedback); + SoundData.echo_feedback = feedback; +} + +void S9xSetEchoDelay (int delay) +{ + SoundData.echo_buffer_size = (512 * delay * so.playback_rate) / 32000; + if (so.stereo) + SoundData.echo_buffer_size <<= 1; + if (SoundData.echo_buffer_size) + SoundData.echo_ptr %= SoundData.echo_buffer_size; + else + SoundData.echo_ptr = 0; + S9xSetEchoEnable (APU.DSP [APU_EON]); +} + +void S9xSetEchoWriteEnable (uint8 byte) +{ + SoundData.echo_write_enabled = byte; + S9xSetEchoDelay (APU.DSP [APU_EDL] & 15); +} + +void S9xSetFrequencyModulationEnable (uint8 byte) +{ + SoundData.pitch_mod = byte & ~1; +} + +void S9xSetSoundKeyOff (int channel) +{ + Channel *ch = &SoundData.channels[channel]; + + if (ch->state != SOUND_SILENT) + { + ch->state = SOUND_RELEASE; + ch->mode = MODE_RELEASE; + S9xSetEnvRate (ch, 8, -1, 0); + } +} + +void S9xFixSoundAfterSnapshotLoad () +{ + SoundData.echo_write_enabled = !(APU.DSP [APU_FLG] & 0x20); + SoundData.echo_channel_enable = APU.DSP [APU_EON]; + S9xSetEchoDelay (APU.DSP [APU_EDL] & 0xf); + S9xSetEchoFeedback ((signed char) APU.DSP [APU_EFB]); + + S9xSetFilterCoefficient (0, (signed char) APU.DSP [APU_C0]); + S9xSetFilterCoefficient (1, (signed char) APU.DSP [APU_C1]); + S9xSetFilterCoefficient (2, (signed char) APU.DSP [APU_C2]); + S9xSetFilterCoefficient (3, (signed char) APU.DSP [APU_C3]); + S9xSetFilterCoefficient (4, (signed char) APU.DSP [APU_C4]); + S9xSetFilterCoefficient (5, (signed char) APU.DSP [APU_C5]); + S9xSetFilterCoefficient (6, (signed char) APU.DSP [APU_C6]); + S9xSetFilterCoefficient (7, (signed char) APU.DSP [APU_C7]); + for (int i = 0; i < 8; i++) + { + SoundData.channels[i].needs_decode = TRUE; + S9xSetSoundFrequency (i, SoundData.channels[i].hertz); + SoundData.channels [i].envxx = SoundData.channels [i].envx << ENVX_SHIFT; + SoundData.channels [i].next_sample = 0; + SoundData.channels [i].interpolate = 0; + SoundData.channels [i].previous [0] = (int32) SoundData.channels [i].previous16 [0]; + SoundData.channels [i].previous [1] = (int32) SoundData.channels [i].previous16 [1]; + } + SoundData.master_volume [Settings.ReverseStereo] = SoundData.master_volume_left; + SoundData.master_volume [1 ^ Settings.ReverseStereo] = SoundData.master_volume_right; + SoundData.echo_volume [Settings.ReverseStereo] = SoundData.echo_volume_left; + SoundData.echo_volume [1 ^ Settings.ReverseStereo] = SoundData.echo_volume_right; + IAPU.Scanline = 0; +} + +void S9xSetFilterCoefficient (int tap, int value) +{ + FilterTaps [tap & 7] = value; + SoundData.no_filter = (FilterTaps [0] == 127 || FilterTaps [0] == 0) && + FilterTaps [1] == 0 && + FilterTaps [2] == 0 && + FilterTaps [3] == 0 && + FilterTaps [4] == 0 && + FilterTaps [5] == 0 && + FilterTaps [6] == 0 && + FilterTaps [7] == 0; +} + +void S9xSetSoundADSR (int channel, int attack_rate, int decay_rate, + int sustain_rate, int sustain_level, int release_rate) +{ + SoundData.channels[channel].attack_rate = attack_rate; + SoundData.channels[channel].decay_rate = decay_rate; + SoundData.channels[channel].sustain_rate = sustain_rate; + SoundData.channels[channel].release_rate = release_rate; + SoundData.channels[channel].sustain_level = sustain_level + 1; + + switch (SoundData.channels[channel].state) + { + case SOUND_ATTACK: + S9xSetEnvelopeRate (channel, attack_rate, 1, 127); + break; + + case SOUND_DECAY: + S9xSetEnvelopeRate (channel, decay_rate, -1, + (MAX_ENVELOPE_HEIGHT * (sustain_level + 1)) >> 3); + break; + case SOUND_SUSTAIN: + S9xSetEnvelopeRate (channel, sustain_rate, -1, 0); + break; + } +} + +void S9xSetEnvelopeHeight (int channel, int level) +{ + Channel *ch = &SoundData.channels[channel]; + + ch->envx = level; + ch->envxx = level << ENVX_SHIFT; + + ch->left_vol_level = (level * ch->volume_left) / 128; + ch->right_vol_level = (level * ch->volume_right) / 128; + + if (ch->envx == 0 && ch->state != SOUND_SILENT && ch->state != SOUND_GAIN) + { + S9xAPUSetEndOfSample (channel, ch); + } +} + +int S9xGetEnvelopeHeight (int channel) +{ + if ((Settings.SoundEnvelopeHeightReading || + SNESGameFixes.SoundEnvelopeHeightReading2) && + SoundData.channels[channel].state != SOUND_SILENT && + SoundData.channels[channel].state != SOUND_GAIN) + { + return (SoundData.channels[channel].envx); + } + + //siren fix from XPP + if (SNESGameFixes.SoundEnvelopeHeightReading2 && + SoundData.channels[channel].state != SOUND_SILENT) + { + return (SoundData.channels[channel].envx); + } + + return (0); +} + +#if 1 +void S9xSetSoundSample (int, uint16) +{ +} +#else +void S9xSetSoundSample (int channel, uint16 sample_number) +{ + register Channel *ch = &SoundData.channels[channel]; + + if (ch->state != SOUND_SILENT && + sample_number != ch->sample_number) + { + int keep = ch->state; + ch->state = SOUND_SILENT; + ch->sample_number = sample_number; + ch->loop = FALSE; + ch->needs_decode = TRUE; + ch->last_block = FALSE; + ch->previous [0] = ch->previous[1] = 0; + uint8 *dir = S9xGetSampleAddress (sample_number); + ch->block_pointer = READ_WORD (dir); + ch->sample_pointer = 0; + ch->state = keep; + } +} +#endif + +void S9xSetSoundFrequency (int channel, int hertz) +{ + if (so.playback_rate) + { + if (SoundData.channels[channel].type == SOUND_NOISE) + hertz = NoiseFreq [APU.DSP [APU_FLG] & 0x1f]; + SoundData.channels[channel].frequency = (int) + (((int64) hertz * FIXED_POINT) / so.playback_rate); + if (Settings.FixFrequency) + { + SoundData.channels[channel].frequency = + (unsigned long) ((double) SoundData.channels[channel].frequency * 0.980); + } + } +} + +void S9xSetSoundHertz (int channel, int hertz) +{ + SoundData.channels[channel].hertz = hertz; + S9xSetSoundFrequency (channel, hertz); +} + +void S9xSetSoundType (int channel, int type_of_sound) +{ + SoundData.channels[channel].type = type_of_sound; +} + +bool8_32 S9xSetSoundMute (bool8_32 mute) +{ + bool8_32 old = so.mute_sound; + so.mute_sound = mute; + return (old); +} + +void AltDecodeBlock_PPC (Channel *ch, struct SIAPU * iapu) +{ + if (ch->block_pointer >= 0x10000 - 9) + { + ch->last_block = TRUE; + ch->loop = FALSE; + ch->block = ch->decoded; + memset ((void *) ch->decoded, 0, sizeof (int16) * 16); + return; + } + signed char *compressed = (signed char *) &iapu->RAM [ch->block_pointer]; + + unsigned char filter = *compressed; + if ((ch->last_block = filter & 1)) + ch->loop = (filter & 2) != 0; + +#if (defined (__i386__) || defined (__i486__) ||\ + defined (__i586__) || defined (__WIN32__) || defined (__DJGPP)) + int16 *raw = ch->block = ch->decoded; + + if (Settings.AltSampleDecode == 1) + DecodeBlockAsm (compressed, raw, &ch->previous [0], &ch->previous [1]); + else + DecodeBlockAsm2 (compressed, raw, &ch->previous [0], &ch->previous [1]); +#else + int32 out; + unsigned char shift; + signed char sample1, sample2; + unsigned int i; + + compressed++; + signed short *raw = ch->block = ch->decoded; + + int32 prev0 = ch->previous [0]; + int32 prev1 = ch->previous [1]; + shift = filter >> 4; + + switch ((filter >> 2) & 3) + { + case 0: + for (i = 8; i != 0; i--) + { + sample1 = *compressed++; + sample2 = sample1 << 4; + sample2 >>= 4; + sample1 >>= 4; + *raw++ = ((int32) sample1 << shift); + *raw++ = ((int32) sample2 << shift); + } + prev1 = *(raw - 2); + prev0 = *(raw - 1); + break; + case 1: + for (i = 8; i != 0; i--) + { + sample1 = *compressed++; + sample2 = sample1 << 4; + sample2 >>= 4; + sample1 >>= 4; + prev0 = (int16) prev0; + *raw++ = prev1 = ((int32) sample1 << shift) + prev0 - (prev0 >> 4); + prev1 = (int16) prev1; + *raw++ = prev0 = ((int32) sample2 << shift) + prev1 - (prev1 >> 4); + } + break; + case 2: + for (i = 8; i != 0; i--) + { + sample1 = *compressed++; + sample2 = sample1 << 4; + sample2 >>= 4; + sample1 >>= 4; + + out = (sample1 << shift) - prev1 + (prev1 >> 4); + prev1 = (int16) prev0; + prev0 &= ~3; + *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 5) - + (prev0 >> 4); + + out = (sample2 << shift) - prev1 + (prev1 >> 4); + prev1 = (int16) prev0; + prev0 &= ~3; + *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 5) - + (prev0 >> 4); + } + break; + case 3: + for (i = 8; i != 0; i--) + { + sample1 = *compressed++; + sample2 = sample1 << 4; + sample2 >>= 4; + sample1 >>= 4; + out = (sample1 << shift); + + out = out - prev1 + (prev1 >> 3) + (prev1 >> 4); + prev1 = (int16) prev0; + prev0 &= ~3; + *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 3) - + (prev0 >> 4) - (prev1 >> 6); + + out = (sample2 << shift); + out = out - prev1 + (prev1 >> 3) + (prev1 >> 4); + prev1 = (int16) prev0; + prev0 &= ~3; + *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 3) - + (prev0 >> 4) - (prev1 >> 6); + } + break; + } + ch->previous [0] = prev0; + ch->previous [1] = prev1; +#endif + + ch->block_pointer += 9; +} + +void AltDecodeBlock (Channel *ch, struct SIAPU * iapu) +{ + if (ch->block_pointer >= 0x10000 - 9) + { + ch->last_block = TRUE; + ch->loop = FALSE; + ch->block = ch->decoded; + memset ((void *) ch->decoded, 0, sizeof (int16) * 16); + return; + } + signed char *compressed = (signed char *) &iapu->RAM [ch->block_pointer]; + + unsigned char filter = *compressed; + if ((ch->last_block = filter & 1)) + ch->loop = (filter & 2) != 0; + +#if (defined (__i386__) || defined (__i486__) ||\ + defined (__i586__) || defined (__WIN32__) || defined (__DJGPP)) + int16 *raw = ch->block = ch->decoded; + + if (Settings.AltSampleDecode == 1) + DecodeBlockAsm (compressed, raw, &ch->previous [0], &ch->previous [1]); + else + DecodeBlockAsm2 (compressed, raw, &ch->previous [0], &ch->previous [1]); +#else + int32 out; + unsigned char shift; + signed char sample1, sample2; + unsigned int i; + + compressed++; + signed short *raw = ch->block = ch->decoded; + + int32 prev0 = ch->previous [0]; + int32 prev1 = ch->previous [1]; + shift = filter >> 4; + + switch ((filter >> 2) & 3) + { + case 0: + for (i = 8; i != 0; i--) + { + sample1 = *compressed++; + sample2 = sample1 << 4; + sample2 >>= 4; + sample1 >>= 4; + *raw++ = ((int32) sample1 << shift); + *raw++ = ((int32) sample2 << shift); + } + prev1 = *(raw - 2); + prev0 = *(raw - 1); + break; + case 1: + for (i = 8; i != 0; i--) + { + sample1 = *compressed++; + sample2 = sample1 << 4; + sample2 >>= 4; + sample1 >>= 4; + prev0 = (int16) prev0; + *raw++ = prev1 = ((int32) sample1 << shift) + prev0 - (prev0 >> 4); + prev1 = (int16) prev1; + *raw++ = prev0 = ((int32) sample2 << shift) + prev1 - (prev1 >> 4); + } + break; + case 2: + for (i = 8; i != 0; i--) + { + sample1 = *compressed++; + sample2 = sample1 << 4; + sample2 >>= 4; + sample1 >>= 4; + + out = (sample1 << shift) - prev1 + (prev1 >> 4); + prev1 = (int16) prev0; + prev0 &= ~3; + *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 5) - + (prev0 >> 4); + + out = (sample2 << shift) - prev1 + (prev1 >> 4); + prev1 = (int16) prev0; + prev0 &= ~3; + *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 5) - + (prev0 >> 4); + } + break; + case 3: + for (i = 8; i != 0; i--) + { + sample1 = *compressed++; + sample2 = sample1 << 4; + sample2 >>= 4; + sample1 >>= 4; + out = (sample1 << shift); + + out = out - prev1 + (prev1 >> 3) + (prev1 >> 4); + prev1 = (int16) prev0; + prev0 &= ~3; + *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 3) - + (prev0 >> 4) - (prev1 >> 6); + + out = (sample2 << shift); + out = out - prev1 + (prev1 >> 3) + (prev1 >> 4); + prev1 = (int16) prev0; + prev0 &= ~3; + *raw++ = prev0 = out + (prev0 << 1) - (prev0 >> 3) - + (prev0 >> 4) - (prev1 >> 6); + } + break; + } + ch->previous [0] = prev0; + ch->previous [1] = prev1; +#endif + + ch->block_pointer += 9; +} + +void AltDecodeBlock2 (Channel *ch) +{ + int32 out; + unsigned char filter; + unsigned char shift; + signed char sample1, sample2; + unsigned char i; + + if (ch->block_pointer > 0x10000 - 9) + { + ch->last_block = TRUE; + ch->loop = FALSE; + ch->block = ch->decoded; + memset ((void *) ch->decoded, 0, sizeof (int16) * 16); + return; + } + + signed char *compressed = (signed char *) &IAPU.RAM [ch->block_pointer]; + + filter = *compressed; + if ((ch->last_block = filter & 1)) + ch->loop = (filter & 2) != 0; + + compressed++; + signed short *raw = ch->block = ch->decoded; + + shift = filter >> 4; + int32 prev0 = ch->previous [0]; + int32 prev1 = ch->previous [1]; + + if(shift > 12) + shift -= 4; + + switch ((filter >> 2) & 3) + { + case 0: + for (i = 8; i != 0; i--) + { + sample1 = *compressed++; + sample2 = sample1 << 4; + //Sample 2 = Bottom Nibble, Sign Extended. + sample2 >>= 4; + //Sample 1 = Top Nibble, shifted down and Sign Extended. + sample1 >>= 4; + + out = (int32)(sample1 << shift); + + prev1 = prev0; + prev0 = out; + CLIP16(out); + *raw++ = (int16)out; + + out = (int32)(sample2 << shift); + + prev1 = prev0; + prev0 = out; + CLIP16(out); + *raw++ = (int16)out; + } + break; + case 1: + for (i = 8; i != 0; i--) + { + sample1 = *compressed++; + sample2 = sample1 << 4; + //Sample 2 = Bottom Nibble, Sign Extended. + sample2 >>= 4; + //Sample 1 = Top Nibble, shifted down and Sign Extended. + sample1 >>= 4; + out = (int32)(sample1 << shift); + out += (int32)((double)prev0 * 15/16); + + prev1 = prev0; + prev0 = out; + CLIP16(out); + *raw++ = (int16)out; + + out = (int32)(sample2 << shift); + out += (int32)((double)prev0 * 15/16); + + prev1 = prev0; + prev0 = out; + CLIP16(out); + *raw++ = (int16)out; + } + break; + case 2: + for (i = 8; i != 0; i--) + { + sample1 = *compressed++; + sample2 = sample1 << 4; + //Sample 2 = Bottom Nibble, Sign Extended. + sample2 >>= 4; + //Sample 1 = Top Nibble, shifted down and Sign Extended. + sample1 >>= 4; + + out = ((sample1 << shift) * 256 + (prev0 & ~0x2) * 488 - prev1 * 240) >> 8; + + prev1 = prev0; + prev0 = (int16)out; + *raw++ = (int16)out; + + out = ((sample2 << shift) * 256 + (prev0 & ~0x2) * 488 - prev1 * 240) >> 8; + + prev1 = prev0; + prev0 = (int16)out; + *raw++ = (int16)out; + } + break; + + case 3: + for (i = 8; i != 0; i--) + { + sample1 = *compressed++; + sample2 = sample1 << 4; + //Sample 2 = Bottom Nibble, Sign Extended. + sample2 >>= 4; + //Sample 1 = Top Nibble, shifted down and Sign Extended. + sample1 >>= 4; + out = (int32)(sample1 << shift); + out += (int32)((double)prev0 * 115/64 - (double)prev1 * 13/16); + + prev1 = prev0; + prev0 = out; + + CLIP16(out); + *raw++ = (int16)out; + + out = (int32)(sample2 << shift); + out += (int32)((double)prev0 * 115/64 - (double)prev1 * 13/16); + + prev1 = prev0; + prev0 = out; + + CLIP16(out); + *raw++ = (int16)out; + } + break; + } + ch->previous [0] = prev0; + ch->previous [1] = prev1; + ch->block_pointer += 9; +} + +void DecodeBlock (Channel *ch) +{ + int32 out; + unsigned char filter; + unsigned char shift; + signed char sample1, sample2; + unsigned char i; + + if (Settings.AltSampleDecode) + { + if (Settings.AltSampleDecode < 3) + AltDecodeBlock (ch, &IAPU); + else + AltDecodeBlock2 (ch); + return; + } + if (ch->block_pointer > 0x10000 - 9) + { + ch->last_block = TRUE; + ch->loop = FALSE; + ch->block = ch->decoded; + return; + } + signed char *compressed = (signed char *) &IAPU.RAM [ch->block_pointer]; + + filter = *compressed; + if ((ch->last_block = filter & 1)) + ch->loop = (filter & 2) != 0; + + // If enabled, results in 'tick' sound on some samples that repeat by + // re-using part of the original sample but generate a slightly different + // waveform. + if (!Settings.DisableSampleCaching && + memcmp ((uint8 *) compressed, &IAPU.ShadowRAM [ch->block_pointer], 9) == 0) + { + ch->block = (signed short *) (IAPU.CachedSamples + (ch->block_pointer << 2)); + ch->previous [0] = ch->block [15]; + ch->previous [1] = ch->block [14]; + } + else + { + if (!Settings.DisableSampleCaching) + memcpy (&IAPU.ShadowRAM [ch->block_pointer], (uint8 *) compressed, 9); + compressed++; + signed short *raw = ch->block = ch->decoded; + + shift = filter >> 4; + filter = ((filter >> 2) & 3); + int32 prev0 = ch->previous [0]; + int32 prev1 = ch->previous [1]; + int32 f0 = FilterValues[filter][0]; + int32 f1 = FilterValues[filter][1]; + + for (i = 8; i != 0; i--) + { + sample1 = *compressed++; + sample2 = sample1 << 4; + //Sample 2 = Bottom Nibble, Sign Extended. + sample2 >>= 4; + //Sample 1 = Top Nibble, shifted down and Sign Extended. + sample1 >>= 4; + out = (sample1 << shift); + out += (prev0 * f0 + prev1 * f1) / 256; + + CLIP16 (out); + prev1 = prev0; + prev0 = out; + *raw++ = (signed short) out; + + out = (sample2 << shift); + out += (prev0 * f0 + prev1 * f1) / 256; + + CLIP16 (out); + prev1 = prev0; + prev0 = out; + *raw++ = (signed short) out; + } + ch->previous [0] = prev0; + ch->previous [1] = prev1; + + if (!Settings.DisableSampleCaching) + { + memcpy (IAPU.CachedSamples + (ch->block_pointer << 2), + (uint8 *) ch->decoded, 32); + } + } + ch->block_pointer += 9; +} + +void MixStereo (int sample_count) +{ + struct SIAPU * iapu = &IAPU; +#if defined(TARGET_OS_MAC) && TARGET_OS_MAC + static int wave[SOUND_BUFFER_SIZE]; +#else + int wave[SOUND_BUFFER_SIZE]; +#endif + int pitch_mod = SoundData.pitch_mod & ~APU.DSP[APU_NON]; + + for (uint32 J = 0; J < NUM_CHANNELS; J++) + { + int32 VL, VR; + Channel *ch = &SoundData.channels[J]; + unsigned long freq0 = ch->frequency; + + if (ch->state == SOUND_SILENT || !(so.sound_switch & (1 << J))) + continue; + +// freq0 = (unsigned long) ((double) freq0 * 0.985); + + bool8_32 mod = pitch_mod & (1 << J); + + if (ch->needs_decode) + { + AltDecodeBlock(ch, iapu); + //DecodeBlock(ch); + ch->needs_decode = FALSE; + ch->sample = ch->block[0]; + ch->sample_pointer = freq0 >> FIXED_POINT_SHIFT; + if (ch->sample_pointer == 0) + ch->sample_pointer = 1; + if (ch->sample_pointer > SOUND_DECODE_LENGTH) + ch->sample_pointer = SOUND_DECODE_LENGTH - 1; + + ch->next_sample = ch->block[ch->sample_pointer]; + ch->interpolate = 0; + + if (Settings.InterpolatedSound && freq0 < FIXED_POINT && !mod) + ch->interpolate = ((ch->next_sample - ch->sample) * + (long) freq0) / (long) FIXED_POINT; + } + VL = (ch->sample * ch-> left_vol_level) / 128; + VR = (ch->sample * ch->right_vol_level) / 128; + + for (uint32 I = 0; I < (uint32) sample_count; I += 2) + { + unsigned long freq = freq0; + + if (mod) + freq = PITCH_MOD(freq, wave [I / 2]); + + ch->env_error += ch->erate; + if (ch->env_error >= FIXED_POINT) + { + uint32 step = ch->env_error >> FIXED_POINT_SHIFT; + + switch (ch->state) + { + case SOUND_ATTACK: + ch->env_error &= FIXED_POINT_REMAINDER; + ch->envx += step << 1; + ch->envxx = ch->envx << ENVX_SHIFT; + + if (ch->envx >= 126) + { + ch->envx = 127; + ch->envxx = 127 << ENVX_SHIFT; + ch->state = SOUND_DECAY; + if (ch->sustain_level != 8) + { + S9xSetEnvRate (ch, ch->decay_rate, -1, + (MAX_ENVELOPE_HEIGHT * ch->sustain_level) + >> 3); + break; + } + ch->state = SOUND_SUSTAIN; + S9xSetEnvRate (ch, ch->sustain_rate, -1, 0); + } + break; + + case SOUND_DECAY: + while (ch->env_error >= FIXED_POINT) + { + ch->envxx = (ch->envxx >> 8) * 255; + ch->env_error -= FIXED_POINT; + } + ch->envx = ch->envxx >> ENVX_SHIFT; + if (ch->envx <= ch->envx_target) + { + if (ch->envx <= 0) + { + S9xAPUSetEndOfSample (J, ch); + goto stereo_exit; + } + ch->state = SOUND_SUSTAIN; + S9xSetEnvRate (ch, ch->sustain_rate, -1, 0); + } + break; + + case SOUND_SUSTAIN: + while (ch->env_error >= FIXED_POINT) + { + ch->envxx = (ch->envxx >> 8) * 255; + ch->env_error -= FIXED_POINT; + } + ch->envx = ch->envxx >> ENVX_SHIFT; + if (ch->envx <= 0) + { + S9xAPUSetEndOfSample (J, ch); + goto stereo_exit; + } + break; + + case SOUND_RELEASE: + while (ch->env_error >= FIXED_POINT) + { + ch->envxx -= (MAX_ENVELOPE_HEIGHT << ENVX_SHIFT) / 256; + ch->env_error -= FIXED_POINT; + } + ch->envx = ch->envxx >> ENVX_SHIFT; + if (ch->envx <= 0) + { + S9xAPUSetEndOfSample (J, ch); + goto stereo_exit; + } + break; + + case SOUND_INCREASE_LINEAR: + ch->env_error &= FIXED_POINT_REMAINDER; + ch->envx += step << 1; + ch->envxx = ch->envx << ENVX_SHIFT; + + if (ch->envx >= 126) + { + ch->envx = 127; + ch->envxx = 127 << ENVX_SHIFT; + ch->state = SOUND_GAIN; + ch->mode = MODE_GAIN; + S9xSetEnvRate (ch, 0, -1, 0); + } + break; + + case SOUND_INCREASE_BENT_LINE: + if (ch->envx >= (MAX_ENVELOPE_HEIGHT * 3) / 4) + { + while (ch->env_error >= FIXED_POINT) + { + ch->envxx += (MAX_ENVELOPE_HEIGHT << ENVX_SHIFT) / 256; + ch->env_error -= FIXED_POINT; + } + ch->envx = ch->envxx >> ENVX_SHIFT; + } + else + { + ch->env_error &= FIXED_POINT_REMAINDER; + ch->envx += step << 1; + ch->envxx = ch->envx << ENVX_SHIFT; + } + + if (ch->envx >= 126) + { + ch->envx = 127; + ch->envxx = 127 << ENVX_SHIFT; + ch->state = SOUND_GAIN; + ch->mode = MODE_GAIN; + S9xSetEnvRate (ch, 0, -1, 0); + } + break; + + case SOUND_DECREASE_LINEAR: + ch->env_error &= FIXED_POINT_REMAINDER; + ch->envx -= step << 1; + ch->envxx = ch->envx << ENVX_SHIFT; + if (ch->envx <= 0) + { + S9xAPUSetEndOfSample (J, ch); + goto stereo_exit; + } + break; + + case SOUND_DECREASE_EXPONENTIAL: + while (ch->env_error >= FIXED_POINT) + { + ch->envxx = (ch->envxx >> 8) * 255; + ch->env_error -= FIXED_POINT; + } + ch->envx = ch->envxx >> ENVX_SHIFT; + if (ch->envx <= 0) + { + S9xAPUSetEndOfSample (J, ch); + goto stereo_exit; + } + break; + + case SOUND_GAIN: + S9xSetEnvRate (ch, 0, -1, 0); + break; + } + ch-> left_vol_level = (ch->envx * ch->volume_left) / 128; + ch->right_vol_level = (ch->envx * ch->volume_right) / 128; + VL = (ch->sample * ch-> left_vol_level) / 128; + VR = (ch->sample * ch->right_vol_level) / 128; + } + + ch->count += freq; + if (ch->count >= FIXED_POINT) + { + VL = ch->count >> FIXED_POINT_SHIFT; + ch->sample_pointer += VL; + ch->count &= FIXED_POINT_REMAINDER; + + ch->sample = ch->next_sample; + if (ch->sample_pointer >= SOUND_DECODE_LENGTH) + { + if (JUST_PLAYED_LAST_SAMPLE(ch)) + { + S9xAPUSetEndOfSample (J, ch); + goto stereo_exit; + } + do + { + ch->sample_pointer -= SOUND_DECODE_LENGTH; + if (ch->last_block) + { + if (!ch->loop) + { + ch->sample_pointer = LAST_SAMPLE; + ch->next_sample = ch->sample; + break; + } + else + { + S9xAPUSetEndX (J); + ch->last_block = FALSE; + uint8 *dir = S9xGetSampleAddress (ch->sample_number); + ch->block_pointer = READ_WORD(dir + 2); + } + } + AltDecodeBlock(ch, iapu); + //DecodeBlock (ch); + } while (ch->sample_pointer >= SOUND_DECODE_LENGTH); + if (!JUST_PLAYED_LAST_SAMPLE (ch)) + ch->next_sample = ch->block [ch->sample_pointer]; + } + else + ch->next_sample = ch->block [ch->sample_pointer]; + + if (ch->type == SOUND_SAMPLE) + { + if (Settings.InterpolatedSound && freq < FIXED_POINT && !mod) + { + ch->interpolate = ((ch->next_sample - ch->sample) * + (long) freq) / (long) FIXED_POINT; + ch->sample = (int16) (ch->sample + (((ch->next_sample - ch->sample) * + (long) (ch->count)) / (long) FIXED_POINT)); + } + else + ch->interpolate = 0; + } + else + { + for (;VL > 0; VL--) + if ((so.noise_gen <<= 1) & 0x80000000L) + so.noise_gen ^= 0x0040001L; + ch->sample = (so.noise_gen << 17) >> 17; + ch->interpolate = 0; + } + + VL = (ch->sample * ch-> left_vol_level) / 128; + VR = (ch->sample * ch->right_vol_level) / 128; + } + else + { + if (ch->interpolate) + { + int32 s = (int32) ch->sample + ch->interpolate; + + CLIP16(s); + ch->sample = (int16) s; + VL = (ch->sample * ch-> left_vol_level) / 128; + VR = (ch->sample * ch->right_vol_level) / 128; + } + } + + if (pitch_mod & (1 << (J + 1))) + wave [I / 2] = ch->sample * ch->envx; + + MixBuffer [I ^ Settings.ReverseStereo] += VL; + MixBuffer [I + (1 ^ Settings.ReverseStereo)] += VR; + ch->echo_buf_ptr [I ^ Settings.ReverseStereo] += VL; + ch->echo_buf_ptr [I + (1 ^ Settings.ReverseStereo)] += VR; + } +stereo_exit: ; + } +} + +#ifdef __DJGPP +END_OF_FUNCTION(MixStereo); +#endif + +void MixMono (int sample_count) +{ + struct SIAPU * iapu = &IAPU; +#if defined(TARGET_OS_MAC) && TARGET_OS_MAC + static int wave[SOUND_BUFFER_SIZE]; +#else +#ifdef _SNESPPC + static int wave[SOUND_BUFFER_SIZE]; +#else + int wave[SOUND_BUFFER_SIZE]; +#endif +#endif + int pitch_mod = SoundData.pitch_mod & (~APU.DSP[APU_NON]); + + for (uint32 J = 0; J < NUM_CHANNELS; J++) + { + Channel *ch = &SoundData.channels[J]; + unsigned long freq0 = ch->frequency; + + if (ch->state == SOUND_SILENT || !(so.sound_switch & (1 << J))) + continue; + +// freq0 = (unsigned long) ((double) freq0 * 0.985); + + bool8_32 mod = pitch_mod & (1 << J); + + if (ch->needs_decode) + { + AltDecodeBlock(ch, iapu); + //DecodeBlock(ch); + ch->needs_decode = FALSE; + ch->sample = ch->block[0]; + ch->sample_pointer = freq0 >> FIXED_POINT_SHIFT; + if (ch->sample_pointer == 0) + ch->sample_pointer = 1; + if (ch->sample_pointer > SOUND_DECODE_LENGTH) + ch->sample_pointer = SOUND_DECODE_LENGTH - 1; + ch->next_sample = ch->block[ch->sample_pointer]; + ch->interpolate = 0; + + if (Settings.InterpolatedSound && freq0 < FIXED_POINT && !mod) + ch->interpolate = ((ch->next_sample - ch->sample) * + (long) freq0) / (long) FIXED_POINT; + } + int32 V = (ch->sample * ch->left_vol_level) / 128; + + for (uint32 I = 0; I < (uint32) sample_count; I++) + { + unsigned long freq = freq0; + + if (mod) + freq = PITCH_MOD(freq, wave [I]); + + ch->env_error += ch->erate; + if (ch->env_error >= FIXED_POINT) + { + uint32 step = ch->env_error >> FIXED_POINT_SHIFT; + + switch (ch->state) + { + case SOUND_ATTACK: + ch->env_error &= FIXED_POINT_REMAINDER; + ch->envx += step << 1; + ch->envxx = ch->envx << ENVX_SHIFT; + + if (ch->envx >= 126) + { + ch->envx = 127; + ch->envxx = 127 << ENVX_SHIFT; + ch->state = SOUND_DECAY; + if (ch->sustain_level != 8) + { + S9xSetEnvRate (ch, ch->decay_rate, -1, + (MAX_ENVELOPE_HEIGHT * ch->sustain_level) + >> 3); + break; + } + ch->state = SOUND_SUSTAIN; + S9xSetEnvRate (ch, ch->sustain_rate, -1, 0); + } + break; + + case SOUND_DECAY: + while (ch->env_error >= FIXED_POINT) + { + ch->envxx = (ch->envxx >> 8) * 255; + ch->env_error -= FIXED_POINT; + } + ch->envx = ch->envxx >> ENVX_SHIFT; + if (ch->envx <= ch->envx_target) + { + if (ch->envx <= 0) + { + S9xAPUSetEndOfSample (J, ch); + goto mono_exit; + } + ch->state = SOUND_SUSTAIN; + S9xSetEnvRate (ch, ch->sustain_rate, -1, 0); + } + break; + + case SOUND_SUSTAIN: + while (ch->env_error >= FIXED_POINT) + { + ch->envxx = (ch->envxx >> 8) * 255; + ch->env_error -= FIXED_POINT; + } + ch->envx = ch->envxx >> ENVX_SHIFT; + if (ch->envx <= 0) + { + S9xAPUSetEndOfSample (J, ch); + goto mono_exit; + } + break; + + case SOUND_RELEASE: + while (ch->env_error >= FIXED_POINT) + { + ch->envxx -= (MAX_ENVELOPE_HEIGHT << ENVX_SHIFT) / 256; + ch->env_error -= FIXED_POINT; + } + ch->envx = ch->envxx >> ENVX_SHIFT; + if (ch->envx <= 0) + { + S9xAPUSetEndOfSample (J, ch); + goto mono_exit; + } + break; + + case SOUND_INCREASE_LINEAR: + ch->env_error &= FIXED_POINT_REMAINDER; + ch->envx += step << 1; + ch->envxx = ch->envx << ENVX_SHIFT; + + if (ch->envx >= 126) + { + ch->envx = 127; + ch->envxx = 127 << ENVX_SHIFT; + ch->state = SOUND_GAIN; + ch->mode = MODE_GAIN; + S9xSetEnvRate (ch, 0, -1, 0); + } + break; + + case SOUND_INCREASE_BENT_LINE: + if (ch->envx >= (MAX_ENVELOPE_HEIGHT * 3) / 4) + { + while (ch->env_error >= FIXED_POINT) + { + ch->envxx += (MAX_ENVELOPE_HEIGHT << ENVX_SHIFT) / 256; + ch->env_error -= FIXED_POINT; + } + ch->envx = ch->envxx >> ENVX_SHIFT; + } + else + { + ch->env_error &= FIXED_POINT_REMAINDER; + ch->envx += step << 1; + ch->envxx = ch->envx << ENVX_SHIFT; + } + + if (ch->envx >= 126) + { + ch->envx = 127; + ch->envxx = 127 << ENVX_SHIFT; + ch->state = SOUND_GAIN; + ch->mode = MODE_GAIN; + S9xSetEnvRate (ch, 0, -1, 0); + } + break; + + case SOUND_DECREASE_LINEAR: + ch->env_error &= FIXED_POINT_REMAINDER; + ch->envx -= step << 1; + ch->envxx = ch->envx << ENVX_SHIFT; + if (ch->envx <= 0) + { + S9xAPUSetEndOfSample (J, ch); + goto mono_exit; + } + break; + + case SOUND_DECREASE_EXPONENTIAL: + while (ch->env_error >= FIXED_POINT) + { + ch->envxx = (ch->envxx >> 8) * 255; + ch->env_error -= FIXED_POINT; + } + ch->envx = ch->envxx >> ENVX_SHIFT; + if (ch->envx <= 0) + { + S9xAPUSetEndOfSample (J, ch); + goto mono_exit; + } + break; + + case SOUND_GAIN: + S9xSetEnvRate (ch, 0, -1, 0); + break; + } + ch->left_vol_level = (ch->envx * ch->volume_left) / 128; + V = (ch->sample * ch->left_vol_level) / 128; + } + + ch->count += freq; + if (ch->count >= FIXED_POINT) + { + V = ch->count >> FIXED_POINT_SHIFT; + ch->sample_pointer += V; + ch->count &= FIXED_POINT_REMAINDER; + + ch->sample = ch->next_sample; + if (ch->sample_pointer >= SOUND_DECODE_LENGTH) + { + if (JUST_PLAYED_LAST_SAMPLE(ch)) + { + S9xAPUSetEndOfSample (J, ch); + goto mono_exit; + } + do + { + ch->sample_pointer -= SOUND_DECODE_LENGTH; + if (ch->last_block) + { + if (!ch->loop) + { + ch->sample_pointer = LAST_SAMPLE; + ch->next_sample = ch->sample; + break; + } + else + { + ch->last_block = FALSE; + uint8 *dir = S9xGetSampleAddress (ch->sample_number); + ch->block_pointer = READ_WORD(dir + 2); + S9xAPUSetEndX (J); + } + } + AltDecodeBlock(ch, iapu); + //DecodeBlock (ch); + } while (ch->sample_pointer >= SOUND_DECODE_LENGTH); + if (!JUST_PLAYED_LAST_SAMPLE (ch)) + ch->next_sample = ch->block [ch->sample_pointer]; + } + else + ch->next_sample = ch->block [ch->sample_pointer]; + + if (ch->type == SOUND_SAMPLE) + { + if (Settings.InterpolatedSound && freq < FIXED_POINT && !mod) + { + ch->interpolate = ((ch->next_sample - ch->sample) * + (long) freq) / (long) FIXED_POINT; + ch->sample = (int16) (ch->sample + (((ch->next_sample - ch->sample) * + (long) (ch->count)) / (long) FIXED_POINT)); + } + else + ch->interpolate = 0; + } + else + { + for (;V > 0; V--) + if ((so.noise_gen <<= 1) & 0x80000000L) + so.noise_gen ^= 0x0040001L; + ch->sample = (so.noise_gen << 17) >> 17; + ch->interpolate = 0; + } + V = (ch->sample * ch-> left_vol_level) / 128; + } + else + { + if (ch->interpolate) + { + int32 s = (int32) ch->sample + ch->interpolate; + + CLIP16(s); + ch->sample = (int16) s; + V = (ch->sample * ch-> left_vol_level) / 128; + } + } + + MixBuffer [I] += V; + ch->echo_buf_ptr [I] += V; + + if (pitch_mod & (1 << (J + 1))) + wave [I] = ch->sample * ch->envx; + } +mono_exit: ; + } +} +#ifdef __DJGPP +END_OF_FUNCTION(MixMono); +#endif + +#ifdef __sun +extern uint8 int2ulaw (int); +#endif + +// For backwards compatibility with older port specific code +void S9xMixSamples (uint8 *buffer, int sample_count) +{ + S9xMixSamplesO (buffer, sample_count, 0); +} +#ifdef __DJGPP +END_OF_FUNCTION(S9xMixSamples); +#endif + +void S9xMixSamplesO (uint8 *buffer, int sample_count, int byte_offset) +{ + int J; + int I; + + if (!so.mute_sound) + { + memset (MixBuffer, 0, sample_count * sizeof (MixBuffer [0])); + if (SoundData.echo_enable) + memset (EchoBuffer, 0, sample_count * sizeof (EchoBuffer [0])); + + if (so.stereo) + MixStereo (sample_count); + else + MixMono (sample_count); + } + + /* Mix and convert waveforms */ + if (so.sixteen_bit) + { + int byte_count = sample_count << 1; + + // 16-bit sound + if (so.mute_sound) + { + memset (buffer + byte_offset, 0, byte_count); + } + else + { + int O = byte_offset >> 1; + if (SoundData.echo_enable && SoundData.echo_buffer_size) + { + if (so.stereo) + { + // 16-bit stereo sound with echo enabled ... + if (SoundData.no_filter) + { + // ... but no filter defined. + for (J = 0; J < sample_count; J++) + { + int E = Echo [SoundData.echo_ptr]; + + Echo [SoundData.echo_ptr] = (E * SoundData.echo_feedback) / 128 + EchoBuffer [J]; + + if ((SoundData.echo_ptr += 1) >= SoundData.echo_buffer_size) + SoundData.echo_ptr = 0; + + I = (MixBuffer [J] * SoundData.master_volume [J & 1] + E * SoundData.echo_volume [J & 1]) / VOL_DIV16; + + CLIP16(I); + ((signed short *) buffer)[J + O] = I; + } + } + else + { + // ... with filter defined. + for (J = 0; J < sample_count; J++) + { + int E = Echo [SoundData.echo_ptr]; + + Loop [(Z - 0) & 15] = E; + E = E * FilterTaps [0]; + E += Loop [(Z - 2) & 15] * FilterTaps [1]; + E += Loop [(Z - 4) & 15] * FilterTaps [2]; + E += Loop [(Z - 6) & 15] * FilterTaps [3]; + E += Loop [(Z - 8) & 15] * FilterTaps [4]; + E += Loop [(Z - 10) & 15] * FilterTaps [5]; + E += Loop [(Z - 12) & 15] * FilterTaps [6]; + E += Loop [(Z - 14) & 15] * FilterTaps [7]; + E /= 128; + Z++; + + Echo [SoundData.echo_ptr] = (E * SoundData.echo_feedback) / 128 + + EchoBuffer [J]; + + if ((SoundData.echo_ptr += 1) >= SoundData.echo_buffer_size) + SoundData.echo_ptr = 0; + + I = (MixBuffer [J] * + SoundData.master_volume [J & 1] + + E * SoundData.echo_volume [J & 1]) / VOL_DIV16; + + CLIP16(I); + ((signed short *) buffer)[J + O] = I; + } + } + } + else + { + // 16-bit mono sound with echo enabled... + if (SoundData.no_filter) + { + // ... no filter defined + for (J = 0; J < sample_count; J++) + { + int E = Echo [SoundData.echo_ptr]; + + Echo [SoundData.echo_ptr] = (E * SoundData.echo_feedback) / 128 + + EchoBuffer [J]; + + if ((SoundData.echo_ptr += 1) >= SoundData.echo_buffer_size) + SoundData.echo_ptr = 0; + + I = (MixBuffer [J] * + SoundData.master_volume [0] + + E * SoundData.echo_volume [0]) / VOL_DIV16; + CLIP16(I); + ((signed short *) buffer)[J + O] = I; + } + } + else + { + // ... with filter defined + for (J = 0; J < sample_count; J++) + { + int E = Echo [SoundData.echo_ptr]; + + Loop [(Z - 0) & 7] = E; + E = E * FilterTaps [0]; + E += Loop [(Z - 1) & 7] * FilterTaps [1]; + E += Loop [(Z - 2) & 7] * FilterTaps [2]; + E += Loop [(Z - 3) & 7] * FilterTaps [3]; + E += Loop [(Z - 4) & 7] * FilterTaps [4]; + E += Loop [(Z - 5) & 7] * FilterTaps [5]; + E += Loop [(Z - 6) & 7] * FilterTaps [6]; + E += Loop [(Z - 7) & 7] * FilterTaps [7]; + E /= 128; + Z++; + + Echo [SoundData.echo_ptr] = (E * SoundData.echo_feedback) / 128 + + EchoBuffer [J]; + + if ((SoundData.echo_ptr += 1) >= SoundData.echo_buffer_size) + SoundData.echo_ptr = 0; + + I = (MixBuffer [J] * SoundData.master_volume [0] + + E * SoundData.echo_volume [0]) / VOL_DIV16; + CLIP16(I); + ((signed short *) buffer)[J + O] = I; + } + } + } + } + else + { + // 16-bit mono or stereo sound, no echo + for (J = 0; J < sample_count; J++) + { + I = (MixBuffer [J] * + SoundData.master_volume [J & 1]) / VOL_DIV16; + + CLIP16(I); + ((signed short *) buffer)[J + O] = I; + } + } + } + } + else + { + int O = byte_offset; + + // 8-bit sound + if (so.mute_sound) + { + memset (buffer + O, 128, sample_count); + } + else +#ifdef __sun + if (so.encoded) + { + for (J = 0; J < sample_count; J++) + { + I = (MixBuffer [J] * SoundData.master_volume_left) / VOL_DIV16; + CLIP16(I); + buffer[J + O] = int2ulaw (I); + } + } + else +#endif + { + if (SoundData.echo_enable && SoundData.echo_buffer_size) + { + if (so.stereo) + { + // 8-bit stereo sound with echo enabled... + if (SoundData.no_filter) + { + // ... but no filter + for (J = 0; J < sample_count; J++) + { + int E = Echo [SoundData.echo_ptr]; + + Echo [SoundData.echo_ptr] = (E * SoundData.echo_feedback) / 128 + + EchoBuffer [J]; + + if ((SoundData.echo_ptr += 1) >= SoundData.echo_buffer_size) + SoundData.echo_ptr = 0; + + I = (MixBuffer [J] * + SoundData.master_volume [J & 1] + + E * SoundData.echo_volume [J & 1]) / VOL_DIV8; + CLIP8(I); + buffer [J + O] = I + 128; + } + } + else + { + // ... with filter + for (J = 0; J < sample_count; J++) + { + int E = Echo [SoundData.echo_ptr]; + + Loop [(Z - 0) & 15] = E; + E = E * FilterTaps [0]; + E += Loop [(Z - 2) & 15] * FilterTaps [1]; + E += Loop [(Z - 4) & 15] * FilterTaps [2]; + E += Loop [(Z - 6) & 15] * FilterTaps [3]; + E += Loop [(Z - 8) & 15] * FilterTaps [4]; + E += Loop [(Z - 10) & 15] * FilterTaps [5]; + E += Loop [(Z - 12) & 15] * FilterTaps [6]; + E += Loop [(Z - 14) & 15] * FilterTaps [7]; + E /= 128; + Z++; + + Echo [SoundData.echo_ptr] = (E * SoundData.echo_feedback) / 128 + + EchoBuffer [J]; + + if ((SoundData.echo_ptr += 1) >= SoundData.echo_buffer_size) + SoundData.echo_ptr = 0; + + I = (MixBuffer [J] * + SoundData.master_volume [J & 1] + + E * SoundData.echo_volume [J & 1]) / VOL_DIV8; + CLIP8(I); + buffer [J + O] = I + 128; + } + } + } + else + { + // 8-bit mono sound with echo enabled... + if (SoundData.no_filter) + { + // ... but no filter. + for (J = 0; J < sample_count; J++) + { + int E = Echo [SoundData.echo_ptr]; + + Echo [SoundData.echo_ptr] = (E * SoundData.echo_feedback) / 128 + + EchoBuffer [J]; + + if ((SoundData.echo_ptr += 1) >= SoundData.echo_buffer_size) + SoundData.echo_ptr = 0; + + I = (MixBuffer [J] * SoundData.master_volume [0] + + E * SoundData.echo_volume [0]) / VOL_DIV8; + CLIP8(I); + buffer [J + O] = I + 128; + } + } + else + { + // ... with filter. + for (J = 0; J < sample_count; J++) + { + int E = Echo [SoundData.echo_ptr]; + + Loop [(Z - 0) & 7] = E; + E = E * FilterTaps [0]; + E += Loop [(Z - 1) & 7] * FilterTaps [1]; + E += Loop [(Z - 2) & 7] * FilterTaps [2]; + E += Loop [(Z - 3) & 7] * FilterTaps [3]; + E += Loop [(Z - 4) & 7] * FilterTaps [4]; + E += Loop [(Z - 5) & 7] * FilterTaps [5]; + E += Loop [(Z - 6) & 7] * FilterTaps [6]; + E += Loop [(Z - 7) & 7] * FilterTaps [7]; + E /= 128; + Z++; + + Echo [SoundData.echo_ptr] = (E * SoundData.echo_feedback) / 128 + + EchoBuffer [J]; + + if ((SoundData.echo_ptr += 1) >= SoundData.echo_buffer_size) + SoundData.echo_ptr = 0; + + I = (MixBuffer [J] * SoundData.master_volume [0] + + E * SoundData.echo_volume [0]) / VOL_DIV8; + CLIP8(I); + buffer [J + O] = I + 128; + } + } + } + } + else + { + // 8-bit mono or stereo sound, no echo + for (J = 0; J < sample_count; J++) + { + I = (MixBuffer [J] * + SoundData.master_volume [J & 1]) / VOL_DIV8; + CLIP8(I); + buffer [J + O] = I + 128; + } + } + } + } +} + +#ifdef __DJGPP +END_OF_FUNCTION(S9xMixSamplesO); +#endif + +void S9xResetSound (bool8_32 full) +{ + for (int i = 0; i < 8; i++) + { + SoundData.channels[i].state = SOUND_SILENT; + SoundData.channels[i].mode = MODE_NONE; + SoundData.channels[i].type = SOUND_SAMPLE; + SoundData.channels[i].volume_left = 0; + SoundData.channels[i].volume_right = 0; + SoundData.channels[i].hertz = 0; + SoundData.channels[i].count = 0; + SoundData.channels[i].loop = FALSE; + SoundData.channels[i].envx_target = 0; + SoundData.channels[i].env_error = 0; + SoundData.channels[i].erate = 0; + SoundData.channels[i].envx = 0; + SoundData.channels[i].envxx = 0; + SoundData.channels[i].left_vol_level = 0; + SoundData.channels[i].right_vol_level = 0; + SoundData.channels[i].direction = 0; + SoundData.channels[i].attack_rate = 0; + SoundData.channels[i].decay_rate = 0; + SoundData.channels[i].sustain_rate = 0; + SoundData.channels[i].release_rate = 0; + SoundData.channels[i].sustain_level = 0; + SoundData.echo_ptr = 0; + SoundData.echo_feedback = 0; + SoundData.echo_buffer_size = 1; + } + FilterTaps [0] = 127; + FilterTaps [1] = 0; + FilterTaps [2] = 0; + FilterTaps [3] = 0; + FilterTaps [4] = 0; + FilterTaps [5] = 0; + FilterTaps [6] = 0; + FilterTaps [7] = 0; + so.mute_sound = TRUE; + so.noise_gen = 1; + so.sound_switch = 255; + so.samples_mixed_so_far = 0; + so.play_position = 0; + so.err_counter = 0; + + if (full) + { + SoundData.master_volume_left = 0; + SoundData.master_volume_right = 0; + SoundData.echo_volume_left = 0; + SoundData.echo_volume_right = 0; + SoundData.echo_enable = 0; + SoundData.echo_write_enabled = 0; + SoundData.echo_channel_enable = 0; + SoundData.pitch_mod = 0; + SoundData.dummy[0] = 0; + SoundData.dummy[1] = 0; + SoundData.dummy[2] = 0; + SoundData.master_volume[0] = 0; + SoundData.master_volume[1] = 0; + SoundData.echo_volume[0] = 0; + SoundData.echo_volume[1] = 0; + SoundData.noise_hertz = 0; + } + + SoundData.master_volume_left = 127; + SoundData.master_volume_right = 127; + SoundData.master_volume [0] = SoundData.master_volume [1] = 127; + if (so.playback_rate) + so.err_rate = (uint32) (FIXED_POINT * SNES_SCANLINE_TIME / (1.0 / so.playback_rate)); + else + so.err_rate = 0; + SoundData.no_filter = TRUE; +} + +void S9xSetPlaybackRate (uint32 playback_rate) +{ + so.playback_rate = playback_rate; + so.err_rate = (uint32) (SNES_SCANLINE_TIME * FIXED_POINT / (1.0 / (double) so.playback_rate)); + S9xSetEchoDelay (APU.DSP [APU_EDL] & 0xf); + for (int i = 0; i < 8; i++) + S9xSetSoundFrequency (i, SoundData.channels [i].hertz); +} + +bool8_32 S9xInitSound (int mode, bool8_32 stereo, int buffer_size) +{ + so.sound_fd = -1; + so.sound_switch = 255; + + so.playback_rate = mode; + so.buffer_size = buffer_size; + so.stereo = false;//stereo; + so.sixteen_bit = Settings.SixteenBitSound; + so.encoded = FALSE; + + S9xResetSound (TRUE); + + //if (!(mode & 7)) + //return (1); + + S9xSetSoundMute (TRUE); + if (!S9xOpenSoundDevice (mode, stereo, buffer_size)) + { + S9xMessage (S9X_ERROR, S9X_SOUND_DEVICE_OPEN_FAILED, + "Sound device open failed"); + return (0); + } + + return (1); +} + +bool8_32 S9xSetSoundMode (int channel, int mode) +{ + Channel *ch = &SoundData.channels[channel]; + + switch (mode) + { + case MODE_RELEASE: + if (ch->mode != MODE_NONE) + { + ch->mode = MODE_RELEASE; + return (TRUE); + } + break; + + case MODE_DECREASE_LINEAR: + case MODE_DECREASE_EXPONENTIAL: + case MODE_GAIN: + if (ch->mode != MODE_RELEASE) + { + ch->mode = mode; + if (ch->state != SOUND_SILENT) + ch->state = mode; + + return (TRUE); + } + break; + + case MODE_INCREASE_LINEAR: + case MODE_INCREASE_BENT_LINE: + if (ch->mode != MODE_RELEASE) + { + ch->mode = mode; + if (ch->state != SOUND_SILENT) + ch->state = mode; + + return (TRUE); + } + break; + + case MODE_ADSR: + if (ch->mode == MODE_NONE || ch->mode == MODE_ADSR) + { + ch->mode = mode; + return (TRUE); + } + } + + return (FALSE); +} + +void S9xSetSoundControl (int sound_switch) +{ + so.sound_switch = sound_switch; +} + +void S9xPlaySample (int channel) +{ + Channel *ch = &SoundData.channels[channel]; + + ch->state = SOUND_SILENT; + ch->mode = MODE_NONE; + ch->envx = 0; + ch->envxx = 0; + + S9xFixEnvelope (channel, + APU.DSP [APU_GAIN + (channel << 4)], + APU.DSP [APU_ADSR1 + (channel << 4)], + APU.DSP [APU_ADSR2 + (channel << 4)]); + + ch->sample_number = APU.DSP [APU_SRCN + channel * 0x10]; + if (APU.DSP [APU_NON] & (1 << channel)) + ch->type = SOUND_NOISE; + else + ch->type = SOUND_SAMPLE; + + S9xSetSoundFrequency (channel, ch->hertz); + ch->loop = FALSE; + ch->needs_decode = TRUE; + ch->last_block = FALSE; + ch->previous [0] = ch->previous[1] = 0; + uint8 *dir = S9xGetSampleAddress (ch->sample_number); + ch->block_pointer = READ_WORD (dir); + ch->sample_pointer = 0; + ch->env_error = 0; + ch->next_sample = 0; + ch->interpolate = 0; + + switch (ch->mode) + { + case MODE_ADSR: + if (ch->attack_rate == 0) + { + if (ch->decay_rate == 0 || ch->sustain_level == 8) + { + ch->state = SOUND_SUSTAIN; + ch->envx = (MAX_ENVELOPE_HEIGHT * ch->sustain_level) >> 3; + S9xSetEnvRate (ch, ch->sustain_rate, -1, 0); + } + else + { + ch->state = SOUND_DECAY; + ch->envx = MAX_ENVELOPE_HEIGHT; + S9xSetEnvRate (ch, ch->decay_rate, -1, + (MAX_ENVELOPE_HEIGHT * ch->sustain_level) >> 3); + } + ch-> left_vol_level = (ch->envx * ch->volume_left) / 128; + ch->right_vol_level = (ch->envx * ch->volume_right) / 128; + } + else + { + ch->state = SOUND_ATTACK; + ch->envx = 0; + ch->left_vol_level = 0; + ch->right_vol_level = 0; + S9xSetEnvRate (ch, ch->attack_rate, 1, MAX_ENVELOPE_HEIGHT); + } + ch->envxx = ch->envx << ENVX_SHIFT; + break; + + case MODE_GAIN: + ch->state = SOUND_GAIN; + break; + + case MODE_INCREASE_LINEAR: + ch->state = SOUND_INCREASE_LINEAR; + break; + + case MODE_INCREASE_BENT_LINE: + ch->state = SOUND_INCREASE_BENT_LINE; + break; + + case MODE_DECREASE_LINEAR: + ch->state = SOUND_DECREASE_LINEAR; + break; + + case MODE_DECREASE_EXPONENTIAL: + ch->state = SOUND_DECREASE_EXPONENTIAL; + break; + + default: + break; + } + + S9xFixEnvelope (channel, + APU.DSP [APU_GAIN + (channel << 4)], + APU.DSP [APU_ADSR1 + (channel << 4)], + APU.DSP [APU_ADSR2 + (channel << 4)]); +} diff --git a/src/snes4iphone_src/sounduxnew.h b/src/snes4iphone_src/sounduxnew.h new file mode 100755 index 0000000..3e92dba --- /dev/null +++ b/src/snes4iphone_src/sounduxnew.h @@ -0,0 +1,197 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#ifndef _SOUND_H_ +#define _SOUND_H_ + +enum { SOUND_SAMPLE = 0, SOUND_NOISE, SOUND_EXTRA_NOISE, SOUND_MUTE }; +enum { SOUND_SILENT, SOUND_ATTACK, SOUND_DECAY, SOUND_SUSTAIN, + SOUND_RELEASE, SOUND_GAIN, SOUND_INCREASE_LINEAR, + SOUND_INCREASE_BENT_LINE, SOUND_DECREASE_LINEAR, + SOUND_DECREASE_EXPONENTIAL}; + +enum { MODE_NONE = SOUND_SILENT, MODE_ADSR, MODE_RELEASE = SOUND_RELEASE, + MODE_GAIN, MODE_INCREASE_LINEAR, MODE_INCREASE_BENT_LINE, + MODE_DECREASE_LINEAR, MODE_DECREASE_EXPONENTIAL}; + +#define MAX_ENVELOPE_HEIGHT 127 +#define ENVELOPE_SHIFT 7 +#define MAX_VOLUME 127 +#define VOLUME_SHIFT 7 +#define VOL_DIV 128 +#define SOUND_DECODE_LENGTH 16 + +#define NUM_CHANNELS 8 +#define SOUND_BUFFER_SIZE (1024 * 16) +#define MAX_BUFFER_SIZE SOUND_BUFFER_SIZE +#define SOUND_BUFFER_SIZE_MASK (SOUND_BUFFER_SIZE - 1) + +#define SOUND_BUFS 4 + +#ifdef __sgi +//# include +#endif /* __sgi */ + +typedef struct { + int sound_fd; + int sound_switch; + int playback_rate; + int buffer_size; + int noise_gen; + bool8_32 mute_sound; + int stereo; + bool8_32 sixteen_bit; + bool8_32 encoded; +#ifdef __sun + int last_eof; +#endif +#ifdef __sgi + ALport al_port; +#endif /* __sgi */ + int32 samples_mixed_so_far; + int32 play_position; + uint32 err_counter; + uint32 err_rate; +} SoundStatus; + +EXTERN_C volatile SoundStatus so; + +typedef struct { + int state; + int type; + short volume_left; + short volume_right; + uint32 hertz; + uint32 frequency; + uint32 count; + bool8_32 loop; + int envx; + short left_vol_level; + short right_vol_level; + short envx_target; + unsigned long int env_error; + unsigned long erate; + int direction; + unsigned long attack_rate; + unsigned long decay_rate; + unsigned long sustain_rate; + unsigned long release_rate; + unsigned long sustain_level; + signed short sample; + signed short decoded [16]; + signed short previous16 [2]; + signed short *block; + uint16 sample_number; + bool8_32 last_block; + bool8_32 needs_decode; + uint32 block_pointer; + uint32 sample_pointer; + int *echo_buf_ptr; + int mode; + int32 envxx; + signed short next_sample; + int32 interpolate; + int32 previous [2]; + // Just incase they are needed in the future, for snapshot compatibility. + uint32 dummy [8]; +} Channel; + +typedef struct +{ + short master_volume_left; + short master_volume_right; + short echo_volume_left; + short echo_volume_right; + int echo_enable; + int echo_feedback; + int echo_ptr; + int echo_buffer_size; + int echo_write_enabled; + int echo_channel_enable; + int pitch_mod; + // Just incase they are needed in the future, for snapshot compatibility. + uint32 dummy [3]; + Channel channels [NUM_CHANNELS]; + bool8_32 no_filter; + int master_volume [2]; + int echo_volume [2]; + int noise_hertz; +} SSoundData; + +EXTERN_C SSoundData SoundData; + +void S9xSetSoundVolume (int channel, short volume_left, short volume_right); +void S9xSetSoundFrequency (int channel, int hertz); +void S9xSetSoundHertz (int channel, int hertz); +void S9xSetSoundType (int channel, int type_of_sound); +void S9xSetMasterVolume (short master_volume_left, short master_volume_right); +void S9xSetEchoVolume (short echo_volume_left, short echo_volume_right); +void S9xSetSoundControl (int sound_switch); +bool8_32 S9xSetSoundMute (bool8_32 mute); +void S9xSetEnvelopeHeight (int channel, int height); +void S9xSetSoundADSR (int channel, int attack, int decay, int sustain, + int sustain_level, int release); +void S9xSetSoundKeyOff (int channel); +void S9xSetSoundDecayMode (int channel); +void S9xSetSoundAttachMode (int channel); +void S9xSoundStartEnvelope (Channel *); +void S9xSetSoundSample (int channel, uint16 sample_number); +void S9xSetEchoFeedback (int echo_feedback); +void S9xSetEchoEnable (uint8 byte); +void S9xSetEchoDelay (int byte); +void S9xSetEchoWriteEnable (uint8 byte); +void S9xSetFilterCoefficient (int tap, int value); +void S9xSetFrequencyModulationEnable (uint8 byte); +void S9xSetEnvelopeRate (int channel, unsigned long rate, int direction, + int target); +bool8_32 S9xSetSoundMode (int channel, int mode); +int S9xGetEnvelopeHeight (int channel); +void S9xResetSound (bool8_32 full); +void S9xFixSoundAfterSnapshotLoad (); +void S9xPlaybackSoundSetting (int channel); +void S9xPlaySample (int channel); +void S9xFixEnvelope (int channel, uint8 gain, uint8 adsr1, uint8 adsr2); +void S9xStartSample (int channel); + +EXTERN_C void S9xMixSamples (uint8 *buffer, int sample_count); +EXTERN_C void S9xMixSamplesO (uint8 *buffer, int sample_count, int byte_offset); +bool8_32 S9xOpenSoundDevice (int, bool8_32, int); +void S9xSetPlaybackRate (uint32 rate); +#endif diff --git a/src/snes4iphone_src/spc700.cpp b/src/snes4iphone_src/spc700.cpp new file mode 100755 index 0000000..7cc41e8 --- /dev/null +++ b/src/snes4iphone_src/spc700.cpp @@ -0,0 +1,2532 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#include "snes9x.h" +#include "memmap.h" +#include "display.h" +#include "cpuexec.h" +#include "apu.h" +#include "spc700.h" + +// SPC700/Sound DSP chips have a 24.57MHz crystal on their PCB. + +#if defined(ASM_SPC700) + + unsigned long regR9[1]; + unsigned long regR9s[1]; + +// we only need the memhandlers +#undef INLINE +#define INLINE extern "C" +#include "apumem.h" + +#else + +#if defined(NO_INLINE_SET_GET) +uint8 S9xAPUGetByteZ (uint8 address); +uint8 S9xAPUGetByte (uint32 address); +void S9xAPUSetByteZ (uint8, uint8 address); +void S9xAPUSetByte (uint8, uint32 address); +#else +#undef INLINE +#define INLINE inline +#include "apumem.h" +#endif + +START_EXTERN_C +extern uint8 Work8; +extern uint16 Work16; +extern uint32 Work32; +extern signed char Int8; +extern short Int16; +extern long Int32; +extern short Int16; +extern uint8 W1; +extern uint8 W2; + +END_EXTERN_C + +#define OP1 (*(IAPU.PC + 1)) +#define OP2 (*(IAPU.PC + 2)) + +#ifdef SPC700_SHUTDOWN +#define APUShutdown() \ + if (Settings.Shutdown && (IAPU.PC == IAPU.WaitAddress1 || IAPU.PC == IAPU.WaitAddress2)) \ + { \ + if (IAPU.WaitCounter == 0) \ + { \ + if (!ICPU.CPUExecuting) \ + CPU.APU_Cycles = CPU.Cycles = CPU.NextEvent; \ + else \ + CPU.APU_APUExecuting = FALSE; \ + } \ + else \ + if (IAPU.WaitCounter >= 2) \ + IAPU.WaitCounter = 1; \ + else \ + IAPU.WaitCounter--; \ + } +#else +#define APUShutdown() +#endif + +#define APUSetZN8(b)\ + IAPU._Zero = (b); + +#define APUSetZN16(w)\ + IAPU._Zero = ((w) != 0) | ((w) >> 8); + +void STOP (char *s) +{ + char buffer[100]; + +#ifdef DEBUGGER + S9xAPUOPrint (buffer, IAPU.PC - IAPU.RAM); +#endif + + sprintf (String, "Sound CPU in unknown state executing %s at %04lX\n%s\n", s, IAPU.PC - IAPU.RAM, buffer); + S9xMessage (S9X_ERROR, S9X_APU_STOPPED, String); + APU.TimerEnabled[0] = APU.TimerEnabled[1] = APU.TimerEnabled[2] = FALSE; + CPU.APU_APUExecuting = FALSE; + +#ifdef DEBUGGER + CPU.Flags |= DEBUG_MODE_FLAG; +#else + S9xExit (); +#endif +} + +#define TCALL(n)\ +{\ + PushW ((IAPU.PC - IAPU.RAM + 1)); \ + IAPU.PC = IAPU.RAM + (APU.ExtraRAM [((15 - n) << 1)] + \ + (APU.ExtraRAM [((15 - n) << 1) + 1] << 8)); \ +} + +// XXX: HalfCarry - BJ fixed? +#define SBC(a,b)\ +Int16 = (short) (a) - (short) (b) + (short) (APUCheckCarry ()) - 1;\ +IAPU._Carry = Int16 >= 0;\ +if ((((a) ^ (b)) & 0x80) && (((a) ^ (uint8) Int16) & 0x80))\ + APUSetOverflow ();\ +else \ + APUClearOverflow (); \ +APUSetHalfCarry ();\ +if(((a) ^ (b) ^ (uint8) Int16) & 0x10)\ + APUClearHalfCarry ();\ +(a) = (uint8) Int16;\ +APUSetZN8 ((uint8) Int16); + +// XXX: HalfCarry - BJ fixed? +#define ADC(a,b)\ +Work16 = (a) + (b) + APUCheckCarry();\ +IAPU._Carry = Work16 >= 0x100; \ +if (~((a) ^ (b)) & ((b) ^ (uint8) Work16) & 0x80)\ + APUSetOverflow ();\ +else \ + APUClearOverflow (); \ +APUClearHalfCarry ();\ +/*if(((a) ^ (b) ^ (uint8) Int16) & 0x10) notaz: Int16!? */\ +if(((a) ^ (b) ^ (uint8) Work16) & 0x10)\ + APUSetHalfCarry ();\ +(a) = (uint8) Work16;\ +APUSetZN8 ((uint8) Work16); + +#define CMP(a,b)\ +Int16 = (short) (a) - (short) (b);\ +IAPU._Carry = Int16 >= 0;\ +APUSetZN8 ((uint8) Int16); + +#define ASL(b)\ + IAPU._Carry = ((b) & 0x80) != 0; \ + (b) <<= 1;\ + APUSetZN8 (b); +#define LSR(b)\ + IAPU._Carry = (b) & 1;\ + (b) >>= 1;\ + APUSetZN8 (b); +#define ROL(b)\ + Work16 = ((b) << 1) | APUCheckCarry (); \ + IAPU._Carry = Work16 >= 0x100; \ + (b) = (uint8) Work16; \ + APUSetZN8 (b); +#define ROR(b)\ + Work16 = (b) | ((uint16) APUCheckCarry () << 8); \ + IAPU._Carry = (uint8) Work16 & 1; \ + Work16 >>= 1; \ + (b) = (uint8) Work16; \ + APUSetZN8 (b); + +#define Push(b)\ + *(IAPU.RAM + 0x100 + IAPU.S) = b;\ + IAPU.S--; + +#define Pop(b)\ + IAPU.S++;\ + (b) = *(IAPU.RAM + 0x100 + IAPU.S); + +#ifdef FAST_LSB_WORD_ACCESS +#define PushW(w)\ + *(uint16 *) (IAPU.RAM + 0xff + IAPU.S) = w;\ + IAPU.S -= 2; +#define PopW(w)\ + IAPU.S += 2;\ + w = *(uint16 *) (IAPU.RAM + 0xff + IAPU.S); +#else +#define PushW(w)\ + *(IAPU.RAM + 0xff + IAPU.S) = w;\ + *(IAPU.RAM + 0x100 + IAPU.S) = (w >> 8);\ + IAPU.S -= 2; +#define PopW(w)\ + IAPU.S += 2; \ + (w) = *(IAPU.RAM + 0xff + IAPU.S) + (*(IAPU.RAM + 0x100 + IAPU.S) << 8); +#endif + +#define Relative()\ + Int8 = OP1;\ + Int16 = (int) (IAPU.PC + 2 - IAPU.RAM) + Int8; + +#define Relative2()\ + Int8 = OP2;\ + Int16 = (int) (IAPU.PC + 3 - IAPU.RAM) + Int8; + +#ifdef FAST_LSB_WORD_ACCESS +#define IndexedXIndirect()\ + IAPU.Address = *(uint16 *) (IAPU.DirectPage + ((OP1 + IAPU.X) & 0xff)); + +#define Absolute()\ + IAPU.Address = *(uint16 *) (IAPU.PC + 1); + +#define AbsoluteX()\ + IAPU.Address = *(uint16 *) (IAPU.PC + 1) + IAPU.X; + +#define AbsoluteY()\ + IAPU.Address = *(uint16 *) (IAPU.PC + 1) + IAPU.YA.B.Y; + +#define MemBit()\ + IAPU.Address = *(uint16 *) (IAPU.PC + 1);\ + IAPU.Bit = (uint8)(IAPU.Address >> 13);\ + IAPU.Address &= 0x1fff; + +#define IndirectIndexedY()\ + IAPU.Address = *(uint16 *) (IAPU.DirectPage + OP1) + IAPU.YA.B.Y; +#else +#define IndexedXIndirect()\ + IAPU.Address = *(IAPU.DirectPage + ((OP1 + IAPU.X) & 0xff)) + \ + (*(IAPU.DirectPage + ((OP1 + IAPU.X + 1) & 0xff)) << 8); +#define Absolute()\ + IAPU.Address = OP1 + (OP2 << 8); + +#define AbsoluteX()\ + IAPU.Address = OP1 + (OP2 << 8) + IAPU.X; + +#define AbsoluteY()\ + IAPU.Address = OP1 + (OP2 << 8) + IAPU.YA.B.Y; + +#define MemBit()\ + IAPU.Address = OP1 + (OP2 << 8);\ + IAPU.Bit = (int8) (IAPU.Address >> 13);\ + IAPU.Address &= 0x1fff; + +#define IndirectIndexedY()\ + IAPU.Address = *(IAPU.DirectPage + OP1) + \ + (*(IAPU.DirectPage + OP1 + 1) << 8) + \ + IAPU.YA.B.Y; +#endif + +void Apu00 () +{ +// NOP + IAPU.PC++; +} + +void Apu01 () { TCALL (0) } + +void Apu11 () { TCALL (1) } + +void Apu21 () { TCALL (2) } + +void Apu31 () { TCALL (3) } + +void Apu41 () { TCALL (4) } + +void Apu51 () { TCALL (5) } + +void Apu61 () { TCALL (6) } + +void Apu71 () { TCALL (7) } + +void Apu81 () { TCALL (8) } + +void Apu91 () { TCALL (9) } + +void ApuA1 () { TCALL (10) } + +void ApuB1 () { TCALL (11) } + +void ApuC1 () { TCALL (12) } + +void ApuD1 () { TCALL (13) } + +void ApuE1 () { TCALL (14) } + +void ApuF1 () { TCALL (15) } + +void Apu3F () // CALL absolute +{ + Absolute (); + // 0xB6f for Star Fox 2 + PushW ((IAPU.PC + 3 - IAPU.RAM)); + IAPU.PC = IAPU.RAM + IAPU.Address; +} + +void Apu4F () // PCALL $XX +{ + Work8 = OP1; + PushW ((IAPU.PC + 2 - IAPU.RAM)); + IAPU.PC = IAPU.RAM + 0xff00 + Work8; +} + +#define SET(b) \ +S9xAPUSetByteZ ((uint8) (S9xAPUGetByteZ (OP1 ) | (1 << (b))), OP1); \ +IAPU.PC += 2 + +void Apu02 () +{ + SET (0); +} + +void Apu22 () +{ + SET (1); +} + +void Apu42 () +{ + SET (2); +} + +void Apu62 () +{ + SET (3); +} + +void Apu82 () +{ + SET (4); +} + +void ApuA2 () +{ + SET (5); +} + +void ApuC2 () +{ + SET (6); +} + +void ApuE2 () +{ + SET (7); +} + +#define CLR(b) \ +S9xAPUSetByteZ ((uint8) (S9xAPUGetByteZ (OP1) & ~(1 << (b))), OP1); \ +IAPU.PC += 2; + +void Apu12 () +{ + CLR (0); +} + +void Apu32 () +{ + CLR (1); +} + +void Apu52 () +{ + CLR (2); +} + +void Apu72 () +{ + CLR (3); +} + +void Apu92 () +{ + CLR (4); +} + +void ApuB2 () +{ + CLR (5); +} + +void ApuD2 () +{ + CLR (6); +} + +void ApuF2 () +{ + CLR (7); +} + +#define BBS(b) \ +Work8 = OP1; \ +Relative2 (); \ +if (S9xAPUGetByteZ (Work8) & (1 << (b))) \ +{ \ + IAPU.PC = IAPU.RAM + (uint16) Int16; \ + CPU.APU_Cycles += IAPU.TwoCycles; \ +} \ +else \ + IAPU.PC += 3 + +void Apu03 () +{ + BBS (0); +} + +void Apu23 () +{ + BBS (1); +} + +void Apu43 () +{ + BBS (2); +} + +void Apu63 () +{ + BBS (3); +} + +void Apu83 () +{ + BBS (4); +} + +void ApuA3 () +{ + BBS (5); +} + +void ApuC3 () +{ + BBS (6); +} + +void ApuE3 () +{ + BBS (7); +} + +#define BBC(b) \ +Work8 = OP1; \ +Relative2 (); \ +if (!(S9xAPUGetByteZ (Work8) & (1 << (b)))) \ +{ \ + IAPU.PC = IAPU.RAM + (uint16) Int16; \ + CPU.APU_Cycles += IAPU.TwoCycles; \ +} \ +else \ + IAPU.PC += 3 + +void Apu13 () +{ + BBC (0); +} + +void Apu33 () +{ + BBC (1); +} + +void Apu53 () +{ + BBC (2); +} + +void Apu73 () +{ + BBC (3); +} + +void Apu93 () +{ + BBC (4); +} + +void ApuB3 () +{ + BBC (5); +} + +void ApuD3 () +{ + BBC (6); +} + +void ApuF3 () +{ + BBC (7); +} + +void Apu04 () +{ +// OR A,dp + IAPU.YA.B.A |= S9xAPUGetByteZ (OP1); + APUSetZN8 (IAPU.YA.B.A); + IAPU.PC += 2; +} + +void Apu05 () +{ +// OR A,abs + Absolute (); + IAPU.YA.B.A |= S9xAPUGetByte (IAPU.Address); + APUSetZN8 (IAPU.YA.B.A); + IAPU.PC += 3; +} + +void Apu06 () +{ +// OR A,(X) + IAPU.YA.B.A |= S9xAPUGetByteZ (IAPU.X); + APUSetZN8 (IAPU.YA.B.A); + IAPU.PC++; +} + +void Apu07 () +{ +// OR A,(dp+X) + IndexedXIndirect (); + IAPU.YA.B.A |= S9xAPUGetByte (IAPU.Address); + APUSetZN8 (IAPU.YA.B.A); + IAPU.PC += 2; +} + +void Apu08 () +{ +// OR A,#00 + IAPU.YA.B.A |= OP1; + APUSetZN8 (IAPU.YA.B.A); + IAPU.PC += 2; +} + +void Apu09 () +{ +// OR dp(dest),dp(src) + Work8 = S9xAPUGetByteZ (OP1); + Work8 |= S9xAPUGetByteZ (OP2); + S9xAPUSetByteZ (Work8, OP2); + APUSetZN8 (Work8); + IAPU.PC += 3; +} + +void Apu14 () +{ +// OR A,dp+X + IAPU.YA.B.A |= S9xAPUGetByteZ (OP1 + IAPU.X); + APUSetZN8 (IAPU.YA.B.A); + IAPU.PC += 2; +} + +void Apu15 () +{ +// OR A,abs+X + AbsoluteX (); + IAPU.YA.B.A |= S9xAPUGetByte (IAPU.Address); + APUSetZN8 (IAPU.YA.B.A); + IAPU.PC += 3; +} + +void Apu16 () +{ +// OR A,abs+Y + AbsoluteY (); + IAPU.YA.B.A |= S9xAPUGetByte (IAPU.Address); + APUSetZN8 (IAPU.YA.B.A); + IAPU.PC += 3; +} + +void Apu17 () +{ +// OR A,(dp)+Y + IndirectIndexedY (); + IAPU.YA.B.A |= S9xAPUGetByte (IAPU.Address); + APUSetZN8 (IAPU.YA.B.A); + IAPU.PC += 2; +} + +void Apu18 () +{ +// OR dp,#00 + Work8 = OP1; + Work8 |= S9xAPUGetByteZ (OP2); + S9xAPUSetByteZ (Work8, OP2); + APUSetZN8 (Work8); + IAPU.PC += 3; +} + +void Apu19 () +{ +// OR (X),(Y) + Work8 = S9xAPUGetByteZ (IAPU.X) | S9xAPUGetByteZ (IAPU.YA.B.Y); + APUSetZN8 (Work8); + S9xAPUSetByteZ (Work8, IAPU.X); + IAPU.PC++; +} + +void Apu0A () +{ +// OR1 C,membit + MemBit (); + if (!APUCheckCarry ()) + { + if (S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit)) + APUSetCarry (); + } + IAPU.PC += 3; +} + +void Apu2A () +{ +// OR1 C,not membit + MemBit (); + if (!APUCheckCarry ()) + { + if (!(S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit))) + APUSetCarry (); + } + IAPU.PC += 3; +} + +void Apu4A () +{ +// AND1 C,membit + MemBit (); + if (APUCheckCarry ()) + { + if (!(S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit))) + APUClearCarry (); + } + IAPU.PC += 3; +} + +void Apu6A () +{ +// AND1 C, not membit + MemBit (); + if (APUCheckCarry ()) + { + if ((S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit))) + APUClearCarry (); + } + IAPU.PC += 3; +} + +void Apu8A () +{ +// EOR1 C, membit + MemBit (); + if (APUCheckCarry ()) + { + if (S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit)) + APUClearCarry (); + } + else + { + if (S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit)) + APUSetCarry (); + } + IAPU.PC += 3; +} + +void ApuAA () +{ +// MOV1 C,membit + MemBit (); + if (S9xAPUGetByte (IAPU.Address) & (1 << IAPU.Bit)) + APUSetCarry (); + else + APUClearCarry (); + IAPU.PC += 3; +} + +void ApuCA () +{ +// MOV1 membit,C + MemBit (); + if (APUCheckCarry ()) + { + S9xAPUSetByte (S9xAPUGetByte (IAPU.Address) | (1 << IAPU.Bit), IAPU.Address); + } + else + { + S9xAPUSetByte (S9xAPUGetByte (IAPU.Address) & ~(1 << IAPU.Bit), IAPU.Address); + } + IAPU.PC += 3; +} + +void ApuEA () +{ +// NOT1 membit + MemBit (); + S9xAPUSetByte (S9xAPUGetByte (IAPU.Address) ^ (1 << IAPU.Bit), IAPU.Address); + IAPU.PC += 3; +} + +void Apu0B () +{ +// ASL dp + Work8 = S9xAPUGetByteZ (OP1); + ASL (Work8); + S9xAPUSetByteZ (Work8, OP1); + IAPU.PC += 2; +} + +void Apu0C () +{ +// ASL abs + Absolute (); + Work8 = S9xAPUGetByte (IAPU.Address); + ASL (Work8); + S9xAPUSetByte (Work8, IAPU.Address); + IAPU.PC += 3; +} + +void Apu1B () +{ +// ASL dp+X + Work8 = S9xAPUGetByteZ (OP1 + IAPU.X); + ASL (Work8); + S9xAPUSetByteZ (Work8, OP1 + IAPU.X); + IAPU.PC += 2; +} + +void Apu1C () +{ +// ASL A + ASL (IAPU.YA.B.A); + IAPU.PC++; +} + +void Apu0D () +{ +// PUSH PSW + S9xAPUPackStatus (); + Push (IAPU.P); + IAPU.PC++; +} + +void Apu2D () +{ +// PUSH A + Push (IAPU.YA.B.A); + IAPU.PC++; +} + +void Apu4D () +{ +// PUSH X + Push (IAPU.X); + IAPU.PC++; +} + +void Apu6D () +{ +// PUSH Y + Push (IAPU.YA.B.Y); + IAPU.PC++; +} + +void Apu8E () +{ +// POP PSW + Pop (IAPU.P); + S9xAPUUnpackStatus (); + if (APUCheckDirectPage ()) + IAPU.DirectPage = IAPU.RAM + 0x100; + else + IAPU.DirectPage = IAPU.RAM; + IAPU.PC++; +} + +void ApuAE () +{ +// POP A + Pop (IAPU.YA.B.A); + IAPU.PC++; +} + +void ApuCE () +{ +// POP X + Pop (IAPU.X); + IAPU.PC++; +} + +void ApuEE () +{ +// POP Y + Pop (IAPU.YA.B.Y); + IAPU.PC++; +} + +void Apu0E () +{ +// TSET1 abs + Absolute (); + Work8 = S9xAPUGetByte (IAPU.Address); + S9xAPUSetByte (Work8 | IAPU.YA.B.A, IAPU.Address); + Work8 &= IAPU.YA.B.A; + APUSetZN8 (Work8); + IAPU.PC += 3; +} + +void Apu4E () +{ +// TCLR1 abs + Absolute (); + Work8 = S9xAPUGetByte (IAPU.Address); + S9xAPUSetByte (Work8 & ~IAPU.YA.B.A, IAPU.Address); + Work8 &= IAPU.YA.B.A; + APUSetZN8 (Work8); + IAPU.PC += 3; +} + +void Apu0F () +{ +// BRK + +#if 0 + STOP ("BRK"); +#else + PushW ((IAPU.PC + 1 - IAPU.RAM)); + S9xAPUPackStatus (); + Push (IAPU.P); + APUSetBreak (); + APUClearInterrupt (); +// XXX:Where is the BRK vector ??? + IAPU.PC = IAPU.RAM + APU.ExtraRAM[0x20] + (APU.ExtraRAM[0x21] << 8); +#endif +} + +void ApuEF () +{ +// SLEEP + // XXX: sleep + // STOP ("SLEEP"); + CPU.APU_APUExecuting = FALSE; + IAPU.PC++; +} + +void ApuFF () +{ +// STOP + // STOP ("STOP"); + CPU.APU_APUExecuting = FALSE; + IAPU.PC++; +} + +void Apu10 () +{ +// BPL + Relative (); + if (!APUCheckNegative ()) + { + IAPU.PC = IAPU.RAM + (uint16) Int16; + CPU.APU_Cycles += IAPU.TwoCycles; + APUShutdown (); + } + else + IAPU.PC += 2; +} + +void Apu30 () +{ +// BMI + Relative (); + if (APUCheckNegative ()) + { + IAPU.PC = IAPU.RAM + (uint16) Int16; + CPU.APU_Cycles += IAPU.TwoCycles; + APUShutdown (); + } + else + IAPU.PC += 2; +} + +void Apu90 () +{ +// BCC + Relative (); + if (!APUCheckCarry ()) + { + IAPU.PC = IAPU.RAM + (uint16) Int16; + CPU.APU_Cycles += IAPU.TwoCycles; + APUShutdown (); + } + else + IAPU.PC += 2; +} + +void ApuB0 () +{ +// BCS + Relative (); + if (APUCheckCarry ()) + { + IAPU.PC = IAPU.RAM + (uint16) Int16; + CPU.APU_Cycles += IAPU.TwoCycles; + APUShutdown (); + } + else + IAPU.PC += 2; +} + +void ApuD0 () +{ +// BNE + Relative (); + if (!APUCheckZero ()) + { + IAPU.PC = IAPU.RAM + (uint16) Int16; + CPU.APU_Cycles += IAPU.TwoCycles; + APUShutdown (); + } + else + IAPU.PC += 2; +} + +void ApuF0 () +{ +// BEQ + Relative (); + if (APUCheckZero ()) + { + IAPU.PC = IAPU.RAM + (uint16) Int16; + CPU.APU_Cycles += IAPU.TwoCycles; + APUShutdown (); + } + else + IAPU.PC += 2; +} + +void Apu50 () +{ +// BVC + Relative (); + if (!APUCheckOverflow ()) + { + IAPU.PC = IAPU.RAM + (uint16) Int16; + CPU.APU_Cycles += IAPU.TwoCycles; + } + else + IAPU.PC += 2; +} + +void Apu70 () +{ +// BVS + Relative (); + if (APUCheckOverflow ()) + { + IAPU.PC = IAPU.RAM + (uint16) Int16; + CPU.APU_Cycles += IAPU.TwoCycles; + } + else + IAPU.PC += 2; +} + +void Apu2F () +{ +// BRA + Relative (); + IAPU.PC = IAPU.RAM + (uint16) Int16; +} + +void Apu80 () +{ +// SETC + APUSetCarry (); + IAPU.PC++; +} + +void ApuED () +{ +// NOTC + IAPU._Carry ^= 1; + IAPU.PC++; +} + +void Apu40 () +{ +// SETP + APUSetDirectPage (); + IAPU.DirectPage = IAPU.RAM + 0x100; + IAPU.PC++; +} + +void Apu1A () +{ +// DECW dp + Work16 = S9xAPUGetByteZ (OP1) + (S9xAPUGetByteZ (OP1 + 1) << 8); + Work16--; + S9xAPUSetByteZ ((uint8) Work16, OP1); + S9xAPUSetByteZ (Work16 >> 8, OP1 + 1); + APUSetZN16 (Work16); + IAPU.PC += 2; +} + +void Apu5A () +{ +// CMPW YA,dp + Work16 = S9xAPUGetByteZ (OP1) + (S9xAPUGetByteZ (OP1 + 1) << 8); + Int32 = (long) IAPU.YA.W - (long) Work16; + IAPU._Carry = Int32 >= 0; + APUSetZN16 ((uint16) Int32); + IAPU.PC += 2; +} + +void Apu3A () +{ +// INCW dp + Work16 = S9xAPUGetByteZ (OP1) + (S9xAPUGetByteZ (OP1 + 1) << 8); + Work16++; + S9xAPUSetByteZ ((uint8) Work16, OP1); + S9xAPUSetByteZ (Work16 >> 8, OP1 + 1); + APUSetZN16 (Work16); + IAPU.PC += 2; +} + +// XXX: HalfCarry - BJ Fixed? Or is it between bits 7 and 8 for ADDW/SUBW? +void Apu7A () +{ +// ADDW YA,dp + Work16 = S9xAPUGetByteZ (OP1) + (S9xAPUGetByteZ (OP1 + 1) << 8); + Work32 = (uint32) IAPU.YA.W + Work16; + IAPU._Carry = Work32 >= 0x10000; + if (~(IAPU.YA.W ^ Work16) & (Work16 ^ (uint16) Work32) & 0x8000) + APUSetOverflow (); + else + APUClearOverflow (); + APUClearHalfCarry (); + if((IAPU.YA.W ^ Work16 ^ (uint16) Work32) & 0x10) + APUSetHalfCarry (); + IAPU.YA.W = (uint16) Work32; + APUSetZN16 (IAPU.YA.W); + IAPU.PC += 2; +} + +// XXX: BJ: i think the old HalfCarry behavior was wrong... +// XXX: Or is it between bits 7 and 8 for ADDW/SUBW? +void Apu9A () +{ +// SUBW YA,dp + Work16 = S9xAPUGetByteZ (OP1) + (S9xAPUGetByteZ (OP1 + 1) << 8); + Int32 = (long) IAPU.YA.W - (long) Work16; + APUClearHalfCarry (); + IAPU._Carry = Int32 >= 0; + if (((IAPU.YA.W ^ Work16) & 0x8000) && + ((IAPU.YA.W ^ (uint16) Int32) & 0x8000)) + APUSetOverflow (); + else + APUClearOverflow (); +// if (((IAPU.YA.W ^ Work16) & 0x0080) && +// ((IAPU.YA.W ^ (uint16) Int32) & 0x0080)) +// APUSetHalfCarry (); // notaz: strange here + APUSetHalfCarry (); +// if((IAPU.YA.W ^ Work16 ^ (uint16) Work32) & 0x10) // notaz: Work32?! + if((IAPU.YA.W ^ Work16 ^ (uint16) Int32) & 0x10) + APUClearHalfCarry (); + IAPU.YA.W = (uint16) Int32; + APUSetZN16 (IAPU.YA.W); + IAPU.PC += 2; +} + +void ApuBA () +{ +// MOVW YA,dp + IAPU.YA.B.A = S9xAPUGetByteZ (OP1); + IAPU.YA.B.Y = S9xAPUGetByteZ (OP1 + 1); + APUSetZN16 (IAPU.YA.W); + IAPU.PC += 2; +} + +void ApuDA () +{ +// MOVW dp,YA + S9xAPUSetByteZ (IAPU.YA.B.A, OP1); + S9xAPUSetByteZ (IAPU.YA.B.Y, OP1 + 1); + IAPU.PC += 2; +} + +void Apu64 () +{ +// CMP A,dp + Work8 = S9xAPUGetByteZ (OP1); + CMP (IAPU.YA.B.A, Work8); + IAPU.PC += 2; +} + +void Apu65 () +{ +// CMP A,abs + Absolute (); + Work8 = S9xAPUGetByte (IAPU.Address); + CMP (IAPU.YA.B.A, Work8); + IAPU.PC += 3; +} + +void Apu66 () +{ +// CMP A,(X) + Work8 = S9xAPUGetByteZ (IAPU.X); + CMP (IAPU.YA.B.A, Work8); + IAPU.PC++; +} + +void Apu67 () +{ +// CMP A,(dp+X) + IndexedXIndirect (); + Work8 = S9xAPUGetByte (IAPU.Address); + CMP (IAPU.YA.B.A, Work8); + IAPU.PC += 2; +} + +void Apu68 () +{ +// CMP A,#00 + Work8 = OP1; + CMP (IAPU.YA.B.A, Work8); + IAPU.PC += 2; +} + +void Apu69 () +{ +// CMP dp(dest), dp(src) + W1 = S9xAPUGetByteZ (OP1); + Work8 = S9xAPUGetByteZ (OP2); + CMP (Work8, W1); + IAPU.PC += 3; +} + +void Apu74 () +{ +// CMP A, dp+X + Work8 = S9xAPUGetByteZ (OP1 + IAPU.X); + CMP (IAPU.YA.B.A, Work8); + IAPU.PC += 2; +} + +void Apu75 () +{ +// CMP A,abs+X + AbsoluteX (); + Work8 = S9xAPUGetByte (IAPU.Address); + CMP (IAPU.YA.B.A, Work8); + IAPU.PC += 3; +} + +void Apu76 () +{ +// CMP A, abs+Y + AbsoluteY (); + Work8 = S9xAPUGetByte (IAPU.Address); + CMP (IAPU.YA.B.A, Work8); + IAPU.PC += 3; +} + +void Apu77 () +{ +// CMP A,(dp)+Y + IndirectIndexedY (); + Work8 = S9xAPUGetByte (IAPU.Address); + CMP (IAPU.YA.B.A, Work8); + IAPU.PC += 2; +} + +void Apu78 () +{ +// CMP dp,#00 + Work8 = OP1; + W1 = S9xAPUGetByteZ (OP2); + CMP (W1, Work8); + IAPU.PC += 3; +} + +void Apu79 () +{ +// CMP (X),(Y) + W1 = S9xAPUGetByteZ (IAPU.X); + Work8 = S9xAPUGetByteZ (IAPU.YA.B.Y); + CMP (W1, Work8); + IAPU.PC++; +} + +void Apu1E () +{ +// CMP X,abs + Absolute (); + Work8 = S9xAPUGetByte (IAPU.Address); + CMP (IAPU.X, Work8); + IAPU.PC += 3; +} + +void Apu3E () +{ +// CMP X,dp + Work8 = S9xAPUGetByteZ (OP1); + CMP (IAPU.X, Work8); + IAPU.PC += 2; +} + +void ApuC8 () +{ +// CMP X,#00 + CMP (IAPU.X, OP1); + IAPU.PC += 2; +} + +void Apu5E () +{ +// CMP Y,abs + Absolute (); + Work8 = S9xAPUGetByte (IAPU.Address); + CMP (IAPU.YA.B.Y, Work8); + IAPU.PC += 3; +} + +void Apu7E () +{ +// CMP Y,dp + Work8 = S9xAPUGetByteZ (OP1); + CMP (IAPU.YA.B.Y, Work8); + IAPU.PC += 2; +} + +void ApuAD () +{ +// CMP Y,#00 + Work8 = OP1; + CMP (IAPU.YA.B.Y, Work8); + IAPU.PC += 2; +} + +void Apu1F () +{ +// JMP (abs+X) + Absolute (); + IAPU.PC = IAPU.RAM + S9xAPUGetByte (IAPU.Address + IAPU.X) + + (S9xAPUGetByte (IAPU.Address + IAPU.X + 1) << 8); +// XXX: HERE: + // APU.Flags |= TRACE_FLAG; +} + +void Apu5F () +{ +// JMP abs + Absolute (); + IAPU.PC = IAPU.RAM + IAPU.Address; +} + +void Apu20 () +{ +// CLRP + APUClearDirectPage (); + IAPU.DirectPage = IAPU.RAM; + IAPU.PC++; +} + +void Apu60 () +{ +// CLRC + APUClearCarry (); + IAPU.PC++; +} + +void ApuE0 () +{ +// CLRV + APUClearHalfCarry (); + APUClearOverflow (); + IAPU.PC++; +} + +void Apu24 () +{ +// AND A,dp + IAPU.YA.B.A &= S9xAPUGetByteZ (OP1); + APUSetZN8 (IAPU.YA.B.A); + IAPU.PC += 2; +} + +void Apu25 () +{ +// AND A,abs + Absolute (); + IAPU.YA.B.A &= S9xAPUGetByte (IAPU.Address); + APUSetZN8 (IAPU.YA.B.A); + IAPU.PC += 3; +} + +void Apu26 () +{ +// AND A,(X) + IAPU.YA.B.A &= S9xAPUGetByteZ (IAPU.X); + APUSetZN8 (IAPU.YA.B.A); + IAPU.PC++; +} + +void Apu27 () +{ +// AND A,(dp+X) + IndexedXIndirect (); + IAPU.YA.B.A &= S9xAPUGetByte (IAPU.Address); + APUSetZN8 (IAPU.YA.B.A); + IAPU.PC += 2; +} + +void Apu28 () +{ +// AND A,#00 + IAPU.YA.B.A &= OP1; + APUSetZN8 (IAPU.YA.B.A); + IAPU.PC += 2; +} + +void Apu29 () +{ +// AND dp(dest),dp(src) + Work8 = S9xAPUGetByteZ (OP1); + Work8 &= S9xAPUGetByteZ (OP2); + S9xAPUSetByteZ (Work8, OP2); + APUSetZN8 (Work8); + IAPU.PC += 3; +} + +void Apu34 () +{ +// AND A,dp+X + IAPU.YA.B.A &= S9xAPUGetByteZ (OP1 + IAPU.X); + APUSetZN8 (IAPU.YA.B.A); + IAPU.PC += 2; +} + +void Apu35 () +{ +// AND A,abs+X + AbsoluteX (); + IAPU.YA.B.A &= S9xAPUGetByte (IAPU.Address); + APUSetZN8 (IAPU.YA.B.A); + IAPU.PC += 3; +} + +void Apu36 () +{ +// AND A,abs+Y + AbsoluteY (); + IAPU.YA.B.A &= S9xAPUGetByte (IAPU.Address); + APUSetZN8 (IAPU.YA.B.A); + IAPU.PC += 3; +} + +void Apu37 () +{ +// AND A,(dp)+Y + IndirectIndexedY (); + IAPU.YA.B.A &= S9xAPUGetByte (IAPU.Address); + APUSetZN8 (IAPU.YA.B.A); + IAPU.PC += 2; +} + +void Apu38 () +{ +// AND dp,#00 + Work8 = OP1; + Work8 &= S9xAPUGetByteZ (OP2); + S9xAPUSetByteZ (Work8, OP2); + APUSetZN8 (Work8); + IAPU.PC += 3; +} + +void Apu39 () +{ +// AND (X),(Y) + Work8 = S9xAPUGetByteZ (IAPU.X) & S9xAPUGetByteZ (IAPU.YA.B.Y); + APUSetZN8 (Work8); + S9xAPUSetByteZ (Work8, IAPU.X); + IAPU.PC++; +} + +void Apu2B () +{ +// ROL dp + Work8 = S9xAPUGetByteZ (OP1); + ROL (Work8); + S9xAPUSetByteZ (Work8, OP1); + IAPU.PC += 2; +} + +void Apu2C () +{ +// ROL abs + Absolute (); + Work8 = S9xAPUGetByte (IAPU.Address); + ROL (Work8); + S9xAPUSetByte (Work8, IAPU.Address); + IAPU.PC += 3; +} + +void Apu3B () +{ +// ROL dp+X + Work8 = S9xAPUGetByteZ (OP1 + IAPU.X); + ROL (Work8); + S9xAPUSetByteZ (Work8, OP1 + IAPU.X); + IAPU.PC += 2; +} + +void Apu3C () +{ +// ROL A + ROL (IAPU.YA.B.A); + IAPU.PC++; +} + +void Apu2E () +{ +// CBNE dp,rel + Work8 = OP1; + Relative2 (); + + if (S9xAPUGetByteZ (Work8) != IAPU.YA.B.A) + { + IAPU.PC = IAPU.RAM + (uint16) Int16; + CPU.APU_Cycles += IAPU.TwoCycles; + APUShutdown (); + } + else + IAPU.PC += 3; +} + +void ApuDE () +{ +// CBNE dp+X,rel + Work8 = OP1 + IAPU.X; + Relative2 (); + + if (S9xAPUGetByteZ (Work8) != IAPU.YA.B.A) + { + IAPU.PC = IAPU.RAM + (uint16) Int16; + CPU.APU_Cycles += IAPU.TwoCycles; + APUShutdown (); + } + else + IAPU.PC += 3; +} + +void Apu3D () +{ +// INC X + IAPU.X++; + APUSetZN8 (IAPU.X); + +#ifdef SPC700_SHUTDOWN + IAPU.WaitCounter++; +#endif + + IAPU.PC++; +} + +void ApuFC () +{ +// INC Y + IAPU.YA.B.Y++; + APUSetZN8 (IAPU.YA.B.Y); + +#ifdef SPC700_SHUTDOWN + IAPU.WaitCounter++; +#endif + + IAPU.PC++; +} + +void Apu1D () +{ +// DEC X + IAPU.X--; + APUSetZN8 (IAPU.X); + +#ifdef SPC700_SHUTDOWN + IAPU.WaitCounter++; +#endif + + IAPU.PC++; +} + +void ApuDC () +{ +// DEC Y + IAPU.YA.B.Y--; + APUSetZN8 (IAPU.YA.B.Y); + +#ifdef SPC700_SHUTDOWN + IAPU.WaitCounter++; +#endif + + IAPU.PC++; +} + +void ApuAB () +{ +// INC dp + Work8 = S9xAPUGetByteZ (OP1) + 1; + S9xAPUSetByteZ (Work8, OP1); + APUSetZN8 (Work8); + +#ifdef SPC700_SHUTDOWN + IAPU.WaitCounter++; +#endif + + IAPU.PC += 2; +} + +void ApuAC () +{ +// INC abs + Absolute (); + Work8 = S9xAPUGetByte (IAPU.Address) + 1; + S9xAPUSetByte (Work8, IAPU.Address); + APUSetZN8 (Work8); + +#ifdef SPC700_SHUTDOWN + IAPU.WaitCounter++; +#endif + + IAPU.PC += 3; +} + +void ApuBB () +{ +// INC dp+X + Work8 = S9xAPUGetByteZ (OP1 + IAPU.X) + 1; + S9xAPUSetByteZ (Work8, OP1 + IAPU.X); + APUSetZN8 (Work8); + +#ifdef SPC700_SHUTDOWN + IAPU.WaitCounter++; +#endif + + IAPU.PC += 2; +} + +void ApuBC () +{ +// INC A + IAPU.YA.B.A++; + APUSetZN8 (IAPU.YA.B.A); + +#ifdef SPC700_SHUTDOWN + IAPU.WaitCounter++; +#endif + + IAPU.PC++; +} + +void Apu8B () +{ +// DEC dp + Work8 = S9xAPUGetByteZ (OP1) - 1; + S9xAPUSetByteZ (Work8, OP1); + APUSetZN8 (Work8); + +#ifdef SPC700_SHUTDOWN + IAPU.WaitCounter++; +#endif + + IAPU.PC += 2; +} + +void Apu8C () +{ +// DEC abs + Absolute (); + Work8 = S9xAPUGetByte (IAPU.Address) - 1; + S9xAPUSetByte (Work8, IAPU.Address); + APUSetZN8 (Work8); + +#ifdef SPC700_SHUTDOWN + IAPU.WaitCounter++; +#endif + + IAPU.PC += 3; +} + +void Apu9B () +{ +// DEC dp+X + Work8 = S9xAPUGetByteZ (OP1 + IAPU.X) - 1; + S9xAPUSetByteZ (Work8, OP1 + IAPU.X); + APUSetZN8 (Work8); + +#ifdef SPC700_SHUTDOWN + IAPU.WaitCounter++; +#endif + + IAPU.PC += 2; +} + +void Apu9C () +{ +// DEC A + IAPU.YA.B.A--; + APUSetZN8 (IAPU.YA.B.A); + +#ifdef SPC700_SHUTDOWN + IAPU.WaitCounter++; +#endif + + IAPU.PC++; +} + +void Apu44 () +{ +// EOR A,dp + IAPU.YA.B.A ^= S9xAPUGetByteZ (OP1); + APUSetZN8 (IAPU.YA.B.A); + IAPU.PC += 2; +} + +void Apu45 () +{ +// EOR A,abs + Absolute (); + IAPU.YA.B.A ^= S9xAPUGetByte (IAPU.Address); + APUSetZN8 (IAPU.YA.B.A); + IAPU.PC += 3; +} + +void Apu46 () +{ +// EOR A,(X) + IAPU.YA.B.A ^= S9xAPUGetByteZ (IAPU.X); + APUSetZN8 (IAPU.YA.B.A); + IAPU.PC++; +} + +void Apu47 () +{ +// EOR A,(dp+X) + IndexedXIndirect (); + IAPU.YA.B.A ^= S9xAPUGetByte (IAPU.Address); + APUSetZN8 (IAPU.YA.B.A); + IAPU.PC += 2; +} + +void Apu48 () +{ +// EOR A,#00 + IAPU.YA.B.A ^= OP1; + APUSetZN8 (IAPU.YA.B.A); + IAPU.PC += 2; +} + +void Apu49 () +{ +// EOR dp(dest),dp(src) + Work8 = S9xAPUGetByteZ (OP1); + Work8 ^= S9xAPUGetByteZ (OP2); + S9xAPUSetByteZ (Work8, OP2); + APUSetZN8 (Work8); + IAPU.PC += 3; +} + +void Apu54 () +{ +// EOR A,dp+X + IAPU.YA.B.A ^= S9xAPUGetByteZ (OP1 + IAPU.X); + APUSetZN8 (IAPU.YA.B.A); + IAPU.PC += 2; +} + +void Apu55 () +{ +// EOR A,abs+X + AbsoluteX (); + IAPU.YA.B.A ^= S9xAPUGetByte (IAPU.Address); + APUSetZN8 (IAPU.YA.B.A); + IAPU.PC += 3; +} + +void Apu56 () +{ +// EOR A,abs+Y + AbsoluteY (); + IAPU.YA.B.A ^= S9xAPUGetByte (IAPU.Address); + APUSetZN8 (IAPU.YA.B.A); + IAPU.PC += 3; +} + +void Apu57 () +{ +// EOR A,(dp)+Y + IndirectIndexedY (); + IAPU.YA.B.A ^= S9xAPUGetByte (IAPU.Address); + APUSetZN8 (IAPU.YA.B.A); + IAPU.PC += 2; +} + +void Apu58 () +{ +// EOR dp,#00 + Work8 = OP1; + Work8 ^= S9xAPUGetByteZ (OP2); + S9xAPUSetByteZ (Work8, OP2); + APUSetZN8 (Work8); + IAPU.PC += 3; +} + +void Apu59 () +{ +// EOR (X),(Y) + Work8 = S9xAPUGetByteZ (IAPU.X) ^ S9xAPUGetByteZ (IAPU.YA.B.Y); + APUSetZN8 (Work8); + S9xAPUSetByteZ (Work8, IAPU.X); + IAPU.PC++; +} + +void Apu4B () +{ +// LSR dp + Work8 = S9xAPUGetByteZ (OP1); + LSR (Work8); + S9xAPUSetByteZ (Work8, OP1); + IAPU.PC += 2; +} + +void Apu4C () +{ +// LSR abs + Absolute (); + Work8 = S9xAPUGetByte (IAPU.Address); + LSR (Work8); + S9xAPUSetByte (Work8, IAPU.Address); + IAPU.PC += 3; +} + +void Apu5B () +{ +// LSR dp+X + Work8 = S9xAPUGetByteZ (OP1 + IAPU.X); + LSR (Work8); + S9xAPUSetByteZ (Work8, OP1 + IAPU.X); + IAPU.PC += 2; +} + +void Apu5C () +{ +// LSR A + LSR (IAPU.YA.B.A); + IAPU.PC++; +} + +void Apu7D () +{ +// MOV A,X + IAPU.YA.B.A = IAPU.X; + APUSetZN8 (IAPU.YA.B.A); + IAPU.PC++; +} + +void ApuDD () +{ +// MOV A,Y + IAPU.YA.B.A = IAPU.YA.B.Y; + APUSetZN8 (IAPU.YA.B.A); + IAPU.PC++; +} + +void Apu5D () +{ +// MOV X,A + IAPU.X = IAPU.YA.B.A; + APUSetZN8 (IAPU.X); + IAPU.PC++; +} + +void ApuFD () +{ +// MOV Y,A + IAPU.YA.B.Y = IAPU.YA.B.A; + APUSetZN8 (IAPU.YA.B.Y); + IAPU.PC++; +} + +void Apu9D () +{ +//MOV X,SP + IAPU.X = IAPU.S; + APUSetZN8 (IAPU.X); + IAPU.PC++; +} + +void ApuBD () +{ +// MOV SP,X + IAPU.S = IAPU.X; + IAPU.PC++; +} + +void Apu6B () +{ +// ROR dp + Work8 = S9xAPUGetByteZ (OP1); + ROR (Work8); + S9xAPUSetByteZ (Work8, OP1); + IAPU.PC += 2; +} + +void Apu6C () +{ +// ROR abs + Absolute (); + Work8 = S9xAPUGetByte (IAPU.Address); + ROR (Work8); + S9xAPUSetByte (Work8, IAPU.Address); + IAPU.PC += 3; +} + +void Apu7B () +{ +// ROR dp+X + Work8 = S9xAPUGetByteZ (OP1 + IAPU.X); + ROR (Work8); + S9xAPUSetByteZ (Work8, OP1 + IAPU.X); + IAPU.PC += 2; +} + +void Apu7C () +{ +// ROR A + ROR (IAPU.YA.B.A); + IAPU.PC++; +} + +void Apu6E () +{ +// DBNZ dp,rel + Work8 = OP1; + Relative2 (); + W1 = S9xAPUGetByteZ (Work8) - 1; + S9xAPUSetByteZ (W1, Work8); + if (W1 != 0) + { + IAPU.PC = IAPU.RAM + (uint16) Int16; + CPU.APU_Cycles += IAPU.TwoCycles; + } + else + IAPU.PC += 3; +} + +void ApuFE () +{ +// DBNZ Y,rel + Relative (); + IAPU.YA.B.Y--; + if (IAPU.YA.B.Y != 0) + { + IAPU.PC = IAPU.RAM + (uint16) Int16; + CPU.APU_Cycles += IAPU.TwoCycles; + } + else + IAPU.PC += 2; +} + +void Apu6F () +{ +// RET + PopW (Work16); + IAPU.PC = IAPU.RAM + Work16; +} + +void Apu7F () +{ +// RETI + // STOP ("RETI"); + Pop (IAPU.P); + S9xAPUUnpackStatus (); + PopW (Work16); + IAPU.PC = IAPU.RAM + Work16; +} + +void Apu84 () +{ +// ADC A,dp + Work8 = S9xAPUGetByteZ (OP1); + ADC (IAPU.YA.B.A, Work8); + IAPU.PC += 2; +} + +void Apu85 () +{ +// ADC A, abs + Absolute (); + Work8 = S9xAPUGetByte (IAPU.Address); + ADC (IAPU.YA.B.A, Work8); + IAPU.PC += 3; +} + +void Apu86 () +{ +// ADC A,(X) + Work8 = S9xAPUGetByteZ (IAPU.X); + ADC (IAPU.YA.B.A, Work8); + IAPU.PC++; +} + +void Apu87 () +{ +// ADC A,(dp+X) + IndexedXIndirect (); + Work8 = S9xAPUGetByte (IAPU.Address); + ADC (IAPU.YA.B.A, Work8); + IAPU.PC += 2; +} + +void Apu88 () +{ +// ADC A,#00 + Work8 = OP1; + ADC (IAPU.YA.B.A, Work8); + IAPU.PC += 2; +} + +void Apu89 () +{ +// ADC dp(dest),dp(src) + Work8 = S9xAPUGetByteZ (OP1); + W1 = S9xAPUGetByteZ (OP2); + ADC (W1, Work8); + S9xAPUSetByteZ (W1, OP2); + IAPU.PC += 3; +} + +void Apu94 () +{ +// ADC A,dp+X + Work8 = S9xAPUGetByteZ (OP1 + IAPU.X); + ADC (IAPU.YA.B.A, Work8); + IAPU.PC += 2; +} + +void Apu95 () +{ +// ADC A, abs+X + AbsoluteX (); + Work8 = S9xAPUGetByte (IAPU.Address); + ADC (IAPU.YA.B.A, Work8); + IAPU.PC += 3; +} + +void Apu96 () +{ +// ADC A, abs+Y + AbsoluteY (); + Work8 = S9xAPUGetByte (IAPU.Address); + ADC (IAPU.YA.B.A, Work8); + IAPU.PC += 3; +} + +void Apu97 () +{ +// ADC A, (dp)+Y + IndirectIndexedY (); + Work8 = S9xAPUGetByte (IAPU.Address); + ADC (IAPU.YA.B.A, Work8); + IAPU.PC += 2; +} + +void Apu98 () +{ +// ADC dp,#00 + Work8 = OP1; + W1 = S9xAPUGetByteZ (OP2); + ADC (W1, Work8); + S9xAPUSetByteZ (W1, OP2); + IAPU.PC += 3; +} + +void Apu99 () +{ +// ADC (X),(Y) + W1 = S9xAPUGetByteZ (IAPU.X); + Work8 = S9xAPUGetByteZ (IAPU.YA.B.Y); + ADC (W1, Work8); + S9xAPUSetByteZ (W1, IAPU.X); + IAPU.PC++; +} + +void Apu8D () +{ +// MOV Y,#00 + IAPU.YA.B.Y = OP1; + APUSetZN8 (IAPU.YA.B.Y); + IAPU.PC += 2; +} + +void Apu8F () +{ +// MOV dp,#00 + Work8 = OP1; + S9xAPUSetByteZ (Work8, OP2); + IAPU.PC += 3; +} + +void Apu9E () +{ +// DIV YA,X + if (IAPU.X == 0) + { + APUSetOverflow (); + IAPU.YA.B.Y = 0xff; + IAPU.YA.B.A = 0xff; + } + else + { + APUClearOverflow (); + Work8 = IAPU.YA.W / IAPU.X; + IAPU.YA.B.Y = IAPU.YA.W % IAPU.X; + IAPU.YA.B.A = Work8; + } +// XXX How should Overflow, Half Carry, Zero and Negative flags be set?? + // APUSetZN16 (IAPU.YA.W); + APUSetZN8 (IAPU.YA.B.A); + IAPU.PC++; +} + +void Apu9F () +{ +// XCN A + IAPU.YA.B.A = (IAPU.YA.B.A >> 4) | (IAPU.YA.B.A << 4); + APUSetZN8 (IAPU.YA.B.A); + IAPU.PC++; +} + +void ApuA4 () +{ +// SBC A, dp + Work8 = S9xAPUGetByteZ (OP1); + SBC (IAPU.YA.B.A, Work8); + IAPU.PC += 2; +} + +void ApuA5 () +{ +// SBC A, abs + Absolute (); + Work8 = S9xAPUGetByte (IAPU.Address); + SBC (IAPU.YA.B.A, Work8); + IAPU.PC += 3; +} + +void ApuA6 () +{ +// SBC A, (X) + Work8 = S9xAPUGetByteZ (IAPU.X); + SBC (IAPU.YA.B.A, Work8); + IAPU.PC++; +} + +void ApuA7 () +{ +// SBC A,(dp+X) + IndexedXIndirect (); + Work8 = S9xAPUGetByte (IAPU.Address); + SBC (IAPU.YA.B.A, Work8); + IAPU.PC += 2; +} + +void ApuA8 () +{ +// SBC A,#00 + Work8 = OP1; + SBC (IAPU.YA.B.A, Work8); + IAPU.PC += 2; +} + +void ApuA9 () +{ +// SBC dp(dest), dp(src) + Work8 = S9xAPUGetByteZ (OP1); + W1 = S9xAPUGetByteZ (OP2); + SBC (W1, Work8); + S9xAPUSetByteZ (W1, OP2); + IAPU.PC += 3; +} + +void ApuB4 () +{ +// SBC A, dp+X + Work8 = S9xAPUGetByteZ (OP1 + IAPU.X); + SBC (IAPU.YA.B.A, Work8); + IAPU.PC += 2; +} + +void ApuB5 () +{ +// SBC A,abs+X + AbsoluteX (); + Work8 = S9xAPUGetByte (IAPU.Address); + SBC (IAPU.YA.B.A, Work8); + IAPU.PC += 3; +} + +void ApuB6 () +{ +// SBC A,abs+Y + AbsoluteY (); + Work8 = S9xAPUGetByte (IAPU.Address); + SBC (IAPU.YA.B.A, Work8); + IAPU.PC += 3; +} + +void ApuB7 () +{ +// SBC A,(dp)+Y + IndirectIndexedY (); + Work8 = S9xAPUGetByte (IAPU.Address); + SBC (IAPU.YA.B.A, Work8); + IAPU.PC += 2; +} + +void ApuB8 () +{ +// SBC dp,#00 + Work8 = OP1; + W1 = S9xAPUGetByteZ (OP2); + SBC (W1, Work8); + S9xAPUSetByteZ (W1, OP2); + IAPU.PC += 3; +} + +void ApuB9 () +{ +// SBC (X),(Y) + W1 = S9xAPUGetByteZ (IAPU.X); + Work8 = S9xAPUGetByteZ (IAPU.YA.B.Y); + SBC (W1, Work8); + S9xAPUSetByteZ (W1, IAPU.X); + IAPU.PC++; +} + +void ApuAF () +{ +// MOV (X)+, A + S9xAPUSetByteZ (IAPU.YA.B.A, IAPU.X++); + IAPU.PC++; +} + +void ApuBE () +{ +// DAS + if ((IAPU.YA.B.A & 0x0f) > 9 || !APUCheckHalfCarry()) + { + IAPU.YA.B.A -= 6; + } + if (IAPU.YA.B.A > 0x9f || !IAPU._Carry) + { + IAPU.YA.B.A -= 0x60; + APUClearCarry (); + } + else { APUSetCarry (); } + APUSetZN8 (IAPU.YA.B.A); + IAPU.PC++; +} + +void ApuBF () +{ +// MOV A,(X)+ + IAPU.YA.B.A = S9xAPUGetByteZ (IAPU.X++); + APUSetZN8 (IAPU.YA.B.A); + IAPU.PC++; +} + +void ApuC0 () +{ +// DI + APUClearInterrupt (); + IAPU.PC++; +} + +void ApuA0 () +{ +// EI + APUSetInterrupt (); + IAPU.PC++; +} + +void ApuC4 () +{ +// MOV dp,A + S9xAPUSetByteZ (IAPU.YA.B.A, OP1); + IAPU.PC += 2; +} + +void ApuC5 () +{ +// MOV abs,A + Absolute (); + S9xAPUSetByte (IAPU.YA.B.A, IAPU.Address); + IAPU.PC += 3; +} + +void ApuC6 () +{ +// MOV (X), A + S9xAPUSetByteZ (IAPU.YA.B.A, IAPU.X); + IAPU.PC++; +} + +void ApuC7 () +{ +// MOV (dp+X),A + IndexedXIndirect (); + S9xAPUSetByte (IAPU.YA.B.A, IAPU.Address); + IAPU.PC += 2; +} + +void ApuC9 () +{ +// MOV abs,X + Absolute (); + S9xAPUSetByte (IAPU.X, IAPU.Address); + IAPU.PC += 3; +} + +void ApuCB () +{ +// MOV dp,Y + S9xAPUSetByteZ (IAPU.YA.B.Y, OP1); + IAPU.PC += 2; +} + +void ApuCC () +{ +// MOV abs,Y + Absolute (); + S9xAPUSetByte (IAPU.YA.B.Y, IAPU.Address); + IAPU.PC += 3; +} + +void ApuCD () +{ +// MOV X,#00 + IAPU.X = OP1; + APUSetZN8 (IAPU.X); + IAPU.PC += 2; +} + +void ApuCF () +{ +// MUL YA + IAPU.YA.W = (uint16) IAPU.YA.B.A * IAPU.YA.B.Y; + APUSetZN16 (IAPU.YA.W); + IAPU.PC++; +} + +void ApuD4 () +{ +// MOV dp+X, A + S9xAPUSetByteZ (IAPU.YA.B.A, OP1 + IAPU.X); + IAPU.PC += 2; +} + +void ApuD5 () +{ +// MOV abs+X,A + AbsoluteX (); + S9xAPUSetByte (IAPU.YA.B.A, IAPU.Address); + IAPU.PC += 3; +} + +void ApuD6 () +{ +// MOV abs+Y,A + AbsoluteY (); + S9xAPUSetByte (IAPU.YA.B.A, IAPU.Address); + IAPU.PC += 3; +} + +void ApuD7 () +{ +// MOV (dp)+Y,A + IndirectIndexedY (); + S9xAPUSetByte (IAPU.YA.B.A, IAPU.Address); + IAPU.PC += 2; +} + +void ApuD8 () +{ +// MOV dp,X + S9xAPUSetByteZ (IAPU.X, OP1); + IAPU.PC += 2; +} + +void ApuD9 () +{ +// MOV dp+Y,X + S9xAPUSetByteZ (IAPU.X, OP1 + IAPU.YA.B.Y); + IAPU.PC += 2; +} + +void ApuDB () +{ +// MOV dp+X,Y + S9xAPUSetByteZ (IAPU.YA.B.Y, OP1 + IAPU.X); + IAPU.PC += 2; +} + +void ApuDF () +{ +// DAA + if ((IAPU.YA.B.A & 0x0f) > 9 || APUCheckHalfCarry()) + { + if(IAPU.YA.B.A > 0xf0) APUSetCarry (); + IAPU.YA.B.A += 6; + //APUSetHalfCarry (); Intel procs do this, but this is a Sony proc... + } + //else { APUClearHalfCarry (); } ditto as above + if (IAPU.YA.B.A > 0x9f || IAPU._Carry) + { + IAPU.YA.B.A += 0x60; + APUSetCarry (); + } + else { APUClearCarry (); } + APUSetZN8 (IAPU.YA.B.A); + IAPU.PC++; +} + +void ApuE4 () +{ +// MOV A, dp + IAPU.YA.B.A = S9xAPUGetByteZ (OP1); + APUSetZN8 (IAPU.YA.B.A); + IAPU.PC += 2; +} + +void ApuE5 () +{ +// MOV A,abs + Absolute (); + IAPU.YA.B.A = S9xAPUGetByte (IAPU.Address); + APUSetZN8 (IAPU.YA.B.A); + IAPU.PC += 3; +} + +void ApuE6 () +{ +// MOV A,(X) + IAPU.YA.B.A = S9xAPUGetByteZ (IAPU.X); + APUSetZN8 (IAPU.YA.B.A); + IAPU.PC++; +} + +void ApuE7 () +{ +// MOV A,(dp+X) + IndexedXIndirect (); + IAPU.YA.B.A = S9xAPUGetByte (IAPU.Address); + APUSetZN8 (IAPU.YA.B.A); + IAPU.PC += 2; +} + +void ApuE8 () +{ +// MOV A,#00 + IAPU.YA.B.A = OP1; + APUSetZN8 (IAPU.YA.B.A); + IAPU.PC += 2; +} + +void ApuE9 () +{ +// MOV X, abs + Absolute (); + IAPU.X = S9xAPUGetByte (IAPU.Address); + APUSetZN8 (IAPU.X); + IAPU.PC += 3; +} + +void ApuEB () +{ +// MOV Y,dp + IAPU.YA.B.Y = S9xAPUGetByteZ (OP1); + APUSetZN8 (IAPU.YA.B.Y); + IAPU.PC += 2; +} + +void ApuEC () +{ +// MOV Y,abs + Absolute (); + IAPU.YA.B.Y = S9xAPUGetByte (IAPU.Address); + APUSetZN8 (IAPU.YA.B.Y); + IAPU.PC += 3; +} + +void ApuF4 () +{ +// MOV A, dp+X + IAPU.YA.B.A = S9xAPUGetByteZ (OP1 + IAPU.X); + APUSetZN8 (IAPU.YA.B.A); + IAPU.PC += 2; +} + +void ApuF5 () +{ +// MOV A, abs+X + AbsoluteX (); + IAPU.YA.B.A = S9xAPUGetByte (IAPU.Address); + APUSetZN8 (IAPU.YA.B.A); + IAPU.PC += 3; +} + +void ApuF6 () +{ +// MOV A, abs+Y + AbsoluteY (); + IAPU.YA.B.A = S9xAPUGetByte (IAPU.Address); + APUSetZN8 (IAPU.YA.B.A); + IAPU.PC += 3; +} + +void ApuF7 () +{ +// MOV A, (dp)+Y + IndirectIndexedY (); + IAPU.YA.B.A = S9xAPUGetByte (IAPU.Address); + APUSetZN8 (IAPU.YA.B.A); + IAPU.PC += 2; +} + +void ApuF8 () +{ +// MOV X,dp + IAPU.X = S9xAPUGetByteZ (OP1); + APUSetZN8 (IAPU.X); + IAPU.PC += 2; +} + +void ApuF9 () +{ +// MOV X,dp+Y + IAPU.X = S9xAPUGetByteZ (OP1 + IAPU.YA.B.Y); + APUSetZN8 (IAPU.X); + IAPU.PC += 2; +} + +void ApuFA () +{ +// MOV dp(dest),dp(src) + S9xAPUSetByteZ (S9xAPUGetByteZ (OP1), OP2); + IAPU.PC += 3; +} + +void ApuFB () +{ +// MOV Y,dp+X + IAPU.YA.B.Y = S9xAPUGetByteZ (OP1 + IAPU.X); + APUSetZN8 (IAPU.YA.B.Y); + IAPU.PC += 2; +} + +#if defined(NO_INLINE_SET_GET) +#undef INLINE +#define INLINE +#include "apumem.h" +#endif + + +void (*S9xApuOpcodes[256]) (void) = +{ + Apu00, Apu01, Apu02, Apu03, Apu04, Apu05, Apu06, Apu07, + Apu08, Apu09, Apu0A, Apu0B, Apu0C, Apu0D, Apu0E, Apu0F, + Apu10, Apu11, Apu12, Apu13, Apu14, Apu15, Apu16, Apu17, + Apu18, Apu19, Apu1A, Apu1B, Apu1C, Apu1D, Apu1E, Apu1F, + Apu20, Apu21, Apu22, Apu23, Apu24, Apu25, Apu26, Apu27, + Apu28, Apu29, Apu2A, Apu2B, Apu2C, Apu2D, Apu2E, Apu2F, + Apu30, Apu31, Apu32, Apu33, Apu34, Apu35, Apu36, Apu37, + Apu38, Apu39, Apu3A, Apu3B, Apu3C, Apu3D, Apu3E, Apu3F, + Apu40, Apu41, Apu42, Apu43, Apu44, Apu45, Apu46, Apu47, + Apu48, Apu49, Apu4A, Apu4B, Apu4C, Apu4D, Apu4E, Apu4F, + Apu50, Apu51, Apu52, Apu53, Apu54, Apu55, Apu56, Apu57, + Apu58, Apu59, Apu5A, Apu5B, Apu5C, Apu5D, Apu5E, Apu5F, + Apu60, Apu61, Apu62, Apu63, Apu64, Apu65, Apu66, Apu67, + Apu68, Apu69, Apu6A, Apu6B, Apu6C, Apu6D, Apu6E, Apu6F, + Apu70, Apu71, Apu72, Apu73, Apu74, Apu75, Apu76, Apu77, + Apu78, Apu79, Apu7A, Apu7B, Apu7C, Apu7D, Apu7E, Apu7F, + Apu80, Apu81, Apu82, Apu83, Apu84, Apu85, Apu86, Apu87, + Apu88, Apu89, Apu8A, Apu8B, Apu8C, Apu8D, Apu8E, Apu8F, + Apu90, Apu91, Apu92, Apu93, Apu94, Apu95, Apu96, Apu97, + Apu98, Apu99, Apu9A, Apu9B, Apu9C, Apu9D, Apu9E, Apu9F, + ApuA0, ApuA1, ApuA2, ApuA3, ApuA4, ApuA5, ApuA6, ApuA7, + ApuA8, ApuA9, ApuAA, ApuAB, ApuAC, ApuAD, ApuAE, ApuAF, + ApuB0, ApuB1, ApuB2, ApuB3, ApuB4, ApuB5, ApuB6, ApuB7, + ApuB8, ApuB9, ApuBA, ApuBB, ApuBC, ApuBD, ApuBE, ApuBF, + ApuC0, ApuC1, ApuC2, ApuC3, ApuC4, ApuC5, ApuC6, ApuC7, + ApuC8, ApuC9, ApuCA, ApuCB, ApuCC, ApuCD, ApuCE, ApuCF, + ApuD0, ApuD1, ApuD2, ApuD3, ApuD4, ApuD5, ApuD6, ApuD7, + ApuD8, ApuD9, ApuDA, ApuDB, ApuDC, ApuDD, ApuDE, ApuDF, + ApuE0, ApuE1, ApuE2, ApuE3, ApuE4, ApuE5, ApuE6, ApuE7, + ApuE8, ApuE9, ApuEA, ApuEB, ApuEC, ApuED, ApuEE, ApuEF, + ApuF0, ApuF1, ApuF2, ApuF3, ApuF4, ApuF5, ApuF6, ApuF7, + ApuF8, ApuF9, ApuFA, ApuFB, ApuFC, ApuFD, ApuFE, ApuFF +}; + +#endif diff --git a/src/snes4iphone_src/spc700.h b/src/snes4iphone_src/spc700.h new file mode 100755 index 0000000..377ab9c --- /dev/null +++ b/src/snes4iphone_src/spc700.h @@ -0,0 +1,173 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#ifndef _SPC700_H_ +#define _SPC700_H_ + +#ifdef SPCTOOL +#define NO_CHANNEL_STRUCT +#include "spctool/dsp.h" +#include "spctool/spc700.h" +#include "spctool/soundmod.h" +#endif + + +#define Carry 1 +#define Zero 2 +#define Interrupt 4 +#define HalfCarry 8 +#define BreakFlag 16 +#define DirectPageFlag 32 +#define Overflow 64 +#define Negative 128 + +#define APUClearCarry() (IAPU._Carry = 0) +#define APUSetCarry() (IAPU._Carry = 1) +#define APUSetInterrupt() (IAPU.P |= Interrupt) +#define APUClearInterrupt() (IAPU.P &= ~Interrupt) +#define APUSetHalfCarry() (IAPU.P |= HalfCarry) +#define APUClearHalfCarry() (IAPU.P &= ~HalfCarry) +#define APUSetBreak() (IAPU.P |= BreakFlag) +#define APUClearBreak() (IAPU.P &= ~BreakFlag) +#define APUSetDirectPage() (IAPU.P |= DirectPageFlag) +#define APUClearDirectPage() (IAPU.P &= ~DirectPageFlag) +#define APUSetOverflow() (IAPU._Overflow = 1) +#define APUClearOverflow() (IAPU._Overflow = 0) + +#define APUCheckZero() (IAPU._Zero == 0) +#define APUCheckCarry() (IAPU._Carry) +#define APUCheckInterrupt() (IAPU.P & Interrupt) +#define APUCheckHalfCarry() (IAPU.P & HalfCarry) +#define APUCheckBreak() (IAPU.P & BreakFlag) +#define APUCheckDirectPage() (IAPU.P & DirectPageFlag) +#define APUCheckOverflow() (IAPU._Overflow) +#define APUCheckNegative() (IAPU._Zero & 0x80) + +//#define APUClearFlags(f) (IAPU.P &= ~(f)) +//#define APUSetFlags(f) (IAPU.P |= (f)) +//#define APUCheckFlag(f) (IAPU.P & (f)) + +typedef union +{ +#ifdef LSB_FIRST + struct { uint8 A, Y; } B; +#else + struct { uint8 Y, A; } B; +#endif + uint16 W; + uint32 _padder; // make sure this whole thing takes 4 bytes +} YAndA; + +struct SAPURegisters{ + uint8 P; + YAndA YA; + uint8 X; + uint8 S; + uint16 PC; +}; + +//EXTERN_C struct SAPURegisters APURegisters; + +// Needed by ILLUSION OF GAIA +//#define ONE_APU_CYCLE 14 +#define ONE_APU_CYCLE 21 + +// Needed by all games written by the software company called Human +//#define ONE_APU_CYCLE_HUMAN 17 +#define ONE_APU_CYCLE_HUMAN 21 + +// 1.953us := 1.024065.54MHz + +#ifdef SPCTOOL +EXTERN_C int32 ESPC (int32); + +#define APU_EXECUTE() \ +{ \ + int32 l = (CPU.Cycles - CPU.APU_Cycles) / 14; \ + if (l > 0) \ + { \ + l -= _EmuSPC(l); \ + CPU.APU_Cycles += l * 14; \ + } \ +} + +#else + +#ifdef ASM_SPC700 + +// return cycles left (always negative) +extern "C" int spc700_execute(int cycles); + +#define APU_EXECUTE1() \ +{ \ + CPU.APU_Cycles -= spc700_execute(0); \ +} + +// notaz: CPU.APU_APUExecuting: 0 == disabled, 1 == enabled normal, 3 == enabled in hack mode + +#define APU_EXECUTE(mode) \ +if (CPU.APU_APUExecuting == mode) \ +{\ + if(CPU.APU_Cycles <= CPU.Cycles) { \ + int cycles = CPU.Cycles - CPU.APU_Cycles; \ + CPU.APU_Cycles += cycles - spc700_execute(cycles); \ + } \ +} + +#else + +#define APU_EXECUTE1() \ +{ \ + CPU.APU_Cycles += S9xAPUCycles [*IAPU.PC]; \ + (*S9xApuOpcodes[*IAPU.PC]) (); \ +} + +#define APU_EXECUTE(x) \ +if (CPU.APU_APUExecuting) \ +{\ + while (CPU.APU_Cycles <= CPU.Cycles) \ + APU_EXECUTE1(); \ +} + +#endif // ASM_SPC700 + +#endif // SPCTOOL + +#endif diff --git a/src/snes4iphone_src/spc700a.s b/src/snes4iphone_src/spc700a.s new file mode 100755 index 0000000..9363949 --- /dev/null +++ b/src/snes4iphone_src/spc700a.s @@ -0,0 +1,4584 @@ + +.text + +@ notaz's SPC700 Emulator v0.11 - Assembler Output + +@ (c) Copyright 2006 notaz, All rights reserved. + +@ this is a rewrite of spc700.cpp in ARM asm, inspired by other asm CPU cores like +@ Cyclone and DrZ80. It is meant to be used in Snes9x emulator ports for ARM platforms. + +@ the code is released under Snes9x license. See spcgen.c or any other source file +@ from Snes9x source tree. + + + .globl _S9xAPUGetByte + .globl _S9xAPUSetByte + .globl _S9xAPUGetByteZ + .globl _S9xAPUSetByteZ + + .globl _spc700_execute @ int cycles + .globl _Spc700JumpTab + + opcode .req r3 + cycles .req r4 + context .req r5 + opcodes .req r6 + spc_pc .req r7 + spc_ya .req r8 + spc_p .req r9 + spc_x .req r10 + spc_s .req r11 + spc_ram .req lr + +#define iapu_directpage 0x00 +#define iapu_ram 0x44 +#define iapu_extraram 0x48 +#define iapu_allregs_load 0x30 +#define iapu_allregs_save 0x34 + +#define flag_c 0x01 +#define flag_z 0x02 +#define flag_i 0x04 +#define flag_h 0x08 +#define flag_b 0x10 +#define flag_d 0x20 +#define flag_o 0x40 +#define flag_n 0x80 + +#define call_c_function(function) ;\ + ldr r12, 1f ;\ + str r9, [r12] ;\ + ldr r12, 2f ;\ + ldr r9, [r12] ;\ + bl _##function ;\ + ldr r12, 1f ;\ + ldr r9, [r12] ;\ + b 3f ;\ +1: ;\ + .long _regR9 ;\ +2: ;\ + .long _regR9s ;\ +3: ;\ + ;\ + +1: + .long _IAPU +2: + .long _CPU +3: + .long _regR9s + +@ --------------------------- Framework -------------------------- +_spc700_execute: @ int cycles + stmfd sp!,{r4-r11,lr} + ldr r1, 3b + str r9, [r1] + ldr context, 1b @ Pointer to SIAPU struct + mov cycles,r0 @ Cycles + add r0,context,#iapu_allregs_load + ldmia r0,{opcodes,spc_pc,spc_ya,spc_p,spc_x,spc_ram} + mov spc_s,spc_x,lsr #8 + and spc_x,spc_x,#0xff + + ldrb opcode,[spc_pc],#1 @ Fetch first opcode + ldr pc,[opcodes,opcode,lsl #2] @ Jump to opcode handler + + +@ We come back here after execution +spc700End: + orr spc_x,spc_x,spc_s,lsl #8 + add r0,context,#iapu_allregs_save + stmia r0,{spc_pc,spc_ya,spc_p,spc_x} + mov r0,cycles + ldmfd sp!,{r4-r11,pc} + +@ .ltorg + + + +Apu00: + subs cycles,cycles,#42 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu01: + sub r0,spc_pc,spc_ram + add r1,spc_ram,spc_s + strb r0,[r1,#0xff] + mov r0,r0,lsr #8 + strb r0,[r1,#0x100] + sub spc_s,spc_s,#2 + ldr r0,[context,#iapu_extraram] + ldrh r0,[r0,#0x1e] + add spc_pc,spc_ram,r0 + subs cycles,cycles,#168 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu02: + ldrb r0,[spc_pc] + call_c_function(S9xAPUGetByteZ) + orr r0,r0,#0x01 + ldrb r1,[spc_pc],#1 + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu03: + ldrb r0,[spc_pc],#1 + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + tst r0,#0x01 + addeq spc_pc,spc_pc,#1 + ldrnesb r0,[spc_pc],#1 + addne spc_pc,spc_pc,r0 + subne cycles,cycles,#42 + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu04: + ldrb r0,[spc_pc],#1 + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + orr spc_ya,spc_ya,r0 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + subs cycles,cycles,#63 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu05: + ldrb r0,[spc_pc],#1 + ldrb r12,[spc_pc],#1 + orr r0,r0,r12,lsl #8 + call_c_function(S9xAPUGetByte) + ldr spc_ram,[context,#iapu_ram] + orr spc_ya,spc_ya,r0 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu06: + mov r0,spc_x + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + orr spc_ya,spc_ya,r0 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + subs cycles,cycles,#63 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu07: + ldrb r0,[spc_pc],#1 + add r0,r0,spc_x + and r0,r0,#0xff + ldr r12,[context,#iapu_directpage] + ldrb r0,[r12,r0]! + ldrb r12,[r12,#1] + orr r0,r0,r12,lsl #8 + call_c_function(S9xAPUGetByte) + ldr spc_ram,[context,#iapu_ram] + orr spc_ya,spc_ya,r0 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + subs cycles,cycles,#126 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu08: + ldrb r0,[spc_pc],#1 + orr spc_ya,spc_ya,r0 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + subs cycles,cycles,#42 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu09: + ldrb r0,[spc_pc],#1 + call_c_function(S9xAPUGetByteZ) + orr spc_x,spc_x,r0,lsl #24 @ save from harm + ldrb r0,[spc_pc] + call_c_function(S9xAPUGetByteZ) + orr r0,r0,spc_x,lsr #24 + and spc_x,spc_x,#0xff + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #24 + ldrb r1,[spc_pc],#1 + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#126 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu0A: + ldrb r0,[spc_pc],#1 + ldrb r1,[spc_pc],#1 + add r0,r0,r1,lsl #8 + mov r1,r1,lsr #5 + mov r0,r0,lsl #19 + mov r0,r0,lsr #19 + orr spc_x,spc_x,r1,lsl #29 @ store membit where it can survive memhandler call + call_c_function(S9xAPUGetByte) + mov r1,spc_x,lsr #29 + and spc_x,spc_x,#0xff + mov r0,r0,lsr r1 + tst r0,#1 + orrne spc_p,spc_p,#flag_c + ldr spc_ram,[context,#iapu_ram] @ restore what memhandler(s) messed up + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu0B: + ldrb r0,[spc_pc] + call_c_function(S9xAPUGetByteZ) + tst r0,#0x80 + orrne spc_p,spc_p,#flag_c + biceq spc_p,spc_p,#flag_c + mov r0,r0,lsl #1 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #24 + ldrb r1,[spc_pc],#1 + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu0C: + ldrb r0,[spc_pc],#1 + ldrb r12,[spc_pc],#1 + orr r0,r0,r12,lsl #8 + stmfd sp!,{r0} + call_c_function(S9xAPUGetByte) + tst r0,#0x80 + orrne spc_p,spc_p,#flag_c + biceq spc_p,spc_p,#flag_c + mov r0,r0,lsl #1 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #24 + ldmfd sp!,{r1} + call_c_function(S9xAPUSetByte) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu0D: + mov r0,spc_p,lsr #24 + and r1,r0,#0x80 + tst r0,r0 + orreq r1,r1,#flag_z + and spc_p,spc_p,#0x7d @ clear N & Z + orr spc_p,spc_p,r1 + add r1,spc_ram,spc_s + strb spc_p,[r1,#0x100] + sub spc_s,spc_s,#1 + orr spc_p,spc_p,r0,lsl #24 + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu0E: + ldrb r0,[spc_pc],#1 + ldrb r12,[spc_pc],#1 + orr r0,r0,r12,lsl #8 + orr spc_x,spc_x,r0,lsl #16 @ save from memhandler + call_c_function(S9xAPUGetByte) + and r2,r0,spc_ya + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r2,lsl #24 + orr r0,r0,spc_ya + mov r1,spc_x,lsr #16 + and spc_x,spc_x,#0xff + call_c_function(S9xAPUSetByte) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#126 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu0F: + sub r0,spc_pc,spc_ram + add r1,spc_ram,spc_s + strb r0,[r1,#0xff] + mov r0,r0,lsr #8 + strb r0,[r1,#0x100] + sub spc_s,spc_s,#2 + mov r0,spc_p,lsr #24 + and r1,r0,#0x80 + tst r0,r0 + orrne r1,r1,#flag_z + and spc_p,spc_p,#0x7d @ clear N & Z + orr spc_p,spc_p,r1 + add r1,spc_ram,spc_s + strb spc_p,[r1,#0x100] + sub spc_s,spc_s,#1 + orr spc_p,spc_p,#flag_b + bic spc_p,spc_p,#flag_i + ldr r0,[context,#iapu_extraram] + ldrh r0,[r0,#0x20] + add spc_pc,spc_ram,r0 + subs cycles,cycles,#168 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu10: + tst spc_p,#0x80000000 + addne spc_pc,spc_pc,#1 + ldreqsb r0,[spc_pc],#1 + addeq spc_pc,spc_pc,r0 + subeq cycles,cycles,#42 + subs cycles,cycles,#42 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu11: + sub r0,spc_pc,spc_ram + add r1,spc_ram,spc_s + strb r0,[r1,#0xff] + mov r0,r0,lsr #8 + strb r0,[r1,#0x100] + sub spc_s,spc_s,#2 + ldr r0,[context,#iapu_extraram] + ldrh r0,[r0,#0x1c] + add spc_pc,spc_ram,r0 + subs cycles,cycles,#168 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu12: + ldrb r0,[spc_pc] + call_c_function(S9xAPUGetByteZ) + bic r0,r0,#0x01 + ldrb r1,[spc_pc],#1 + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu13: + ldrb r0,[spc_pc],#1 + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + tst r0,#0x01 + addne spc_pc,spc_pc,#1 + ldreqsb r0,[spc_pc],#1 + addeq spc_pc,spc_pc,r0 + subeq cycles,cycles,#42 + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu14: + ldrb r0,[spc_pc],#1 + add r0,r0,spc_x + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + orr spc_ya,spc_ya,r0 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu15: + ldrb r0,[spc_pc],#1 + ldrb r12,[spc_pc],#1 + orr r0,r0,r12,lsl #8 + add r0,r0,spc_x + call_c_function(S9xAPUGetByte) + ldr spc_ram,[context,#iapu_ram] + orr spc_ya,spc_ya,r0 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu16: + ldrb r0,[spc_pc],#1 + ldrb r12,[spc_pc],#1 + orr r0,r0,r12,lsl #8 + add r0,r0,spc_ya,lsr #8 + call_c_function(S9xAPUGetByte) + ldr spc_ram,[context,#iapu_ram] + orr spc_ya,spc_ya,r0 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu17: + ldrb r0,[spc_pc],#1 + ldr r12,[context,#iapu_directpage] + ldrb r0,[r12,r0]! + ldrb r12,[r12,#1] + orr r0,r0,r12,lsl #8 + add r0,r0,spc_ya,lsr #8 + call_c_function(S9xAPUGetByte) + ldr spc_ram,[context,#iapu_ram] + orr spc_ya,spc_ya,r0 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + subs cycles,cycles,#126 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu18: + ldrb r0,[spc_pc,#1] + call_c_function(S9xAPUGetByteZ) + ldrb r1,[spc_pc],#1 + orr r0,r0,r1 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #24 + ldrb r1,[spc_pc],#1 + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu19: + mov r0,spc_x + call_c_function(S9xAPUGetByteZ) + orr spc_x,spc_x,r0,lsl #24 + mov r0,spc_ya,lsr #8 + call_c_function(S9xAPUGetByteZ) + orr r0,r0,spc_x,lsr #24 + and spc_x,spc_x,#0xff + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #24 + mov r1,spc_x + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu1A: + ldrb r0,[spc_pc] + call_c_function(S9xAPUGetByteZ) + stmfd sp!,{r0} + ldrb r0,[spc_pc] + add r0,r0,#1 + call_c_function(S9xAPUGetByteZ) + ldmfd sp!,{r1} + orr r1,r1,r0,lsl #8 + sub r0,r1,#1 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #16 + tst r0,#0xff + orrne spc_p,spc_p,#0x01000000 + stmfd sp!,{r0} + ldrb r1,[spc_pc] + call_c_function(S9xAPUSetByteZ) + ldmfd sp!,{r0} + mov r0,r0,lsr #8 + ldrb r1,[spc_pc],#1 + add r1,r1,#1 + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#126 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu1B: + ldrb r0,[spc_pc],#1 + add r0,r0,spc_x + stmfd sp!,{r0} + call_c_function(S9xAPUGetByteZ) + tst r0,#0x80 + orrne spc_p,spc_p,#flag_c + biceq spc_p,spc_p,#flag_c + mov r0,r0,lsl #1 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #24 + ldmfd sp!,{r1} + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu1C: + tst spc_ya,#0x80 + orrne spc_p,spc_p,#flag_c + biceq spc_p,spc_p,#flag_c + and r0,spc_ya,#0x7f + and spc_ya,spc_ya,#0xff00 + orr spc_ya,spc_ya,r0,lsl #1 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + subs cycles,cycles,#42 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu1D: + sub spc_x,spc_x,#1 + and spc_x,spc_x,#0xff + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_x,lsl #24 + subs cycles,cycles,#42 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu1E: + ldrb r0,[spc_pc],#1 + ldrb r12,[spc_pc],#1 + orr r0,r0,r12,lsl #8 + call_c_function(S9xAPUGetByte) + ldr spc_ram,[context,#iapu_ram] + subs r12,spc_x,r0 + orrge spc_p,spc_p,#flag_c + biclt spc_p,spc_p,#flag_c + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r12,lsl #24 + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu1F: + ldrb r0,[spc_pc],#1 + ldrb r12,[spc_pc],#1 + orr r0,r0,r12,lsl #8 + add r0,r0,spc_x + sub sp,sp,#8 + str r0,[sp,#4] + call_c_function(S9xAPUGetByte) + str r0,[sp] + ldr r0,[sp,#4] + add r0,r0,#1 + call_c_function(S9xAPUGetByte) + ldr spc_ram,[context,#iapu_ram] + ldr r1,[sp],#8 + orr r0,r1,r0,lsl #8 + add spc_pc,spc_ram,r0 + subs cycles,cycles,#126 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu20: + bic spc_p,spc_p,#flag_d + str spc_ram,[context,#iapu_directpage] + subs cycles,cycles,#42 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu21: + sub r0,spc_pc,spc_ram + add r1,spc_ram,spc_s + strb r0,[r1,#0xff] + mov r0,r0,lsr #8 + strb r0,[r1,#0x100] + sub spc_s,spc_s,#2 + ldr r0,[context,#iapu_extraram] + ldrh r0,[r0,#0x1a] + add spc_pc,spc_ram,r0 + subs cycles,cycles,#168 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu22: + ldrb r0,[spc_pc] + call_c_function(S9xAPUGetByteZ) + orr r0,r0,#0x02 + ldrb r1,[spc_pc],#1 + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu23: + ldrb r0,[spc_pc],#1 + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + tst r0,#0x02 + addeq spc_pc,spc_pc,#1 + ldrnesb r0,[spc_pc],#1 + addne spc_pc,spc_pc,r0 + subne cycles,cycles,#42 + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu24: + ldrb r0,[spc_pc],#1 + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + orr r0,r0,#0xff00 + and spc_ya,spc_ya,r0 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + subs cycles,cycles,#63 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu25: + ldrb r0,[spc_pc],#1 + ldrb r12,[spc_pc],#1 + orr r0,r0,r12,lsl #8 + call_c_function(S9xAPUGetByte) + ldr spc_ram,[context,#iapu_ram] + orr r0,r0,#0xff00 + and spc_ya,spc_ya,r0 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu26: + mov r0,spc_x + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + orr r0,r0,#0xff00 + and spc_ya,spc_ya,r0 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + subs cycles,cycles,#63 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu27: + ldrb r0,[spc_pc],#1 + add r0,r0,spc_x + and r0,r0,#0xff + ldr r12,[context,#iapu_directpage] + ldrb r0,[r12,r0]! + ldrb r12,[r12,#1] + orr r0,r0,r12,lsl #8 + call_c_function(S9xAPUGetByte) + ldr spc_ram,[context,#iapu_ram] + orr r0,r0,#0xff00 + and spc_ya,spc_ya,r0 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + subs cycles,cycles,#126 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu28: + ldrb r0,[spc_pc],#1 + orr r0,r0,#0xff00 + and spc_ya,spc_ya,r0 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + subs cycles,cycles,#42 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu29: + ldrb r0,[spc_pc],#1 + call_c_function(S9xAPUGetByteZ) + stmfd sp!,{r0} + ldrb r0,[spc_pc] + call_c_function(S9xAPUGetByteZ) + ldmfd sp!,{r1} + and r0,r0,r1 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #24 + ldrb r1,[spc_pc],#1 + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#126 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu2A: + ldrb r0,[spc_pc],#1 + ldrb r1,[spc_pc],#1 + add r0,r0,r1,lsl #8 + mov r1,r1,lsr #5 + mov r0,r0,lsl #19 + mov r0,r0,lsr #19 + orr spc_x,spc_x,r1,lsl #29 @ store membit where it can survive memhandler call + call_c_function(S9xAPUGetByte) + mov r1,spc_x,lsr #29 + and spc_x,spc_x,#0xff + mov r0,r0,lsr r1 + tst r0,#1 + orreq spc_p,spc_p,#flag_c + ldr spc_ram,[context,#iapu_ram] @ restore what memhandler(s) messed up + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu2B: + ldrb r0,[spc_pc] + call_c_function(S9xAPUGetByteZ) + mov r0,r0,lsl #1 + tst spc_p,#flag_c + orrne r0,r0,#1 + tst r0,#0x100 + orrne spc_p,spc_p,#flag_c + biceq spc_p,spc_p,#flag_c + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #24 + ldrb r1,[spc_pc],#1 + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu2C: + ldrb r0,[spc_pc],#1 + ldrb r12,[spc_pc],#1 + orr r0,r0,r12,lsl #8 + stmfd sp!,{r0} + call_c_function(S9xAPUGetByte) + mov r0,r0,lsl #1 + tst spc_p,#flag_c + orrne r0,r0,#1 + tst r0,#0x100 + orrne spc_p,spc_p,#flag_c + biceq spc_p,spc_p,#flag_c + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #24 + ldmfd sp!,{r1} + call_c_function(S9xAPUSetByte) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu2D: + add r1,spc_ram,spc_s + strb spc_ya,[r1,#0x100] + sub spc_s,spc_s,#1 + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu2E: + ldrb r0,[spc_pc],#1 + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + and r1,spc_ya,#0xff + cmp r0,r1 + addeq spc_pc,spc_pc,#1 + ldrnesb r0,[spc_pc],#1 + addne spc_pc,spc_pc,r0 + subne cycles,cycles,#42 + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu2F: + ldrsb r0,[spc_pc],#1 + add spc_pc,spc_pc,r0 + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu30: + tst spc_p,#0x80000000 + addeq spc_pc,spc_pc,#1 + ldrnesb r0,[spc_pc],#1 + addne spc_pc,spc_pc,r0 + subne cycles,cycles,#42 + subs cycles,cycles,#42 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu31: + sub r0,spc_pc,spc_ram + add r1,spc_ram,spc_s + strb r0,[r1,#0xff] + mov r0,r0,lsr #8 + strb r0,[r1,#0x100] + sub spc_s,spc_s,#2 + ldr r0,[context,#iapu_extraram] + ldrh r0,[r0,#0x18] + add spc_pc,spc_ram,r0 + subs cycles,cycles,#168 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu32: + ldrb r0,[spc_pc] + call_c_function(S9xAPUGetByteZ) + bic r0,r0,#0x02 + ldrb r1,[spc_pc],#1 + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu33: + ldrb r0,[spc_pc],#1 + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + tst r0,#0x02 + addne spc_pc,spc_pc,#1 + ldreqsb r0,[spc_pc],#1 + addeq spc_pc,spc_pc,r0 + subeq cycles,cycles,#42 + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu34: + ldrb r0,[spc_pc],#1 + add r0,r0,spc_x + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + orr r0,r0,#0xff00 + and spc_ya,spc_ya,r0 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu35: + ldrb r0,[spc_pc],#1 + ldrb r12,[spc_pc],#1 + orr r0,r0,r12,lsl #8 + add r0,r0,spc_x + call_c_function(S9xAPUGetByte) + ldr spc_ram,[context,#iapu_ram] + orr r0,r0,#0xff00 + and spc_ya,spc_ya,r0 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu36: + ldrb r0,[spc_pc],#1 + ldrb r12,[spc_pc],#1 + orr r0,r0,r12,lsl #8 + add r0,r0,spc_ya,lsr #8 + call_c_function(S9xAPUGetByte) + ldr spc_ram,[context,#iapu_ram] + orr r0,r0,#0xff00 + and spc_ya,spc_ya,r0 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu37: + ldrb r0,[spc_pc],#1 + ldr r12,[context,#iapu_directpage] + ldrb r0,[r12,r0]! + ldrb r12,[r12,#1] + orr r0,r0,r12,lsl #8 + add r0,r0,spc_ya,lsr #8 + call_c_function(S9xAPUGetByte) + ldr spc_ram,[context,#iapu_ram] + orr r0,r0,#0xff00 + and spc_ya,spc_ya,r0 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + subs cycles,cycles,#126 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu38: + ldrb r0,[spc_pc,#1] + call_c_function(S9xAPUGetByteZ) + ldrb r1,[spc_pc],#2 + and r0,r0,r1 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #24 + ldrb r1,[spc_pc,#-1] + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu39: + mov r0,spc_x + call_c_function(S9xAPUGetByteZ) + stmfd sp!,{r0} + mov r0,spc_ya,lsr #8 + call_c_function(S9xAPUGetByteZ) + ldmfd sp!,{r1} + and r0,r0,r1 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #24 + mov r1,spc_x + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu3A: + ldrb r0,[spc_pc] + call_c_function(S9xAPUGetByteZ) + stmfd sp!,{r0} + ldrb r0,[spc_pc] + add r0,r0,#1 + call_c_function(S9xAPUGetByteZ) + ldmfd sp!,{r1} + orr r1,r1,r0,lsl #8 + add r0,r1,#1 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #16 + tst r0,#0xff + orrne spc_p,spc_p,#0x01000000 + stmfd sp!,{r0} + ldrb r1,[spc_pc] + call_c_function(S9xAPUSetByteZ) + ldmfd sp!,{r0} + mov r0,r0,lsr #8 + ldrb r1,[spc_pc],#1 + add r1,r1,#1 + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#126 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu3B: + ldrb r0,[spc_pc] + add r0,r0,spc_x + call_c_function(S9xAPUGetByteZ) + mov r0,r0,lsl #1 + tst spc_p,#flag_c + orrne r0,r0,#1 + tst r0,#0x100 + orrne spc_p,spc_p,#flag_c + biceq spc_p,spc_p,#flag_c + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #24 + ldrb r1,[spc_pc],#1 + add r1,r1,spc_x + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu3C: + and r0,spc_ya,#0xff + mov r0,r0,lsl #1 + tst spc_p,#flag_c + orrne r0,r0,#1 + tst r0,#0x100 + orrne spc_p,spc_p,#flag_c + biceq spc_p,spc_p,#flag_c + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #24 + and r0,r0,#0xff + mov spc_ya,spc_ya,lsr #8 + orr spc_ya,r0,spc_ya,lsl #8 + subs cycles,cycles,#42 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu3D: + add spc_x,spc_x,#1 + and spc_x,spc_x,#0xff + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_x,lsl #24 + subs cycles,cycles,#42 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu3E: + ldrb r0,[spc_pc],#1 + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs r12,spc_x,r0 + orrge spc_p,spc_p,#flag_c + biclt spc_p,spc_p,#flag_c + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r12,lsl #24 + subs cycles,cycles,#63 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu3F: + ldrb r2,[spc_pc],#1 + ldrb r12,[spc_pc],#1 + orr r2,r2,r12,lsl #8 + sub r0,spc_pc,spc_ram + add r1,spc_ram,spc_s + strb r0,[r1,#0xff] + mov r0,r0,lsr #8 + strb r0,[r1,#0x100] + sub spc_s,spc_s,#2 + add spc_pc,spc_ram,r2 + subs cycles,cycles,#168 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu40: + orr spc_p,spc_p,#flag_d + add r0,spc_ram,#0x100 + str r0,[context,#iapu_directpage] + subs cycles,cycles,#42 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu41: + sub r0,spc_pc,spc_ram + add r1,spc_ram,spc_s + strb r0,[r1,#0xff] + mov r0,r0,lsr #8 + strb r0,[r1,#0x100] + sub spc_s,spc_s,#2 + ldr r0,[context,#iapu_extraram] + ldrh r0,[r0,#0x16] + add spc_pc,spc_ram,r0 + subs cycles,cycles,#168 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu42: + ldrb r0,[spc_pc] + call_c_function(S9xAPUGetByteZ) + orr r0,r0,#0x04 + ldrb r1,[spc_pc],#1 + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu43: + ldrb r0,[spc_pc],#1 + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + tst r0,#0x04 + addeq spc_pc,spc_pc,#1 + ldrnesb r0,[spc_pc],#1 + addne spc_pc,spc_pc,r0 + subne cycles,cycles,#42 + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu44: + ldrb r0,[spc_pc],#1 + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + eor spc_ya,spc_ya,r0 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + subs cycles,cycles,#63 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu45: + ldrb r0,[spc_pc],#1 + ldrb r12,[spc_pc],#1 + orr r0,r0,r12,lsl #8 + call_c_function(S9xAPUGetByte) + ldr spc_ram,[context,#iapu_ram] + eor spc_ya,spc_ya,r0 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu46: + mov r0,spc_x + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + eor spc_ya,spc_ya,r0 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + subs cycles,cycles,#63 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu47: + ldrb r0,[spc_pc],#1 + add r0,r0,spc_x + and r0,r0,#0xff + ldr r12,[context,#iapu_directpage] + ldrb r0,[r12,r0]! + ldrb r12,[r12,#1] + orr r0,r0,r12,lsl #8 + call_c_function(S9xAPUGetByte) + ldr spc_ram,[context,#iapu_ram] + eor spc_ya,spc_ya,r0 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + subs cycles,cycles,#126 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu48: + ldrb r0,[spc_pc],#1 + eor spc_ya,spc_ya,r0 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + subs cycles,cycles,#42 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu49: + ldrb r0,[spc_pc],#1 + call_c_function(S9xAPUGetByteZ) + stmfd sp!,{r0} + ldrb r0,[spc_pc] + call_c_function(S9xAPUGetByteZ) + ldmfd sp!,{r1} + eor r0,r0,r1 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #24 + ldrb r1,[spc_pc],#1 + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#126 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu4A: + ldrb r0,[spc_pc],#1 + ldrb r1,[spc_pc],#1 + add r0,r0,r1,lsl #8 + mov r1,r1,lsr #5 + mov r0,r0,lsl #19 + mov r0,r0,lsr #19 + orr spc_x,spc_x,r1,lsl #29 @ store membit where it can survive memhandler call + call_c_function(S9xAPUGetByte) + mov r1,spc_x,lsr #29 + and spc_x,spc_x,#0xff + mov r0,r0,lsr r1 + tst r0,#1 + biceq spc_p,spc_p,#flag_c + ldr spc_ram,[context,#iapu_ram] @ restore what memhandler(s) messed up + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu4B: + ldrb r0,[spc_pc] + call_c_function(S9xAPUGetByteZ) + tst r0,#0x01 + orrne spc_p,spc_p,#flag_c + biceq spc_p,spc_p,#flag_c + mov r0,r0,lsr #1 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #24 + ldrb r1,[spc_pc],#1 + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu4C: + ldrb r0,[spc_pc],#1 + ldrb r12,[spc_pc],#1 + orr r0,r0,r12,lsl #8 + stmfd sp!,{r0} + call_c_function(S9xAPUGetByte) + tst r0,#0x01 + orrne spc_p,spc_p,#flag_c + biceq spc_p,spc_p,#flag_c + mov r0,r0,lsr #1 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #24 + ldmfd sp!,{r1} + call_c_function(S9xAPUSetByte) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu4D: + add r1,spc_ram,spc_s + strb spc_x,[r1,#0x100] + sub spc_s,spc_s,#1 + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu4E: + ldrb r0,[spc_pc],#1 + ldrb r12,[spc_pc],#1 + orr r0,r0,r12,lsl #8 + orr spc_x,spc_x,r0,lsl #16 @ save from memhandler + call_c_function(S9xAPUGetByte) + and r2,r0,spc_ya + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r2,lsl #24 + bic r0,r0,spc_ya + mov r1,spc_x,lsr #16 + and spc_x,spc_x,#0xff + call_c_function(S9xAPUSetByte) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#126 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu4F: + ldrb r2,[spc_pc],#1 + sub r0,spc_pc,spc_ram + add r1,spc_ram,spc_s + strb r0,[r1,#0xff] + mov r0,r0,lsr #8 + strb r0,[r1,#0x100] + sub spc_s,spc_s,#2 + add spc_pc,spc_ram,r2 + add spc_pc,spc_pc,#0xff00 + subs cycles,cycles,#126 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu50: + tst spc_p,#0x00000040 + addne spc_pc,spc_pc,#1 + ldreqsb r0,[spc_pc],#1 + addeq spc_pc,spc_pc,r0 + subeq cycles,cycles,#42 + subs cycles,cycles,#42 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu51: + sub r0,spc_pc,spc_ram + add r1,spc_ram,spc_s + strb r0,[r1,#0xff] + mov r0,r0,lsr #8 + strb r0,[r1,#0x100] + sub spc_s,spc_s,#2 + ldr r0,[context,#iapu_extraram] + ldrh r0,[r0,#0x14] + add spc_pc,spc_ram,r0 + subs cycles,cycles,#168 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu52: + ldrb r0,[spc_pc] + call_c_function(S9xAPUGetByteZ) + bic r0,r0,#0x04 + ldrb r1,[spc_pc],#1 + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu53: + ldrb r0,[spc_pc],#1 + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + tst r0,#0x04 + addne spc_pc,spc_pc,#1 + ldreqsb r0,[spc_pc],#1 + addeq spc_pc,spc_pc,r0 + subeq cycles,cycles,#42 + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu54: + ldrb r0,[spc_pc],#1 + add r0,r0,spc_x + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + eor spc_ya,spc_ya,r0 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu55: + ldrb r0,[spc_pc],#1 + ldrb r12,[spc_pc],#1 + orr r0,r0,r12,lsl #8 + add r0,r0,spc_x + call_c_function(S9xAPUGetByte) + ldr spc_ram,[context,#iapu_ram] + eor spc_ya,spc_ya,r0 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu56: + ldrb r0,[spc_pc],#1 + ldrb r12,[spc_pc],#1 + orr r0,r0,r12,lsl #8 + add r0,r0,spc_ya,lsr #8 + call_c_function(S9xAPUGetByte) + ldr spc_ram,[context,#iapu_ram] + eor spc_ya,spc_ya,r0 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu57: + ldrb r0,[spc_pc],#1 + ldr r12,[context,#iapu_directpage] + ldrb r0,[r12,r0]! + ldrb r12,[r12,#1] + orr r0,r0,r12,lsl #8 + add r0,r0,spc_ya,lsr #8 + call_c_function(S9xAPUGetByte) + ldr spc_ram,[context,#iapu_ram] + eor spc_ya,spc_ya,r0 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + subs cycles,cycles,#126 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu58: + ldrb r0,[spc_pc,#1] + call_c_function(S9xAPUGetByteZ) + ldrb r1,[spc_pc],#2 + eor r0,r0,r1 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #24 + ldrb r1,[spc_pc,#-1] + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu59: + mov r0,spc_x + call_c_function(S9xAPUGetByteZ) + stmfd sp!,{r0} + mov r0,spc_ya,lsr #8 + call_c_function(S9xAPUGetByteZ) + ldmfd sp!,{r1} + eor r0,r0,r1 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #24 + mov r1,spc_x + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu5A: + ldrb r0,[spc_pc] + call_c_function(S9xAPUGetByteZ) + stmfd sp!,{r0} + ldrb r0,[spc_pc],#1 + add r0,r0,#1 + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + ldmfd sp!,{r1} + orr r1,r1,r0,lsl #8 + subs r0,spc_ya,r1 + orrge spc_p,spc_p,#flag_c + biclt spc_p,spc_p,#flag_c + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #16 + tst r0,#0xff + orrne spc_p,spc_p,#0x01000000 + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu5B: + ldrb r0,[spc_pc] + add r0,r0,spc_x + call_c_function(S9xAPUGetByteZ) + tst r0,#0x01 + orrne spc_p,spc_p,#flag_c + biceq spc_p,spc_p,#flag_c + mov r0,r0,lsr #1 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #24 + ldrb r1,[spc_pc],#1 + add r1,r1,spc_x + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu5C: + and r0,spc_ya,#0xff + tst r0,#0x01 + orrne spc_p,spc_p,#flag_c + biceq spc_p,spc_p,#flag_c + mov r0,r0,lsr #1 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #24 + mov spc_ya,spc_ya,lsr #8 + orr spc_ya,r0,spc_ya,lsl #8 + subs cycles,cycles,#42 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu5D: + and spc_x,spc_ya,#0xff + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_x,lsl #24 + subs cycles,cycles,#42 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu5E: + ldrb r0,[spc_pc],#1 + ldrb r12,[spc_pc],#1 + orr r0,r0,r12,lsl #8 + call_c_function(S9xAPUGetByte) + ldr spc_ram,[context,#iapu_ram] + mov r1,spc_ya,lsr #8 + subs r12,r1,r0 + orrge spc_p,spc_p,#flag_c + biclt spc_p,spc_p,#flag_c + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r12,lsl #24 + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu5F: + ldrb r0,[spc_pc],#1 + ldrb r12,[spc_pc],#1 + orr r0,r0,r12,lsl #8 + add spc_pc,spc_ram,r0 + subs cycles,cycles,#63 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu60: + bic spc_p,spc_p,#flag_c + subs cycles,cycles,#42 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu61: + sub r0,spc_pc,spc_ram + add r1,spc_ram,spc_s + strb r0,[r1,#0xff] + mov r0,r0,lsr #8 + strb r0,[r1,#0x100] + sub spc_s,spc_s,#2 + ldr r0,[context,#iapu_extraram] + ldrh r0,[r0,#0x12] + add spc_pc,spc_ram,r0 + subs cycles,cycles,#168 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu62: + ldrb r0,[spc_pc] + call_c_function(S9xAPUGetByteZ) + orr r0,r0,#0x08 + ldrb r1,[spc_pc],#1 + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu63: + ldrb r0,[spc_pc],#1 + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + tst r0,#0x08 + addeq spc_pc,spc_pc,#1 + ldrnesb r0,[spc_pc],#1 + addne spc_pc,spc_pc,r0 + subne cycles,cycles,#42 + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu64: + ldrb r0,[spc_pc],#1 + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + and r12,spc_ya,#0xff + subs r12,r12,r0 + orrge spc_p,spc_p,#flag_c + biclt spc_p,spc_p,#flag_c + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r12,lsl #24 + subs cycles,cycles,#63 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu65: + ldrb r0,[spc_pc],#1 + ldrb r12,[spc_pc],#1 + orr r0,r0,r12,lsl #8 + call_c_function(S9xAPUGetByte) + ldr spc_ram,[context,#iapu_ram] + and r12,spc_ya,#0xff + subs r12,r12,r0 + orrge spc_p,spc_p,#flag_c + biclt spc_p,spc_p,#flag_c + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r12,lsl #24 + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu66: + mov r0,spc_x + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + and r12,spc_ya,#0xff + subs r12,r12,r0 + orrge spc_p,spc_p,#flag_c + biclt spc_p,spc_p,#flag_c + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r12,lsl #24 + subs cycles,cycles,#63 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu67: + ldrb r0,[spc_pc],#1 + add r0,r0,spc_x + and r0,r0,#0xff + ldr r12,[context,#iapu_directpage] + ldrb r0,[r12,r0]! + ldrb r12,[r12,#1] + orr r0,r0,r12,lsl #8 + call_c_function(S9xAPUGetByte) + ldr spc_ram,[context,#iapu_ram] + and r12,spc_ya,#0xff + subs r12,r12,r0 + orrge spc_p,spc_p,#flag_c + biclt spc_p,spc_p,#flag_c + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r12,lsl #24 + subs cycles,cycles,#126 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu68: + ldrb r0,[spc_pc],#1 + and r12,spc_ya,#0xff + subs r12,r12,r0 + orrge spc_p,spc_p,#flag_c + biclt spc_p,spc_p,#flag_c + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r12,lsl #24 + subs cycles,cycles,#42 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu69: + ldrb r0,[spc_pc],#1 + call_c_function(S9xAPUGetByteZ) + orr spc_x,spc_x,r0,lsl #24 + ldrb r0,[spc_pc],#1 + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + mov r1,spc_x,lsr #24 + subs r12,r0,r1 + orrge spc_p,spc_p,#flag_c + biclt spc_p,spc_p,#flag_c + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r12,lsl #24 + and spc_x,spc_x,#0xff + subs cycles,cycles,#126 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu6A: + ldrb r0,[spc_pc],#1 + ldrb r1,[spc_pc],#1 + add r0,r0,r1,lsl #8 + mov r1,r1,lsr #5 + mov r0,r0,lsl #19 + mov r0,r0,lsr #19 + orr spc_x,spc_x,r1,lsl #29 @ store membit where it can survive memhandler call + call_c_function(S9xAPUGetByte) + mov r1,spc_x,lsr #29 + and spc_x,spc_x,#0xff + mov r0,r0,lsr r1 + tst r0,#1 + bicne spc_p,spc_p,#flag_c + ldr spc_ram,[context,#iapu_ram] @ restore what memhandler(s) messed up + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu6B: + ldrb r0,[spc_pc] + call_c_function(S9xAPUGetByteZ) + tst spc_p,#flag_c + orrne r0,r0,#0x100 + movs r0,r0,lsr #1 + orrcs spc_p,spc_p,#flag_c + biccc spc_p,spc_p,#flag_c + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #24 + ldrb r1,[spc_pc],#1 + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu6C: + ldrb r0,[spc_pc],#1 + ldrb r12,[spc_pc],#1 + orr r0,r0,r12,lsl #8 + stmfd sp!,{r0} + call_c_function(S9xAPUGetByte) + tst spc_p,#flag_c + orrne r0,r0,#0x100 + movs r0,r0,lsr #1 + orrcs spc_p,spc_p,#flag_c + biccc spc_p,spc_p,#flag_c + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #24 + ldmfd sp!,{r1} + call_c_function(S9xAPUSetByte) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu6D: + mov r0,spc_ya,lsr #8 + add r1,spc_ram,spc_s + strb r0,[r1,#0x100] + sub spc_s,spc_s,#1 + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu6E: + ldrb r0,[spc_pc] + call_c_function(S9xAPUGetByteZ) + ldrb r1,[spc_pc],#1 + sub r0,r0,#1 + tst r0,r0 + addeq spc_pc,spc_pc,#1 + ldrnesb r2,[spc_pc],#1 + addne spc_pc,spc_pc,r2 + subne cycles,cycles,#42 + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu6F: + add spc_s,spc_s,#2 + add r1,spc_ram,spc_s + ldrb r0,[r1,#0xff] + ldrb r1,[r1,#0x100] + orr r0,r0,r1,lsl #8 + add spc_pc,spc_ram,r0 + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu70: + tst spc_p,#0x00000040 + addeq spc_pc,spc_pc,#1 + ldrnesb r0,[spc_pc],#1 + addne spc_pc,spc_pc,r0 + subne cycles,cycles,#42 + subs cycles,cycles,#42 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu71: + sub r0,spc_pc,spc_ram + add r1,spc_ram,spc_s + strb r0,[r1,#0xff] + mov r0,r0,lsr #8 + strb r0,[r1,#0x100] + sub spc_s,spc_s,#2 + ldr r0,[context,#iapu_extraram] + ldrh r0,[r0,#0x10] + add spc_pc,spc_ram,r0 + subs cycles,cycles,#168 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu72: + ldrb r0,[spc_pc] + call_c_function(S9xAPUGetByteZ) + bic r0,r0,#0x08 + ldrb r1,[spc_pc],#1 + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu73: + ldrb r0,[spc_pc],#1 + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + tst r0,#0x08 + addne spc_pc,spc_pc,#1 + ldreqsb r0,[spc_pc],#1 + addeq spc_pc,spc_pc,r0 + subeq cycles,cycles,#42 + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu74: + ldrb r0,[spc_pc],#1 + add r0,r0,spc_x + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + and r12,spc_ya,#0xff + subs r12,r12,r0 + orrge spc_p,spc_p,#flag_c + biclt spc_p,spc_p,#flag_c + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r12,lsl #24 + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu75: + ldrb r0,[spc_pc],#1 + ldrb r12,[spc_pc],#1 + orr r0,r0,r12,lsl #8 + add r0,r0,spc_x + call_c_function(S9xAPUGetByte) + ldr spc_ram,[context,#iapu_ram] + and r12,spc_ya,#0xff + subs r12,r12,r0 + orrge spc_p,spc_p,#flag_c + biclt spc_p,spc_p,#flag_c + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r12,lsl #24 + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu76: + ldrb r0,[spc_pc],#1 + ldrb r12,[spc_pc],#1 + orr r0,r0,r12,lsl #8 + add r0,r0,spc_ya,lsr #8 + call_c_function(S9xAPUGetByte) + ldr spc_ram,[context,#iapu_ram] + and r12,spc_ya,#0xff + subs r12,r12,r0 + orrge spc_p,spc_p,#flag_c + biclt spc_p,spc_p,#flag_c + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r12,lsl #24 + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu77: + ldrb r0,[spc_pc],#1 + ldr r12,[context,#iapu_directpage] + ldrb r0,[r12,r0]! + ldrb r12,[r12,#1] + orr r0,r0,r12,lsl #8 + add r0,r0,spc_ya,lsr #8 + call_c_function(S9xAPUGetByte) + ldr spc_ram,[context,#iapu_ram] + and r12,spc_ya,#0xff + subs r12,r12,r0 + orrge spc_p,spc_p,#flag_c + biclt spc_p,spc_p,#flag_c + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r12,lsl #24 + subs cycles,cycles,#126 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu78: + ldrb r0,[spc_pc,#1] + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + ldrb r1,[spc_pc],#2 + subs r12,r0,r1 + orrge spc_p,spc_p,#flag_c + biclt spc_p,spc_p,#flag_c + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r12,lsl #24 + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu79: + mov r0,spc_x + call_c_function(S9xAPUGetByteZ) + orr spc_x,spc_x,r0,lsl #24 + mov r0,spc_ya,lsr #8 + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + mov r1,spc_x,lsr #24 + subs r12,r1,r0 + orrge spc_p,spc_p,#flag_c + biclt spc_p,spc_p,#flag_c + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r12,lsl #24 + and spc_x,spc_x,#0xff + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu7A: + ldrb r0,[spc_pc] + call_c_function(S9xAPUGetByteZ) + stmfd sp!,{r0} + ldrb r0,[spc_pc],#1 + add r0,r0,#1 + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + ldmfd sp!,{r1} + orr r1,r1,r0,lsl #8 + add r0,spc_ya,r1 + movs r2,r0,lsr #16 + orrne spc_p,spc_p,#flag_c + biceq spc_p,spc_p,#flag_c + bic r2,r0,#0x00ff0000 + eor r3,r1,r2 + eor r12,spc_ya,r1 + mvn r12,r12 + and r12,r12,r3 + tst r12,#0x8000 + orrne spc_p,spc_p,#flag_o + biceq spc_p,spc_p,#flag_o + eor r12,r3,spc_ya + tst r12,#0x10 + orrne spc_p,spc_p,#flag_h + biceq spc_p,spc_p,#flag_h + mov spc_ya,r2 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #16 + tst spc_ya,#0xff + orrne spc_p,spc_p,#0x01000000 + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu7B: + ldrb r0,[spc_pc] + add r0,r0,spc_x + call_c_function(S9xAPUGetByteZ) + tst spc_p,#flag_c + orrne r0,r0,#0x100 + movs r0,r0,lsr #1 + orrcs spc_p,spc_p,#flag_c + biccc spc_p,spc_p,#flag_c + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #24 + ldrb r1,[spc_pc],#1 + add r1,r1,spc_x + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu7C: + and r0,spc_ya,#0xff + tst spc_p,#flag_c + orrne r0,r0,#0x100 + movs r0,r0,lsr #1 + orrcs spc_p,spc_p,#flag_c + biccc spc_p,spc_p,#flag_c + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #24 + mov spc_ya,spc_ya,lsr #8 + orr spc_ya,r0,spc_ya,lsl #8 + subs cycles,cycles,#42 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu7D: + and spc_ya,spc_ya,#0xff00 + orr spc_ya,spc_ya,spc_x + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + subs cycles,cycles,#42 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu7E: + ldrb r0,[spc_pc],#1 + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + mov r1,spc_ya,lsr #8 + subs r12,r1,r0 + orrge spc_p,spc_p,#flag_c + biclt spc_p,spc_p,#flag_c + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r12,lsl #24 + subs cycles,cycles,#63 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu7F: + add spc_s,spc_s,#1 + add spc_p,spc_ram,spc_s + ldrb spc_p,[spc_p,#0x100] + and r0,spc_p,#(flag_z|flag_n) + eor r0,r0,#flag_z + orr spc_p,spc_p,r0,lsl #24 + tst spc_p,#flag_d + addne r0,spc_ram,#0x100 + moveq r0,spc_ram + str r0,[context,#iapu_directpage] + add spc_s,spc_s,#2 + add r1,spc_ram,spc_s + ldrb r0,[r1,#0xff] + ldrb r1,[r1,#0x100] + orr r0,r0,r1,lsl #8 + add spc_pc,spc_ram,r0 + subs cycles,cycles,#126 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu80: + orr spc_p,spc_p,#flag_c + subs cycles,cycles,#42 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu81: + sub r0,spc_pc,spc_ram + add r1,spc_ram,spc_s + strb r0,[r1,#0xff] + mov r0,r0,lsr #8 + strb r0,[r1,#0x100] + sub spc_s,spc_s,#2 + ldr r0,[context,#iapu_extraram] + ldrh r0,[r0,#0xe] + add spc_pc,spc_ram,r0 + subs cycles,cycles,#168 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu82: + ldrb r0,[spc_pc] + call_c_function(S9xAPUGetByteZ) + orr r0,r0,#0x10 + ldrb r1,[spc_pc],#1 + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu83: + ldrb r0,[spc_pc],#1 + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + tst r0,#0x10 + addeq spc_pc,spc_pc,#1 + ldrnesb r0,[spc_pc],#1 + addne spc_pc,spc_pc,r0 + subne cycles,cycles,#42 + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu84: + ldrb r0,[spc_pc],#1 + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + and r1,spc_ya,#0xff00 + and spc_ya,spc_ya,#0xff + eor r3,spc_ya,r0 + add spc_ya,spc_ya,r0 + tst spc_p,#flag_c + addne spc_ya,spc_ya,#1 + movs r12,spc_ya,lsr #8 + orrne spc_p,spc_p,#flag_c + biceq spc_p,spc_p,#flag_c + eor r12,spc_ya,r0 + bic r12,r12,r3 + tst r12,#0x80 + orrne spc_p,spc_p,#flag_o + biceq spc_p,spc_p,#flag_o + eor r12,r3,spc_ya + tst r12,#0x10 + orrne spc_p,spc_p,#flag_h + biceq spc_p,spc_p,#flag_h + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + and spc_ya,spc_ya,#0xff + orr spc_ya,spc_ya,r1 + subs cycles,cycles,#63 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu85: + ldrb r0,[spc_pc],#1 + ldrb r12,[spc_pc],#1 + orr r0,r0,r12,lsl #8 + call_c_function(S9xAPUGetByte) + ldr spc_ram,[context,#iapu_ram] + and r1,spc_ya,#0xff00 + and spc_ya,spc_ya,#0xff + eor r3,spc_ya,r0 + add spc_ya,spc_ya,r0 + tst spc_p,#flag_c + addne spc_ya,spc_ya,#1 + movs r12,spc_ya,lsr #8 + orrne spc_p,spc_p,#flag_c + biceq spc_p,spc_p,#flag_c + eor r12,spc_ya,r0 + bic r12,r12,r3 + tst r12,#0x80 + orrne spc_p,spc_p,#flag_o + biceq spc_p,spc_p,#flag_o + eor r12,r3,spc_ya + tst r12,#0x10 + orrne spc_p,spc_p,#flag_h + biceq spc_p,spc_p,#flag_h + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + and spc_ya,spc_ya,#0xff + orr spc_ya,spc_ya,r1 + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu86: + mov r0,spc_x + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + and r1,spc_ya,#0xff00 + and spc_ya,spc_ya,#0xff + eor r3,spc_ya,r0 + add spc_ya,spc_ya,r0 + tst spc_p,#flag_c + addne spc_ya,spc_ya,#1 + movs r12,spc_ya,lsr #8 + orrne spc_p,spc_p,#flag_c + biceq spc_p,spc_p,#flag_c + eor r12,spc_ya,r0 + bic r12,r12,r3 + tst r12,#0x80 + orrne spc_p,spc_p,#flag_o + biceq spc_p,spc_p,#flag_o + eor r12,r3,spc_ya + tst r12,#0x10 + orrne spc_p,spc_p,#flag_h + biceq spc_p,spc_p,#flag_h + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + and spc_ya,spc_ya,#0xff + orr spc_ya,spc_ya,r1 + subs cycles,cycles,#63 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu87: + ldrb r0,[spc_pc],#1 + add r0,r0,spc_x + and r0,r0,#0xff + ldr r12,[context,#iapu_directpage] + ldrb r0,[r12,r0]! + ldrb r12,[r12,#1] + orr r0,r0,r12,lsl #8 + call_c_function(S9xAPUGetByte) + ldr spc_ram,[context,#iapu_ram] + and r1,spc_ya,#0xff00 + and spc_ya,spc_ya,#0xff + eor r3,spc_ya,r0 + add spc_ya,spc_ya,r0 + tst spc_p,#flag_c + addne spc_ya,spc_ya,#1 + movs r12,spc_ya,lsr #8 + orrne spc_p,spc_p,#flag_c + biceq spc_p,spc_p,#flag_c + eor r12,spc_ya,r0 + bic r12,r12,r3 + tst r12,#0x80 + orrne spc_p,spc_p,#flag_o + biceq spc_p,spc_p,#flag_o + eor r12,r3,spc_ya + tst r12,#0x10 + orrne spc_p,spc_p,#flag_h + biceq spc_p,spc_p,#flag_h + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + and spc_ya,spc_ya,#0xff + orr spc_ya,spc_ya,r1 + subs cycles,cycles,#126 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu88: + ldrb r0,[spc_pc],#1 + and r1,spc_ya,#0xff00 + and spc_ya,spc_ya,#0xff + eor r3,spc_ya,r0 + add spc_ya,spc_ya,r0 + tst spc_p,#flag_c + addne spc_ya,spc_ya,#1 + movs r12,spc_ya,lsr #8 + orrne spc_p,spc_p,#flag_c + biceq spc_p,spc_p,#flag_c + eor r12,spc_ya,r0 + bic r12,r12,r3 + tst r12,#0x80 + orrne spc_p,spc_p,#flag_o + biceq spc_p,spc_p,#flag_o + eor r12,r3,spc_ya + tst r12,#0x10 + orrne spc_p,spc_p,#flag_h + biceq spc_p,spc_p,#flag_h + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + and spc_ya,spc_ya,#0xff + orr spc_ya,spc_ya,r1 + subs cycles,cycles,#42 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu89: + ldrb r0,[spc_pc],#1 + call_c_function(S9xAPUGetByteZ) + stmfd sp!,{r0} + ldrb r0,[spc_pc] + call_c_function(S9xAPUGetByteZ) + ldmfd sp!,{r1} + eor r3,r0,r1 + add r0,r0,r1 + tst spc_p,#flag_c + addne r0,r0,#1 + movs r12,r0,lsr #8 + orrne spc_p,spc_p,#flag_c + biceq spc_p,spc_p,#flag_c + eor r12,r0,r1 + bic r12,r12,r3 + tst r12,#0x80 + orrne spc_p,spc_p,#flag_o + biceq spc_p,spc_p,#flag_o + eor r12,r3,r0 + tst r12,#0x10 + orrne spc_p,spc_p,#flag_h + biceq spc_p,spc_p,#flag_h + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #24 + ldrb r1,[spc_pc],#1 + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#126 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu8A: + ldrb r0,[spc_pc],#1 + ldrb r1,[spc_pc],#1 + add r0,r0,r1,lsl #8 + mov r1,r1,lsr #5 + mov r0,r0,lsl #19 + mov r0,r0,lsr #19 + orr spc_x,spc_x,r1,lsl #29 @ store membit where it can survive memhandler call + call_c_function(S9xAPUGetByte) + mov r1,spc_x,lsr #29 + and spc_x,spc_x,#0xff + mov r0,r0,lsr r1 + tst r0,#1 + eorne spc_p,spc_p,#flag_c + ldr spc_ram,[context,#iapu_ram] @ restore what memhandler(s) messed up + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu8B: + ldrb r0,[spc_pc] + call_c_function(S9xAPUGetByteZ) + sub r0,r0,#1 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #24 + ldrb r1,[spc_pc],#1 + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu8C: + ldrb r0,[spc_pc],#1 + ldrb r12,[spc_pc],#1 + orr r0,r0,r12,lsl #8 + stmfd sp!,{r0} + call_c_function(S9xAPUGetByte) + sub r0,r0,#1 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #24 + ldmfd sp!,{r1} + call_c_function(S9xAPUSetByte) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu8D: + ldrb r0,[spc_pc],#1 + and spc_ya,spc_ya,#0xff + orr spc_ya,spc_ya,r0,lsl #8 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #24 + subs cycles,cycles,#42 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu8E: + add spc_s,spc_s,#1 + add spc_p,spc_ram,spc_s + ldrb spc_p,[spc_p,#0x100] + and r0,spc_p,#(flag_z|flag_n) + eor r0,r0,#flag_z + orr spc_p,spc_p,r0,lsl #24 + tst spc_p,#flag_d + addne r0,spc_ram,#0x100 + moveq r0,spc_ram + str r0,[context,#iapu_directpage] + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu8F: + ldrb r0,[spc_pc],#1 + ldrb r1,[spc_pc],#1 + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu90: + tst spc_p,#0x00000001 + addne spc_pc,spc_pc,#1 + ldreqsb r0,[spc_pc],#1 + addeq spc_pc,spc_pc,r0 + subeq cycles,cycles,#42 + subs cycles,cycles,#42 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu91: + sub r0,spc_pc,spc_ram + add r1,spc_ram,spc_s + strb r0,[r1,#0xff] + mov r0,r0,lsr #8 + strb r0,[r1,#0x100] + sub spc_s,spc_s,#2 + ldr r0,[context,#iapu_extraram] + ldrh r0,[r0,#0xc] + add spc_pc,spc_ram,r0 + subs cycles,cycles,#168 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu92: + ldrb r0,[spc_pc] + call_c_function(S9xAPUGetByteZ) + bic r0,r0,#0x10 + ldrb r1,[spc_pc],#1 + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu93: + ldrb r0,[spc_pc],#1 + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + tst r0,#0x10 + addne spc_pc,spc_pc,#1 + ldreqsb r0,[spc_pc],#1 + addeq spc_pc,spc_pc,r0 + subeq cycles,cycles,#42 + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu94: + ldrb r0,[spc_pc],#1 + add r0,r0,spc_x + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + and r1,spc_ya,#0xff00 + and spc_ya,spc_ya,#0xff + eor r3,spc_ya,r0 + add spc_ya,spc_ya,r0 + tst spc_p,#flag_c + addne spc_ya,spc_ya,#1 + movs r12,spc_ya,lsr #8 + orrne spc_p,spc_p,#flag_c + biceq spc_p,spc_p,#flag_c + eor r12,spc_ya,r0 + bic r12,r12,r3 + tst r12,#0x80 + orrne spc_p,spc_p,#flag_o + biceq spc_p,spc_p,#flag_o + eor r12,r3,spc_ya + tst r12,#0x10 + orrne spc_p,spc_p,#flag_h + biceq spc_p,spc_p,#flag_h + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + and spc_ya,spc_ya,#0xff + orr spc_ya,spc_ya,r1 + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu95: + ldrb r0,[spc_pc],#1 + ldrb r12,[spc_pc],#1 + orr r0,r0,r12,lsl #8 + add r0,r0,spc_x + call_c_function(S9xAPUGetByte) + ldr spc_ram,[context,#iapu_ram] + and r1,spc_ya,#0xff00 + and spc_ya,spc_ya,#0xff + eor r3,spc_ya,r0 + add spc_ya,spc_ya,r0 + tst spc_p,#flag_c + addne spc_ya,spc_ya,#1 + movs r12,spc_ya,lsr #8 + orrne spc_p,spc_p,#flag_c + biceq spc_p,spc_p,#flag_c + eor r12,spc_ya,r0 + bic r12,r12,r3 + tst r12,#0x80 + orrne spc_p,spc_p,#flag_o + biceq spc_p,spc_p,#flag_o + eor r12,r3,spc_ya + tst r12,#0x10 + orrne spc_p,spc_p,#flag_h + biceq spc_p,spc_p,#flag_h + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + and spc_ya,spc_ya,#0xff + orr spc_ya,spc_ya,r1 + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu96: + ldrb r0,[spc_pc],#1 + ldrb r12,[spc_pc],#1 + orr r0,r0,r12,lsl #8 + add r0,r0,spc_ya,lsr #8 + call_c_function(S9xAPUGetByte) + ldr spc_ram,[context,#iapu_ram] + and r1,spc_ya,#0xff00 + and spc_ya,spc_ya,#0xff + eor r3,spc_ya,r0 + add spc_ya,spc_ya,r0 + tst spc_p,#flag_c + addne spc_ya,spc_ya,#1 + movs r12,spc_ya,lsr #8 + orrne spc_p,spc_p,#flag_c + biceq spc_p,spc_p,#flag_c + eor r12,spc_ya,r0 + bic r12,r12,r3 + tst r12,#0x80 + orrne spc_p,spc_p,#flag_o + biceq spc_p,spc_p,#flag_o + eor r12,r3,spc_ya + tst r12,#0x10 + orrne spc_p,spc_p,#flag_h + biceq spc_p,spc_p,#flag_h + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + and spc_ya,spc_ya,#0xff + orr spc_ya,spc_ya,r1 + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu97: + ldrb r0,[spc_pc],#1 + ldr r12,[context,#iapu_directpage] + ldrb r0,[r12,r0]! + ldrb r12,[r12,#1] + orr r0,r0,r12,lsl #8 + add r0,r0,spc_ya,lsr #8 + call_c_function(S9xAPUGetByte) + ldr spc_ram,[context,#iapu_ram] + and r1,spc_ya,#0xff00 + and spc_ya,spc_ya,#0xff + eor r3,spc_ya,r0 + add spc_ya,spc_ya,r0 + tst spc_p,#flag_c + addne spc_ya,spc_ya,#1 + movs r12,spc_ya,lsr #8 + orrne spc_p,spc_p,#flag_c + biceq spc_p,spc_p,#flag_c + eor r12,spc_ya,r0 + bic r12,r12,r3 + tst r12,#0x80 + orrne spc_p,spc_p,#flag_o + biceq spc_p,spc_p,#flag_o + eor r12,r3,spc_ya + tst r12,#0x10 + orrne spc_p,spc_p,#flag_h + biceq spc_p,spc_p,#flag_h + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + and spc_ya,spc_ya,#0xff + orr spc_ya,spc_ya,r1 + subs cycles,cycles,#126 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu98: + ldrb r0,[spc_pc,#1] + call_c_function(S9xAPUGetByteZ) + ldrb r1,[spc_pc],#2 + eor r3,r0,r1 + add r0,r0,r1 + tst spc_p,#flag_c + addne r0,r0,#1 + movs r12,r0,lsr #8 + orrne spc_p,spc_p,#flag_c + biceq spc_p,spc_p,#flag_c + eor r12,r0,r1 + bic r12,r12,r3 + tst r12,#0x80 + orrne spc_p,spc_p,#flag_o + biceq spc_p,spc_p,#flag_o + eor r12,r3,r0 + tst r12,#0x10 + orrne spc_p,spc_p,#flag_h + biceq spc_p,spc_p,#flag_h + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #24 + ldrb r1,[spc_pc,#-1] + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu99: + mov r0,spc_x + call_c_function(S9xAPUGetByteZ) + stmfd sp!,{r0} + mov r0,spc_ya,lsr #8 + call_c_function(S9xAPUGetByteZ) + ldmfd sp!,{r1} + eor r3,r0,r1 + add r0,r0,r1 + tst spc_p,#flag_c + addne r0,r0,#1 + movs r12,r0,lsr #8 + orrne spc_p,spc_p,#flag_c + biceq spc_p,spc_p,#flag_c + eor r12,r0,r1 + bic r12,r12,r3 + tst r12,#0x80 + orrne spc_p,spc_p,#flag_o + biceq spc_p,spc_p,#flag_o + eor r12,r3,r0 + tst r12,#0x10 + orrne spc_p,spc_p,#flag_h + biceq spc_p,spc_p,#flag_h + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #24 + mov r1,spc_x + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu9A: + ldrb r0,[spc_pc] + call_c_function(S9xAPUGetByteZ) + stmfd sp!,{r0} + ldrb r0,[spc_pc],#1 + add r0,r0,#1 + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + ldmfd sp!,{r1} + orr r1,r1,r0,lsl #8 + subs r0,spc_ya,r1 + orrge spc_p,spc_p,#flag_c + biclt spc_p,spc_p,#flag_c + mov r2,r0,lsl #16 + mov r2,r2,lsr #16 + eor r3,spc_ya,r2 + eor r12,spc_ya,r1 + and r12,r12,r3 + tst r12,#0x8000 + orrne spc_p,spc_p,#flag_o + biceq spc_p,spc_p,#flag_o + eor r12,r3,r1 + tst r12,#0x10 + bicne spc_p,spc_p,#flag_h + orreq spc_p,spc_p,#flag_h + mov spc_ya,r2 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #16 + tst spc_ya,#0xff + orrne spc_p,spc_p,#0x01000000 + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu9B: + ldrb r0,[spc_pc] + add r0,r0,spc_x + call_c_function(S9xAPUGetByteZ) + sub r0,r0,#1 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #24 + ldrb r1,[spc_pc],#1 + add r1,r1,spc_x + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu9C: + and r0,spc_ya,#0xff + sub r0,r0,#1 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #24 + and r0,r0,#0xff + mov spc_ya,spc_ya,lsr #8 + orr spc_ya,r0,spc_ya,lsl #8 + subs cycles,cycles,#42 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu9D: + mov spc_x,spc_s + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_x,lsl #24 + subs cycles,cycles,#42 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu9E: + tst spc_x,spc_x @ div by 0? + orreq spc_ya,spc_ya,#0xff00 + orreq spc_ya,spc_ya,#0x00ff + orreq spc_p,spc_p,#flag_o + beq Apu9E_end + bic spc_p,spc_p,#flag_o +@ Divide spc_ya by spc_x + mov r3,#0 + mov r1,spc_x + +@ Shift up divisor till it's just less than numerator +divshift: + cmp r1,spc_ya,lsr #1 + movls r1,r1,lsl #1 + bcc divshift + +divloop: + cmp spc_ya,r1 + adc r3,r3,r3 ;@ Double r3 and add 1 if carry set + subcs spc_ya,spc_ya,r1 + teq r1,spc_x + movne r1,r1,lsr #1 + bne divloop + + and spc_ya,spc_ya,#0xff + and r3,r3,#0xff + orr spc_ya,r3,spc_ya,lsl #8 +Apu9E_end: + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + subs cycles,cycles,#252 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +Apu9F: + and r0,spc_ya,#0xff + mov r1,r0,lsl #28 + orr r0,r1,r0,lsl #20 + and spc_ya,spc_ya,#0xff00 + orr spc_ya,spc_ya,r0,lsr #24 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuA0: + orr spc_p,spc_p,#flag_i + subs cycles,cycles,#63 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuA1: + sub r0,spc_pc,spc_ram + add r1,spc_ram,spc_s + strb r0,[r1,#0xff] + mov r0,r0,lsr #8 + strb r0,[r1,#0x100] + sub spc_s,spc_s,#2 + ldr r0,[context,#iapu_extraram] + ldrh r0,[r0,#0xa] + add spc_pc,spc_ram,r0 + subs cycles,cycles,#168 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuA2: + ldrb r0,[spc_pc] + call_c_function(S9xAPUGetByteZ) + orr r0,r0,#0x20 + ldrb r1,[spc_pc],#1 + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuA3: + ldrb r0,[spc_pc],#1 + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + tst r0,#0x20 + addeq spc_pc,spc_pc,#1 + ldrnesb r0,[spc_pc],#1 + addne spc_pc,spc_pc,r0 + subne cycles,cycles,#42 + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuA4: + ldrb r0,[spc_pc],#1 + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + and r1,spc_ya,#0xff00 + and spc_ya,spc_ya,#0xff + movs r12,spc_p,lsr #1 + sbcs r2,spc_ya,r0 + orrge spc_p,spc_p,#flag_c + biclt spc_p,spc_p,#flag_c + eor r12,spc_ya,r2 + eor r3,spc_ya,r0 + and r12,r12,r3 + tst r12,#0x80 + orrne spc_p,spc_p,#flag_o + biceq spc_p,spc_p,#flag_o + eor r12,r3,r2 + tst r12,#0x10 + orreq spc_p,spc_p,#flag_h + bicne spc_p,spc_p,#flag_h + mov spc_ya,r2 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + and spc_ya,spc_ya,#0xff + orr spc_ya,spc_ya,r1 + subs cycles,cycles,#63 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuA5: + ldrb r0,[spc_pc],#1 + ldrb r12,[spc_pc],#1 + orr r0,r0,r12,lsl #8 + call_c_function(S9xAPUGetByte) + ldr spc_ram,[context,#iapu_ram] + and r1,spc_ya,#0xff00 + and spc_ya,spc_ya,#0xff + movs r12,spc_p,lsr #1 + sbcs r2,spc_ya,r0 + orrge spc_p,spc_p,#flag_c + biclt spc_p,spc_p,#flag_c + eor r12,spc_ya,r2 + eor r3,spc_ya,r0 + and r12,r12,r3 + tst r12,#0x80 + orrne spc_p,spc_p,#flag_o + biceq spc_p,spc_p,#flag_o + eor r12,r3,r2 + tst r12,#0x10 + orreq spc_p,spc_p,#flag_h + bicne spc_p,spc_p,#flag_h + mov spc_ya,r2 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + and spc_ya,spc_ya,#0xff + orr spc_ya,spc_ya,r1 + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuA6: + mov r0,spc_x + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + and r1,spc_ya,#0xff00 + and spc_ya,spc_ya,#0xff + movs r12,spc_p,lsr #1 + sbcs r2,spc_ya,r0 + orrge spc_p,spc_p,#flag_c + biclt spc_p,spc_p,#flag_c + eor r12,spc_ya,r2 + eor r3,spc_ya,r0 + and r12,r12,r3 + tst r12,#0x80 + orrne spc_p,spc_p,#flag_o + biceq spc_p,spc_p,#flag_o + eor r12,r3,r2 + tst r12,#0x10 + orreq spc_p,spc_p,#flag_h + bicne spc_p,spc_p,#flag_h + mov spc_ya,r2 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + and spc_ya,spc_ya,#0xff + orr spc_ya,spc_ya,r1 + subs cycles,cycles,#63 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuA7: + ldrb r0,[spc_pc],#1 + add r0,r0,spc_x + and r0,r0,#0xff + ldr r12,[context,#iapu_directpage] + ldrb r0,[r12,r0]! + ldrb r12,[r12,#1] + orr r0,r0,r12,lsl #8 + call_c_function(S9xAPUGetByte) + ldr spc_ram,[context,#iapu_ram] + and r1,spc_ya,#0xff00 + and spc_ya,spc_ya,#0xff + movs r12,spc_p,lsr #1 + sbcs r2,spc_ya,r0 + orrge spc_p,spc_p,#flag_c + biclt spc_p,spc_p,#flag_c + eor r12,spc_ya,r2 + eor r3,spc_ya,r0 + and r12,r12,r3 + tst r12,#0x80 + orrne spc_p,spc_p,#flag_o + biceq spc_p,spc_p,#flag_o + eor r12,r3,r2 + tst r12,#0x10 + orreq spc_p,spc_p,#flag_h + bicne spc_p,spc_p,#flag_h + mov spc_ya,r2 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + and spc_ya,spc_ya,#0xff + orr spc_ya,spc_ya,r1 + subs cycles,cycles,#126 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuA8: + ldrb r0,[spc_pc],#1 + and r1,spc_ya,#0xff00 + and spc_ya,spc_ya,#0xff + movs r12,spc_p,lsr #1 + sbcs r2,spc_ya,r0 + orrge spc_p,spc_p,#flag_c + biclt spc_p,spc_p,#flag_c + eor r12,spc_ya,r2 + eor r3,spc_ya,r0 + and r12,r12,r3 + tst r12,#0x80 + orrne spc_p,spc_p,#flag_o + biceq spc_p,spc_p,#flag_o + eor r12,r3,r2 + tst r12,#0x10 + orreq spc_p,spc_p,#flag_h + bicne spc_p,spc_p,#flag_h + mov spc_ya,r2 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + and spc_ya,spc_ya,#0xff + orr spc_ya,spc_ya,r1 + subs cycles,cycles,#42 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuA9: + ldrb r0,[spc_pc],#1 + call_c_function(S9xAPUGetByteZ) + stmfd sp!,{r0} + ldrb r0,[spc_pc] + call_c_function(S9xAPUGetByteZ) + ldmfd sp!,{r1} + movs r12,spc_p,lsr #1 + sbcs r2,r0,r1 + orrge spc_p,spc_p,#flag_c + biclt spc_p,spc_p,#flag_c + eor r12,r0,r2 + eor r3,r0,r1 + and r12,r12,r3 + tst r12,#0x80 + orrne spc_p,spc_p,#flag_o + biceq spc_p,spc_p,#flag_o + eor r12,r3,r2 + tst r12,#0x10 + orreq spc_p,spc_p,#flag_h + bicne spc_p,spc_p,#flag_h + mov r0,r2 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #24 + ldrb r1,[spc_pc],#1 + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#126 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuAA: + ldrb r0,[spc_pc],#1 + ldrb r1,[spc_pc],#1 + add r0,r0,r1,lsl #8 + mov r1,r1,lsr #5 + mov r0,r0,lsl #19 + mov r0,r0,lsr #19 + orr spc_x,spc_x,r1,lsl #29 @ store membit where it can survive memhandler call + call_c_function(S9xAPUGetByte) + mov r1,spc_x,lsr #29 + and spc_x,spc_x,#0xff + mov r0,r0,lsr r1 + tst r0,#1 + orrne spc_p,spc_p,#flag_c + biceq spc_p,spc_p,#flag_c + ldr spc_ram,[context,#iapu_ram] @ restore what memhandler(s) messed up + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuAB: + ldrb r0,[spc_pc] + call_c_function(S9xAPUGetByteZ) + add r0,r0,#1 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #24 + ldrb r1,[spc_pc],#1 + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuAC: + ldrb r0,[spc_pc],#1 + ldrb r12,[spc_pc],#1 + orr r0,r0,r12,lsl #8 + stmfd sp!,{r0} + call_c_function(S9xAPUGetByte) + add r0,r0,#1 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #24 + ldmfd sp!,{r1} + call_c_function(S9xAPUSetByte) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuAD: + ldrb r0,[spc_pc],#1 + mov r1,spc_ya,lsr #8 + subs r12,r1,r0 + orrge spc_p,spc_p,#flag_c + biclt spc_p,spc_p,#flag_c + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r12,lsl #24 + subs cycles,cycles,#42 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuAE: + add spc_s,spc_s,#1 + add r0,spc_ram,spc_s + ldrb r0,[r0,#0x100] + and spc_ya,spc_ya,#0xff00 + orr spc_ya,spc_ya,r0 + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuAF: + mov r0,spc_ya + mov r1,spc_x + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + add spc_x,spc_x,#1 + and spc_x,spc_x,#0xff + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuB0: + tst spc_p,#0x00000001 + addeq spc_pc,spc_pc,#1 + ldrnesb r0,[spc_pc],#1 + addne spc_pc,spc_pc,r0 + subne cycles,cycles,#42 + subs cycles,cycles,#42 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuB1: + sub r0,spc_pc,spc_ram + add r1,spc_ram,spc_s + strb r0,[r1,#0xff] + mov r0,r0,lsr #8 + strb r0,[r1,#0x100] + sub spc_s,spc_s,#2 + ldr r0,[context,#iapu_extraram] + ldrh r0,[r0,#0x8] + add spc_pc,spc_ram,r0 + subs cycles,cycles,#168 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuB2: + ldrb r0,[spc_pc] + call_c_function(S9xAPUGetByteZ) + bic r0,r0,#0x20 + ldrb r1,[spc_pc],#1 + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuB3: + ldrb r0,[spc_pc],#1 + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + tst r0,#0x20 + addne spc_pc,spc_pc,#1 + ldreqsb r0,[spc_pc],#1 + addeq spc_pc,spc_pc,r0 + subeq cycles,cycles,#42 + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuB4: + ldrb r0,[spc_pc],#1 + add r0,r0,spc_x + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + and r1,spc_ya,#0xff00 + and spc_ya,spc_ya,#0xff + movs r12,spc_p,lsr #1 + sbcs r2,spc_ya,r0 + orrge spc_p,spc_p,#flag_c + biclt spc_p,spc_p,#flag_c + eor r12,spc_ya,r2 + eor r3,spc_ya,r0 + and r12,r12,r3 + tst r12,#0x80 + orrne spc_p,spc_p,#flag_o + biceq spc_p,spc_p,#flag_o + eor r12,r3,r2 + tst r12,#0x10 + orreq spc_p,spc_p,#flag_h + bicne spc_p,spc_p,#flag_h + mov spc_ya,r2 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + and spc_ya,spc_ya,#0xff + orr spc_ya,spc_ya,r1 + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuB5: + ldrb r0,[spc_pc],#1 + ldrb r12,[spc_pc],#1 + orr r0,r0,r12,lsl #8 + add r0,r0,spc_x + call_c_function(S9xAPUGetByte) + ldr spc_ram,[context,#iapu_ram] + and r1,spc_ya,#0xff00 + and spc_ya,spc_ya,#0xff + movs r12,spc_p,lsr #1 + sbcs r2,spc_ya,r0 + orrge spc_p,spc_p,#flag_c + biclt spc_p,spc_p,#flag_c + eor r12,spc_ya,r2 + eor r3,spc_ya,r0 + and r12,r12,r3 + tst r12,#0x80 + orrne spc_p,spc_p,#flag_o + biceq spc_p,spc_p,#flag_o + eor r12,r3,r2 + tst r12,#0x10 + orreq spc_p,spc_p,#flag_h + bicne spc_p,spc_p,#flag_h + mov spc_ya,r2 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + and spc_ya,spc_ya,#0xff + orr spc_ya,spc_ya,r1 + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuB6: + ldrb r0,[spc_pc],#1 + ldrb r12,[spc_pc],#1 + orr r0,r0,r12,lsl #8 + add r0,r0,spc_ya,lsr #8 + call_c_function(S9xAPUGetByte) + ldr spc_ram,[context,#iapu_ram] + and r1,spc_ya,#0xff00 + and spc_ya,spc_ya,#0xff + movs r12,spc_p,lsr #1 + sbcs r2,spc_ya,r0 + orrge spc_p,spc_p,#flag_c + biclt spc_p,spc_p,#flag_c + eor r12,spc_ya,r2 + eor r3,spc_ya,r0 + and r12,r12,r3 + tst r12,#0x80 + orrne spc_p,spc_p,#flag_o + biceq spc_p,spc_p,#flag_o + eor r12,r3,r2 + tst r12,#0x10 + orreq spc_p,spc_p,#flag_h + bicne spc_p,spc_p,#flag_h + mov spc_ya,r2 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + and spc_ya,spc_ya,#0xff + orr spc_ya,spc_ya,r1 + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuB7: + ldrb r0,[spc_pc],#1 + ldr r12,[context,#iapu_directpage] + ldrb r0,[r12,r0]! + ldrb r12,[r12,#1] + orr r0,r0,r12,lsl #8 + add r0,r0,spc_ya,lsr #8 + call_c_function(S9xAPUGetByte) + ldr spc_ram,[context,#iapu_ram] + and r1,spc_ya,#0xff00 + and spc_ya,spc_ya,#0xff + movs r12,spc_p,lsr #1 + sbcs r2,spc_ya,r0 + orrge spc_p,spc_p,#flag_c + biclt spc_p,spc_p,#flag_c + eor r12,spc_ya,r2 + eor r3,spc_ya,r0 + and r12,r12,r3 + tst r12,#0x80 + orrne spc_p,spc_p,#flag_o + biceq spc_p,spc_p,#flag_o + eor r12,r3,r2 + tst r12,#0x10 + orreq spc_p,spc_p,#flag_h + bicne spc_p,spc_p,#flag_h + mov spc_ya,r2 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + and spc_ya,spc_ya,#0xff + orr spc_ya,spc_ya,r1 + subs cycles,cycles,#126 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuB8: + ldrb r0,[spc_pc,#1] + call_c_function(S9xAPUGetByteZ) + ldrb r1,[spc_pc],#2 + movs r12,spc_p,lsr #1 + sbcs r2,r0,r1 + orrge spc_p,spc_p,#flag_c + biclt spc_p,spc_p,#flag_c + eor r12,r0,r2 + eor r3,r0,r1 + and r12,r12,r3 + tst r12,#0x80 + orrne spc_p,spc_p,#flag_o + biceq spc_p,spc_p,#flag_o + eor r12,r3,r2 + tst r12,#0x10 + orreq spc_p,spc_p,#flag_h + bicne spc_p,spc_p,#flag_h + mov r0,r2 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #24 + ldrb r1,[spc_pc,#-1] + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuB9: + mov r0,spc_x + call_c_function(S9xAPUGetByteZ) + stmfd sp!,{r0} + mov r0,spc_ya,lsr #8 + call_c_function(S9xAPUGetByteZ) + ldmfd sp!,{r1} + movs r12,spc_p,lsr #1 + sbcs r2,r0,r1 + orrge spc_p,spc_p,#flag_c + biclt spc_p,spc_p,#flag_c + eor r12,r0,r2 + eor r3,r0,r1 + and r12,r12,r3 + tst r12,#0x80 + orrne spc_p,spc_p,#flag_o + biceq spc_p,spc_p,#flag_o + eor r12,r3,r2 + tst r12,#0x10 + orreq spc_p,spc_p,#flag_h + bicne spc_p,spc_p,#flag_h + mov r0,r2 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #24 + mov r1,spc_x + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuBA: + ldrb r0,[spc_pc] + call_c_function(S9xAPUGetByteZ) + mov spc_ya,r0 + ldrb r0,[spc_pc],#1 + add r0,r0,#1 + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + orr spc_ya,spc_ya,r0,lsl #8 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #16 + tst spc_ya,#0xff + orrne spc_p,spc_p,#0x01000000 + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuBB: + ldrb r0,[spc_pc] + add r0,r0,spc_x + call_c_function(S9xAPUGetByteZ) + add r0,r0,#1 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #24 + ldrb r1,[spc_pc],#1 + add r1,r1,spc_x + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuBC: + and r0,spc_ya,#0xff + add r0,r0,#1 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #24 + and r0,r0,#0xff + mov spc_ya,spc_ya,lsr #8 + orr spc_ya,r0,spc_ya,lsl #8 + subs cycles,cycles,#42 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuBD: + mov spc_s,spc_x + subs cycles,cycles,#42 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuBE: + and r0,spc_ya,#0xff + and r1,spc_ya,#0x0f + cmp r1,#9 + subhi r0,r0,#6 + tstls spc_p,#flag_h + subeq r0,r0,#6 + cmp r0,#0x9f + bhi ApuBE_tens + tst spc_p,#flag_c + beq ApuBE_tens + orr spc_p,spc_p,#flag_c + b ApuBE_end +ApuBE_tens: + sub r0,r0,#0x60 + bic spc_p,spc_p,#flag_c +ApuBE_end: + and spc_ya,spc_ya,#0xff00 + orr spc_ya,spc_ya,r0 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + subs cycles,cycles,#63 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuBF: + mov r0,spc_x + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + and spc_ya,spc_ya,#0xff00 + orr spc_ya,spc_ya,r0 + add spc_x,spc_x,#1 + and spc_x,spc_x,#0xff + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuC0: + bic spc_p,spc_p,#flag_i + subs cycles,cycles,#63 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuC1: + sub r0,spc_pc,spc_ram + add r1,spc_ram,spc_s + strb r0,[r1,#0xff] + mov r0,r0,lsr #8 + strb r0,[r1,#0x100] + sub spc_s,spc_s,#2 + ldr r0,[context,#iapu_extraram] + ldrh r0,[r0,#0x6] + add spc_pc,spc_ram,r0 + subs cycles,cycles,#168 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuC2: + ldrb r0,[spc_pc] + call_c_function(S9xAPUGetByteZ) + orr r0,r0,#0x40 + ldrb r1,[spc_pc],#1 + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuC3: + ldrb r0,[spc_pc],#1 + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + tst r0,#0x40 + addeq spc_pc,spc_pc,#1 + ldrnesb r0,[spc_pc],#1 + addne spc_pc,spc_pc,r0 + subne cycles,cycles,#42 + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuC4: + ldrb r1,[spc_pc],#1 + mov r0,spc_ya + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuC5: + ldrb r1,[spc_pc],#1 + ldrb r12,[spc_pc],#1 + orr r1,r1,r12,lsl #8 + mov r0,spc_ya + call_c_function(S9xAPUSetByte) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuC6: + mov r0,spc_ya + mov r1,spc_x + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuC7: + ldrb r1,[spc_pc],#1 + add r1,r1,spc_x + and r1,r1,#0xff + ldr r12,[context,#iapu_directpage] + ldrb r1,[r12,r1]! + ldrb r12,[r12,#1] + orr r1,r1,r12,lsl #8 + mov r0,spc_ya + call_c_function(S9xAPUSetByte) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#147 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuC8: + ldrb r0,[spc_pc],#1 + subs r12,spc_x,r0 + orrge spc_p,spc_p,#flag_c + biclt spc_p,spc_p,#flag_c + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r12,lsl #24 + subs cycles,cycles,#42 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuC9: + ldrb r1,[spc_pc],#1 + ldrb r12,[spc_pc],#1 + orr r1,r1,r12,lsl #8 + mov r0,spc_x + call_c_function(S9xAPUSetByte) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuCA: + ldrb r0,[spc_pc],#1 + ldrb r1,[spc_pc],#1 + add r0,r0,r1,lsl #8 + mov r1,r1,lsr #5 + mov r0,r0,lsl #19 + mov r0,r0,lsr #19 + orr spc_x,spc_x,r1,lsl #29 @ store membit where it can survive memhandler call + stmfd sp!,{r0} + call_c_function(S9xAPUGetByte) + mov r1,spc_x,lsr #29 + and spc_x,spc_x,#0xff + mov r2,#1 + mov r2,r2,lsl r1 + tst spc_p,#flag_c + orrne r0,r0,r2 + biceq r0,r0,r2 + ldmfd sp!,{r1} + call_c_function(S9xAPUSetByte) + ldr spc_ram,[context,#iapu_ram] @ restore what memhandler(s) messed up + subs cycles,cycles,#126 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuCB: + ldrb r1,[spc_pc],#1 + mov r0,spc_ya,lsr #8 + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuCC: + ldrb r1,[spc_pc],#1 + ldrb r12,[spc_pc],#1 + orr r1,r1,r12,lsl #8 + mov r0,spc_ya,lsr #8 + call_c_function(S9xAPUSetByte) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuCD: + ldrb spc_x,[spc_pc],#1 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_x,lsl #24 + subs cycles,cycles,#42 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuCE: + add spc_s,spc_s,#1 + add spc_x,spc_ram,spc_s + ldrb spc_x,[spc_x,#0x100] + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuCF: + mov r0,spc_ya,lsr #8 + and spc_ya,spc_ya,#0xff + mul spc_ya,r0,spc_ya + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #16 + tst spc_ya,#0xff + orrne spc_p,spc_p,#0x01000000 + subs cycles,cycles,#189 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuD0: + tst spc_p,#0xFF000000 + addeq spc_pc,spc_pc,#1 + ldrnesb r0,[spc_pc],#1 + addne spc_pc,spc_pc,r0 + subne cycles,cycles,#42 + subs cycles,cycles,#42 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuD1: + sub r0,spc_pc,spc_ram + add r1,spc_ram,spc_s + strb r0,[r1,#0xff] + mov r0,r0,lsr #8 + strb r0,[r1,#0x100] + sub spc_s,spc_s,#2 + ldr r0,[context,#iapu_extraram] + ldrh r0,[r0,#0x4] + add spc_pc,spc_ram,r0 + subs cycles,cycles,#168 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuD2: + ldrb r0,[spc_pc] + call_c_function(S9xAPUGetByteZ) + bic r0,r0,#0x40 + ldrb r1,[spc_pc],#1 + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuD3: + ldrb r0,[spc_pc],#1 + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + tst r0,#0x40 + addne spc_pc,spc_pc,#1 + ldreqsb r0,[spc_pc],#1 + addeq spc_pc,spc_pc,r0 + subeq cycles,cycles,#42 + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuD4: + mov r0,spc_ya + ldrb r1,[spc_pc],#1 + add r1,r1,spc_x + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuD5: + ldrb r1,[spc_pc],#1 + ldrb r12,[spc_pc],#1 + orr r1,r1,r12,lsl #8 + add r1,r1,spc_x + mov r0,spc_ya + call_c_function(S9xAPUSetByte) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#126 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuD6: + ldrb r1,[spc_pc],#1 + ldrb r12,[spc_pc],#1 + orr r1,r1,r12,lsl #8 + add r1,r1,spc_ya,lsr #8 + mov r0,spc_ya + call_c_function(S9xAPUSetByte) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#126 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuD7: + ldrb r1,[spc_pc],#1 + ldr r12,[context,#iapu_directpage] + ldrb r1,[r12,r1]! + ldrb r12,[r12,#1] + orr r1,r1,r12,lsl #8 + add r1,r1,spc_ya,lsr #8 + mov r0,spc_ya + call_c_function(S9xAPUSetByte) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#147 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuD8: + ldrb r1,[spc_pc],#1 + mov r0,spc_x + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuD9: + ldrb r1,[spc_pc],#1 + add r1,r1,spc_ya,lsr #8 + mov r0,spc_x + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuDA: + ldrb r1,[spc_pc] + mov r0,spc_ya + call_c_function(S9xAPUSetByteZ) + ldrb r1,[spc_pc],#1 + add r1,r1,#1 + mov r0,spc_ya,lsr #8 + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuDB: + ldrb r1,[spc_pc],#1 + add r1,r1,spc_x + mov r0,spc_ya,lsr #8 + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuDC: + mov r0,spc_ya,lsr #8 + sub r0,r0,#1 + and r0,r0,#0xff + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #24 + and spc_ya,spc_ya,#0xff + orr spc_ya,spc_ya,r0,lsl #8 + subs cycles,cycles,#42 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuDD: + and spc_ya,spc_ya,#0xff00 + orr spc_ya,spc_ya,spc_ya,lsr #8 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + subs cycles,cycles,#42 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuDE: + ldrb r0,[spc_pc],#1 + add r0,r0,spc_x + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + and r1,spc_ya,#0xff + cmp r0,r1 + addeq spc_pc,spc_pc,#1 + ldrnesb r0,[spc_pc],#1 + addne spc_pc,spc_pc,r0 + subne cycles,cycles,#42 + subs cycles,cycles,#126 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuDF: + and r0,spc_ya,#0xff + and r1,spc_ya,#0x0f + cmp r1,#9 + addhi r0,r0,#6 + bls ApuDF_testHc + cmphi r0,#0xf0 + orrhi spc_p,spc_p,#flag_c + b ApuDF_test2 +ApuDF_testHc: + tst spc_p,#flag_h + addne r0,r0,#6 + beq ApuDF_test2 + cmp r0,#0xf0 + orrhi spc_p,spc_p,#flag_c +ApuDF_test2: + tst spc_p,#flag_c + addne r0,r0,#0x60 + bne ApuDF_end + cmp r0,#0x9f + addhi r0,r0,#0x60 + orrhi spc_p,spc_p,#flag_c + bicls spc_p,spc_p,#flag_c +ApuDF_end: + and spc_ya,spc_ya,#0xff00 + orr spc_ya,spc_ya,r0 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + subs cycles,cycles,#63 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuE0: + bic spc_p,spc_p,#(flag_o|flag_h) + subs cycles,cycles,#42 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuE1: + sub r0,spc_pc,spc_ram + add r1,spc_ram,spc_s + strb r0,[r1,#0xff] + mov r0,r0,lsr #8 + strb r0,[r1,#0x100] + sub spc_s,spc_s,#2 + ldr r0,[context,#iapu_extraram] + ldrh r0,[r0,#0x2] + add spc_pc,spc_ram,r0 + subs cycles,cycles,#168 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuE2: + ldrb r0,[spc_pc] + call_c_function(S9xAPUGetByteZ) + orr r0,r0,#0x80 + ldrb r1,[spc_pc],#1 + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuE3: + ldrb r0,[spc_pc],#1 + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + tst r0,#0x80 + addeq spc_pc,spc_pc,#1 + ldrnesb r0,[spc_pc],#1 + addne spc_pc,spc_pc,r0 + subne cycles,cycles,#42 + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuE4: + ldrb r0,[spc_pc],#1 + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + and spc_ya,spc_ya,#0xff00 + orr spc_ya,spc_ya,r0 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + subs cycles,cycles,#63 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuE5: + ldrb r0,[spc_pc],#1 + ldrb r12,[spc_pc],#1 + orr r0,r0,r12,lsl #8 + call_c_function(S9xAPUGetByte) + ldr spc_ram,[context,#iapu_ram] + and spc_ya,spc_ya,#0xff00 + orr spc_ya,spc_ya,r0 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuE6: + mov r0,spc_x + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + and spc_ya,spc_ya,#0xff00 + orr spc_ya,spc_ya,r0 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + subs cycles,cycles,#63 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuE7: + ldrb r0,[spc_pc],#1 + add r0,r0,spc_x + and r0,r0,#0xff + ldr r12,[context,#iapu_directpage] + ldrb r0,[r12,r0]! + ldrb r12,[r12,#1] + orr r0,r0,r12,lsl #8 + call_c_function(S9xAPUGetByte) + ldr spc_ram,[context,#iapu_ram] + and spc_ya,spc_ya,#0xff00 + orr spc_ya,spc_ya,r0 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + subs cycles,cycles,#126 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuE8: + ldrb r0,[spc_pc],#1 + and spc_ya,spc_ya,#0xff00 + orr spc_ya,spc_ya,r0 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + subs cycles,cycles,#42 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuE9: + ldrb r0,[spc_pc],#1 + ldrb r12,[spc_pc],#1 + orr r0,r0,r12,lsl #8 + call_c_function(S9xAPUGetByte) + ldr spc_ram,[context,#iapu_ram] + mov spc_x,r0 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_x,lsl #24 + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuEA: + ldrb r0,[spc_pc],#1 + ldrb r1,[spc_pc],#1 + add r0,r0,r1,lsl #8 + mov r1,r1,lsr #5 + mov r0,r0,lsl #19 + mov r0,r0,lsr #19 + orr spc_x,spc_x,r1,lsl #29 @ store membit where it can survive memhandler call + stmfd sp!,{r0} + call_c_function(S9xAPUGetByte) + mov r1,spc_x,lsr #29 + and spc_x,spc_x,#0xff + mov r2,#1 + mov r2,r2,lsl r1 + eor r0,r0,r2 + ldmfd sp!,{r1} + call_c_function(S9xAPUSetByte) + ldr spc_ram,[context,#iapu_ram] @ restore what memhandler(s) messed up + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuEB: + ldrb r0,[spc_pc],#1 + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + and spc_ya,spc_ya,#0xff + orr spc_ya,spc_ya,r0,lsl #8 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #24 + subs cycles,cycles,#63 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuEC: + ldrb r0,[spc_pc],#1 + ldrb r12,[spc_pc],#1 + orr r0,r0,r12,lsl #8 + call_c_function(S9xAPUGetByte) + ldr spc_ram,[context,#iapu_ram] + and spc_ya,spc_ya,#0xff + orr spc_ya,spc_ya,r0,lsl #8 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #24 + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuED: + eor spc_p,spc_p,#flag_c + subs cycles,cycles,#63 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuEE: + add spc_s,spc_s,#1 + add r0,spc_ram,spc_s + ldrb r0,[r0,#0x100] + and spc_ya,spc_ya,#0xff + orr spc_ya,spc_ya,r0,lsl #8 + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + +20: + .long _CPU +ApuEF: + ldr r0, 20b + mov r1,#0 + strb r1,[r0,#122] + subs cycles,cycles,#63 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuF0: + tst spc_p,#0xFF000000 + addne spc_pc,spc_pc,#1 + ldreqsb r0,[spc_pc],#1 + addeq spc_pc,spc_pc,r0 + subeq cycles,cycles,#42 + subs cycles,cycles,#42 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuF1: + sub r0,spc_pc,spc_ram + add r1,spc_ram,spc_s + strb r0,[r1,#0xff] + mov r0,r0,lsr #8 + strb r0,[r1,#0x100] + sub spc_s,spc_s,#2 + ldr r0,[context,#iapu_extraram] + ldrh r0,[r0,#0x0] + add spc_pc,spc_ram,r0 + subs cycles,cycles,#168 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuF2: + ldrb r0,[spc_pc] + call_c_function(S9xAPUGetByteZ) + bic r0,r0,#0x80 + ldrb r1,[spc_pc],#1 + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuF3: + ldrb r0,[spc_pc],#1 + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + tst r0,#0x80 + addne spc_pc,spc_pc,#1 + ldreqsb r0,[spc_pc],#1 + addeq spc_pc,spc_pc,r0 + subeq cycles,cycles,#42 + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuF4: + ldrb r0,[spc_pc],#1 + add r0,r0,spc_x + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + and spc_ya,spc_ya,#0xff00 + orr spc_ya,spc_ya,r0 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuF5: + ldrb r0,[spc_pc],#1 + ldrb r12,[spc_pc],#1 + orr r0,r0,r12,lsl #8 + add r0,r0,spc_x + call_c_function(S9xAPUGetByte) + ldr spc_ram,[context,#iapu_ram] + and spc_ya,spc_ya,#0xff00 + orr spc_ya,spc_ya,r0 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuF6: + ldrb r0,[spc_pc],#1 + ldrb r12,[spc_pc],#1 + orr r0,r0,r12,lsl #8 + add r0,r0,spc_ya,lsr #8 + call_c_function(S9xAPUGetByte) + ldr spc_ram,[context,#iapu_ram] + and spc_ya,spc_ya,#0xff00 + orr spc_ya,spc_ya,r0 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuF7: + ldrb r0,[spc_pc],#1 + ldr r12,[context,#iapu_directpage] + ldrb r0,[r12,r0]! + ldrb r12,[r12,#1] + orr r0,r0,r12,lsl #8 + add r0,r0,spc_ya,lsr #8 + call_c_function(S9xAPUGetByte) + ldr spc_ram,[context,#iapu_ram] + and spc_ya,spc_ya,#0xff00 + orr spc_ya,spc_ya,r0 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + subs cycles,cycles,#126 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuF8: + ldrb r0,[spc_pc],#1 + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + mov spc_x,r0 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_x,lsl #24 + subs cycles,cycles,#63 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuF9: + ldrb r0,[spc_pc],#1 + add r0,r0,spc_ya,lsr #8 + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + mov spc_x,r0 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_x,lsl #24 + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuFA: + ldrb r0,[spc_pc],#1 + call_c_function(S9xAPUGetByteZ) + ldrb r1,[spc_pc],#1 + call_c_function(S9xAPUSetByteZ) + ldr spc_ram,[context,#iapu_ram] + subs cycles,cycles,#105 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuFB: + ldrb r0,[spc_pc],#1 + add r0,r0,spc_x + call_c_function(S9xAPUGetByteZ) + ldr spc_ram,[context,#iapu_ram] + and spc_ya,spc_ya,#0xff + orr spc_ya,spc_ya,r0,lsl #8 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #24 + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuFC: + mov r0,spc_ya,lsr #8 + add r0,r0,#1 + and r0,r0,#0xff + and spc_p,spc_p,#0xff + orr spc_p,spc_p,r0,lsl #24 + and spc_ya,spc_ya,#0xff + orr spc_ya,spc_ya,r0,lsl #8 + subs cycles,cycles,#42 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuFD: + and spc_ya,spc_ya,#0xff + orr spc_ya,spc_ya,spc_ya,lsl #8 + and spc_p,spc_p,#0xff + orr spc_p,spc_p,spc_ya,lsl #24 + subs cycles,cycles,#42 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +ApuFE: + sub spc_ya,spc_ya,#0x100 + mov spc_ya,spc_ya,lsl #16 + mov spc_ya,spc_ya,lsr #16 + movs r0,spc_ya,lsr #8 + addeq spc_pc,spc_pc,#1 + ldrnesb r0,[spc_pc],#1 + addne spc_pc,spc_pc,r0 + subne cycles,cycles,#42 + subs cycles,cycles,#84 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + +21: + .long _CPU +ApuFF: + ldr r0, 21b + mov r1,#0 + strb r1,[r0,#122] + subs cycles,cycles,#63 + ldrgeb opcode,[spc_pc],#1 + ldrge pc,[opcodes,opcode,lsl #2] + b spc700End + + +@ -------------------------- Jump Table -------------------------- +_Spc700JumpTab: + .long Apu00, Apu01, Apu02, Apu03, Apu04, Apu05, Apu06, Apu07 @ 00 + .long Apu08, Apu09, Apu0A, Apu0B, Apu0C, Apu0D, Apu0E, Apu0F @ 08 + .long Apu10, Apu11, Apu12, Apu13, Apu14, Apu15, Apu16, Apu17 @ 10 + .long Apu18, Apu19, Apu1A, Apu1B, Apu1C, Apu1D, Apu1E, Apu1F @ 18 + .long Apu20, Apu21, Apu22, Apu23, Apu24, Apu25, Apu26, Apu27 @ 20 + .long Apu28, Apu29, Apu2A, Apu2B, Apu2C, Apu2D, Apu2E, Apu2F @ 28 + .long Apu30, Apu31, Apu32, Apu33, Apu34, Apu35, Apu36, Apu37 @ 30 + .long Apu38, Apu39, Apu3A, Apu3B, Apu3C, Apu3D, Apu3E, Apu3F @ 38 + .long Apu40, Apu41, Apu42, Apu43, Apu44, Apu45, Apu46, Apu47 @ 40 + .long Apu48, Apu49, Apu4A, Apu4B, Apu4C, Apu4D, Apu4E, Apu4F @ 48 + .long Apu50, Apu51, Apu52, Apu53, Apu54, Apu55, Apu56, Apu57 @ 50 + .long Apu58, Apu59, Apu5A, Apu5B, Apu5C, Apu5D, Apu5E, Apu5F @ 58 + .long Apu60, Apu61, Apu62, Apu63, Apu64, Apu65, Apu66, Apu67 @ 60 + .long Apu68, Apu69, Apu6A, Apu6B, Apu6C, Apu6D, Apu6E, Apu6F @ 68 + .long Apu70, Apu71, Apu72, Apu73, Apu74, Apu75, Apu76, Apu77 @ 70 + .long Apu78, Apu79, Apu7A, Apu7B, Apu7C, Apu7D, Apu7E, Apu7F @ 78 + .long Apu80, Apu81, Apu82, Apu83, Apu84, Apu85, Apu86, Apu87 @ 80 + .long Apu88, Apu89, Apu8A, Apu8B, Apu8C, Apu8D, Apu8E, Apu8F @ 88 + .long Apu90, Apu91, Apu92, Apu93, Apu94, Apu95, Apu96, Apu97 @ 90 + .long Apu98, Apu99, Apu9A, Apu9B, Apu9C, Apu9D, Apu9E, Apu9F @ 98 + .long ApuA0, ApuA1, ApuA2, ApuA3, ApuA4, ApuA5, ApuA6, ApuA7 @ a0 + .long ApuA8, ApuA9, ApuAA, ApuAB, ApuAC, ApuAD, ApuAE, ApuAF @ a8 + .long ApuB0, ApuB1, ApuB2, ApuB3, ApuB4, ApuB5, ApuB6, ApuB7 @ b0 + .long ApuB8, ApuB9, ApuBA, ApuBB, ApuBC, ApuBD, ApuBE, ApuBF @ b8 + .long ApuC0, ApuC1, ApuC2, ApuC3, ApuC4, ApuC5, ApuC6, ApuC7 @ c0 + .long ApuC8, ApuC9, ApuCA, ApuCB, ApuCC, ApuCD, ApuCE, ApuCF @ c8 + .long ApuD0, ApuD1, ApuD2, ApuD3, ApuD4, ApuD5, ApuD6, ApuD7 @ d0 + .long ApuD8, ApuD9, ApuDA, ApuDB, ApuDC, ApuDD, ApuDE, ApuDF @ d8 + .long ApuE0, ApuE1, ApuE2, ApuE3, ApuE4, ApuE5, ApuE6, ApuE7 @ e0 + .long ApuE8, ApuE9, ApuEA, ApuEB, ApuEC, ApuED, ApuEE, ApuEF @ e8 + .long ApuF0, ApuF1, ApuF2, ApuF3, ApuF4, ApuF5, ApuF6, ApuF7 @ f0 + .long ApuF8, ApuF9, ApuFA, ApuFB, ApuFC, ApuFD, ApuFE, ApuFF @ f8 diff --git a/src/snes4iphone_src/spc_decode.S b/src/snes4iphone_src/spc_decode.S new file mode 100755 index 0000000..07b1e61 --- /dev/null +++ b/src/snes4iphone_src/spc_decode.S @@ -0,0 +1,791 @@ + + .align 4 + .globl DecodeBlockAsm + .globl DecodeBlockAsm2 + +/* +;Bit-Rate Expand Waveform +; +;Desc: +; Decompresses a 9-byte bit-rate reduced block into 16 16-bit samples. +; This procedure is designed to be recursively called to decompress a series of blocks. +;In: +; R0=ESI-> Sample Block +; R1=EDI -> Output buffer +; R2=EDX =3D Last sample of previous block (32-bit) +; R3=EBX =3D Next to last sample (sign extended from 16-bits) +;Out: +; R0=ESI -> Next Block +; R1=EDI -> After last sample +; R2=EDX =3D Last sample (32-bit) +; R3=EBX =3D Next to last sample (16-bit) +;Destroys: +; R4=EAX +*/ + +.macro SMP12CLIP16 + CMP R4, R12 + BGT 1111f + MOVNE R4, R12 + B 1112f +1111: + CMP R4, R11 + MOVGT R4, R11 +1112: + CMP R2, R12 + BGT 1121f + MOVNE R2, R12 + B 1122f +1121: + CMP R2, R11 + MOVGT R2, R11 +1122: +.endm + +@ void DecodeBlockAsm2 (int8 *, int16 *, int32 *, int32 *); +@ DecodeBlockAsm2 (compressed, raw, &ch->previous [0], &ch->previous [1]); + .align 4 +DecodeBlockAsm: + + STMFD SP!,{R4,LR} + + STMFD SP!,{R2,R3} + LDR R2,[R2] + LDR R3,[R3] + BL BREWave + LDMFD SP!,{R0,R1} + STR R2,[R0] + STR R3,[R1] + + LDMFD SP!,{R4,LR} + MOV PC,LR + +BREWave: + STMFD SP!,{R5,R6,R7} + @ Mov AL,[ESI] ;Get header byte + @ Inc ESI + + LDRB R4,[R0],#1 + @ Mov CL,0CFh + @ Sub CL,AL + @ SetC AH + @ Dec AH + @ And CL,AH + @ ShR CL,4 ;Isolate range + CMP R4,#0xD0 + MOVHS R5,#0 + MOVLO R5,#0xCF + SUBLO R5,R5,R4 + MOVLO R5,R5,LSR #4 + + @ Mov CH,8 ;Decompress 8 bytes (16 nybbles) + MOV R6,#8 + @ Test AL,0Ch ;Does block use ADPCM compression? + @ JZ @@Method0 ; No + TST R4,#0xC + BEQ Method0 + @ Test AL,8 ;Does block use method 1? + @ JZ @@Method1 ; Yes + TST R4,#0x8 + BEQ Method1 + @ Test AL,4 ;Does block use method 2? + @ jnz @@Method3 ; Yes + @ jmp @@Method2 + TST R4,#0x4 + BEQ Method2 + B Method3 @ ;Must use method 3 +/* +ALIGN 16 + ;[Smp] ----------------------------------*/ +Method0: + ADD R5,R5,#16 +Method0loop: + @ XOr EAX,EAX + @ XOr EDX,EDX + @ Mov AH,byte[ESI] ;Get byte + @ Mov DH,AH + @ And AH,0F0h ;AH = High nybble << 12 + @ ShL DH,4 ;DH = Low nybble << 12 + LDRB R4,[R0],#1 + @ R4 = 0x000000hl + MOV R2,R4,LSL #(28) + @ R2 = 0xl0000000 + MOV R4,R4,LSL #(24) + @ R4 = 0xhl000000 + BIC R4,R4,#0x0F000000 + @ R4 = 0xh0000000 + + @ SAR AX,CL ;Reduce samples according to range + @ SAR DX,CL + MOV R4,R4,ASR R5 + MOV R2,R2,ASR R5 + + @ Mov word[EDI],AX + @ Mov word[2+EDI],DX + STRH R4,[R1],#2 + STRH R2,[R1],#2 + + @ Add EDI,4 + @ Inc ESI + @ Dec CH + @ JNZ Short @@Method0 + @ MovSX EDX,DX + @ MovSX EBX,AX + @ Ret + SUBS R6,R6,#1 + BNE Method0loop + MOV R2,R2,LSL #16 + MOV R2,R2,ASR #16 + MOV R3,R4,LSL #16 + MOV R3,R3,ASR #16 + LDMFD SP!,{R5,R6,R7} + MOV PC,LR + +@ ALIGN 16 +@ ;[Delta]+[Smp-1](15/16) ----------------- +Method1: + ADD R7,R5,#16 +Method1loop: + @ MovSX EBX,byte[ESI] ;Sign extend upper nybble into EBX + @ And BL,0F0h + @ ShL EBX,8 + @ SAR EBX,CL + LDRSB R3,[R0] + BIC R3,R3,#0xF + MOV R3,R3,LSL #8 + MOV R3,R3,ASR R5 + + @ MovSX EAX,DX + @ Add EBX,EAX + @ SAR EAX,4 + @ Sub EBX,EAX + MOV R4,R2,LSL #16 + ADD R3,R3,R4,ASR #16 + SUB R3,R3,R4,ASR #20 + + @ Mov word[EDI],BX + STRH R3,[R1],#2 + + @ Mov DL,byte[ESI] + @ ShL EDX,12 + @ MovSX EDX,DX + @ SAR EDX,CL + LDRSB R2,[R0],#1 + MOV R2,R2,LSL #(12+16) + MOV R2,R2,ASR R7 + + @ MovSX EAX,BX + @ Add EDX,EAX + @ SAR EAX,4 + @ Sub EDX,EAX + MOV R4,R3,LSL #16 + ADD R2,R2,R4,ASR #16 + SUB R2,R2,R4,ASR #20 + + @ Mov word[2+EDI],DX + STRH R2,[R1],#2 + @ Add EDI,4 + + @ Inc ESI + + @ Dec CH + @ JNZ Short @@Method1 + @ MovSX EBX,BX + @ Ret + SUBS R6,R6,#1 + BNE Method1loop + + MOV R3,R3,LSL #16 + MOV R3,R3,ASR #16 + + LDMFD SP!,{R5,R6,R7} + MOV PC,LR + +@ ALIGN 16 + @ ;[Delta]+[Smp-1](61/32)-[Smp-2](30/32) -- +Method2: + ADD R7,R5,#16 +Method2loop: + @ MovSX EAX,Byte[ESI] ;EAX = Delta + LDRSB R4,[R0] + @ And AL,0F0h + @ ShL EAX,8 + @ SAR EAX,CL + BIC R4,R4,#0xF + MOV R4,R4,LSL #8 + MOV R4,R4,ASR R5 + + @ ;Subtract 15/16 of second sample ----- + @ Sub EAX,EBX + @ SAR EBX,4 + @ Add EAX,EBX + @ MovSX EBX,DX + SUB R4,R4,R3 + ADD R4,R4,R3,ASR #4 + MOV R3,R2 + + @ ;Add 61/32 of last sample ------------ + @ And DL,~3 + @ Add EAX,EDX + @ Add EAX,EDX + @ SAR EDX,4 + @ Sub EAX,EDX + @ SAR EDX,1 + BIC R2,R2,#3 + ADD R4,R4,R2,LSL #1 + SUB R4,R4,R2,ASR #4 + @ MovSX EDX,DX + @ Sub EAX,EDX + SUB R4,R4,R2,ASR #5 + @ Mov word[EDI],AX + STRH R4,[R1],#2 + + @ Mov DL,byte[ESI] + LDRB R2,[R0],#1 + @ ShL EDX,12 + @ MovSX EDX,DX + @ SAR EDX,CL + MOV R2,R2,LSL #(12+16) + MOV R2,R2,ASR R7 + + @ Sub EDX,EBX + @ SAR EBX,4 + @ Add EDX,EBX + @ MovSX EBX,AX + SUB R2,R2,R3 + ADD R2,R2,R3,ASR #4 + MOV R3,R4 + + @ And AL,~3 + @ Add EDX,EAX + @ Add EDX,EAX + @ SAR EAX,4 + @ Sub EDX,EAX + @ SAR EAX,1 + BIC R4,R4,#3 + ADD R2,R2,R4,LSL #1 + SUB R2,R2,R4,ASR #4 + @ MovSX EAX,AX + @ Sub EDX,EAX + SUB R2,R2,R4,ASR #5 + + @ Mov word[2+EDI],DX + STRH R2,[R1],#2 + @ Add EDI,4 + + @ Inc ESI + + @ Dec CH + @ JNZ @@Method2 + @ Ret + SUBS R6,R6,#1 + BNE Method2loop + LDMFD SP!,{R5,R6,R7} + MOV PC,LR + +@ ALIGN 16 + @ ;[Delta]+[Smp-1](115/64)-[Smp-2](52/64) - +Method3: + ADD R7,R5,#16 +Method3loop: + @ MovSX EAX,Byte[ESI] + LDRSB R4,[R0] + @ And AL,0F0h + @ ShL EAX,8 + @ SAR EAX,CL + BIC R4,R4,#0xF + MOV R4,R4,LSL #8 + MOV R4,R4,ASR R5 + + @ ;Subtract 13/16 of second sample ----- + @ Sub EAX,EBX + @ SAR EBX,3 + @ Add EAX,EBX + @ SAR EBX,1 + @ Add EAX,EBX + @ MovSX EBX,DX + SUB R4,R4,R3 + ADD R4,R4,R3,ASR #3 + ADD R4,R4,R3,ASR #4 + MOV R3,R2 + + @ ;Add 115/64 of last sample ----------- + @ And DL, ~3 + @ Add EAX,EDX + @ Add EAX,EDX + @ SAR EDX,3 + @ Sub EAX,EDX + @ SAR EDX,1 + @ Sub EAX,EDX + @ SAR EDX,2 + @ Sub EAX,EDX + BIC R2,R2,#3 + ADD R4,R4,R2,LSL #1 + SUB R4,R4,R2,ASR #3 + SUB R4,R4,R2,ASR #4 + SUB R4,R4,R2,ASR #6 + + @ Mov word[EDI],AX + STRH R4,[R1],#2 + + @ Mov DL,byte[ESI] + LDRB R2,[R0],#1 + + @ ShL EDX,12 + @ MovSX EDX,DX + @ SAR EDX,CL + MOV R2,R2,LSL #(12+16) + MOV R2,R2,ASR R7 + + @ Sub EDX,EBX + @ SAR EBX,3 + @ Add EDX,EBX + @ SAR EBX,1 + @ Add EDX,EBX + @ MovSX EBX,AX + SUB R2,R2,R3 + ADD R2,R2,R3,ASR #3 + ADD R2,R2,R3,ASR #4 + MOV R3,R4 + + @ And AL, ~3 + @ Add EDX,EAX + @ Add EDX,EAX + @ SAR EAX,3 + @ Sub EDX,EAX + @ SAR EAX,1 + @ Sub EDX,EAX + @ SAR EAX,2 + @ Sub EDX,EAX + BIC R4,R4,#3 + ADD R2,R2,R4,LSL #1 + SUB R2,R2,R4,ASR #3 + SUB R2,R2,R4,ASR #4 + SUB R2,R2,R4,ASR #6 + + @ Mov word[2+EDI],DX + STRH R4,[R1],#2 + @ Add EDI,4 + + @ Inc ESI + + @ Dec CH + @ JNZ @@Method3 + @ Ret + SUBS R6,R6,#1 + BNE Method3loop + + LDMFD SP!,{R5,R6,R7} + MOV PC,LR + + +DecodeBlockAsm2: + STMFD SP!,{R4,R11,LR} + + @ R12 = -32768 + LDR R12, = (-32768) + @ R11 = 32767 + LDR R11, = 32767 + + + @ R0 = source (compressed) + @ R1 = destination (uncompressed) + @ + + /*mov esi,dword[esp+20] + mov edi,dword[esp+24] + mov edx,dword[esp+28] + mov edx,dword[edx] + mov ebx,dword[esp+32] + mov ebx,dword[ebx]*/ + + @ call BREWave2 + @ sauvgarde les valeurs de R2 et R3 (&ch->prev[0] et &...[1]) + STMFD SP!,{R2,R3} + LDR R2,[R2] + LDR R3,[R3] + BL BREWave2 + @ renvoie dans R2 et R3 les valeurs a mettre dans &ch->prev[0] et &ch...[1] + /*mov eax,dword[esp+28] + mov dword[eax],edx + mov eax,dword[esp+32] + mov dword[eax],ebx*/ + LDMFD SP!,{R0,R1} + STR R2,[R0] + STR R3,[R1] + + LDMFD SP!,{R4,R11,LR} + MOV PC,LR + @ ret + +@ ALIGN 16 +BREWave2: + @ Push CX + STMFD SP!,{R5,R6} + @ Mov AL,byte [esi] ;Get header byte + @ Inc esi + LDRB R4,[R0],#1 + @ Mov CL,0CFh + @ Sub CL,AL ;Invert range + @ ShR CL,4 ;Isolate range + MOV R5,#0xCF + SUB R5,R5,R4 + MOV R5,R5,LSR #4 + @ Mov CH,8 ;Decompress 8 bytes (16 nybbles) + MOV R6,#8 + @ Test AL,0Ch ;Does block use ADPCM compression? + @ JZ @@Method02 ; No + TST R4,#0xC + BEQ Method02 + @ Test AL,8 ;Does block use method 1? + @ JZ @@Method12 ; Yes + TST R4,#0x8 + BEQ Method12 + @ Test AL,4 ;Does block use method 2? + @ jnz @@Method332 ; Yes + @ jmp @@Method22 + TST R4,#0x4 + BEQ Method22 + B Method32 +@ @@Method332: + @ Jmp @@Method32 ;Must use method 3 + +@ ALIGN 16 +@ ;[Smp] ---------------------------------- +@ @@Method02: +Method02: + @ shr al, 4 + MOV R4,R4,LSR #4 + @ mov cl, al + MOV R5,R4 + @ cmp cl, 12 + CMP R4,#12 + @ jbe @@Method022 + SUBLS R5,R5,#4 + @ sub cl, 4 +Method022: + @ XOr AX,AX + @ XOr DX,DX + @ Mov al,byte [esi] ;Get byte + LDRSB R4,[R0],#1 + @ mov dl, al + @ sar al, 4 + @ sal dl, 4 + @ sar dl, 4 + @ movsx eax, al + @ movsx edx, dl + MOV R2,R4,LSL #28 + MOV R4,R4,ASR #4 @ top nib + MOV R2,R2,ASR #28 @ bottom nib + @ sal eax,cl ;Reduce samples according to range + @ sal edx,cl + MOV R4,R4,ASL R5 @ < +#include +#include +#include +#include +#include +#include + +extern char **g_argv; + +/* Call this MMU Hack kernel module after doing mmap, and before doing memset*/ +int mmuhack(void) +{ + char kocmd[1024]; + int i, mmufd = open("/dev/mmuhack", O_RDWR); + + if(mmufd < 0) { + strcpy(kocmd, "/sbin/insmod "); + strncpy(kocmd+13, g_argv[0], 1023-13); + kocmd[1023] = 0; + for (i = strlen(kocmd); i > 0; i--) + if (kocmd[i] == '/') { kocmd[i] = 0; break; } + strcat(kocmd, "/mmuhack.o"); + + printf("Installing NK's kernel module for Squidge MMU Hack (%s)...\n", kocmd); + system(kocmd); + mmufd = open("/dev/mmuhack", O_RDWR); + } + if(mmufd < 0) return 0; + + close(mmufd); + return 1; +} + + +/* Unload MMU Hack kernel module after closing all memory devices*/ +int mmuunhack(void) +{ + int ret; + printf("Removing NK's kernel module for Squidge MMU Hack... "); fflush(stdout); + ret = system("/sbin/rmmod mmuhack"); + printf("done (%i)\n", ret); + + return ret; +} diff --git a/src/snes4iphone_src/squidgehack.h b/src/snes4iphone_src/squidgehack.h new file mode 100755 index 0000000..3a6ee7a --- /dev/null +++ b/src/snes4iphone_src/squidgehack.h @@ -0,0 +1,15 @@ +#ifndef __MMUHACK__ +#define __MMUHACK__ + +#ifdef __cplusplus +extern "C" { +#endif + +extern int mmuhack(void); +extern int mmuunhack(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __MMUHACK__ */ diff --git a/src/snes4iphone_src/srtc.cpp b/src/snes4iphone_src/srtc.cpp new file mode 100755 index 0000000..0cd306f --- /dev/null +++ b/src/snes4iphone_src/srtc.cpp @@ -0,0 +1,529 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#include +#include +#include "snes9x.h" +#include "srtc.h" +#include "memmap.h" + +/*** The format of the rtc_data structure is: + +Index Description Range (nibble) +----- -------------- --------------------------------------- + + 0 Seconds low 0-9 + 1 Seconds high 0-5 + + 2 Minutes low 0-9 + 3 Minutes high 0-5 + + 4 Hour low 0-9 + 5 Hour high 0-2 + + 6 Day low 0-9 + 7 Day high 0-3 + + 8 Month 1-C (0xC is December, 12th month) + + 9 Year ones 0-9 + A Year tens 0-9 + B Year High 9-B (9=19xx, A=20xx, B=21xx) + + C Day of week 0-6 (0=Sunday, 1=Monday,...,6=Saturday) + +***/ + +SRTC_DATA rtc; + + +static int month_keys[12] = { 1, 4, 4, 0, 2, 5, 0, 3, 6, 1, 4, 6 }; + + +/********************************************************************************************* + * + * Note, if you are doing a save state for this game: + * + * On save: + * + * Call S9xUpdateSrtcTime and save the rtc data structure. + * + * On load: + * + * restore the rtc data structure + * rtc.system_timestamp = time (NULL); + * + * + *********************************************************************************************/ + + +void S9xResetSRTC () +{ + rtc.index = -1; + rtc.mode = MODE_READ; +} + +void S9xHardResetSRTC () +{ + ZeroMemory (&rtc, sizeof (rtc)); + rtc.index = -1; + rtc.mode = MODE_READ; + rtc.count_enable = FALSE; + rtc.needs_init = TRUE; + + // Get system timestamp + rtc.system_timestamp = time (NULL); +} + +/**********************************************************************************************/ +/* S9xSRTCComputeDayOfWeek() */ +/* Return 0-6 for Sunday-Saturday */ +/**********************************************************************************************/ +unsigned int S9xSRTCComputeDayOfWeek () +{ + unsigned year = rtc.data[10]*10 + rtc.data[9]; + unsigned month = rtc.data[8]; + unsigned day = rtc.data[7]*10 + rtc.data[6]; + unsigned day_of_week; + + year += (rtc.data[11] - 9) * 100; + + // Range check the month for valid array indicies + if ( month > 12 ) + month = 1; + + day_of_week = year + (year / 4) + month_keys[month-1] + day - 1; + + if(( year % 4 == 0 ) && ( month <= 2 ) ) + day_of_week--; + + day_of_week %= 7; + + return day_of_week; +} + + +/**********************************************************************************************/ +/* S9xSRTCDaysInMonth() */ +/* Return the number of days in a specific month for a certain year */ +/**********************************************************************************************/ +int S9xSRTCDaysInMmonth( int month, int year ) +{ + int mdays; + + switch ( month ) + { + case 2: + if ( ( year % 4 == 0 ) ) // DKJM2 only uses 199x - 22xx + mdays = 29; + else + mdays = 28; + break; + + case 4: + case 6: + case 9: + case 11: + mdays = 30; + break; + + default: // months 1,3,5,7,8,10,12 + mdays = 31; + break; + } + + return mdays; +} + + +#define DAYTICKS (60*60*24) +#define HOURTICKS (60*60) +#define MINUTETICKS 60 + + +/**********************************************************************************************/ +/* S9xUpdateSrtcTime() */ +/* Advance the S-RTC time if counting is enabled */ +/**********************************************************************************************/ +void S9xUpdateSrtcTime () +{ + time_t cur_systime; + long time_diff; + + // Keep track of game time by computing the number of seconds that pass on the system + // clock and adding the same number of seconds to the S-RTC clock structure. + // I originally tried using mktime and localtime library functions to keep track + // of time but some of the GNU time functions fail when the year goes to 2099 + // (and maybe less) and this would have caused a bug with DKJM2 so I'm doing + // it this way to get around that problem. + + // Note: Dai Kaijyu Monogatari II only allows dates in the range 1996-21xx. + + if (rtc.count_enable && !rtc.needs_init) + { + cur_systime = time (NULL); + + // This method assumes one time_t clock tick is one second + // which should work on PCs and GNU systems. + // If your tick interval is different adjust the + // DAYTICK, HOURTICK, and MINUTETICK defines + + time_diff = (long) (cur_systime - rtc.system_timestamp); + rtc.system_timestamp = cur_systime; + + if ( time_diff > 0 ) + { + int seconds; + int minutes; + int hours; + int days; + int month; + int year; + int temp_days; + + int year_hundreds; + int year_tens; + int year_ones; + + + if ( time_diff > DAYTICKS ) + { + days = time_diff / DAYTICKS; + time_diff = time_diff - days * DAYTICKS; + } + else + { + days = 0; + } + + if ( time_diff > HOURTICKS ) + { + hours = time_diff / HOURTICKS; + time_diff = time_diff - hours * HOURTICKS; + } + else + { + hours = 0; + } + + if ( time_diff > MINUTETICKS ) + { + minutes = time_diff / MINUTETICKS; + time_diff = time_diff - minutes * MINUTETICKS; + } + else + { + minutes = 0; + } + + if ( time_diff > 0 ) + { + seconds = time_diff; + } + else + { + seconds = 0; + } + + + seconds += (rtc.data[1]*10 + rtc.data[0]); + if ( seconds >= 60 ) + { + seconds -= 60; + minutes += 1; + } + + minutes += (rtc.data[3]*10 + rtc.data[2]); + if ( minutes >= 60 ) + { + minutes -= 60; + hours += 1; + } + + hours += (rtc.data[5]*10 + rtc.data[4]); + if ( hours >= 24 ) + { + hours -= 24; + days += 1; + } + + if ( days > 0 ) + { + year = rtc.data[10]*10 + rtc.data[9]; + year += ( 1000 + rtc.data[11] * 100 ); + + month = rtc.data[8]; + days += (rtc.data[7]*10 + rtc.data[6]); + while ( days > (temp_days = S9xSRTCDaysInMmonth( month, year )) ) + { + days -= temp_days; + month += 1; + if ( month > 12 ) + { + year += 1; + month = 1; + } + } + + year_tens = year % 100; + year_ones = year_tens % 10; + year_tens /= 10; + year_hundreds = (year - 1000) / 100; + + rtc.data[6] = days % 10; + rtc.data[7] = days / 10; + rtc.data[8] = month; + rtc.data[9] = year_ones; + rtc.data[10] = year_tens; + rtc.data[11] = year_hundreds; + rtc.data[12] = S9xSRTCComputeDayOfWeek (); + } + + rtc.data[0] = seconds % 10; + rtc.data[1] = seconds / 10; + rtc.data[2] = minutes % 10; + rtc.data[3] = minutes / 10; + rtc.data[4] = hours % 10; + rtc.data[5] = hours / 10; + + return; + } + } +} + + +/**********************************************************************************************/ +/* S9xSetSRTC() */ +/* This function sends data to the S-RTC used in Dai Kaijyu Monogatari II */ +/**********************************************************************************************/ +void S9xSetSRTC (uint8 data, uint16 Address) +{ + + data &= 0x0F; // Data is only 4-bits, mask out unused bits. + + if( data >= 0xD ) + { + // It's an RTC command + + switch ( data ) + { + case 0xD: + rtc.mode = MODE_READ; + rtc.index = -1; + break; + + case 0xE: + rtc.mode = MODE_COMMAND; + break; + + default: + // Ignore the write if it's an 0xF ??? + // Probably should switch back to read mode -- but this + // sequence never occurs in DKJM2 + break; + } + + return; + } + + if ( rtc.mode == MODE_LOAD_RTC ) + { + if ( (rtc.index >= 0) || (rtc.index < MAX_RTC_INDEX) ) + { + rtc.data[rtc.index++] = data; + + if ( rtc.index == MAX_RTC_INDEX ) + { + // We have all the data for the RTC load + + rtc.system_timestamp = time (NULL); // Get local system time + + // Get the day of the week + rtc.data[rtc.index++] = S9xSRTCComputeDayOfWeek (); + + // Start RTC counting again + rtc.count_enable = TRUE; + rtc.needs_init = FALSE; + } + + return; + } + else + { + // Attempting to write too much data + // error(); // ignore?? + } + } + else if ( rtc.mode == MODE_COMMAND ) + { + switch( data ) + { + case COMMAND_CLEAR_RTC: + // Disable RTC counter + rtc.count_enable = FALSE; + + ZeroMemory (rtc.data, MAX_RTC_INDEX+1); + rtc.index = -1; + rtc.mode = MODE_COMMAND_DONE; + break; + + case COMMAND_LOAD_RTC: + // Disable RTC counter + rtc.count_enable = FALSE; + + rtc.index = 0; // Setup for writing + rtc.mode = MODE_LOAD_RTC; + break; + + default: + rtc.mode = MODE_COMMAND_DONE; + // unrecognized command - need to implement. + } + + return; + } + else + { + if ( rtc.mode == MODE_READ ) + { + // Attempting to write while in read mode. Ignore. + } + + if ( rtc.mode == MODE_COMMAND_DONE ) + { + // Maybe this isn't an error. Maybe we should kick off + // a new E command. But is this valid? + } + } +} + +/**********************************************************************************************/ +/* S9xGetSRTC() */ +/* This function retrieves data from the S-RTC */ +/**********************************************************************************************/ +uint8 S9xGetSRTC (uint16 Address) +{ + if ( rtc.mode == MODE_READ ) + { + if ( rtc.index < 0 ) + { + S9xUpdateSrtcTime (); // Only update it if the game reads it + rtc.index++; + return ( 0x0f ); // Send start marker. + } + else if (rtc.index > MAX_RTC_INDEX) + { + rtc.index = -1; // Setup for next set of reads + return ( 0x0f ); // Data done marker. + } + else + { + // Feed out the data + return rtc.data[rtc.index++]; + } + } + else + { + return 0x0; + } +} + +void S9xSRTCPreSaveState () +{ + if (Settings.SRTC) + { + S9xUpdateSrtcTime (); + + int s = Memory.SRAMSize ? + (1 << (Memory.SRAMSize + 3)) * 128 : 0; + if (s > 0x20000) + s = 0x20000; + + SRAM [s + 0] = rtc.needs_init; + SRAM [s + 1] = rtc.count_enable; + memmove (&SRAM [s + 2], rtc.data, MAX_RTC_INDEX + 1); + SRAM [s + 3 + MAX_RTC_INDEX] = rtc.index; + SRAM [s + 4 + MAX_RTC_INDEX] = rtc.mode; + +#ifdef LSB_FIRST + memmove (&SRAM [s + 5 + MAX_RTC_INDEX], &rtc.system_timestamp, 8); +#else + SRAM [s + 5 + MAX_RTC_INDEX] = (uint8) (rtc.system_timestamp >> 0); + SRAM [s + 6 + MAX_RTC_INDEX] = (uint8) (rtc.system_timestamp >> 8); + SRAM [s + 7 + MAX_RTC_INDEX] = (uint8) (rtc.system_timestamp >> 16); + SRAM [s + 8 + MAX_RTC_INDEX] = (uint8) (rtc.system_timestamp >> 24); + SRAM [s + 9 + MAX_RTC_INDEX] = (uint8) (rtc.system_timestamp >> 32); + SRAM [s + 10 + MAX_RTC_INDEX] = (uint8) (rtc.system_timestamp >> 40); + SRAM [s + 11 + MAX_RTC_INDEX] = (uint8) (rtc.system_timestamp >> 48); + SRAM [s + 12 + MAX_RTC_INDEX] = (uint8) (rtc.system_timestamp >> 56); +#endif + } +} + +void S9xSRTCPostLoadState () +{ + if (Settings.SRTC) + { + int s = Memory.SRAMSize ? + (1 << (Memory.SRAMSize + 3)) * 128 : 0; + if (s > 0x20000) + s = 0x20000; + + rtc.needs_init = SRAM [s + 0]; + rtc.count_enable = SRAM [s + 1]; + memmove (rtc.data, &SRAM [s + 2], MAX_RTC_INDEX + 1); + rtc.index = SRAM [s + 3 + MAX_RTC_INDEX]; + rtc.mode = SRAM [s + 4 + MAX_RTC_INDEX]; + +#ifdef LSB_FIRST + memmove (&rtc.system_timestamp, &SRAM [s + 5 + MAX_RTC_INDEX], 8); +#else + rtc.system_timestamp |= (SRAM [s + 5 + MAX_RTC_INDEX] << 0); + rtc.system_timestamp |= (SRAM [s + 6 + MAX_RTC_INDEX] << 8); + rtc.system_timestamp |= (SRAM [s + 7 + MAX_RTC_INDEX] << 16); + rtc.system_timestamp |= (SRAM [s + 8 + MAX_RTC_INDEX] << 24); + rtc.system_timestamp |= (SRAM [s + 9 + MAX_RTC_INDEX] << 32); + rtc.system_timestamp |= (SRAM [s + 10 + MAX_RTC_INDEX] << 40); + rtc.system_timestamp |= (SRAM [s + 11 + MAX_RTC_INDEX] << 48); + rtc.system_timestamp |= (SRAM [s + 12 + MAX_RTC_INDEX] << 56); +#endif + S9xUpdateSrtcTime (); + } +} diff --git a/src/snes4iphone_src/srtc.h b/src/snes4iphone_src/srtc.h new file mode 100755 index 0000000..ba19a8b --- /dev/null +++ b/src/snes4iphone_src/srtc.h @@ -0,0 +1,110 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#ifndef _srtc_h_ +#define _srtc_h_ + +#if !defined(_SNESPPC) && !defined(__GIZ__) && !defined(__GP2X__) && !defined(__IPHONE__) +#include +#endif + +#define MAX_RTC_INDEX 0xC + +#define MODE_READ 0 +#define MODE_LOAD_RTC 1 +#define MODE_COMMAND 2 +#define MODE_COMMAND_DONE 3 + +#define COMMAND_LOAD_RTC 0 +#define COMMAND_CLEAR_RTC 4 + + +/*** The format of the rtc_data structure is: + +Index Description Range (nibble) +----- -------------- --------------------------------------- + + 0 Seconds low 0-9 + 1 Seconds high 0-5 + + 2 Minutes low 0-9 + 3 Minutes high 0-5 + + 4 Hour low 0-9 + 5 Hour high 0-2 + + 6 Day low 0-9 + 7 Day high 0-3 + + 8 Month 1-C (0xC is December, 12th month) + + 9 Year ones 0-9 + A Year tens 0-9 + B Year High 9-B (9=19xx, A=20xx, B=21xx) + + C Day of week 0-6 (0=Sunday, 1=Monday,...,6=Saturday) + +***/ + +typedef struct +{ + bool8_32 needs_init; + bool8_32 count_enable; // Does RTC mark time or is it frozen + uint8 data [MAX_RTC_INDEX+1]; + int8 index; + uint8 mode; + + time_t system_timestamp; // Of latest RTC load time + uint32 pad; +} SRTC_DATA; + +extern SRTC_DATA rtc; + +void S9xUpdateSrtcTime (); +void S9xSetSRTC (uint8 data, uint16 Address); +uint8 S9xGetSRTC (uint16 Address); +void S9xSRTCPreSaveState (); +void S9xSRTCPostLoadState (); +void S9xResetSRTC (); +void S9xHardResetSRTC (); + +#define SRTC_SRAM_PAD (4 + 8 + 1 + MAX_RTC_INDEX) + +#endif // _srtc_h diff --git a/src/snes4iphone_src/tile.cpp b/src/snes4iphone_src/tile.cpp new file mode 100755 index 0000000..d2a88ad --- /dev/null +++ b/src/snes4iphone_src/tile.cpp @@ -0,0 +1,1186 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#include "snes9x.h" + +#include "memmap.h" +#include "ppu.h" +#include "display.h" +#include "gfx.h" +#include "tile.h" + +#ifdef USE_GLIDE +#include "3d.h" +#endif + +extern uint32 HeadMask [4]; +extern uint32 TailMask [5]; + +uint8 ConvertTile (uint8 *pCache, uint32 TileAddr) +{ + register uint8 *tp = &Memory.VRAM[TileAddr]; + uint32 *p = (uint32 *) pCache; + uint32 non_zero = 0; + uint8 line; + uint32 p1; + uint32 p2; + register uint8 pix; + + switch (BG.BitShift) + { + case 8: + for (line = 8; line != 0; line--, tp += 2) + { + p1 = p2 = 0; + if ((pix = *(tp + 0))) + { + p1 |= odd_high[0][pix >> 4]; + p2 |= odd_low[0][pix & 0xf]; + } + if ((pix = *(tp + 1))) + { + p1 |= even_high[0][pix >> 4]; + p2 |= even_low[0][pix & 0xf]; + } + if ((pix = *(tp + 16))) + { + p1 |= odd_high[1][pix >> 4]; + p2 |= odd_low[1][pix & 0xf]; + } + if ((pix = *(tp + 17))) + { + p1 |= even_high[1][pix >> 4]; + p2 |= even_low[1][pix & 0xf]; + } + if ((pix = *(tp + 32))) + { + p1 |= odd_high[2][pix >> 4]; + p2 |= odd_low[2][pix & 0xf]; + } + if ((pix = *(tp + 33))) + { + p1 |= even_high[2][pix >> 4]; + p2 |= even_low[2][pix & 0xf]; + } + if ((pix = *(tp + 48))) + { + p1 |= odd_high[3][pix >> 4]; + p2 |= odd_low[3][pix & 0xf]; + } + if ((pix = *(tp + 49))) + { + p1 |= even_high[3][pix >> 4]; + p2 |= even_low[3][pix & 0xf]; + } + *p++ = p1; + *p++ = p2; + non_zero |= p1 | p2; + } + break; + + case 4: + for (line = 8; line != 0; line--, tp += 2) + { + p1 = p2 = 0; + if ((pix = *(tp + 0))) + { + p1 |= odd_high[0][pix >> 4]; + p2 |= odd_low[0][pix & 0xf]; + } + if ((pix = *(tp + 1))) + { + p1 |= even_high[0][pix >> 4]; + p2 |= even_low[0][pix & 0xf]; + } + if ((pix = *(tp + 16))) + { + p1 |= odd_high[1][pix >> 4]; + p2 |= odd_low[1][pix & 0xf]; + } + if ((pix = *(tp + 17))) + { + p1 |= even_high[1][pix >> 4]; + p2 |= even_low[1][pix & 0xf]; + } + *p++ = p1; + *p++ = p2; + non_zero |= p1 | p2; + } + break; + + case 2: + for (line = 8; line != 0; line--, tp += 2) + { + p1 = p2 = 0; + if ((pix = *(tp + 0))) + { + p1 |= odd_high[0][pix >> 4]; + p2 |= odd_low[0][pix & 0xf]; + } + if ((pix = *(tp + 1))) + { + p1 |= even_high[0][pix >> 4]; + p2 |= even_low[0][pix & 0xf]; + } + *p++ = p1; + *p++ = p2; + non_zero |= p1 | p2; + } + break; + } + return (non_zero ? TRUE : BLANK_TILE); +} + +INLINE void WRITE_4PIXELS (uint32 Offset, uint8 *Pixels, struct SGFX * gfx) +{ + register uint8 Pixel; + uint8 *Screen = gfx->S + Offset; + uint8 *Depth = gfx->DB + Offset; + +#define FN(N) \ + if (gfx->Z1 > Depth [N] && (Pixel = Pixels[N])) \ + { \ + Screen [N] = (uint8) gfx->ScreenColors [Pixel]; \ + Depth [N] = gfx->Z2; \ + } + + FN(0) + FN(1) + FN(2) + FN(3) +#undef FN +} + +INLINE void WRITE_4PIXELS_FLIPPED (uint32 Offset, uint8 *Pixels, struct SGFX * gfx) +{ + register uint8 Pixel; + uint8 *Screen = gfx->S + Offset; + uint8 *Depth = gfx->DB + Offset; + +#define FN(N) \ + if (gfx->Z1 > Depth [N] && (Pixel = Pixels[3 - N])) \ + { \ + Screen [N] = (uint8) gfx->ScreenColors [Pixel]; \ + Depth [N] = gfx->Z2; \ + } + + FN(0) + FN(1) + FN(2) + FN(3) +#undef FN +} + +inline void WRITE_4PIXELSHI16 (uint32 Offset, uint8 *Pixels) +{ + uint32 Pixel; + uint16 *Screen = (uint16 *) GFX.S + Offset; + uint8 *Depth = GFX.DB + Offset; + +#define FN(N) \ + if (GFX.Z1 > Depth [N] && (Pixel = Pixels[2*N])) \ + { \ + Screen [N] = GFX.ScreenColors [Pixel]; \ + Depth [N] = GFX.Z2; \ + } + + FN(0) + FN(1) + FN(2) + FN(3) +#undef FN +} + +inline void WRITE_4PIXELSHI16_FLIPPED (uint32 Offset, uint8 *Pixels) +{ + uint32 Pixel; + uint16 *Screen = (uint16 *) GFX.S + Offset; + uint8 *Depth = GFX.DB + Offset; + +#define FN(N) \ + if (GFX.Z1 > Depth [N] && (Pixel = Pixels[6 - 2*N])) \ + { \ + Screen [N] = GFX.ScreenColors [Pixel]; \ + Depth [N] = GFX.Z2; \ + } + + FN(0) + FN(1) + FN(2) + FN(3) +#undef FN +} + +INLINE void WRITE_4PIXELSx2 (uint32 Offset, uint8 *Pixels, struct SGFX * gfx) +{ + register uint8 Pixel; + uint8 *Screen = gfx->S + Offset; + uint8 *Depth = gfx->DB + Offset; + +#define FN(N) \ + if (gfx->Z1 > Depth [0] && (Pixel = Pixels[N])) \ + { \ + Screen [N * 2] = Screen [N * 2 + 1] = (uint8) gfx->ScreenColors [Pixel]; \ + Depth [N * 2] = Depth [N * 2 + 1] = gfx->Z2; \ + } + + FN(0) + FN(1) + FN(2) + FN(3) +#undef FN +} + +INLINE void WRITE_4PIXELS_FLIPPEDx2 (uint32 Offset, uint8 *Pixels, struct SGFX * gfx) +{ + register uint8 Pixel; + uint8 *Screen = gfx->S + Offset; + uint8 *Depth = gfx->DB + Offset; + +#define FN(N) \ + if (gfx->Z1 > Depth [N * 2] && (Pixel = Pixels[3 - N])) \ + { \ + Screen [N * 2] = Screen [N * 2 + 1] = (uint8) gfx->ScreenColors [Pixel]; \ + Depth [N * 2] = Depth [N * 2 + 1] = gfx->Z2; \ + } + + FN(0) + FN(1) + FN(2) + FN(3) +#undef FN +} + +INLINE void WRITE_4PIXELSx2x2 (uint32 Offset, uint8 *Pixels, struct SGFX * gfx) +{ + register uint8 Pixel; + uint8 *Screen = gfx->S + Offset; + uint8 *Depth = gfx->DB + Offset; + +#define FN(N) \ + if (gfx->Z1 > Depth [N * 2] && (Pixel = Pixels[N])) \ + { \ + Screen [N * 2] = Screen [N * 2 + 1] = Screen [gfx->RealPitch + N * 2] = \ + Screen [gfx->RealPitch + N * 2 + 1] = (uint8) gfx->ScreenColors [Pixel]; \ + Depth [N * 2] = Depth [N * 2 + 1] = Depth [gfx->RealPitch + N * 2] = \ + Depth [gfx->RealPitch + N * 2 + 1] = gfx->Z2; \ + } + + FN(0) + FN(1) + FN(2) + FN(3) +#undef FN +} + +INLINE void WRITE_4PIXELS_FLIPPEDx2x2 (uint32 Offset, uint8 *Pixels, struct SGFX * gfx) +{ + register uint8 Pixel; + uint8 *Screen = gfx->S + Offset; + uint8 *Depth = gfx->DB + Offset; + +#define FN(N) \ + if (gfx->Z1 > Depth [N * 2] && (Pixel = Pixels[3 - N])) \ + { \ + Screen [N * 2] = Screen [N * 2 + 1] = Screen [gfx->RealPitch + N * 2] = \ + Screen [gfx->RealPitch + N * 2 + 1] = (uint8) gfx->ScreenColors [Pixel]; \ + Depth [N * 2] = Depth [N * 2 + 1] = Depth [gfx->RealPitch + N * 2] = \ + Depth [gfx->RealPitch + N * 2 + 1] = gfx->Z2; \ + } + + FN(0) + FN(1) + FN(2) + FN(3) +#undef FN +} + +void DrawTile (uint32 Tile, uint32 Offset, uint32 StartLine, + uint32 LineCount, struct SGFX * gfx) +{ + TILE_PREAMBLE + + register uint8 *bp; + + RENDER_TILE(WRITE_4PIXELS, WRITE_4PIXELS_FLIPPED, 4) +} + +void DrawClippedTile (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount, struct SGFX * gfx) +{ + TILE_PREAMBLE + register uint8 *bp; + + TILE_CLIP_PREAMBLE + RENDER_CLIPPED_TILE(WRITE_4PIXELS, WRITE_4PIXELS_FLIPPED, 4) +} + +void DrawTilex2 (uint32 Tile, uint32 Offset, uint32 StartLine, + uint32 LineCount, struct SGFX * gfx) +{ + TILE_PREAMBLE + + register uint8 *bp; + + RENDER_TILE(WRITE_4PIXELSx2, WRITE_4PIXELS_FLIPPEDx2, 8) +} + +void DrawClippedTilex2 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount, struct SGFX * gfx) +{ + TILE_PREAMBLE + register uint8 *bp; + + TILE_CLIP_PREAMBLE + RENDER_CLIPPED_TILE(WRITE_4PIXELSx2, WRITE_4PIXELS_FLIPPEDx2, 8) +} + +void DrawTilex2x2 (uint32 Tile, uint32 Offset, uint32 StartLine, + uint32 LineCount, struct SGFX * gfx) +{ + TILE_PREAMBLE + + register uint8 *bp; + + RENDER_TILE(WRITE_4PIXELSx2x2, WRITE_4PIXELS_FLIPPEDx2x2, 8) +} + +void DrawClippedTilex2x2 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount, struct SGFX * gfx) +{ + TILE_PREAMBLE + register uint8 *bp; + + TILE_CLIP_PREAMBLE + RENDER_CLIPPED_TILE(WRITE_4PIXELSx2x2, WRITE_4PIXELS_FLIPPEDx2x2, 8) +} + +void DrawLargePixel (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Pixels, + uint32 StartLine, uint32 LineCount, struct SGFX * gfx) +{ + TILE_PREAMBLE + + register uint8 *sp = gfx->S + Offset; + uint8 *Depth = gfx->DB + Offset; + uint8 pixel; +#define PLOT_PIXEL(screen, pixel) (pixel) + + RENDER_TILE_LARGE (((uint8) gfx->ScreenColors [pixel]), PLOT_PIXEL) +} + +INLINE void WRITE_4PIXELS16 (uint32 Offset, uint8 *Pixels, struct SGFX * gfx) +{ + register uint32 Pixel; + uint16 *Screen = (uint16 *) gfx->S + Offset; + uint8 *Depth = gfx->DB + Offset; + +#define FN(N) \ + if (gfx->Z1 > Depth [N] && (Pixel = Pixels[N])) \ + { \ + Screen [N] = gfx->ScreenColors [Pixel]; \ + Depth [N] = gfx->Z2; \ + } + + FN(0) + FN(1) + FN(2) + FN(3) +#undef FN +} + +INLINE void WRITE_4PIXELS16_FLIPPED (uint32 Offset, uint8 *Pixels, struct SGFX * gfx) +{ + register uint32 Pixel; + uint16 *Screen = (uint16 *) gfx->S + Offset; + uint8 *Depth = gfx->DB + Offset; + +#define FN(N) \ + if (gfx->Z1 > Depth [N] && (Pixel = Pixels[3 - N])) \ + { \ + Screen [N] = gfx->ScreenColors [Pixel]; \ + Depth [N] = gfx->Z2; \ + } + + FN(0) + FN(1) + FN(2) + FN(3) +#undef FN +} + +INLINE void WRITE_4PIXELS16x2 (uint32 Offset, uint8 *Pixels, struct SGFX * gfx) +{ + register uint32 Pixel; + uint16 *Screen = (uint16 *) gfx->S + Offset; + uint8 *Depth = gfx->DB + Offset; + +#define FN(N) \ + if (gfx->Z1 > Depth [N * 2] && (Pixel = Pixels[N])) \ + { \ + Screen [N * 2] = Screen [N * 2 + 1] = gfx->ScreenColors [Pixel]; \ + Depth [N * 2] = Depth [N * 2 + 1] = gfx->Z2; \ + } + + FN(0) + FN(1) + FN(2) + FN(3) +#undef FN +} + +INLINE void WRITE_4PIXELS16_FLIPPEDx2 (uint32 Offset, uint8 *Pixels, struct SGFX * gfx) +{ + register uint32 Pixel; + uint16 *Screen = (uint16 *) gfx->S + Offset; + uint8 *Depth = gfx->DB + Offset; + +#define FN(N) \ + if (gfx->Z1 > Depth [N * 2] && (Pixel = Pixels[3 - N])) \ + { \ + Screen [N * 2] = Screen [N * 2 + 1] = gfx->ScreenColors [Pixel]; \ + Depth [N * 2] = Depth [N * 2 + 1] = gfx->Z2; \ + } + + FN(0) + FN(1) + FN(2) + FN(3) +#undef FN +} + +INLINE void WRITE_4PIXELS16x2x2 (uint32 Offset, uint8 *Pixels, struct SGFX * gfx) +{ + register uint32 Pixel; + uint16 *Screen = (uint16 *) gfx->S + Offset; + uint8 *Depth = gfx->DB + Offset; + +#define FN(N) \ + if (gfx->Z1 > Depth [N * 2] && (Pixel = Pixels[N])) \ + { \ + Screen [N * 2] = Screen [N * 2 + 1] = Screen [(gfx->RealPitch >> 1) + N * 2] = \ + Screen [(gfx->RealPitch >> 1) + N * 2 + 1] = gfx->ScreenColors [Pixel]; \ + Depth [N * 2] = Depth [N * 2 + 1] = Depth [(gfx->RealPitch >> 1) + N * 2] = \ + Depth [(gfx->RealPitch >> 1) + N * 2 + 1] = gfx->Z2; \ + } + + FN(0) + FN(1) + FN(2) + FN(3) +#undef FN +} + +INLINE void WRITE_4PIXELS16_FLIPPEDx2x2 (uint32 Offset, uint8 *Pixels, struct SGFX * gfx) +{ + register uint32 Pixel; + uint16 *Screen = (uint16 *) gfx->S + Offset; + uint8 *Depth = gfx->DB + Offset; + +#define FN(N) \ + if (gfx->Z1 > Depth [N * 2] && (Pixel = Pixels[3 - N])) \ + { \ + Screen [N * 2] = Screen [N * 2 + 1] = Screen [(gfx->RealPitch >> 1) + N * 2] = \ + Screen [(gfx->RealPitch >> 1) + N * 2 + 1] = gfx->ScreenColors [Pixel]; \ + Depth [N * 2] = Depth [N * 2 + 1] = Depth [(gfx->RealPitch >> 1) + N * 2] = \ + Depth [(gfx->RealPitch >> 1) + N * 2 + 1] = gfx->Z2; \ + } + + FN(0) + FN(1) + FN(2) + FN(3) +#undef FN +} + +void DrawTile16 (uint32 Tile, uint32 Offset, uint32 StartLine, + uint32 LineCount, struct SGFX * gfx) +{ + TILE_PREAMBLE + register uint8 *bp; + + RENDER_TILE(WRITE_4PIXELS16, WRITE_4PIXELS16_FLIPPED, 4) +} + +void DrawClippedTile16 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount, struct SGFX * gfx) +{ + TILE_PREAMBLE + register uint8 *bp; + + TILE_CLIP_PREAMBLE + RENDER_CLIPPED_TILE(WRITE_4PIXELS16, WRITE_4PIXELS16_FLIPPED, 4) +} + +void DrawTile16x2 (uint32 Tile, uint32 Offset, uint32 StartLine, + uint32 LineCount, struct SGFX * gfx) +{ + TILE_PREAMBLE + register uint8 *bp; + + RENDER_TILE(WRITE_4PIXELS16x2, WRITE_4PIXELS16_FLIPPEDx2, 8) +} + +void DrawClippedTile16x2 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount, struct SGFX * gfx) +{ + TILE_PREAMBLE + register uint8 *bp; + + TILE_CLIP_PREAMBLE + RENDER_CLIPPED_TILE(WRITE_4PIXELS16x2, WRITE_4PIXELS16_FLIPPEDx2, 8) +} + +void DrawTile16x2x2 (uint32 Tile, uint32 Offset, uint32 StartLine, + uint32 LineCount, struct SGFX * gfx) +{ + TILE_PREAMBLE + register uint8 *bp; + + RENDER_TILE(WRITE_4PIXELS16x2x2, WRITE_4PIXELS16_FLIPPEDx2x2, 8) +} + +void DrawClippedTile16x2x2 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount, struct SGFX * gfx) +{ + TILE_PREAMBLE + register uint8 *bp; + + TILE_CLIP_PREAMBLE + RENDER_CLIPPED_TILE(WRITE_4PIXELS16x2x2, WRITE_4PIXELS16_FLIPPEDx2x2, 8) +} + +void DrawLargePixel16 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Pixels, + uint32 StartLine, uint32 LineCount, struct SGFX * gfx) +{ + TILE_PREAMBLE + + register uint16 *sp = (uint16 *) gfx->S + Offset; + uint8 *Depth = gfx->DB + Offset; + uint16 pixel; + + RENDER_TILE_LARGE (gfx->ScreenColors [pixel], PLOT_PIXEL) +} + +INLINE void WRITE_4PIXELS16_ADD (uint32 Offset, uint8 *Pixels, struct SGFX * gfx) +{ + register uint32 Pixel; + uint16 *Screen = (uint16 *) gfx->S + Offset; + uint8 *Depth = gfx->ZBuffer + Offset; + uint8 *SubDepth = gfx->SubZBuffer + Offset; + +#define FN(N) \ + if (gfx->Z1 > Depth [N] && (Pixel = Pixels[N])) \ + { \ + if (SubDepth [N]) \ + { \ + if (SubDepth [N] != 1) \ + Screen [N] = COLOR_ADD (gfx->ScreenColors [Pixel], \ + Screen [gfx->Delta + N]); \ + else \ + Screen [N] = COLOR_ADD (gfx->ScreenColors [Pixel], \ + gfx->FixedColour); \ + } \ + else \ + Screen [N] = gfx->ScreenColors [Pixel]; \ + Depth [N] = gfx->Z2; \ + } + + FN(0) + FN(1) + FN(2) + FN(3) + +#undef FN +} + +INLINE void WRITE_4PIXELS16_FLIPPED_ADD (uint32 Offset, uint8 *Pixels, struct SGFX * gfx) +{ + register uint32 Pixel; + uint16 *Screen = (uint16 *) gfx->S + Offset; + uint8 *Depth = gfx->ZBuffer + Offset; + uint8 *SubDepth = gfx->SubZBuffer + Offset; + +#define FN(N) \ + if (gfx->Z1 > Depth [N] && (Pixel = Pixels[3 - N])) \ + { \ + if (SubDepth [N]) \ + { \ + if (SubDepth [N] != 1) \ + Screen [N] = COLOR_ADD (gfx->ScreenColors [Pixel], \ + Screen [gfx->Delta + N]); \ + else \ + Screen [N] = COLOR_ADD (gfx->ScreenColors [Pixel], \ + gfx->FixedColour); \ + } \ + else \ + Screen [N] = gfx->ScreenColors [Pixel]; \ + Depth [N] = gfx->Z2; \ + } + + FN(0) + FN(1) + FN(2) + FN(3) + +#undef FN +} + +INLINE void WRITE_4PIXELS16_ADD1_2 (uint32 Offset, uint8 *Pixels, struct SGFX * gfx) +{ + register uint32 Pixel; + uint16 *Screen = (uint16 *) gfx->S + Offset; + uint8 *Depth = gfx->ZBuffer + Offset; + uint8 *SubDepth = gfx->SubZBuffer + Offset; + +#define FN(N) \ + if (gfx->Z1 > Depth [N] && (Pixel = Pixels[N])) \ + { \ + if (SubDepth [N]) \ + { \ + if (SubDepth [N] != 1) \ + Screen [N] = (uint16) (COLOR_ADD1_2 (gfx->ScreenColors [Pixel], \ + Screen [gfx->Delta + N])); \ + else \ + Screen [N] = COLOR_ADD (gfx->ScreenColors [Pixel], \ + gfx->FixedColour); \ + } \ + else \ + Screen [N] = gfx->ScreenColors [Pixel]; \ + Depth [N] = gfx->Z2; \ + } + + FN(0) + FN(1) + FN(2) + FN(3) + +#undef FN +} + +INLINE void WRITE_4PIXELS16_FLIPPED_ADD1_2 (uint32 Offset, uint8 *Pixels, struct SGFX * gfx) +{ + register uint32 Pixel; + uint16 *Screen = (uint16 *) gfx->S + Offset; + uint8 *Depth = gfx->ZBuffer + Offset; + uint8 *SubDepth = gfx->SubZBuffer + Offset; + +#define FN(N) \ + if (gfx->Z1 > Depth [N] && (Pixel = Pixels[3 - N])) \ + { \ + if (SubDepth [N]) \ + { \ + if (SubDepth [N] != 1) \ + Screen [N] = (uint16) (COLOR_ADD1_2 (gfx->ScreenColors [Pixel], \ + Screen [gfx->Delta + N])); \ + else \ + Screen [N] = COLOR_ADD (gfx->ScreenColors [Pixel], \ + gfx->FixedColour); \ + } \ + else \ + Screen [N] = gfx->ScreenColors [Pixel]; \ + Depth [N] = gfx->Z2; \ + } + + FN(0) + FN(1) + FN(2) + FN(3) + +#undef FN +} + +INLINE void WRITE_4PIXELS16_SUB (uint32 Offset, uint8 *Pixels, struct SGFX * gfx) +{ + register uint32 Pixel; + uint16 *Screen = (uint16 *) gfx->S + Offset; + uint8 *Depth = gfx->ZBuffer + Offset; + uint8 *SubDepth = gfx->SubZBuffer + Offset; + +#define FN(N) \ + if (gfx->Z1 > Depth [N] && (Pixel = Pixels[N])) \ + { \ + if (SubDepth [N]) \ + { \ + if (SubDepth [N] != 1) \ + Screen [N] = (uint16) COLOR_SUB (gfx->ScreenColors [Pixel], \ + Screen [gfx->Delta + N]); \ + else \ + Screen [N] = (uint16) COLOR_SUB (gfx->ScreenColors [Pixel], \ + gfx->FixedColour); \ + } \ + else \ + Screen [N] = gfx->ScreenColors [Pixel]; \ + Depth [N] = gfx->Z2; \ + } + + FN(0) + FN(1) + FN(2) + FN(3) + +#undef FN +} + +INLINE void WRITE_4PIXELS16_FLIPPED_SUB (uint32 Offset, uint8 *Pixels, struct SGFX * gfx) +{ + register uint32 Pixel; + uint16 *Screen = (uint16 *) gfx->S + Offset; + uint8 *Depth = gfx->ZBuffer + Offset; + uint8 *SubDepth = gfx->SubZBuffer + Offset; + +#define FN(N) \ + if (gfx->Z1 > Depth [N] && (Pixel = Pixels[3 - N])) \ + { \ + if (SubDepth [N]) \ + { \ + if (SubDepth [N] != 1) \ + Screen [N] = (uint16) COLOR_SUB (gfx->ScreenColors [Pixel], \ + Screen [gfx->Delta + N]); \ + else \ + Screen [N] = (uint16) COLOR_SUB (gfx->ScreenColors [Pixel], \ + gfx->FixedColour); \ + } \ + else \ + Screen [N] = gfx->ScreenColors [Pixel]; \ + Depth [N] = gfx->Z2; \ + } + + FN(0) + FN(1) + FN(2) + FN(3) + +#undef FN +} + +INLINE void WRITE_4PIXELS16_SUB1_2 (uint32 Offset, uint8 *Pixels, struct SGFX * gfx) +{ + register uint32 Pixel; + uint16 *Screen = (uint16 *) gfx->S + Offset; + uint8 *Depth = gfx->ZBuffer + Offset; + uint8 *SubDepth = gfx->SubZBuffer + Offset; + +#define FN(N) \ + if (gfx->Z1 > Depth [N] && (Pixel = Pixels[N])) \ + { \ + if (SubDepth [N]) \ + { \ + if (SubDepth [N] != 1) \ + Screen [N] = (uint16) COLOR_SUB1_2 (gfx->ScreenColors [Pixel], \ + Screen [gfx->Delta + N]); \ + else \ + Screen [N] = (uint16) COLOR_SUB (gfx->ScreenColors [Pixel], \ + gfx->FixedColour); \ + } \ + else \ + Screen [N] = gfx->ScreenColors [Pixel]; \ + Depth [N] = gfx->Z2; \ + } + + FN(0) + FN(1) + FN(2) + FN(3) + +#undef FN +} + +INLINE void WRITE_4PIXELS16_FLIPPED_SUB1_2 (uint32 Offset, uint8 *Pixels, struct SGFX * gfx) +{ + register uint32 Pixel; + uint16 *Screen = (uint16 *) gfx->S + Offset; + uint8 *Depth = gfx->ZBuffer + Offset; + uint8 *SubDepth = gfx->SubZBuffer + Offset; + +#define FN(N) \ + if (gfx->Z1 > Depth [N] && (Pixel = Pixels[3 - N])) \ + { \ + if (SubDepth [N]) \ + { \ + if (SubDepth [N] != 1) \ + Screen [N] = (uint16) COLOR_SUB1_2 (gfx->ScreenColors [Pixel], \ + Screen [gfx->Delta + N]); \ + else \ + Screen [N] = (uint16) COLOR_SUB (gfx->ScreenColors [Pixel], \ + gfx->FixedColour); \ + } \ + else \ + Screen [N] = gfx->ScreenColors [Pixel]; \ + Depth [N] = gfx->Z2; \ + } + + FN(0) + FN(1) + FN(2) + FN(3) + +#undef FN +} + + +void DrawTile16Add (uint32 Tile, uint32 Offset, uint32 StartLine, + uint32 LineCount, struct SGFX * gfx) +{ + TILE_PREAMBLE + register uint8 *bp; + + RENDER_TILE(WRITE_4PIXELS16_ADD, WRITE_4PIXELS16_FLIPPED_ADD, 4) +} + +void DrawClippedTile16Add (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount, struct SGFX * gfx) +{ + TILE_PREAMBLE + register uint8 *bp; + + TILE_CLIP_PREAMBLE + RENDER_CLIPPED_TILE(WRITE_4PIXELS16_ADD, WRITE_4PIXELS16_FLIPPED_ADD, 4) +} + +void DrawTile16Add1_2 (uint32 Tile, uint32 Offset, uint32 StartLine, + uint32 LineCount, struct SGFX * gfx) +{ + TILE_PREAMBLE + register uint8 *bp; + + RENDER_TILE(WRITE_4PIXELS16_ADD1_2, WRITE_4PIXELS16_FLIPPED_ADD1_2, 4) +} + +void DrawClippedTile16Add1_2 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount, struct SGFX * gfx) +{ + TILE_PREAMBLE + register uint8 *bp; + + TILE_CLIP_PREAMBLE + RENDER_CLIPPED_TILE(WRITE_4PIXELS16_ADD1_2, WRITE_4PIXELS16_FLIPPED_ADD1_2, 4) +} + +void DrawTile16Sub (uint32 Tile, uint32 Offset, uint32 StartLine, + uint32 LineCount, struct SGFX * gfx) +{ + TILE_PREAMBLE + register uint8 *bp; + + RENDER_TILE(WRITE_4PIXELS16_SUB, WRITE_4PIXELS16_FLIPPED_SUB, 4) +} + +void DrawClippedTile16Sub (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount, struct SGFX * gfx) +{ + TILE_PREAMBLE + register uint8 *bp; + + TILE_CLIP_PREAMBLE + RENDER_CLIPPED_TILE(WRITE_4PIXELS16_SUB, WRITE_4PIXELS16_FLIPPED_SUB, 4) +} + +void DrawTile16Sub1_2 (uint32 Tile, uint32 Offset, uint32 StartLine, + uint32 LineCount, struct SGFX * gfx) +{ + TILE_PREAMBLE + register uint8 *bp; + + RENDER_TILE(WRITE_4PIXELS16_SUB1_2, WRITE_4PIXELS16_FLIPPED_SUB1_2, 4) +} + +void DrawClippedTile16Sub1_2 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount, struct SGFX * gfx) +{ + TILE_PREAMBLE + register uint8 *bp; + + TILE_CLIP_PREAMBLE + RENDER_CLIPPED_TILE(WRITE_4PIXELS16_SUB1_2, WRITE_4PIXELS16_FLIPPED_SUB1_2, 4) +} + +INLINE void WRITE_4PIXELS16_ADDF1_2 (uint32 Offset, uint8 *Pixels, struct SGFX * gfx) +{ + register uint32 Pixel; + uint16 *Screen = (uint16 *) gfx->S + Offset; + uint8 *Depth = gfx->ZBuffer + Offset; + uint8 *SubDepth = gfx->SubZBuffer + Offset; + +#define FN(N) \ + if (gfx->Z1 > Depth [N] && (Pixel = Pixels[N])) \ + { \ + if (SubDepth [N] == 1) \ + Screen [N] = (uint16) (COLOR_ADD1_2 (gfx->ScreenColors [Pixel], \ + gfx->FixedColour)); \ + else \ + Screen [N] = gfx->ScreenColors [Pixel];\ + Depth [N] = gfx->Z2; \ + } + + FN(0) + FN(1) + FN(2) + FN(3) + +#undef FN +} + +INLINE void WRITE_4PIXELS16_FLIPPED_ADDF1_2 (uint32 Offset, uint8 *Pixels, struct SGFX * gfx) +{ + register uint32 Pixel; + uint16 *Screen = (uint16 *) gfx->S + Offset; + uint8 *Depth = gfx->ZBuffer + Offset; + uint8 *SubDepth = gfx->SubZBuffer + Offset; + +#define FN(N) \ + if (gfx->Z1 > Depth [N] && (Pixel = Pixels[3 - N])) \ + { \ + if (SubDepth [N] == 1) \ + Screen [N] = (uint16) (COLOR_ADD1_2 (gfx->ScreenColors [Pixel], \ + gfx->FixedColour)); \ + else \ + Screen [N] = gfx->ScreenColors [Pixel];\ + Depth [N] = gfx->Z2; \ + } + + FN(0) + FN(1) + FN(2) + FN(3) + +#undef FN +} + +INLINE void WRITE_4PIXELS16_SUBF1_2 (uint32 Offset, uint8 *Pixels, struct SGFX * gfx) +{ + register uint32 Pixel; + uint16 *Screen = (uint16 *) gfx->S + Offset; + uint8 *Depth = gfx->ZBuffer + Offset; + uint8 *SubDepth = gfx->SubZBuffer + Offset; + +#define FN(N) \ + if (gfx->Z1 > Depth [N] && (Pixel = Pixels[N])) \ + { \ + if (SubDepth [N] == 1) \ + Screen [N] = (uint16) COLOR_SUB1_2 (gfx->ScreenColors [Pixel], \ + gfx->FixedColour); \ + else \ + Screen [N] = gfx->ScreenColors [Pixel]; \ + Depth [N] = gfx->Z2; \ + } + + FN(0) + FN(1) + FN(2) + FN(3) + +#undef FN +} + +INLINE void WRITE_4PIXELS16_FLIPPED_SUBF1_2 (uint32 Offset, uint8 *Pixels, struct SGFX * gfx) +{ + register uint32 Pixel; + uint16 *Screen = (uint16 *) gfx->S + Offset; + uint8 *Depth = gfx->ZBuffer + Offset; + uint8 *SubDepth = gfx->SubZBuffer + Offset; + +#define FN(N) \ + if (gfx->Z1 > Depth [N] && (Pixel = Pixels[3 - N])) \ + { \ + if (SubDepth [N] == 1) \ + Screen [N] = (uint16) COLOR_SUB1_2 (gfx->ScreenColors [Pixel], \ + gfx->FixedColour); \ + else \ + Screen [N] = gfx->ScreenColors [Pixel]; \ + Depth [N] = gfx->Z2; \ + } + + FN(0) + FN(1) + FN(2) + FN(3) + +#undef FN +} + +void DrawTile16FixedAdd1_2 (uint32 Tile, uint32 Offset, uint32 StartLine, + uint32 LineCount, struct SGFX * gfx) +{ + TILE_PREAMBLE + register uint8 *bp; + + RENDER_TILE(WRITE_4PIXELS16_ADDF1_2, WRITE_4PIXELS16_FLIPPED_ADDF1_2, 4) +} + +void DrawClippedTile16FixedAdd1_2 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount, struct SGFX * gfx) +{ + TILE_PREAMBLE + register uint8 *bp; + + TILE_CLIP_PREAMBLE + RENDER_CLIPPED_TILE(WRITE_4PIXELS16_ADDF1_2, + WRITE_4PIXELS16_FLIPPED_ADDF1_2, 4) +} + +void DrawTile16FixedSub1_2 (uint32 Tile, uint32 Offset, uint32 StartLine, + uint32 LineCount, struct SGFX * gfx) +{ + TILE_PREAMBLE + register uint8 *bp; + + RENDER_TILE(WRITE_4PIXELS16_SUBF1_2, WRITE_4PIXELS16_FLIPPED_SUBF1_2, 4) +} + +void DrawClippedTile16FixedSub1_2 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount, struct SGFX * gfx) +{ + TILE_PREAMBLE + register uint8 *bp; + + TILE_CLIP_PREAMBLE + RENDER_CLIPPED_TILE(WRITE_4PIXELS16_SUBF1_2, + WRITE_4PIXELS16_FLIPPED_SUBF1_2, 4) +} + +void DrawLargePixel16Add (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Pixels, + uint32 StartLine, uint32 LineCount, struct SGFX * gfx) +{ + TILE_PREAMBLE + + register uint16 *sp = (uint16 *) gfx->S + Offset; + uint8 *Depth = gfx->ZBuffer + Offset; + register uint16 pixel; + +#define LARGE_ADD_PIXEL(s, p) \ +(Depth [z + gfx->DepthDelta] ? (Depth [z + gfx->DepthDelta] != 1 ? \ + COLOR_ADD (p, *(s + gfx->Delta)) : \ + COLOR_ADD (p, gfx->FixedColour)) \ + : p) + + RENDER_TILE_LARGE (gfx->ScreenColors [pixel], LARGE_ADD_PIXEL) +} + +void DrawLargePixel16Add1_2 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Pixels, + uint32 StartLine, uint32 LineCount, struct SGFX * gfx) +{ + TILE_PREAMBLE + + register uint16 *sp = (uint16 *) gfx->S + Offset; + uint8 *Depth = gfx->ZBuffer + Offset; + register uint16 pixel; + +#define LARGE_ADD_PIXEL1_2(s, p) \ +((uint16) (Depth [z + gfx->DepthDelta] ? (Depth [z + gfx->DepthDelta] != 1 ? \ + COLOR_ADD1_2 (p, *(s + gfx->Delta)) : \ + COLOR_ADD (p, gfx->FixedColour)) \ + : p)) + + RENDER_TILE_LARGE (gfx->ScreenColors [pixel], LARGE_ADD_PIXEL1_2) +} + +void DrawLargePixel16Sub (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Pixels, + uint32 StartLine, uint32 LineCount, struct SGFX * gfx) +{ + TILE_PREAMBLE + + register uint16 *sp = (uint16 *) gfx->S + Offset; + uint8 *Depth = gfx->ZBuffer + Offset; + register uint16 pixel; + +#define LARGE_SUB_PIXEL(s, p) \ +(Depth [z + gfx->DepthDelta] ? (Depth [z + gfx->DepthDelta] != 1 ? \ + COLOR_SUB (p, *(s + gfx->Delta)) : \ + COLOR_SUB (p, gfx->FixedColour)) \ + : p) + + RENDER_TILE_LARGE (gfx->ScreenColors [pixel], LARGE_SUB_PIXEL) +} + +void DrawLargePixel16Sub1_2 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Pixels, + uint32 StartLine, uint32 LineCount, struct SGFX * gfx) +{ + TILE_PREAMBLE + + register uint16 *sp = (uint16 *) gfx->S + Offset; + uint8 *Depth = gfx->ZBuffer + Offset; + uint16 pixel; + +#define LARGE_SUB_PIXEL1_2(s, p) \ +(Depth [z + gfx->DepthDelta] ? (Depth [z + gfx->DepthDelta] != 1 ? \ + COLOR_SUB1_2 (p, *(s + gfx->Delta)) : \ + COLOR_SUB (p, gfx->FixedColour)) \ + : p) + + RENDER_TILE_LARGE (gfx->ScreenColors [pixel], LARGE_SUB_PIXEL1_2) +} + +void DrawHiResTile16 (uint32 Tile, uint32 Offset, uint32 StartLine, + uint32 LineCount, struct SGFX * gfx) +{ + TILE_PREAMBLE + register uint8 *bp; + + RENDER_TILEHI(WRITE_4PIXELSHI16, WRITE_4PIXELSHI16_FLIPPED, 4) +} + +void DrawHiResClippedTile16 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount, struct SGFX * gfx) +{ + TILE_PREAMBLE + register uint8 *bp; + + TILE_CLIP_PREAMBLE + RENDER_CLIPPED_TILEHI(WRITE_4PIXELSHI16, WRITE_4PIXELSHI16_FLIPPED, 4) +} diff --git a/src/snes4iphone_src/tile.h b/src/snes4iphone_src/tile.h new file mode 100755 index 0000000..3a4e544 --- /dev/null +++ b/src/snes4iphone_src/tile.h @@ -0,0 +1,356 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#ifndef _TILE_H_ +#define _TILE_H_ + +#define TILE_PREAMBLE \ + uint8 *pCache; \ +\ + uint32 TileAddr = BG.TileAddress + ((Tile & 0x3ff) << BG.TileShift); \ + if ((Tile & 0x1ff) >= 256) \ + TileAddr += BG.NameSelect; \ +\ + TileAddr &= 0xffff; \ +\ + uint32 TileNumber; \ + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) << 6]; \ +\ + if (!BG.Buffered [TileNumber]) \ + BG.Buffered[TileNumber] = ConvertTile (pCache, TileAddr); \ +\ + if (BG.Buffered [TileNumber] == BLANK_TILE) \ + return; \ +\ + register uint32 l; \ + if (BG.DirectColourMode) \ + { \ + if (IPPU.DirectColourMapsNeedRebuild) \ + S9xBuildDirectColourMaps (); \ + gfx->ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; \ + } \ + else \ + gfx->ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + +#define RENDER_TILE(NORMAL, FLIPPED, N) \ + if (!(Tile & (V_FLIP | H_FLIP))) \ + { \ + bp = pCache + StartLine; \ + for (l = LineCount; l != 0; l--, bp += 8, Offset += gfx->PPL) \ + { \ + if (*(uint32 *) bp) \ + NORMAL (Offset, bp, gfx); \ + if (*(uint32 *) (bp + 4)) \ + NORMAL (Offset + N, bp + 4, gfx); \ + } \ + } \ + else \ + if (!(Tile & V_FLIP)) \ + { \ + bp = pCache + StartLine; \ + for (l = LineCount; l != 0; l--, bp += 8, Offset += gfx->PPL) \ + { \ + if (*(uint32 *) (bp + 4)) \ + FLIPPED (Offset, bp + 4, gfx); \ + if (*(uint32 *) bp) \ + FLIPPED (Offset + N, bp, gfx); \ + } \ + } \ + else \ + if (Tile & H_FLIP) \ + { \ + bp = pCache + 56 - StartLine; \ + for (l = LineCount; l != 0; l--, bp -= 8, Offset += gfx->PPL) \ + { \ + if (*(uint32 *) (bp + 4)) \ + FLIPPED (Offset, bp + 4, gfx); \ + if (*(uint32 *) bp) \ + FLIPPED (Offset + N, bp, gfx); \ + } \ + } \ + else \ + { \ + bp = pCache + 56 - StartLine; \ + for (l = LineCount; l != 0; l--, bp -= 8, Offset += gfx->PPL) \ + { \ + if (*(uint32 *) bp) \ + NORMAL (Offset, bp, gfx); \ + if (*(uint32 *) (bp + 4)) \ + NORMAL (Offset + N, bp + 4, gfx); \ + } \ + } + +#define TILE_CLIP_PREAMBLE \ + uint32 dd; \ + uint32 d1; \ + uint32 d2; \ +\ + if (StartPixel < 4) \ + { \ + d1 = HeadMask [StartPixel]; \ + if (StartPixel + Width < 4) \ + d1 &= TailMask [StartPixel + Width]; \ + } \ + else \ + d1 = 0; \ +\ + if (StartPixel + Width > 4) \ + { \ + if (StartPixel > 4) \ + d2 = HeadMask [StartPixel - 4]; \ + else \ + d2 = 0xffffffff; \ +\ + d2 &= TailMask [(StartPixel + Width - 4)]; \ + } \ + else \ + d2 = 0; + + +#define RENDER_CLIPPED_TILE(NORMAL, FLIPPED, N) \ + if (!(Tile & (V_FLIP | H_FLIP))) \ + { \ + bp = pCache + StartLine; \ + for (l = LineCount; l != 0; l--, bp += 8, Offset += gfx->PPL) \ + { \ + if ((dd = (*(uint32 *) bp) & d1)) \ + NORMAL (Offset, (uint8 *) &dd, gfx); \ + if ((dd = (*(uint32 *) (bp + 4)) & d2)) \ + NORMAL (Offset + N, (uint8 *) &dd, gfx); \ + } \ + } \ + else \ + if (!(Tile & V_FLIP)) \ + { \ + bp = pCache + StartLine; \ + SWAP_DWORD (d1); \ + SWAP_DWORD (d2); \ + for (l = LineCount; l != 0; l--, bp += 8, Offset += gfx->PPL) \ + { \ + if ((dd = *(uint32 *) (bp + 4) & d1)) \ + FLIPPED (Offset, (uint8 *) &dd, gfx); \ + if ((dd = *(uint32 *) bp & d2)) \ + FLIPPED (Offset + N, (uint8 *) &dd, gfx); \ + } \ + } \ + else \ + if (Tile & H_FLIP) \ + { \ + bp = pCache + 56 - StartLine; \ + SWAP_DWORD (d1); \ + SWAP_DWORD (d2); \ + for (l = LineCount; l != 0; l--, bp -= 8, Offset += gfx->PPL) \ + { \ + if ((dd = *(uint32 *) (bp + 4) & d1)) \ + FLIPPED (Offset, (uint8 *) &dd, gfx); \ + if ((dd = *(uint32 *) bp & d2)) \ + FLIPPED (Offset + N, (uint8 *) &dd, gfx); \ + } \ + } \ + else \ + { \ + bp = pCache + 56 - StartLine; \ + for (l = LineCount; l != 0; l--, bp -= 8, Offset += gfx->PPL) \ + { \ + if ((dd = (*(uint32 *) bp) & d1)) \ + NORMAL (Offset, (uint8 *) &dd, gfx); \ + if ((dd = (*(uint32 *) (bp + 4)) & d2)) \ + NORMAL (Offset + N, (uint8 *) &dd, gfx); \ + } \ + } + +#define RENDER_TILE_LARGE(PIXEL, FUNCTION) \ + if (!(Tile & (V_FLIP | H_FLIP))) \ + { \ + if ((pixel = *(pCache + StartLine + StartPixel))) \ + { \ + pixel = PIXEL; \ + for (l = LineCount; l != 0; l--, sp += gfx->PPL, Depth += gfx->PPL) \ + { \ + for (int z = Pixels - 1; z >= 0; z--) \ + if (gfx->Z1 > Depth [z]) \ + { \ + sp [z] = FUNCTION(sp + z, pixel); \ + Depth [z] = gfx->Z2; \ + }\ + } \ + } \ + } \ + else \ + if (!(Tile & V_FLIP)) \ + { \ + StartPixel = 7 - StartPixel; \ + if ((pixel = *(pCache + StartLine + StartPixel))) \ + { \ + pixel = PIXEL; \ + for (l = LineCount; l != 0; l--, sp += gfx->PPL, Depth += gfx->PPL) \ + { \ + for (int z = Pixels - 1; z >= 0; z--) \ + if (gfx->Z1 > Depth [z]) \ + { \ + sp [z] = FUNCTION(sp + z, pixel); \ + Depth [z] = gfx->Z2; \ + }\ + } \ + } \ + } \ + else \ + if (Tile & H_FLIP) \ + { \ + StartPixel = 7 - StartPixel; \ + if ((pixel = *(pCache + 56 - StartLine + StartPixel))) \ + { \ + pixel = PIXEL; \ + for (l = LineCount; l != 0; l--, sp += gfx->PPL, Depth += gfx->PPL) \ + { \ + for (int z = Pixels - 1; z >= 0; z--) \ + if (gfx->Z1 > Depth [z]) \ + { \ + sp [z] = FUNCTION(sp + z, pixel); \ + Depth [z] = gfx->Z2; \ + }\ + } \ + } \ + } \ + else \ + { \ + if ((pixel = *(pCache + 56 - StartLine + StartPixel))) \ + { \ + pixel = PIXEL; \ + for (l = LineCount; l != 0; l--, sp += gfx->PPL, Depth += gfx->PPL) \ + { \ + for (int z = Pixels - 1; z >= 0; z--) \ + if (gfx->Z1 > Depth [z]) \ + { \ + sp [z] = FUNCTION(sp + z, pixel); \ + Depth [z] = gfx->Z2; \ + }\ + } \ + } \ + } + +#define RENDER_TILEHI(NORMAL, FLIPPED, N) \ + if (!(Tile & (V_FLIP | H_FLIP))) \ + { \ + bp = pCache + StartLine; \ + for (l = LineCount; l != 0; l--, bp += 8, Offset += gfx->PPL) \ + { \ + /*if (*(uint32 *) bp)*/if (((uint32)bp[0])|((uint32)bp[2])|((uint32)bp[4])|((uint32)bp[6])) \ + NORMAL (Offset, bp); \ + } \ + } \ + else \ + if (!(Tile & V_FLIP)) \ + { \ + bp = pCache + StartLine; \ + for (l = LineCount; l != 0; l--, bp += 8, Offset += gfx->PPL) \ + { \ + /*if (*(uint32 *) (bp + 4))*/if (((uint32)bp[0])|((uint32)bp[2])|((uint32)bp[4])|((uint32)bp[6])) \ + FLIPPED (Offset, bp); \ + } \ + } \ + else \ + if (Tile & H_FLIP) \ + { \ + bp = pCache + 56 - StartLine; \ + for (l = LineCount; l != 0; l--, bp -= 8, Offset += gfx->PPL) \ + { \ + /*if (*(uint32 *) (bp + 4))*/if (((uint32)bp[0])|((uint32)bp[2])|((uint32)bp[4])|((uint32)bp[6])) \ + FLIPPED (Offset, bp); \ + } \ + } \ + else \ + { \ + bp = pCache + 56 - StartLine; \ + for (l = LineCount; l != 0; l--, bp -= 8, Offset += gfx->PPL) \ + { \ + /*if (*(uint32 *) bp)*/if (((uint32)bp[0])|((uint32)bp[2])|((uint32)bp[4])|((uint32)bp[6])) \ + NORMAL (Offset, bp); \ + } \ + } + + + +#define RENDER_CLIPPED_TILEHI(NORMAL, FLIPPED, N) \ + d1=(d1&0xFF)|((d1&0xFF0000)>>8)|((d2&0xFF)<<16)|((d2&0xFF0000)<<8);\ + if (!(Tile & (V_FLIP | H_FLIP))) \ + { \ + bp = pCache + StartLine; \ + for (l = LineCount; l != 0; l--, bp += 8, Offset += gfx->PPL) \ + { \ + /*if ((dd = (*(uint32 *) bp) & d1))*/if (dd = (((((uint32)bp[6])<<24)|(((uint32)bp[4])<<16)|(((uint32)bp[2])<<8)|((uint32)bp[0]))&d1)) \ + NORMAL (Offset, (uint8 *) &dd); \ + } \ + } \ + else \ + if (!(Tile & V_FLIP)) \ + { \ + bp = pCache + StartLine; \ + SWAP_DWORD (d1); \ + /*SWAP_DWORD (d2);*/ \ + for (l = LineCount; l != 0; l--, bp += 8, Offset += gfx->PPL) \ + { \ + /*if ((dd = *(uint32 *) (bp + 4) & d1))*/if (dd = (((((uint32)bp[6])<<24)|(((uint32)bp[4])<<16)|(((uint32)bp[2])<<8)|((uint32)bp[0]))&d1)) \ + FLIPPED (Offset, (uint8 *) &dd); \ + } \ + } \ + else \ + if (Tile & H_FLIP) \ + { \ + bp = pCache + 56 - StartLine; \ + SWAP_DWORD (d1); \ + /*SWAP_DWORD (d2);*/ \ + for (l = LineCount; l != 0; l--, bp -= 8, Offset += gfx->PPL) \ + { \ + /*if ((dd = *(uint32 *) (bp + 4) & d1))*/if (dd = (((((uint32)bp[6])<<24)|(((uint32)bp[4])<<16)|(((uint32)bp[2])<<8)|((uint32)bp[0]))&d1)) \ + FLIPPED (Offset, (uint8 *) &dd); \ + } \ + } \ + else \ + { \ + bp = pCache + 56 - StartLine; \ + for (l = LineCount; l != 0; l--, bp -= 8, Offset += gfx->PPL) \ + { \ + /*if ((dd = (*(uint32 *) bp) & d1))*/ if (dd = (((((uint32)bp[6])<<24)|(((uint32)bp[4])<<16)|(((uint32)bp[2])<<8)|((uint32)bp[0]))&d1)) \ + NORMAL (Offset, (uint8 *) &dd); \ + } \ + } + +#endif diff --git a/src/snes4iphone_src/tile_org.cpp b/src/snes4iphone_src/tile_org.cpp new file mode 100755 index 0000000..b7d4371 --- /dev/null +++ b/src/snes4iphone_src/tile_org.cpp @@ -0,0 +1,996 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#include "snes9x.h" + +#include "memmap.h" +#include "ppu.h" +#include "cpuexec.h" +#include "display.h" +#include "gfx.h" +#include "apu.h" +#include "tile_org.h" + + +extern uint32 HeadMask [4]; +extern uint32 TailMask [5]; + +uint8 orgConvertTile (uint8 *pCache, uint32 TileAddr) +{ + register uint8 *tp = &Memory.VRAM[TileAddr]; + uint32 *p = (uint32 *) pCache; + uint32 non_zero = 0; + uint8 line; + + switch (BG.BitShift) + { + case 8: + for (line = 8; line != 0; line--, tp += 2) + { + uint32 p1 = 0; + uint32 p2 = 0; + register uint8 pix; + + if ((pix = *(tp + 0))) + { + p1 |= odd_high[0][pix >> 4]; + p2 |= odd_low[0][pix & 0xf]; + } + if ((pix = *(tp + 1))) + { + p1 |= even_high[0][pix >> 4]; + p2 |= even_low[0][pix & 0xf]; + } + if ((pix = *(tp + 16))) + { + p1 |= odd_high[1][pix >> 4]; + p2 |= odd_low[1][pix & 0xf]; + } + if ((pix = *(tp + 17))) + { + p1 |= even_high[1][pix >> 4]; + p2 |= even_low[1][pix & 0xf]; + } + if ((pix = *(tp + 32))) + { + p1 |= odd_high[2][pix >> 4]; + p2 |= odd_low[2][pix & 0xf]; + } + if ((pix = *(tp + 33))) + { + p1 |= even_high[2][pix >> 4]; + p2 |= even_low[2][pix & 0xf]; + } + if ((pix = *(tp + 48))) + { + p1 |= odd_high[3][pix >> 4]; + p2 |= odd_low[3][pix & 0xf]; + } + if ((pix = *(tp + 49))) + { + p1 |= even_high[3][pix >> 4]; + p2 |= even_low[3][pix & 0xf]; + } + *p++ = p1; + *p++ = p2; + non_zero |= p1 | p2; + } + break; + + case 4: + for (line = 8; line != 0; line--, tp += 2) + { + uint32 p1 = 0; + uint32 p2 = 0; + register uint8 pix; + if ((pix = *(tp + 0))) + { + p1 |= odd_high[0][pix >> 4]; + p2 |= odd_low[0][pix & 0xf]; + } + if ((pix = *(tp + 1))) + { + p1 |= even_high[0][pix >> 4]; + p2 |= even_low[0][pix & 0xf]; + } + if ((pix = *(tp + 16))) + { + p1 |= odd_high[1][pix >> 4]; + p2 |= odd_low[1][pix & 0xf]; + } + if ((pix = *(tp + 17))) + { + p1 |= even_high[1][pix >> 4]; + p2 |= even_low[1][pix & 0xf]; + } + *p++ = p1; + *p++ = p2; + non_zero |= p1 | p2; + } + break; + + case 2: + for (line = 8; line != 0; line--, tp += 2) + { + uint32 p1 = 0; + uint32 p2 = 0; + register uint8 pix; + if ((pix = *(tp + 0))) + { + p1 |= odd_high[0][pix >> 4]; + p2 |= odd_low[0][pix & 0xf]; + } + if ((pix = *(tp + 1))) + { + p1 |= even_high[0][pix >> 4]; + p2 |= even_low[0][pix & 0xf]; + } + *p++ = p1; + *p++ = p2; + non_zero |= p1 | p2; + } + break; + } + return (non_zero ? TRUE : BLANK_TILE); +} + + + +#define PLOT_PIXEL(screen, pixel) (pixel) + +inline void WRITE_4PIXELS16 (uint32 Offset, uint8 *Pixels) +{ + uint32 Pixel; + uint16 *Screen = (uint16 *) GFX.S + Offset; + uint8 *Depth = GFX.DB + Offset; + +#define FN(N) \ + if (GFX.Z1 > Depth [N] && (Pixel = Pixels[N])) \ + { \ + Screen [N] = GFX.ScreenColors [Pixel]; \ + Depth [N] = GFX.Z2; \ + } + + FN(0) + FN(1) + FN(2) + FN(3) +#undef FN +} + +inline void WRITE_4PIXELS16_FLIPPED (uint32 Offset, uint8 *Pixels) +{ + uint32 Pixel; + uint16 *Screen = (uint16 *) GFX.S + Offset; + uint8 *Depth = GFX.DB + Offset; + +#define FN(N) \ + if (GFX.Z1 > Depth [N] && (Pixel = Pixels[3 - N])) \ + { \ + Screen [N] = GFX.ScreenColors [Pixel]; \ + Depth [N] = GFX.Z2; \ + } + + FN(0) + FN(1) + FN(2) + FN(3) +#undef FN +} + + +inline void WRITE_4PIXELSHI16 (uint32 Offset, uint8 *Pixels) +{ + uint32 Pixel; + uint16 *Screen = (uint16 *) GFX.S + Offset; + uint8 *Depth = GFX.DB + Offset; + +#define FN(N) \ + if (GFX.Z1 > Depth [N] && (Pixel = Pixels[2*N])) \ + { \ + Screen [N] = GFX.ScreenColors [Pixel]; \ + Depth [N] = GFX.Z2; \ + } + + FN(0) + FN(1) + FN(2) + FN(3) +#undef FN +} + +inline void WRITE_4PIXELSHI16_FLIPPED (uint32 Offset, uint8 *Pixels) +{ + uint32 Pixel; + uint16 *Screen = (uint16 *) GFX.S + Offset; + uint8 *Depth = GFX.DB + Offset; + +#define FN(N) \ + if (GFX.Z1 > Depth [N] && (Pixel = Pixels[6 - 2*N])) \ + { \ + Screen [N] = GFX.ScreenColors [Pixel]; \ + Depth [N] = GFX.Z2; \ + } + + FN(0) + FN(1) + FN(2) + FN(3) +#undef FN +} + + +inline void WRITE_4PIXELS16x2 (uint32 Offset, uint8 *Pixels) +{ + uint32 Pixel; + uint16 *Screen = (uint16 *) GFX.S + Offset; + uint8 *Depth = GFX.DB + Offset; + +#define FN(N) \ + if (GFX.Z1 > Depth [N * 2] && (Pixel = Pixels[N])) \ + { \ + Screen [N * 2] = Screen [N * 2 + 1] = GFX.ScreenColors [Pixel]; \ + Depth [N * 2] = Depth [N * 2 + 1] = GFX.Z2; \ + } + + FN(0) + FN(1) + FN(2) + FN(3) +#undef FN +} + +inline void WRITE_4PIXELS16_FLIPPEDx2 (uint32 Offset, uint8 *Pixels) +{ + uint32 Pixel; + uint16 *Screen = (uint16 *) GFX.S + Offset; + uint8 *Depth = GFX.DB + Offset; + +#define FN(N) \ + if (GFX.Z1 > Depth [N * 2] && (Pixel = Pixels[3 - N])) \ + { \ + Screen [N * 2] = Screen [N * 2 + 1] = GFX.ScreenColors [Pixel]; \ + Depth [N * 2] = Depth [N * 2 + 1] = GFX.Z2; \ + } + + FN(0) + FN(1) + FN(2) + FN(3) +#undef FN +} + +inline void WRITE_4PIXELS16x2x2 (uint32 Offset, uint8 *Pixels) +{ + uint32 Pixel; + uint16 *Screen = (uint16 *) GFX.S + Offset; + uint8 *Depth = GFX.DB + Offset; + +#define FN(N) \ + if (GFX.Z1 > Depth [N * 2] && (Pixel = Pixels[N])) \ + { \ + Screen [N * 2] = Screen [N * 2 + 1] = Screen [(GFX.RealPitch >> 1) + N * 2] = \ + Screen [(GFX.RealPitch >> 1) + N * 2 + 1] = GFX.ScreenColors [Pixel]; \ + Depth [N * 2] = Depth [N * 2 + 1] = Depth [(GFX.RealPitch >> 1) + N * 2] = \ + Depth [(GFX.RealPitch >> 1) + N * 2 + 1] = GFX.Z2; \ + } + + FN(0) + FN(1) + FN(2) + FN(3) +#undef FN +} + +inline void WRITE_4PIXELS16_FLIPPEDx2x2 (uint32 Offset, uint8 *Pixels) +{ + uint32 Pixel; + uint16 *Screen = (uint16 *) GFX.S + Offset; + uint8 *Depth = GFX.DB + Offset; + +#define FN(N) \ + if (GFX.Z1 > Depth [N * 2] && (Pixel = Pixels[3 - N])) \ + { \ + Screen [N * 2] = Screen [N * 2 + 1] = Screen [(GFX.RealPitch >> 1) + N * 2] = \ + Screen [(GFX.RealPitch >> 1) + N * 2 + 1] = GFX.ScreenColors [Pixel]; \ + Depth [N * 2] = Depth [N * 2 + 1] = Depth [(GFX.RealPitch >> 1) + N * 2] = \ + Depth [(GFX.RealPitch >> 1) + N * 2 + 1] = GFX.Z2; \ + } + + FN(0) + FN(1) + FN(2) + FN(3) +#undef FN +} + +void orgDrawTile16 (uint32 Tile, uint32 Offset, uint32 StartLine, + uint32 LineCount) +{ + TILE_PREAMBLE + register uint8 *bp; + + RENDER_TILE(WRITE_4PIXELS16, WRITE_4PIXELS16_FLIPPED, 4) +} + +void orgDrawClippedTile16 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount) +{ + TILE_PREAMBLE + register uint8 *bp; + + TILE_CLIP_PREAMBLE + RENDER_CLIPPED_TILE(WRITE_4PIXELS16, WRITE_4PIXELS16_FLIPPED, 4) +} + +void orgDrawTileHi16 (uint32 Tile, uint32 Offset, uint32 StartLine, + uint32 LineCount) +{ + TILE_PREAMBLE + register uint8 *bp; + + RENDER_TILEHI(WRITE_4PIXELSHI16, WRITE_4PIXELSHI16_FLIPPED, 4) +} + +void orgDrawClippedTileHi16 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount) +{ + TILE_PREAMBLE + register uint8 *bp; + + TILE_CLIP_PREAMBLE + RENDER_CLIPPED_TILEHI(WRITE_4PIXELSHI16, WRITE_4PIXELSHI16_FLIPPED, 4) +} + + +void orgDrawTile16x2 (uint32 Tile, uint32 Offset, uint32 StartLine, + uint32 LineCount) +{ + TILE_PREAMBLE + register uint8 *bp; + + RENDER_TILE(WRITE_4PIXELS16x2, WRITE_4PIXELS16_FLIPPEDx2, 8) +} + +void orgDrawClippedTile16x2 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount) +{ + TILE_PREAMBLE + register uint8 *bp; + + TILE_CLIP_PREAMBLE + RENDER_CLIPPED_TILE(WRITE_4PIXELS16x2, WRITE_4PIXELS16_FLIPPEDx2, 8) +} + +void orgDrawTile16x2x2 (uint32 Tile, uint32 Offset, uint32 StartLine, + uint32 LineCount) +{ + TILE_PREAMBLE + register uint8 *bp; + + RENDER_TILE(WRITE_4PIXELS16x2x2, WRITE_4PIXELS16_FLIPPEDx2x2, 8) +} + +void orgDrawClippedTile16x2x2 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount) +{ + TILE_PREAMBLE + register uint8 *bp; + + TILE_CLIP_PREAMBLE + RENDER_CLIPPED_TILE(WRITE_4PIXELS16x2x2, WRITE_4PIXELS16_FLIPPEDx2x2, 8) +} + +void orgDrawLargePixel16 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Pixels, + uint32 StartLine, uint32 LineCount) +{ + TILE_PREAMBLE + + register uint16 *sp = (uint16 *) GFX.S + Offset; + uint8 *Depth = GFX.DB + Offset; + uint16 pixel; + + RENDER_TILE_LARGE (GFX.ScreenColors [pixel], PLOT_PIXEL) +} + +inline void WRITE_4PIXELS16_ADD (uint32 Offset, uint8 *Pixels) +{ + uint32 Pixel; + uint16 *Screen = (uint16 *) GFX.S + Offset; + uint8 *Depth = GFX.ZBuffer + Offset; + uint8 *SubDepth = GFX.SubZBuffer + Offset; + +#define FN(N) \ + if (GFX.Z1 > Depth [N] && (Pixel = Pixels[N])) \ + { \ + if (SubDepth [N]) \ + { \ + if (SubDepth [N] != 1) \ + Screen [N] = COLOR_ADD (GFX.ScreenColors [Pixel], \ + Screen [GFX.Delta + N]); \ + else \ + Screen [N] = COLOR_ADD (GFX.ScreenColors [Pixel], \ + GFX.FixedColour); \ + } \ + else \ + Screen [N] = GFX.ScreenColors [Pixel]; \ + Depth [N] = GFX.Z2; \ + } + + FN(0) + FN(1) + FN(2) + FN(3) + +#undef FN +} + +inline void WRITE_4PIXELS16_FLIPPED_ADD (uint32 Offset, uint8 *Pixels) +{ + uint32 Pixel; + uint16 *Screen = (uint16 *) GFX.S + Offset; + uint8 *Depth = GFX.ZBuffer + Offset; + uint8 *SubDepth = GFX.SubZBuffer + Offset; + +#define FN(N) \ + if (GFX.Z1 > Depth [N] && (Pixel = Pixels[3 - N])) \ + { \ + if (SubDepth [N]) \ + { \ + if (SubDepth [N] != 1) \ + Screen [N] = COLOR_ADD (GFX.ScreenColors [Pixel], \ + Screen [GFX.Delta + N]); \ + else \ + Screen [N] = COLOR_ADD (GFX.ScreenColors [Pixel], \ + GFX.FixedColour); \ + } \ + else \ + Screen [N] = GFX.ScreenColors [Pixel]; \ + Depth [N] = GFX.Z2; \ + } + + FN(0) + FN(1) + FN(2) + FN(3) + +#undef FN +} + +inline void WRITE_4PIXELS16_ADD1_2 (uint32 Offset, uint8 *Pixels) +{ + uint32 Pixel; + uint16 *Screen = (uint16 *) GFX.S + Offset; + uint8 *Depth = GFX.ZBuffer + Offset; + uint8 *SubDepth = GFX.SubZBuffer + Offset; + +#define FN(N) \ + if (GFX.Z1 > Depth [N] && (Pixel = Pixels[N])) \ + { \ + if (SubDepth [N]) \ + { \ + if (SubDepth [N] != 1) \ + Screen [N] = (uint16) (COLOR_ADD1_2 (GFX.ScreenColors [Pixel], \ + Screen [GFX.Delta + N])); \ + else \ + Screen [N] = COLOR_ADD (GFX.ScreenColors [Pixel], \ + GFX.FixedColour); \ + } \ + else \ + Screen [N] = GFX.ScreenColors [Pixel]; \ + Depth [N] = GFX.Z2; \ + } + + FN(0) + FN(1) + FN(2) + FN(3) + +#undef FN +} + +inline void WRITE_4PIXELS16_FLIPPED_ADD1_2 (uint32 Offset, uint8 *Pixels) +{ + uint32 Pixel; + uint16 *Screen = (uint16 *) GFX.S + Offset; + uint8 *Depth = GFX.ZBuffer + Offset; + uint8 *SubDepth = GFX.SubZBuffer + Offset; + +#define FN(N) \ + if (GFX.Z1 > Depth [N] && (Pixel = Pixels[3 - N])) \ + { \ + if (SubDepth [N]) \ + { \ + if (SubDepth [N] != 1) \ + Screen [N] = (uint16) (COLOR_ADD1_2 (GFX.ScreenColors [Pixel], \ + Screen [GFX.Delta + N])); \ + else \ + Screen [N] = COLOR_ADD (GFX.ScreenColors [Pixel], \ + GFX.FixedColour); \ + } \ + else \ + Screen [N] = GFX.ScreenColors [Pixel]; \ + Depth [N] = GFX.Z2; \ + } + + FN(0) + FN(1) + FN(2) + FN(3) + +#undef FN +} + +inline void WRITE_4PIXELS16_SUB (uint32 Offset, uint8 *Pixels) +{ + uint32 Pixel; + uint16 *Screen = (uint16 *) GFX.S + Offset; + uint8 *Depth = GFX.ZBuffer + Offset; + uint8 *SubDepth = GFX.SubZBuffer + Offset; + +#define FN(N) \ + if (GFX.Z1 > Depth [N] && (Pixel = Pixels[N])) \ + { \ + if (SubDepth [N]) \ + { \ + if (SubDepth [N] != 1) \ + Screen [N] = (uint16) COLOR_SUB (GFX.ScreenColors [Pixel], \ + Screen [GFX.Delta + N]); \ + else \ + Screen [N] = (uint16) COLOR_SUB (GFX.ScreenColors [Pixel], \ + GFX.FixedColour); \ + } \ + else \ + Screen [N] = GFX.ScreenColors [Pixel]; \ + Depth [N] = GFX.Z2; \ + } + + FN(0) + FN(1) + FN(2) + FN(3) + +#undef FN +} + +inline void WRITE_4PIXELS16_FLIPPED_SUB (uint32 Offset, uint8 *Pixels) +{ + uint32 Pixel; + uint16 *Screen = (uint16 *) GFX.S + Offset; + uint8 *Depth = GFX.ZBuffer + Offset; + uint8 *SubDepth = GFX.SubZBuffer + Offset; + +#define FN(N) \ + if (GFX.Z1 > Depth [N] && (Pixel = Pixels[3 - N])) \ + { \ + if (SubDepth [N]) \ + { \ + if (SubDepth [N] != 1) \ + Screen [N] = (uint16) COLOR_SUB (GFX.ScreenColors [Pixel], \ + Screen [GFX.Delta + N]); \ + else \ + Screen [N] = (uint16) COLOR_SUB (GFX.ScreenColors [Pixel], \ + GFX.FixedColour); \ + } \ + else \ + Screen [N] = GFX.ScreenColors [Pixel]; \ + Depth [N] = GFX.Z2; \ + } + + FN(0) + FN(1) + FN(2) + FN(3) + +#undef FN +} + +inline void WRITE_4PIXELS16_SUB1_2 (uint32 Offset, uint8 *Pixels) +{ + uint32 Pixel; + uint16 *Screen = (uint16 *) GFX.S + Offset; + uint8 *Depth = GFX.ZBuffer + Offset; + uint8 *SubDepth = GFX.SubZBuffer + Offset; + +#define FN(N) \ + if (GFX.Z1 > Depth [N] && (Pixel = Pixels[N])) \ + { \ + if (SubDepth [N]) \ + { \ + if (SubDepth [N] != 1) \ + Screen [N] = (uint16) COLOR_SUB1_2 (GFX.ScreenColors [Pixel], \ + Screen [GFX.Delta + N]); \ + else \ + Screen [N] = (uint16) COLOR_SUB (GFX.ScreenColors [Pixel], \ + GFX.FixedColour); \ + } \ + else \ + Screen [N] = GFX.ScreenColors [Pixel]; \ + Depth [N] = GFX.Z2; \ + } + + FN(0) + FN(1) + FN(2) + FN(3) + +#undef FN +} + +inline void WRITE_4PIXELS16_FLIPPED_SUB1_2 (uint32 Offset, uint8 *Pixels) +{ + uint32 Pixel; + uint16 *Screen = (uint16 *) GFX.S + Offset; + uint8 *Depth = GFX.ZBuffer + Offset; + uint8 *SubDepth = GFX.SubZBuffer + Offset; + +#define FN(N) \ + if (GFX.Z1 > Depth [N] && (Pixel = Pixels[3 - N])) \ + { \ + if (SubDepth [N]) \ + { \ + if (SubDepth [N] != 1) \ + Screen [N] = (uint16) COLOR_SUB1_2 (GFX.ScreenColors [Pixel], \ + Screen [GFX.Delta + N]); \ + else \ + Screen [N] = (uint16) COLOR_SUB (GFX.ScreenColors [Pixel], \ + GFX.FixedColour); \ + } \ + else \ + Screen [N] = GFX.ScreenColors [Pixel]; \ + Depth [N] = GFX.Z2; \ + } + + FN(0) + FN(1) + FN(2) + FN(3) + +#undef FN +} + + +void orgDrawTile16Add (uint32 Tile, uint32 Offset, uint32 StartLine, + uint32 LineCount) +{ + TILE_PREAMBLE + register uint8 *bp; + + RENDER_TILE(WRITE_4PIXELS16_ADD, WRITE_4PIXELS16_FLIPPED_ADD, 4) +} + +void orgDrawClippedTile16Add (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount) +{ + TILE_PREAMBLE + register uint8 *bp; + + TILE_CLIP_PREAMBLE + RENDER_CLIPPED_TILE(WRITE_4PIXELS16_ADD, WRITE_4PIXELS16_FLIPPED_ADD, 4) +} + +void orgDrawTile16Add1_2 (uint32 Tile, uint32 Offset, uint32 StartLine, + uint32 LineCount) +{ + TILE_PREAMBLE + register uint8 *bp; + + RENDER_TILE(WRITE_4PIXELS16_ADD1_2, WRITE_4PIXELS16_FLIPPED_ADD1_2, 4) +} + +void orgDrawClippedTile16Add1_2 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount) +{ + TILE_PREAMBLE + register uint8 *bp; + + TILE_CLIP_PREAMBLE + RENDER_CLIPPED_TILE(WRITE_4PIXELS16_ADD1_2, WRITE_4PIXELS16_FLIPPED_ADD1_2, 4) +} + +void orgDrawTile16Sub (uint32 Tile, uint32 Offset, uint32 StartLine, + uint32 LineCount) +{ + TILE_PREAMBLE + register uint8 *bp; + + RENDER_TILE(WRITE_4PIXELS16_SUB, WRITE_4PIXELS16_FLIPPED_SUB, 4) +} + +void orgDrawClippedTile16Sub (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount) +{ + TILE_PREAMBLE + register uint8 *bp; + + TILE_CLIP_PREAMBLE + RENDER_CLIPPED_TILE(WRITE_4PIXELS16_SUB, WRITE_4PIXELS16_FLIPPED_SUB, 4) +} + +void orgDrawTile16Sub1_2 (uint32 Tile, uint32 Offset, uint32 StartLine, + uint32 LineCount) +{ + TILE_PREAMBLE + register uint8 *bp; + + RENDER_TILE(WRITE_4PIXELS16_SUB1_2, WRITE_4PIXELS16_FLIPPED_SUB1_2, 4) +} + +void orgDrawClippedTile16Sub1_2 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount) +{ + TILE_PREAMBLE + register uint8 *bp; + + TILE_CLIP_PREAMBLE + RENDER_CLIPPED_TILE(WRITE_4PIXELS16_SUB1_2, WRITE_4PIXELS16_FLIPPED_SUB1_2, 4) +} + +inline void WRITE_4PIXELS16_ADDF1_2 (uint32 Offset, uint8 *Pixels) +{ + uint32 Pixel; + uint16 *Screen = (uint16 *) GFX.S + Offset; + uint8 *Depth = GFX.ZBuffer + Offset; + uint8 *SubDepth = GFX.SubZBuffer + Offset; + +#define FN(N) \ + if (GFX.Z1 > Depth [N] && (Pixel = Pixels[N])) \ + { \ + if (SubDepth [N] == 1) \ + Screen [N] = (uint16) (COLOR_ADD1_2 (GFX.ScreenColors [Pixel], \ + GFX.FixedColour)); \ + else \ + Screen [N] = GFX.ScreenColors [Pixel];\ + Depth [N] = GFX.Z2; \ + } + + FN(0) + FN(1) + FN(2) + FN(3) + +#undef FN +} + +inline void WRITE_4PIXELS16_FLIPPED_ADDF1_2 (uint32 Offset, uint8 *Pixels) +{ + uint32 Pixel; + uint16 *Screen = (uint16 *) GFX.S + Offset; + uint8 *Depth = GFX.ZBuffer + Offset; + uint8 *SubDepth = GFX.SubZBuffer + Offset; + +#define FN(N) \ + if (GFX.Z1 > Depth [N] && (Pixel = Pixels[3 - N])) \ + { \ + if (SubDepth [N] == 1) \ + Screen [N] = (uint16) (COLOR_ADD1_2 (GFX.ScreenColors [Pixel], \ + GFX.FixedColour)); \ + else \ + Screen [N] = GFX.ScreenColors [Pixel];\ + Depth [N] = GFX.Z2; \ + } + + FN(0) + FN(1) + FN(2) + FN(3) + +#undef FN +} + +inline void WRITE_4PIXELS16_SUBF1_2 (uint32 Offset, uint8 *Pixels) +{ + uint32 Pixel; + uint16 *Screen = (uint16 *) GFX.S + Offset; + uint8 *Depth = GFX.ZBuffer + Offset; + uint8 *SubDepth = GFX.SubZBuffer + Offset; + +#define FN(N) \ + if (GFX.Z1 > Depth [N] && (Pixel = Pixels[N])) \ + { \ + if (SubDepth [N] == 1) \ + Screen [N] = (uint16) COLOR_SUB1_2 (GFX.ScreenColors [Pixel], \ + GFX.FixedColour); \ + else \ + Screen [N] = GFX.ScreenColors [Pixel]; \ + Depth [N] = GFX.Z2; \ + } + + FN(0) + FN(1) + FN(2) + FN(3) + +#undef FN +} + +inline void WRITE_4PIXELS16_FLIPPED_SUBF1_2 (uint32 Offset, uint8 *Pixels) +{ + uint32 Pixel; + uint16 *Screen = (uint16 *) GFX.S + Offset; + uint8 *Depth = GFX.ZBuffer + Offset; + uint8 *SubDepth = GFX.SubZBuffer + Offset; + +#define FN(N) \ + if (GFX.Z1 > Depth [N] && (Pixel = Pixels[3 - N])) \ + { \ + if (SubDepth [N] == 1) \ + Screen [N] = (uint16) COLOR_SUB1_2 (GFX.ScreenColors [Pixel], \ + GFX.FixedColour); \ + else \ + Screen [N] = GFX.ScreenColors [Pixel]; \ + Depth [N] = GFX.Z2; \ + } + + FN(0) + FN(1) + FN(2) + FN(3) + +#undef FN +} + +void orgDrawTile16FixedAdd1_2 (uint32 Tile, uint32 Offset, uint32 StartLine, + uint32 LineCount) +{ + TILE_PREAMBLE + register uint8 *bp; + + RENDER_TILE(WRITE_4PIXELS16_ADDF1_2, WRITE_4PIXELS16_FLIPPED_ADDF1_2, 4) +} + +void orgDrawClippedTile16FixedAdd1_2 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount) +{ + TILE_PREAMBLE + register uint8 *bp; + + TILE_CLIP_PREAMBLE + RENDER_CLIPPED_TILE(WRITE_4PIXELS16_ADDF1_2, + WRITE_4PIXELS16_FLIPPED_ADDF1_2, 4) +} + +void orgDrawTile16FixedSub1_2 (uint32 Tile, uint32 Offset, uint32 StartLine, + uint32 LineCount) +{ + TILE_PREAMBLE + register uint8 *bp; + + RENDER_TILE(WRITE_4PIXELS16_SUBF1_2, WRITE_4PIXELS16_FLIPPED_SUBF1_2, 4) +} + +void orgDrawClippedTile16FixedSub1_2 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount) +{ + TILE_PREAMBLE + register uint8 *bp; + + TILE_CLIP_PREAMBLE + RENDER_CLIPPED_TILE(WRITE_4PIXELS16_SUBF1_2, + WRITE_4PIXELS16_FLIPPED_SUBF1_2, 4) +} + +void orgDrawLargePixel16Add (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Pixels, + uint32 StartLine, uint32 LineCount) +{ + TILE_PREAMBLE + + register uint16 *sp = (uint16 *) GFX.S + Offset; + uint8 *Depth = GFX.ZBuffer + Offset; + uint16 pixel; + +#define LARGE_ADD_PIXEL(s, p) \ +(Depth [z + GFX.DepthDelta] ? (Depth [z + GFX.DepthDelta] != 1 ? \ + COLOR_ADD (p, *(s + GFX.Delta)) : \ + COLOR_ADD (p, GFX.FixedColour)) \ + : p) + + RENDER_TILE_LARGE (GFX.ScreenColors [pixel], LARGE_ADD_PIXEL) +} + +void orgDrawLargePixel16Add1_2 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Pixels, + uint32 StartLine, uint32 LineCount) +{ + TILE_PREAMBLE + + register uint16 *sp = (uint16 *) GFX.S + Offset; + uint8 *Depth = GFX.ZBuffer + Offset; + uint16 pixel; + +#define LARGE_ADD_PIXEL1_2(s, p) \ +((uint16) (Depth [z + GFX.DepthDelta] ? (Depth [z + GFX.DepthDelta] != 1 ? \ + COLOR_ADD1_2 (p, *(s + GFX.Delta)) : \ + COLOR_ADD (p, GFX.FixedColour)) \ + : p)) + + RENDER_TILE_LARGE (GFX.ScreenColors [pixel], LARGE_ADD_PIXEL1_2) +} + +void orgDrawLargePixel16Sub (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Pixels, + uint32 StartLine, uint32 LineCount) +{ + TILE_PREAMBLE + + register uint16 *sp = (uint16 *) GFX.S + Offset; + uint8 *Depth = GFX.ZBuffer + Offset; + uint16 pixel; + +#define LARGE_SUB_PIXEL(s, p) \ +(Depth [z + GFX.DepthDelta] ? (Depth [z + GFX.DepthDelta] != 1 ? \ + COLOR_SUB (p, *(s + GFX.Delta)) : \ + COLOR_SUB (p, GFX.FixedColour)) \ + : p) + + RENDER_TILE_LARGE (GFX.ScreenColors [pixel], LARGE_SUB_PIXEL) +} + +void orgDrawLargePixel16Sub1_2 (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Pixels, + uint32 StartLine, uint32 LineCount) +{ + TILE_PREAMBLE + + register uint16 *sp = (uint16 *) GFX.S + Offset; + uint8 *Depth = GFX.ZBuffer + Offset; + uint16 pixel; + +#define LARGE_SUB_PIXEL1_2(s, p) \ +(Depth [z + GFX.DepthDelta] ? (Depth [z + GFX.DepthDelta] != 1 ? \ + COLOR_SUB1_2 (p, *(s + GFX.Delta)) : \ + COLOR_SUB (p, GFX.FixedColour)) \ + : p) + + RENDER_TILE_LARGE (GFX.ScreenColors [pixel], LARGE_SUB_PIXEL1_2) +} + diff --git a/src/snes4iphone_src/tile_org.h b/src/snes4iphone_src/tile_org.h new file mode 100755 index 0000000..2ed9f43 --- /dev/null +++ b/src/snes4iphone_src/tile_org.h @@ -0,0 +1,362 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ +#ifndef _TILE_ORG_H_ +#define _TILE_ORG_H_ + +#define TILE_PREAMBLE \ + uint8 *pCache; \ +\ + uint32 TileAddr = BG.TileAddress + ((Tile & 0x3ff) << BG.TileShift); \ + if ((Tile & 0x1ff) >= 256) \ + TileAddr += BG.NameSelect; \ +\ + TileAddr &= 0xffff; \ +\ + uint32 TileNumber; \ + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) << 6]; \ +\ + if (!BG.Buffered [TileNumber<<1]) \ + BG.Buffered[TileNumber<<1] = orgConvertTile (pCache, TileAddr); \ +\ + if (BG.Buffered [TileNumber<<1] == BLANK_TILE) \ + return; \ +\ + register uint32 l; \ + if (BG.DirectColourMode) \ + { \ + if (IPPU.DirectColourMapsNeedRebuild) \ + S9xBuildDirectColourMaps (); \ + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; \ + } \ + else \ + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + +#define RENDER_TILE(NORMAL, FLIPPED, N) \ + if (!(Tile & (V_FLIP | H_FLIP))) \ + { \ + bp = pCache + StartLine; \ + for (l = LineCount; l != 0; l--, bp += 8, Offset += GFX.PPL) \ + { \ + /*if (*(uint32 *) bp)*/if (((uint32)bp[0])|((uint32)bp[1])|((uint32)bp[2])|((uint32)bp[3])) \ + NORMAL (Offset, bp); \ + /*if (*(uint32 *) (bp + 4))*/if (((uint32)bp[4])|((uint32)bp[5])|((uint32)bp[6])|((uint32)bp[7])) \ + NORMAL (Offset + N, bp + 4); \ + } \ + } \ + else \ + if (!(Tile & V_FLIP)) \ + { \ + bp = pCache + StartLine; \ + for (l = LineCount; l != 0; l--, bp += 8, Offset += GFX.PPL) \ + { \ + /*if (*(uint32 *) (bp + 4))*/if (((uint32)bp[4])|((uint32)bp[5])|((uint32)bp[6])|((uint32)bp[7])) \ + FLIPPED (Offset, bp + 4); \ + /*if (*(uint32 *) bp)*/if (((uint32)bp[0])|((uint32)bp[1])|((uint32)bp[2])|((uint32)bp[3])) \ + FLIPPED (Offset + N, bp); \ + } \ + } \ + else \ + if (Tile & H_FLIP) \ + { \ + bp = pCache + 56 - StartLine; \ + for (l = LineCount; l != 0; l--, bp -= 8, Offset += GFX.PPL) \ + { \ + /*if (*(uint32 *) (bp + 4))*/if (((uint32)bp[4])|((uint32)bp[5])|((uint32)bp[6])|((uint32)bp[7])) \ + FLIPPED (Offset, bp + 4); \ + /*if (*(uint32 *) bp)*/if (((uint32)bp[0])|((uint32)bp[1])|((uint32)bp[2])|((uint32)bp[3])) \ + FLIPPED (Offset + N, bp); \ + } \ + } \ + else \ + { \ + bp = pCache + 56 - StartLine; \ + for (l = LineCount; l != 0; l--, bp -= 8, Offset += GFX.PPL) \ + { \ + /*if (*(uint32 *) bp)*/if (((uint32)bp[0])|((uint32)bp[1])|((uint32)bp[2])|((uint32)bp[3])) \ + NORMAL (Offset, bp); \ + /*if (*(uint32 *) (bp + 4))*/if (((uint32)bp[4])|((uint32)bp[5])|((uint32)bp[6])|((uint32)bp[7])) \ + NORMAL (Offset + N, bp + 4); \ + } \ + } + +#define TILE_CLIP_PREAMBLE \ + uint32 dd; \ + uint32 d1; \ + uint32 d2; \ +\ + if (StartPixel < 4) \ + { \ + d1 = HeadMask [StartPixel]; \ + if (StartPixel + Width < 4) \ + d1 &= TailMask [StartPixel + Width]; \ + } \ + else \ + d1 = 0; \ +\ + if (StartPixel + Width > 4) \ + { \ + if (StartPixel > 4) \ + d2 = HeadMask [StartPixel - 4]; \ + else \ + d2 = 0xffffffff; \ +\ + d2 &= TailMask [(StartPixel + Width - 4)]; \ + } \ + else \ + d2 = 0; + + +#define RENDER_CLIPPED_TILE(NORMAL, FLIPPED, N) \ + if (!(Tile & (V_FLIP | H_FLIP))) \ + { \ + bp = pCache + StartLine; \ + for (l = LineCount; l != 0; l--, bp += 8, Offset += GFX.PPL) \ + { \ + /*if ((dd = (*(uint32 *) bp) & d1))*/if (dd = (((((uint32)bp[3])<<24)|(((uint32)bp[2])<<16)|(((uint32)bp[1])<<8)|((uint32)bp[0]))&d1)) \ + NORMAL (Offset, (uint8 *) &dd); \ + /*if ((dd = (*(uint32 *) (bp + 4)) & d2))*/if (dd = (((((uint32)bp[7])<<24)|(((uint32)bp[6])<<16)|(((uint32)bp[5])<<8)|((uint32)bp[4]))&d2)) \ + NORMAL (Offset + N, (uint8 *) &dd); \ + } \ + } \ + else \ + if (!(Tile & V_FLIP)) \ + { \ + bp = pCache + StartLine; \ + SWAP_DWORD (d1); \ + SWAP_DWORD (d2); \ + for (l = LineCount; l != 0; l--, bp += 8, Offset += GFX.PPL) \ + { \ + /*if ((dd = *(uint32 *) (bp + 4) & d1))*/if (dd = (((((uint32)bp[7])<<24)|(((uint32)bp[6])<<16)|(((uint32)bp[5])<<8)|((uint32)bp[4]))&d1)) \ + FLIPPED (Offset, (uint8 *) &dd); \ + /*if ((dd = *(uint32 *) bp & d2))*/if (dd = (((((uint32)bp[3])<<24)|(((uint32)bp[2])<<16)|(((uint32)bp[1])<<8)|((uint32)bp[0]))&d2)) \ + FLIPPED (Offset + N, (uint8 *) &dd); \ + } \ + } \ + else \ + if (Tile & H_FLIP) \ + { \ + bp = pCache + 56 - StartLine; \ + SWAP_DWORD (d1); \ + SWAP_DWORD (d2); \ + for (l = LineCount; l != 0; l--, bp -= 8, Offset += GFX.PPL) \ + { \ + /*if ((dd = *(uint32 *) (bp + 4) & d1))*/if (dd = (((((uint32)bp[7])<<24)|(((uint32)bp[6])<<16)|(((uint32)bp[5])<<8)|((uint32)bp[4]))&d1)) \ + FLIPPED (Offset, (uint8 *) &dd); \ + /*if ((dd = *(uint32 *) bp & d2))*/if (dd = (((((uint32)bp[3])<<24)|(((uint32)bp[2])<<16)|(((uint32)bp[1])<<8)|((uint32)bp[0]))&d2)) \ + FLIPPED (Offset + N, (uint8 *) &dd); \ + } \ + } \ + else \ + { \ + bp = pCache + 56 - StartLine; \ + for (l = LineCount; l != 0; l--, bp -= 8, Offset += GFX.PPL) \ + { \ + /*if ((dd = (*(uint32 *) bp) & d1))*/ if (dd = (((((uint32)bp[3])<<24)|(((uint32)bp[2])<<16)|(((uint32)bp[1])<<8)|((uint32)bp[0]))&d1)) \ + NORMAL (Offset, (uint8 *) &dd); \ + /*if ((dd = (*(uint32 *) (bp + 4)) & d2))*/if (dd = (((((uint32)bp[7])<<24)|(((uint32)bp[6])<<16)|(((uint32)bp[5])<<8)|((uint32)bp[4]))&d2)) \ + NORMAL (Offset + N, (uint8 *) &dd); \ + } \ + } + +#define RENDER_TILE_LARGE(PIXEL, FUNCTION) \ + if (!(Tile & (V_FLIP | H_FLIP))) \ + { \ + if ((pixel = *(pCache + StartLine + StartPixel))) \ + { \ + pixel = PIXEL; \ + for (l = LineCount; l != 0; l--, sp += GFX.PPL, Depth += GFX.PPL) \ + { \ + for (int z = Pixels - 1; z >= 0; z--) \ + if (GFX.Z1 > Depth [z]) \ + { \ + sp [z] = FUNCTION(sp + z, pixel); \ + Depth [z] = GFX.Z2; \ + }\ + } \ + } \ + } \ + else \ + if (!(Tile & V_FLIP)) \ + { \ + StartPixel = 7 - StartPixel; \ + if ((pixel = *(pCache + StartLine + StartPixel))) \ + { \ + pixel = PIXEL; \ + for (l = LineCount; l != 0; l--, sp += GFX.PPL, Depth += GFX.PPL) \ + { \ + for (int z = Pixels - 1; z >= 0; z--) \ + if (GFX.Z1 > Depth [z]) \ + { \ + sp [z] = FUNCTION(sp + z, pixel); \ + Depth [z] = GFX.Z2; \ + }\ + } \ + } \ + } \ + else \ + if (Tile & H_FLIP) \ + { \ + StartPixel = 7 - StartPixel; \ + if ((pixel = *(pCache + 56 - StartLine + StartPixel))) \ + { \ + pixel = PIXEL; \ + for (l = LineCount; l != 0; l--, sp += GFX.PPL, Depth += GFX.PPL) \ + { \ + for (int z = Pixels - 1; z >= 0; z--) \ + if (GFX.Z1 > Depth [z]) \ + { \ + sp [z] = FUNCTION(sp + z, pixel); \ + Depth [z] = GFX.Z2; \ + }\ + } \ + } \ + } \ + else \ + { \ + if ((pixel = *(pCache + 56 - StartLine + StartPixel))) \ + { \ + pixel = PIXEL; \ + for (l = LineCount; l != 0; l--, sp += GFX.PPL, Depth += GFX.PPL) \ + { \ + for (int z = Pixels - 1; z >= 0; z--) \ + if (GFX.Z1 > Depth [z]) \ + { \ + sp [z] = FUNCTION(sp + z, pixel); \ + Depth [z] = GFX.Z2; \ + }\ + } \ + } \ + } + + + + + +#define RENDER_TILEHI(NORMAL, FLIPPED, N) \ + if (!(Tile & (V_FLIP | H_FLIP))) \ + { \ + bp = pCache + StartLine; \ + for (l = LineCount; l != 0; l--, bp += 8, Offset += GFX.PPL) \ + { \ + /*if (*(uint32 *) bp)*/if (((uint32)bp[0])|((uint32)bp[2])|((uint32)bp[4])|((uint32)bp[6])) \ + NORMAL (Offset, bp); \ + } \ + } \ + else \ + if (!(Tile & V_FLIP)) \ + { \ + bp = pCache + StartLine; \ + for (l = LineCount; l != 0; l--, bp += 8, Offset += GFX.PPL) \ + { \ + /*if (*(uint32 *) (bp + 4))*/if (((uint32)bp[0])|((uint32)bp[2])|((uint32)bp[4])|((uint32)bp[6])) \ + FLIPPED (Offset, bp); \ + } \ + } \ + else \ + if (Tile & H_FLIP) \ + { \ + bp = pCache + 56 - StartLine; \ + for (l = LineCount; l != 0; l--, bp -= 8, Offset += GFX.PPL) \ + { \ + /*if (*(uint32 *) (bp + 4))*/if (((uint32)bp[0])|((uint32)bp[2])|((uint32)bp[4])|((uint32)bp[6])) \ + FLIPPED (Offset, bp); \ + } \ + } \ + else \ + { \ + bp = pCache + 56 - StartLine; \ + for (l = LineCount; l != 0; l--, bp -= 8, Offset += GFX.PPL) \ + { \ + /*if (*(uint32 *) bp)*/if (((uint32)bp[0])|((uint32)bp[2])|((uint32)bp[4])|((uint32)bp[6])) \ + NORMAL (Offset, bp); \ + } \ + } + + + +#define RENDER_CLIPPED_TILEHI(NORMAL, FLIPPED, N) \ + d1=(d1&0xFF)|((d1&0xFF0000)>>8)|((d2&0xFF)<<16)|((d2&0xFF0000)<<8);\ + if (!(Tile & (V_FLIP | H_FLIP))) \ + { \ + bp = pCache + StartLine; \ + for (l = LineCount; l != 0; l--, bp += 8, Offset += GFX.PPL) \ + { \ + /*if ((dd = (*(uint32 *) bp) & d1))*/if (dd = (((((uint32)bp[6])<<24)|(((uint32)bp[4])<<16)|(((uint32)bp[2])<<8)|((uint32)bp[0]))&d1)) \ + NORMAL (Offset, (uint8 *) &dd); \ + } \ + } \ + else \ + if (!(Tile & V_FLIP)) \ + { \ + bp = pCache + StartLine; \ + SWAP_DWORD (d1); \ + /*SWAP_DWORD (d2);*/ \ + for (l = LineCount; l != 0; l--, bp += 8, Offset += GFX.PPL) \ + { \ + /*if ((dd = *(uint32 *) (bp + 4) & d1))*/if (dd = (((((uint32)bp[6])<<24)|(((uint32)bp[4])<<16)|(((uint32)bp[2])<<8)|((uint32)bp[0]))&d1)) \ + FLIPPED (Offset, (uint8 *) &dd); \ + } \ + } \ + else \ + if (Tile & H_FLIP) \ + { \ + bp = pCache + 56 - StartLine; \ + SWAP_DWORD (d1); \ + /*SWAP_DWORD (d2);*/ \ + for (l = LineCount; l != 0; l--, bp -= 8, Offset += GFX.PPL) \ + { \ + /*if ((dd = *(uint32 *) (bp + 4) & d1))*/if (dd = (((((uint32)bp[6])<<24)|(((uint32)bp[4])<<16)|(((uint32)bp[2])<<8)|((uint32)bp[0]))&d1)) \ + FLIPPED (Offset, (uint8 *) &dd); \ + } \ + } \ + else \ + { \ + bp = pCache + 56 - StartLine; \ + for (l = LineCount; l != 0; l--, bp -= 8, Offset += GFX.PPL) \ + { \ + /*if ((dd = (*(uint32 *) bp) & d1))*/ if (dd = (((((uint32)bp[6])<<24)|(((uint32)bp[4])<<16)|(((uint32)bp[2])<<8)|((uint32)bp[0]))&d1)) \ + NORMAL (Offset, (uint8 *) &dd); \ + } \ + } + + +#endif + diff --git a/src/snes4iphone_src/tiledave.cpp b/src/snes4iphone_src/tiledave.cpp new file mode 100755 index 0000000..53e12f0 --- /dev/null +++ b/src/snes4iphone_src/tiledave.cpp @@ -0,0 +1,13512 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ + +//#ifndef asmPPU +#include "snes9x.h" + +#include "memmap.h" +#include "ppu.h" +#include "cpuexec.h" +#include "display.h" +#include "gfx.h" +#include "apu.h" + + +//#define asmPPU16 +#define asmPPU8 +//#define asmPPU16T + +typedef union +{ + struct { uint8 b0,b1,b2,b3; } B; + uint32 W; +} yo_uint32; + +uint8 *SubScreenTranspBuffer; +uint8 tmpCache[64]; +extern int squidgetranshackenable; + + +#ifdef asmPPU16 +extern "C" void asmDrawTile16(uint32 cache,uint32 solidbuf,uint32 OffsetGP32,uint32 Flip); +extern "C" void asmDrawTileClipped16(uint32 cache,uint32 solidbuf,uint32 OffsetGP32,uint32 Flip); +#endif + +#ifdef asmPPU8 +extern "C" void asmDrawTile8(uint32 cache,uint32 solidbuf,uint32 OffsetGP32,uint32 Flip); +extern "C" void asmDrawTileClipped8(uint32 cache,uint32 solidbuf,uint32 OffsetGP32,uint32 Flip); +#endif + +// RGB565 +#define yoRGB_REMOVE_LOW_BITS_MASK ((30<<11)|(62<<5)|(30)) +#define yoRGB_LOW_BITS_MASK ((1<<11)|(1<<5)|(1<<1)) +#define yoRGB_HI_BITS_MASKx2 (((16<<11)|(32<<5)|(16))<<1) + + +#define COLOR_ADD(C1, C2) \ +GFX.X2 [((((C1) & yoRGB_REMOVE_LOW_BITS_MASK) + \ + ((C2) & yoRGB_REMOVE_LOW_BITS_MASK)) >> 1) + \ + ((C1) & (C2) & yoRGB_LOW_BITS_MASK)] + + +#define COLOR_ADD1_2(C1, C2) \ +(((((C1) & yoRGB_REMOVE_LOW_BITS_MASK) + \ + ((C2) & yoRGB_REMOVE_LOW_BITS_MASK)) >> 1) + \ + ((C1) & (C2) & yoRGB_LOW_BITS_MASK) | ALPHA_BITS_MASK) + +#define COLOR_SUB(C1, C2) \ +GFX.ZERO_OR_X2 [(((C1) | yoRGB_HI_BITS_MASKx2) - \ + ((C2) & yoRGB_REMOVE_LOW_BITS_MASK)) >> 1] + +#define COLOR_SUB1_2(C1, C2) \ +GFX.ZERO [(((C1) | yoRGB_HI_BITS_MASKx2) - \ + ((C2) & yoRGB_REMOVE_LOW_BITS_MASK)) >> 1] + + + +__inline uint8 ConvertTile16New (uint8 *pCache,uint32 TileAddr,uint16 *ScreenColors) +{ +#if 1 + register uint8 *tp = &Memory.VRAM[TileAddr]; + uint32 *p = (uint32*)tmpCache; + uint32 non_zero,tile_opaque,tile_mono; + uint8 line; + uint32 p1; + uint32 p2; + register uint8 pix; + + non_zero=0; + switch (BG.BitShift) + { + case 8: + for (line = 8; line != 0; line--, tp += 2) + { + p1 = 0; + p2 = 0; + if ((pix = *(tp + 0))) + { + p1 |= odd_high[0][pix >> 4]; + p2 |= odd_low[0][pix & 0xf]; + } + if ((pix = *(tp + 1))) + { + p1 |= even_high[0][pix >> 4]; + p2 |= even_low[0][pix & 0xf]; + } + if ((pix = *(tp + 16))) + { + p1 |= odd_high[1][pix >> 4]; + p2 |= odd_low[1][pix & 0xf]; + } + if ((pix = *(tp + 17))) + { + p1 |= even_high[1][pix >> 4]; + p2 |= even_low[1][pix & 0xf]; + } + if ((pix = *(tp + 32))) + { + p1 |= odd_high[2][pix >> 4]; + p2 |= odd_low[2][pix & 0xf]; + } + if ((pix = *(tp + 33))) + { + p1 |= even_high[2][pix >> 4]; + p2 |= even_low[2][pix & 0xf]; + } + if ((pix = *(tp + 48))) + { + p1 |= odd_high[3][pix >> 4]; + p2 |= odd_low[3][pix & 0xf]; + } + if ((pix = *(tp + 49))) + { + p1 |= even_high[3][pix >> 4]; + p2 |= even_low[3][pix & 0xf]; + } + + *p++=p1; + *p++=p2; + non_zero |= p1 | p2; + } + break; + + case 4: + for (line = 8; line != 0; line--, tp += 2) + { + p1 = 0; + p2 = 0; + if ((pix = *(tp + 0))) + { + p1 |= odd_high[0][pix >> 4]; + p2 |= odd_low[0][pix & 0xf]; + } + if ((pix = *(tp + 1))) + { + p1 |= even_high[0][pix >> 4]; + p2 |= even_low[0][pix & 0xf]; + } + if ((pix = *(tp + 16))) + { + p1 |= odd_high[1][pix >> 4]; + p2 |= odd_low[1][pix & 0xf]; + } + if ((pix = *(tp + 17))) + { + p1 |= even_high[1][pix >> 4]; + p2 |= even_low[1][pix & 0xf]; + } + *p++=p1; + *p++=p2; + non_zero |= p1 | p2; + } + break; + + case 2: + for (line = 8; line != 0; line--, tp += 2) + { + p1 = 0; + p2 = 0; + if ((pix = *(tp + 0))) + { + p1 |= odd_high[0][pix >> 4]; + p2 |= odd_low[0][pix & 0xf]; + } + if ((pix = *(tp + 1))) + { + p1 |= even_high[0][pix >> 4]; + p2 |= even_low[0][pix & 0xf]; + } + + *p++=p1; + *p++=p2; + non_zero |= p1 | p2; + } + break; + } + if (non_zero) + { + tile_opaque=1; + uint8 *p3=tmpCache; + uint8 *q = pCache; + uint32 i; + for (line = 8;line != 0; line--,q++,p3+=8) + { + if (!p3[0]) i=0x80; + else i=0; + if (!p3[1]) i|=0x40; + if (!p3[2]) i|=0x20; + if (!p3[3]) i|=0x10; + if (!p3[4]) i|=0x08; + if (!p3[5]) i|=0x04; + if (!p3[6]) i|=0x02; + if (!p3[7]) i|=0x01; + if (i) tile_opaque=0; + *q=i; + } + uint16 *r = (uint16*)(pCache)+4; + for (line = 0;line <64;line++) + r[line]=ScreenColors[tmpCache[line]]; + + + if (tile_opaque) return 2; //Tile is cached and opaque + return 3; //Tile is cached and transp + } + else return 1; //Tile is totally transparent +#else + return 2; +#endif +} + +#if 1 +__inline uint8 ConvertTile8New (uint8 *pCache,uint32 TileAddr) +{ + register uint8 *tp = &Memory.VRAM[TileAddr]; + uint32 *p = (uint32*)pCache+((8+64)>>2); + uint32 non_zero,tile_opaque,tile_mono; + uint8 line; + uint32 p1; + uint32 p2; + register uint8 pix; + + non_zero=0; + switch (BG.BitShift) + { + case 8: + for (line = 8; line != 0; line--, tp += 2) + { + p1 = 0; + p2 = 0; + if ((pix = *(tp + 0))) + { + p1 |= odd_high[0][pix >> 4]; + p2 |= odd_low[0][pix & 0xf]; + } + if ((pix = *(tp + 1))) + { + p1 |= even_high[0][pix >> 4]; + p2 |= even_low[0][pix & 0xf]; + } + if ((pix = *(tp + 16))) + { + p1 |= odd_high[1][pix >> 4]; + p2 |= odd_low[1][pix & 0xf]; + } + if ((pix = *(tp + 17))) + { + p1 |= even_high[1][pix >> 4]; + p2 |= even_low[1][pix & 0xf]; + } + if ((pix = *(tp + 32))) + { + p1 |= odd_high[2][pix >> 4]; + p2 |= odd_low[2][pix & 0xf]; + } + if ((pix = *(tp + 33))) + { + p1 |= even_high[2][pix >> 4]; + p2 |= even_low[2][pix & 0xf]; + } + if ((pix = *(tp + 48))) + { + p1 |= odd_high[3][pix >> 4]; + p2 |= odd_low[3][pix & 0xf]; + } + if ((pix = *(tp + 49))) + { + p1 |= even_high[3][pix >> 4]; + p2 |= even_low[3][pix & 0xf]; + } + + *p++=p1; + *p++=p2; + non_zero |= p1 | p2; + } + break; + + case 4: + for (line = 8; line != 0; line--, tp += 2) + { + p1 = 0; + p2 = 0; + if ((pix = *(tp + 0))) + { + p1 |= odd_high[0][pix >> 4]; + p2 |= odd_low[0][pix & 0xf]; + } + if ((pix = *(tp + 1))) + { + p1 |= even_high[0][pix >> 4]; + p2 |= even_low[0][pix & 0xf]; + } + if ((pix = *(tp + 16))) + { + p1 |= odd_high[1][pix >> 4]; + p2 |= odd_low[1][pix & 0xf]; + } + if ((pix = *(tp + 17))) + { + p1 |= even_high[1][pix >> 4]; + p2 |= even_low[1][pix & 0xf]; + } + *p++=p1; + *p++=p2; + non_zero |= p1 | p2; + } + break; + + case 2: + for (line = 8; line != 0; line--, tp += 2) + { + p1 = 0; + p2 = 0; + if ((pix = *(tp + 0))) + { + p1 |= odd_high[0][pix >> 4]; + p2 |= odd_low[0][pix & 0xf]; + } + if ((pix = *(tp + 1))) + { + p1 |= even_high[0][pix >> 4]; + p2 |= even_low[0][pix & 0xf]; + } + + *p++=p1; + *p++=p2; + non_zero |= p1 | p2; + } + break; + } + if (non_zero) + { + tile_opaque=1; + uint8 *p3=pCache+8+64; + uint8 *q = pCache; + uint32 i; + for (line = 8;line != 0; line--,q++,p+=8) + { + /*if (!p3[0]) i=0x80; + else i=0; + if (!p3[1]) i|=0x40; + if (!p3[2]) i|=0x20; + if (!p3[3]) i|=0x10; + if (!p3[4]) i|=0x08; + if (!p3[5]) i|=0x04; + if (!p3[6]) i|=0x02; + if (!p3[7]) i|=0x01;*/ + + if (p3[0]) i=0x01; + else i=0; + if (p3[1]) i|=0x02; + if (p3[2]) i|=0x04; + if (p3[3]) i|=0x08; + if (p3[4]) i|=0x10; + if (p3[5]) i|=0x20; + if (p3[6]) i|=0x40; + if (p3[7]) i|=0x80; + + //if (i==0) tile_opaque=0; + *q=i; + } + + //if (tile_opaque) return 2; //Tile is cached and opaque + return 3; //Tile is cached and transp + } + else return 1; //Tile is totally transparent +} +#endif + +/********************************/ +__inline void NORMAL16_T (uint32 Offset,uint16 *Pixels,uint32 solid) +{ +#if 1 + uint16 *Screen = (uint16 *) GFX.S + Offset; + + #define FN(N) \ + if (!(solid&(1<<(7-N)))) *Screen = *Pixels; \ + Screen++; Pixels++; + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +#endif +} + +__inline void NORMAL16_O (uint32 Offset,uint16 *Pixels) +{ +#if 1 + uint16 *Screen = (uint16 *) GFX.S + Offset; + + *Screen++=*Pixels++; + *Screen++=*Pixels++; + *Screen++=*Pixels++; + *Screen++=*Pixels++; + *Screen++=*Pixels++; + *Screen++=*Pixels++; + *Screen++=*Pixels++; + *Screen++=*Pixels++; +#endif +} + +__inline void FLIPPED16_T (uint32 Offset,uint16 *Pixels,uint32 solid) +{ + uint16 *Screen = (uint16 *) GFX.S + Offset; + + #define FN(N) \ + if (!(solid&(1<<(7-N)))) *Screen = *Pixels; \ + Screen--; Pixels++; + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +} + +__inline void FLIPPED16_O (uint32 Offset,uint16 *Pixels) +{ + uint16 *Screen = (uint16 *) GFX.S + Offset; + + *Screen--=*Pixels++; + *Screen--=*Pixels++; + *Screen--=*Pixels++; + *Screen--=*Pixels++; + *Screen--=*Pixels++; + *Screen--=*Pixels++; + *Screen--=*Pixels++; + *Screen--=*Pixels++; +} + + + +__inline void NORMAL16_SPR_T (uint32 Offset,uint16 *Pixels,uint32 solid,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.S + Offset; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset; + + #define FN(N) \ + if ((!(solid&(1<<(7-N))))&&(*ZB>index_spr)) { *Screen = *Pixels; *ZB=index_spr; } \ + Screen += 320; Pixels++; ZB += 320; + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +} + +__inline void NORMAL16_SPR_O (uint32 Offset,uint16 *Pixels,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.S + Offset; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset; + + #define FN \ + if (*ZB>index_spr) {*Screen=*Pixels; *ZB=index_spr;} \ + Screen += 320; Pixels++; ZB += 320; + FN + FN + FN + FN + FN + FN + FN + FN + #undef FN +} + +__inline void FLIPPED16_SPR_T (uint32 Offset,uint16 *Pixels,uint32 solid,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.S + Offset + (7 * 320); + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset + (7 * 320); + + #define FN(N) \ + if ((!(solid&(1<<(7-N))))&&(*ZB>index_spr)) { *Screen = *Pixels; *ZB=index_spr; }\ + Screen -= 320; Pixels++; ZB -= 320; + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +} + +__inline void FLIPPED16_SPR_O (uint32 Offset,uint16 *Pixels,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.S + Offset + (7 * 320); + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset + (7 * 320); + + #define FN \ + if (*ZB>index_spr) {*Screen=*Pixels; *ZB=index_spr;} \ + Screen -= 320; Pixels++; ZB -= 320; + FN + FN + FN + FN + FN + FN + FN + FN + #undef FN +} + + + + +__inline void NORMAL_ADD_16_T (uint32 Offset,uint16 *Pixels,uint32 solid) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + #define FN(N) \ + if (!(solid&(1<<(7-N)))) {\ + if (*SubScreen) *Screen = COLOR_ADD(*Pixels,*SubScreen); \ + else *Screen=*Pixels;}\ + Screen += 320; SubScreen += 320; Pixels++; + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +} + +__inline void NORMAL_ADD_16_O (uint32 Offset,uint16 *Pixels) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + #define FN \ + if (*SubScreen) *Screen = COLOR_ADD(*Pixels,*SubScreen);\ + else *Screen=*Pixels; \ + Screen += 320; SubScreen += 320; Pixels++; + FN + FN + FN + FN + FN + FN + FN + FN + #undef FN +} + +__inline void FLIPPED_ADD_16_T (uint32 Offset,uint16 *Pixels,uint32 solid) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + Screen += (7 * 320); + SubScreen += (7 * 320); + #define FN(N) \ + if (!(solid&(1<<(7-N)))) {\ + if (*SubScreen) *Screen = COLOR_ADD(*Pixels,*SubScreen); \ + else *Screen=*Pixels;}\ + Screen -= 320; SubScreen -= 320; Pixels++; + + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +} + +__inline void FLIPPED_ADD_16_O (uint32 Offset,uint16 *Pixels) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + Screen += (7 * 320); + SubScreen += (7 * 320); + #define FN \ + if (*SubScreen) *Screen = COLOR_ADD(*Pixels,*SubScreen);\ + else *Screen=*Pixels; \ + Screen -= 320; SubScreen -= 320; Pixels++; + FN + FN + FN + FN + FN + FN + FN + FN + #undef FN +} + + + +__inline void NORMAL_ADD_16_SPR_T (uint32 Offset,uint16 *Pixels,uint32 solid,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset; + + #define FN(N) \ + if ((!(solid&(1<<(7-N))))&&(*ZB>index_spr)) { \ + if (*SubScreen) *Screen = COLOR_ADD(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr; \ + } \ + Screen += 320; SubScreen += 320; Pixels++; ZB += 320; + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +} + +__inline void NORMAL_ADD_16_SPR_O (uint32 Offset,uint16 *Pixels,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset; + + #define FN \ + if (*ZB>index_spr) {\ + if (*SubScreen) *Screen = COLOR_ADD(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr;} \ + Screen += 320; SubScreen += 320; Pixels++; ZB += 320; + FN + FN + FN + FN + FN + FN + FN + FN + #undef FN +} + +__inline void FLIPPED_ADD_16_SPR_T (uint32 Offset,uint16 *Pixels,uint32 solid,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset + (7 * 320); + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset + (7 * 320); + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset + (7 * 320); + + #define FN(N) \ + if ((!(solid&(1<<(7-N))))&&(*ZB>index_spr)) { \ + if (*SubScreen) *Screen = COLOR_ADD(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr; }\ + Screen -= 320; SubScreen -= 320; Pixels++; ZB -= 320; + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +} + +__inline void FLIPPED_ADD_16_SPR_O (uint32 Offset,uint16 *Pixels,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset + (7 * 320); + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset + (7 * 320); + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset + (7 * 320); + + #define FN \ + if (*ZB>index_spr) {\ + if (*SubScreen) *Screen = COLOR_ADD(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr;} \ + Screen -= 320; SubScreen -= 320; Pixels++; ZB -= 320; + FN + FN + FN + FN + FN + FN + FN + FN + #undef FN +} + +//////////////////// fooble +__inline void NORMAL_ADD1_2_16_T (uint32 Offset,uint16 *Pixels,uint32 solid) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + #define FN(N) \ + if (!(solid&(1<<(7-N)))) {\ + if (*SubScreen) *Screen = COLOR_ADD1_2(*Pixels,*SubScreen); \ + else *Screen=*Pixels;}\ + Screen += 320; SubScreen += 320; Pixels++; + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +} + +__inline void NORMAL_ADD1_2_16_O (uint32 Offset,uint16 *Pixels) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + #define FN \ + if (*SubScreen) *Screen = COLOR_ADD1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels; \ + Screen += 320; SubScreen += 320; Pixels++; + FN + FN + FN + FN + FN + FN + FN + FN + #undef FN +} + +__inline void FLIPPED_ADD1_2_16_T (uint32 Offset,uint16 *Pixels,uint32 solid) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + Screen += (7 * 320); + SubScreen += (7 * 320); + #define FN(N) \ + if (!(solid&(1<<(7-N)))) {\ + if (*SubScreen) *Screen = COLOR_ADD1_2(*Pixels,*SubScreen); \ + else *Screen=*Pixels;}\ + Screen -= 320; SubScreen -= 320; Pixels++; + + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +} + +__inline void FLIPPED_ADD1_2_16_O (uint32 Offset,uint16 *Pixels) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + Screen += (7 * 320); + SubScreen += (7 * 320); + #define FN \ + if (*SubScreen) *Screen = COLOR_ADD1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels; \ + Screen -= 320; SubScreen -= 320; Pixels++; + FN + FN + FN + FN + FN + FN + FN + FN + #undef FN +} + + + +__inline void NORMAL_ADD1_2_16_SPR_T (uint32 Offset,uint16 *Pixels,uint32 solid,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset; + + #define FN(N) \ + if ((!(solid&(1<<(7-N))))&&(*ZB>index_spr)) { \ + if (*SubScreen) *Screen = COLOR_ADD1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr; \ + } \ + Screen += 320; SubScreen += 320; Pixels++; ZB += 320; + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +} + +__inline void NORMAL_ADD1_2_16_SPR_O (uint32 Offset,uint16 *Pixels,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset; + + #define FN \ + if (*ZB>index_spr) {\ + if (*SubScreen) *Screen = COLOR_ADD1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr;} \ + Screen += 320; SubScreen += 320; Pixels++; ZB += 320; + FN + FN + FN + FN + FN + FN + FN + FN + #undef FN +} + +__inline void FLIPPED_ADD1_2_16_SPR_T (uint32 Offset,uint16 *Pixels,uint32 solid,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset + (7 * 320); + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset + (7 * 320); + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset + (7 * 320); + + #define FN(N) \ + if ((!(solid&(1<<(7-N))))&&(*ZB>index_spr)) { \ + if (*SubScreen) *Screen = COLOR_ADD1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr; }\ + Screen -= 320; SubScreen -= 320; Pixels++; ZB -= 320; + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +} + +__inline void FLIPPED_ADD1_2_16_SPR_O (uint32 Offset,uint16 *Pixels,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset + (7 * 320); + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset + (7 * 320); + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset + (7 * 320); + + #define FN \ + if (*ZB>index_spr) {\ + if (*SubScreen) *Screen = COLOR_ADD1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr;} \ + Screen -= 320; SubScreen -= 320; Pixels++; ZB -= 320; + FN + FN + FN + FN + FN + FN + FN + FN + #undef FN +} + +__inline void NORMAL_SUB_16_T (uint32 Offset,uint16 *Pixels,uint32 solid) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + #define FN(N) \ + if (!(solid&(1<<(7-N)))) {\ + if (*SubScreen) *Screen = COLOR_SUB(*Pixels,*SubScreen); \ + else *Screen=*Pixels;}\ + Screen += 320; SubScreen += 320; Pixels++; + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +} + +__inline void NORMAL_SUB_16_O (uint32 Offset,uint16 *Pixels) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + #define FN \ + if (*SubScreen) *Screen = COLOR_SUB(*Pixels,*SubScreen);\ + else *Screen=*Pixels; \ + Screen += 320; SubScreen += 320; Pixels++; + FN + FN + FN + FN + FN + FN + FN + FN + #undef FN +} + +__inline void FLIPPED_SUB_16_T (uint32 Offset,uint16 *Pixels,uint32 solid) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + Screen += (7 * 320); + SubScreen += (7 * 320); + #define FN(N) \ + if (!(solid&(1<<(7-N)))) {\ + if (*SubScreen) *Screen = COLOR_SUB(*Pixels,*SubScreen); \ + else *Screen=*Pixels;}\ + Screen -= 320; SubScreen -= 320; Pixels++; + + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +} + +__inline void FLIPPED_SUB_16_O (uint32 Offset,uint16 *Pixels) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + Screen += (7 * 320); + SubScreen += (7 * 320); + #define FN \ + if (*SubScreen) *Screen = COLOR_SUB(*Pixels,*SubScreen);\ + else *Screen=*Pixels; \ + Screen -= 320; SubScreen -= 320; Pixels++; + FN + FN + FN + FN + FN + FN + FN + FN + #undef FN +} + + + +__inline void NORMAL_SUB_16_SPR_T (uint32 Offset,uint16 *Pixels,uint32 solid,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset; + + #define FN(N) \ + if ((!(solid&(1<<(7-N))))&&(*ZB>index_spr)) { \ + if (*SubScreen) *Screen = COLOR_SUB(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr; \ + } \ + Screen += 320; SubScreen += 320; Pixels++; ZB += 320; + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +} + +__inline void NORMAL_SUB_16_SPR_O (uint32 Offset,uint16 *Pixels,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset; + + #define FN \ + if (*ZB>index_spr) {\ + if (*SubScreen) *Screen = COLOR_SUB(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr;} \ + Screen += 320; SubScreen += 320; Pixels++; ZB += 320; + FN + FN + FN + FN + FN + FN + FN + FN + #undef FN +} + +__inline void FLIPPED_SUB_16_SPR_T (uint32 Offset,uint16 *Pixels,uint32 solid,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset + (7 * 320); + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset + (7 * 320); + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset + (7 * 320); + + #define FN(N) \ + if ((!(solid&(1<<(7-N))))&&(*ZB>index_spr)) { \ + if (*SubScreen) *Screen = COLOR_SUB(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr; }\ + Screen -= 320; SubScreen -= 320; Pixels++; ZB -= 320; + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +} + +__inline void FLIPPED_SUB_16_SPR_O (uint32 Offset,uint16 *Pixels,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset + (7 * 320); + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset + (7 * 320); + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset + (7 * 320); + + #define FN \ + if (*ZB>index_spr) {\ + if (*SubScreen) *Screen = COLOR_SUB(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr;} \ + Screen -= 320; SubScreen -= 320; Pixels++; ZB -= 320; + FN + FN + FN + FN + FN + FN + FN + FN + #undef FN +} + +///// +__inline void NORMAL_SUB1_2_16_T (uint32 Offset,uint16 *Pixels,uint32 solid) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + #define FN(N) \ + if (!(solid&(1<<(7-N)))) {\ + if (*SubScreen) *Screen = COLOR_SUB1_2(*Pixels,*SubScreen); \ + else *Screen=*Pixels;}\ + Screen += 320; SubScreen += 320; Pixels++; + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +} + +__inline void NORMAL_SUB1_2_16_O (uint32 Offset,uint16 *Pixels) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + #define FN \ + if (*SubScreen) *Screen = COLOR_SUB1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels; \ + Screen += 320; SubScreen += 320; Pixels++; + FN + FN + FN + FN + FN + FN + FN + FN + #undef FN +} + +__inline void FLIPPED_SUB1_2_16_T (uint32 Offset,uint16 *Pixels,uint32 solid) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + Screen += (7 * 320); + SubScreen += (7 * 320); + #define FN(N) \ + if (!(solid&(1<<(7-N)))) {\ + if (*SubScreen) *Screen = COLOR_SUB1_2(*Pixels,*SubScreen); \ + else *Screen=*Pixels;}\ + Screen -= 320; SubScreen -= 320; Pixels++; + + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +} + +__inline void FLIPPED_SUB1_2_16_O (uint32 Offset,uint16 *Pixels) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + Screen += (7 * 320); + SubScreen += (7 * 320); + #define FN \ + if (*SubScreen) *Screen = COLOR_SUB1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels; \ + Screen -= 320; SubScreen -= 320; Pixels++; + FN + FN + FN + FN + FN + FN + FN + FN + #undef FN +} + + + +__inline void NORMAL_SUB1_2_16_SPR_T (uint32 Offset,uint16 *Pixels,uint32 solid,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset; + + #define FN(N) \ + if ((!(solid&(1<<(7-N))))&&(*ZB>index_spr)) { \ + if (*SubScreen) *Screen = COLOR_SUB1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr; \ + } \ + Screen += 320; SubScreen += 320; Pixels++; ZB += 320; + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +} + +__inline void NORMAL_SUB1_2_16_SPR_O (uint32 Offset,uint16 *Pixels,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset; + + #define FN \ + if (*ZB>index_spr) {\ + if (*SubScreen) *Screen = COLOR_SUB1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr;} \ + Screen += 320; SubScreen += 320; Pixels++; ZB += 320; + FN + FN + FN + FN + FN + FN + FN + FN + #undef FN +} + +__inline void FLIPPED_SUB1_2_16_SPR_T (uint32 Offset,uint16 *Pixels,uint32 solid,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset + (7 * 320); + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset + (7 * 320); + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset + (7 * 320); + + #define FN(N) \ + if ((!(solid&(1<<(7-N))))&&(*ZB>index_spr)) { \ + if (*SubScreen) *Screen = COLOR_SUB1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr; }\ + Screen -= 320; SubScreen -= 320; Pixels++; ZB -= 320; + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +} + +__inline void FLIPPED_SUB1_2_16_SPR_O (uint32 Offset,uint16 *Pixels,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset + (7 * 320); + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset + (7 * 320); + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset + (7 * 320); + + #define FN \ + if (*ZB>index_spr) {\ + if (*SubScreen) *Screen = COLOR_SUB1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr;} \ + Screen -= 320; SubScreen -= 320; Pixels++; ZB -= 320; + FN + FN + FN + FN + FN + FN + FN + FN + #undef FN +} + +// Some of these are pointless, but what the hell... + +__inline void SqTrans_NORMAL16_T (uint32 Offset,uint16 *Pixels,uint32 solid) +{ +#if 1 + uint16 *Screen = (uint16 *) GFX.S + Offset; + + #define FN(N) \ + if (!(solid&(1<<(7-N)))) *Screen = *Pixels; \ + Screen+=640; Pixels+=2; + FN(0) + FN(2) + FN(4) + FN(6) + #undef FN +#endif +} + +__inline void SqTrans_NORMAL16_O (uint32 Offset,uint16 *Pixels) +{ +#if 1 + uint16 *Screen = (uint16 *) GFX.S + Offset; + + *Screen=*Pixels; + Screen+=640; Pixels+=2; + *Screen=*Pixels; + Screen+=640; Pixels+=2; + *Screen=*Pixels; + Screen+=640; Pixels+=2; + *Screen=*Pixels; +#endif +} + +__inline void SqTrans_FLIPPED16_T (uint32 Offset,uint16 *Pixels,uint32 solid) +{ + uint16 *Screen = (uint16 *) GFX.S + Offset; + + Screen += 6 * 320; + #define FN(N) \ + if (!(solid&(1<<(7-N)))) *Screen = *Pixels; \ + Screen -= 640; Pixels+=2; + FN(1) + FN(3) + FN(5) + FN(7) + #undef FN +} + +__inline void SqTrans_FLIPPED16_O (uint32 Offset,uint16 *Pixels) +{ + uint16 *Screen = (uint16 *) GFX.S + Offset; + + Screen += 6 * 320; + + *Screen=*Pixels; + Screen-=640; Pixels+=2; + *Screen=*Pixels; + Screen-=640; Pixels+=2; + *Screen=*Pixels; + Screen-=640; Pixels+=2; + *Screen=*Pixels; +} + + + +__inline void SqTrans_NORMAL16_SPR_T (uint32 Offset,uint16 *Pixels,uint32 solid,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.S + Offset; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset; + + #define FN(N) \ + if ((!(solid&(1<<(7-N))))&&(*ZB>index_spr)) { *Screen = *Pixels; *ZB=index_spr; } \ + Screen += 640; Pixels+=2; ZB += 640; + FN(0) + FN(2) + FN(4) + FN(6) + #undef FN +} + +__inline void SqTrans_NORMAL16_SPR_O (uint32 Offset,uint16 *Pixels,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.S + Offset; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset; + + #define FN \ + if (*ZB>index_spr) {*Screen=*Pixels; *ZB=index_spr;} \ + Screen += 640; Pixels+=2; ZB += 640; + FN + FN + FN + FN + #undef FN +} + +__inline void SqTrans_FLIPPED16_SPR_T (uint32 Offset,uint16 *Pixels,uint32 solid,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.S + Offset + (6 * 640); + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset + (6 * 640); + + #define FN(N) \ + if ((!(solid&(1<<(7-N))))&&(*ZB>index_spr)) { *Screen = *Pixels; *ZB=index_spr; }\ + Screen -= 640; Pixels+=2; ZB -= 640; + FN(1) + FN(3) + FN(5) + FN(7) + #undef FN +} + +__inline void SqTrans_FLIPPED16_SPR_O (uint32 Offset,uint16 *Pixels,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.S + Offset + (6 * 640); + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset + (6 * 640); + + #define FN \ + if (*ZB>index_spr) {*Screen=*Pixels; *ZB=index_spr;} \ + Screen -= 640; Pixels+=2; ZB -= 640; + FN + FN + FN + FN + #undef FN +} + + +__inline void SqTrans_NORMAL_ADD_16_T (uint32 Offset,uint16 *Pixels,uint32 solid) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + #define FN(N) \ + if (!(solid&(1<<(7-N)))) {\ + if (*SubScreen) *Screen = COLOR_ADD(*Pixels,*SubScreen); \ + else *Screen=*Pixels;}\ + Screen += 640; SubScreen += 640; Pixels+=2; + FN(0) + FN(2) + FN(4) + FN(6) + #undef FN +} + +__inline void SqTrans_NORMAL_ADD_16_O (uint32 Offset,uint16 *Pixels) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + #define FN \ + if (*SubScreen) *Screen = COLOR_ADD(*Pixels,*SubScreen);\ + else *Screen=*Pixels; \ + Screen += 640; SubScreen += 640; Pixels+=2; + FN + FN + FN + FN + #undef FN +} + +__inline void SqTrans_FLIPPED_ADD_16_T (uint32 Offset,uint16 *Pixels,uint32 solid) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + Screen += (6 * 640); + SubScreen += (6 * 640); + #define FN(N) \ + if (!(solid&(1<<(7-N)))) {\ + if (*SubScreen) *Screen = COLOR_ADD(*Pixels,*SubScreen); \ + else *Screen=*Pixels;}\ + Screen -= 640; SubScreen -= 640; Pixels+=2; + + FN(1) + FN(3) + FN(5) + FN(7) + #undef FN +} + +__inline void SqTrans_FLIPPED_ADD_16_O (uint32 Offset,uint16 *Pixels) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + Screen += (6 * 640); + SubScreen += (6 * 640); + #define FN \ + if (*SubScreen) *Screen = COLOR_ADD(*Pixels,*SubScreen);\ + else *Screen=*Pixels; \ + Screen -= 640; SubScreen -= 640; Pixels+=2; + FN + FN + FN + FN + #undef FN +} + + + +__inline void SqTrans_NORMAL_ADD_16_SPR_T (uint32 Offset,uint16 *Pixels,uint32 solid,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset; + + #define FN(N) \ + if ((!(solid&(1<<(7-N))))&&(*ZB>index_spr)) { \ + if (*SubScreen) *Screen = COLOR_ADD(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr; \ + } \ + Screen += 640; SubScreen += 640; Pixels+=2; ZB += 640; + FN(0) + FN(2) + FN(4) + FN(6) + #undef FN +} + +__inline void SqTrans_NORMAL_ADD_16_SPR_O (uint32 Offset,uint16 *Pixels,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset; + + #define FN \ + if (*ZB>index_spr) {\ + if (*SubScreen) *Screen = COLOR_ADD(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr;} \ + Screen += 640; SubScreen += 640; Pixels+=2; ZB += 640; + FN + FN + FN + FN + #undef FN +} + +__inline void SqTrans_FLIPPED_ADD_16_SPR_T (uint32 Offset,uint16 *Pixels,uint32 solid,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset + (6 * 640); + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset + (6 * 640); + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset + (6 * 640); + + #define FN(N) \ + if ((!(solid&(1<<(7-N))))&&(*ZB>index_spr)) { \ + if (*SubScreen) *Screen = COLOR_ADD(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr; }\ + Screen -= 640; SubScreen -= 640; Pixels+=2; ZB -= 640; + FN(1) + FN(3) + FN(5) + FN(7) + #undef FN +} + +__inline void SqTrans_FLIPPED_ADD_16_SPR_O (uint32 Offset,uint16 *Pixels,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset + (6 * 640); + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset + (6 * 640); + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset + (6 * 640); + + #define FN \ + if (*ZB>index_spr) {\ + if (*SubScreen) *Screen = COLOR_ADD(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr;} \ + Screen -= 640; SubScreen -= 640; Pixels+=2; ZB -= 640; + FN + FN + FN + FN + #undef FN +} + +//////////////////// fooble +__inline void SqTrans_NORMAL_ADD1_2_16_T (uint32 Offset,uint16 *Pixels,uint32 solid) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + #define FN(N) \ + if (!(solid&(1<<(7-N)))) {\ + if (*SubScreen) *Screen = COLOR_ADD1_2(*Pixels,*SubScreen); \ + else *Screen=*Pixels;}\ + Screen += 640; SubScreen += 640; Pixels+=2; + FN(0) + FN(2) + FN(4) + FN(6) + #undef FN +} + +__inline void SqTrans_NORMAL_ADD1_2_16_O (uint32 Offset,uint16 *Pixels) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + #define FN \ + if (*SubScreen) *Screen = COLOR_ADD1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels; \ + Screen += 640; SubScreen += 640; Pixels+=2; + FN + FN + FN + FN + #undef FN +} + +__inline void SqTrans_FLIPPED_ADD1_2_16_T (uint32 Offset,uint16 *Pixels,uint32 solid) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + Screen += (6 * 640); + SubScreen += (6 * 640); + #define FN(N) \ + if (!(solid&(1<<(7-N)))) {\ + if (*SubScreen) *Screen = COLOR_ADD1_2(*Pixels,*SubScreen); \ + else *Screen=*Pixels;}\ + Screen -= 640; SubScreen -= 640; Pixels+=2; + + FN(1) + FN(3) + FN(5) + FN(7) + #undef FN +} + +__inline void SqTrans_FLIPPED_ADD1_2_16_O (uint32 Offset,uint16 *Pixels) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + Screen += (6 * 640); + SubScreen += (6 * 640); + #define FN \ + if (*SubScreen) *Screen = COLOR_ADD1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels; \ + Screen -= 640; SubScreen -= 640; Pixels+=2; + FN + FN + FN + FN + #undef FN +} + + + +__inline void SqTrans_NORMAL_ADD1_2_16_SPR_T (uint32 Offset,uint16 *Pixels,uint32 solid,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset; + + #define FN(N) \ + if ((!(solid&(1<<(7-N))))&&(*ZB>index_spr)) { \ + if (*SubScreen) *Screen = COLOR_ADD1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr; \ + } \ + Screen += 640; SubScreen += 640; Pixels+=2; ZB += 640; + FN(0) + FN(2) + FN(4) + FN(6) + #undef FN +} + +__inline void SqTrans_NORMAL_ADD1_2_16_SPR_O (uint32 Offset,uint16 *Pixels,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset; + + #define FN \ + if (*ZB>index_spr) {\ + if (*SubScreen) *Screen = COLOR_ADD1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr;} \ + Screen += 640; SubScreen += 640; Pixels+=2; ZB += 640; + FN + FN + FN + FN + #undef FN +} + +__inline void SqTrans_FLIPPED_ADD1_2_16_SPR_T (uint32 Offset,uint16 *Pixels,uint32 solid,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset + (6 * 640); + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset + (6 * 640); + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset + (6 * 640); + + #define FN(N) \ + if ((!(solid&(1<<(7-N))))&&(*ZB>index_spr)) { \ + if (*SubScreen) *Screen = COLOR_ADD1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr; }\ + Screen -= 640; SubScreen -= 640; Pixels+=2; ZB -= 640; + FN(1) + FN(3) + FN(5) + FN(7) + #undef FN +} + +__inline void SqTrans_FLIPPED_ADD1_2_16_SPR_O (uint32 Offset,uint16 *Pixels,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset + (6 * 640); + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset + (6 * 640); + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset + (6 * 640); + + #define FN \ + if (*ZB>index_spr) {\ + if (*SubScreen) *Screen = COLOR_ADD1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr;} \ + Screen -= 640; SubScreen -= 640; Pixels+=2; ZB -= 640; + FN + FN + FN + FN + #undef FN +} + +__inline void SqTrans_NORMAL_SUB_16_T (uint32 Offset,uint16 *Pixels,uint32 solid) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + #define FN(N) \ + if (!(solid&(1<<(7-N)))) {\ + if (*SubScreen) *Screen = COLOR_SUB(*Pixels,*SubScreen); \ + else *Screen=*Pixels;}\ + Screen += 640; SubScreen += 640; Pixels+=2; + FN(0) + FN(2) + FN(4) + FN(6) + #undef FN +} + +__inline void SqTrans_NORMAL_SUB_16_O (uint32 Offset,uint16 *Pixels) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + #define FN \ + if (*SubScreen) *Screen = COLOR_SUB(*Pixels,*SubScreen);\ + else *Screen=*Pixels; \ + Screen += 640; SubScreen += 640; Pixels+=2; + FN + FN + FN + FN + #undef FN +} + +__inline void SqTrans_FLIPPED_SUB_16_T (uint32 Offset,uint16 *Pixels,uint32 solid) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + Screen += (6 * 640); + SubScreen += (6 * 640); + #define FN(N) \ + if (!(solid&(1<<(7-N)))) {\ + if (*SubScreen) *Screen = COLOR_SUB(*Pixels,*SubScreen); \ + else *Screen=*Pixels;}\ + Screen -= 640; SubScreen -= 640; Pixels+=2; + + FN(1) + FN(3) + FN(5) + FN(7) + #undef FN +} + +__inline void SqTrans_FLIPPED_SUB_16_O (uint32 Offset,uint16 *Pixels) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + Screen += (6 * 640); + SubScreen += (6 * 640); + #define FN \ + if (*SubScreen) *Screen = COLOR_SUB(*Pixels,*SubScreen);\ + else *Screen=*Pixels; \ + Screen -= 640; SubScreen -= 640; Pixels+=2; + FN + FN + FN + FN + #undef FN +} + + + +__inline void SqTrans_NORMAL_SUB_16_SPR_T (uint32 Offset,uint16 *Pixels,uint32 solid,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset; + + #define FN(N) \ + if ((!(solid&(1<<(7-N))))&&(*ZB>index_spr)) { \ + if (*SubScreen) *Screen = COLOR_SUB(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr; \ + } \ + Screen += 640; SubScreen += 640; Pixels+=2; ZB += 640; + FN(0) + FN(2) + FN(4) + FN(6) + #undef FN +} + +__inline void SqTrans_NORMAL_SUB_16_SPR_O (uint32 Offset,uint16 *Pixels,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset; + + #define FN \ + if (*ZB>index_spr) {\ + if (*SubScreen) *Screen = COLOR_SUB(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr;} \ + Screen += 640; SubScreen += 640; Pixels+=2; ZB += 640; + FN + FN + FN + FN + #undef FN +} + +__inline void SqTrans_FLIPPED_SUB_16_SPR_T (uint32 Offset,uint16 *Pixels,uint32 solid,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset + (6 * 640); + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset + (6 * 640); + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset + (6 * 640); + + #define FN(N) \ + if ((!(solid&(1<<(7-N))))&&(*ZB>index_spr)) { \ + if (*SubScreen) *Screen = COLOR_SUB(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr; }\ + Screen -= 640; SubScreen -= 640; Pixels+=2; ZB -= 640; + FN(1) + FN(3) + FN(5) + FN(7) + #undef FN +} + +__inline void SqTrans_FLIPPED_SUB_16_SPR_O (uint32 Offset,uint16 *Pixels,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset + (6 * 640); + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset + (6 * 640); + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset + (6 * 640); + + #define FN \ + if (*ZB>index_spr) {\ + if (*SubScreen) *Screen = COLOR_SUB(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr;} \ + Screen -= 640; SubScreen -= 640; Pixels+=2; ZB -= 640; + FN + FN + FN + FN + #undef FN +} + +///// +__inline void SqTrans_NORMAL_SUB1_2_16_T (uint32 Offset,uint16 *Pixels,uint32 solid) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + #define FN(N) \ + if (!(solid&(1<<(7-N)))) {\ + if (*SubScreen) *Screen = COLOR_SUB1_2(*Pixels,*SubScreen); \ + else *Screen=*Pixels;}\ + Screen += 640; SubScreen += 640; Pixels+=2; + FN(0) + FN(2) + FN(4) + FN(6) + #undef FN +} + +__inline void SqTrans_NORMAL_SUB1_2_16_O (uint32 Offset,uint16 *Pixels) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + #define FN \ + if (*SubScreen) *Screen = COLOR_SUB1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels; \ + Screen += 640; SubScreen += 640; Pixels+=2; + FN + FN + FN + FN + #undef FN +} + +__inline void SqTrans_FLIPPED_SUB1_2_16_T (uint32 Offset,uint16 *Pixels,uint32 solid) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + Screen += (6 * 640); + SubScreen += (6 * 640); + #define FN(N) \ + if (!(solid&(1<<(7-N)))) {\ + if (*SubScreen) *Screen = COLOR_SUB1_2(*Pixels,*SubScreen); \ + else *Screen=*Pixels;}\ + Screen -= 640; SubScreen -= 640; Pixels+=2; + + FN(1) + FN(3) + FN(5) + FN(7) + #undef FN +} + +__inline void SqTrans_FLIPPED_SUB1_2_16_O (uint32 Offset,uint16 *Pixels) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + Screen += (6 * 640); + SubScreen += (6 * 640); + #define FN \ + if (*SubScreen) *Screen = COLOR_SUB1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels; \ + Screen -= 640; SubScreen -= 640; Pixels+=2; + FN + FN + FN + FN + #undef FN +} + + + +__inline void SqTrans_NORMAL_SUB1_2_16_SPR_T (uint32 Offset,uint16 *Pixels,uint32 solid,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset; + + #define FN(N) \ + if ((!(solid&(1<<(7-N))))&&(*ZB>index_spr)) { \ + if (*SubScreen) *Screen = COLOR_SUB1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr; \ + } \ + Screen += 640; SubScreen += 640; Pixels+=2; ZB += 640; + FN(0) + FN(2) + FN(4) + FN(6) + #undef FN +} + +__inline void SqTrans_NORMAL_SUB1_2_16_SPR_O (uint32 Offset,uint16 *Pixels,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset; + + #define FN \ + if (*ZB>index_spr) {\ + if (*SubScreen) *Screen = COLOR_SUB1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr;} \ + Screen += 640; SubScreen += 640; Pixels+=2; ZB += 640; + FN + FN + FN + FN + #undef FN +} + +__inline void SqTrans_FLIPPED_SUB1_2_16_SPR_T (uint32 Offset,uint16 *Pixels,uint32 solid,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset + (6 * 640); + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset + (6 * 640); + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset + (6 * 640); + + #define FN(N) \ + if ((!(solid&(1<<(7-N))))&&(*ZB>index_spr)) { \ + if (*SubScreen) *Screen = COLOR_SUB1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr; }\ + Screen -= 640; SubScreen -= 640; Pixels+=2; ZB -= 640; + FN(1) + FN(3) + FN(5) + FN(7) + #undef FN +} + +__inline void SqTrans_FLIPPED_SUB1_2_16_SPR_O (uint32 Offset,uint16 *Pixels,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset + (6 * 640); + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset + (6 * 640); + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset + (6 * 640); + + #define FN \ + if (*ZB>index_spr) {\ + if (*SubScreen) *Screen = COLOR_SUB1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr;} \ + Screen -= 640; SubScreen -= 640; Pixels+=2; ZB -= 640; + FN + FN + FN + FN + #undef FN +} + + + +/********************************/ + +#if 1 +__inline void NORMAL8_T (uint32 Offset,uint8 *Pixels,uint32 solid) +{ + uint8 *Screen = (uint8 *) GFX.S + Offset; + + #define FN(N) \ + if (!(solid&(1<<(7-N)))) *Screen = *Pixels; \ + Screen--; Pixels++; + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +} +__inline void NORMAL8_O (uint32 Offset,uint8 *Pixels) +{ + uint8 *Screen = (uint8 *) GFX.S + Offset; + + *Screen=*Pixels; + Screen--; Pixels++; + *Screen=*Pixels; + Screen--; Pixels++; + *Screen=*Pixels; + Screen--; Pixels++; + *Screen=*Pixels; + Screen--; Pixels++; + *Screen=*Pixels; + Screen--; Pixels++; + *Screen=*Pixels; + Screen--; Pixels++; + *Screen=*Pixels; + Screen--; Pixels++; + *Screen=*Pixels; + +} + +__inline void FLIPPED8_T (uint32 Offset,uint8 *Pixels,uint32 solid) +{ + uint8 *Screen = (uint8 *) GFX.S + Offset; + + Screen -= 7; + #define FN(N) \ + if (!(solid&(1<<(7-N)))) *Screen = *Pixels; \ + Screen++; Pixels++; + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +} + +__inline void FLIPPED8_O (uint32 Offset,uint8 *Pixels) +{ + uint8 *Screen = (uint8 *) GFX.S + Offset; + + Screen -= 7; + + *Screen=*Pixels; + Screen++; Pixels++; + *Screen=*Pixels; + Screen++; Pixels++; + *Screen=*Pixels; + Screen++; Pixels++; + *Screen=*Pixels; + Screen++; Pixels++; + *Screen=*Pixels; + Screen++; Pixels++; + *Screen=*Pixels; + Screen++; Pixels++; + *Screen=*Pixels; + Screen++; Pixels++; + *Screen=*Pixels; +} + + +__inline void NORMAL8_SPR_T (uint32 Offset,uint8 *Pixels,uint32 solid,uint32 index_spr) +{ + uint8 *Screen = (uint8 *) GFX.S + Offset; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset; + + #define FN(N) \ + if ((!(solid&(1<<(7-N))))&&(*ZB>index_spr)) { *Screen = *Pixels; *ZB=index_spr; } \ + Screen--; Pixels++; ZB--; + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +} + +__inline void NORMAL8_SPR_O (uint32 Offset,uint8 *Pixels,uint32 index_spr) +{ + uint8 *Screen = (uint8 *) GFX.S + Offset; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset; + + #define FN \ + if (*ZB>index_spr) {*Screen=*Pixels; *ZB=index_spr;} \ + Screen--; Pixels++; ZB--; + FN + FN + FN + FN + FN + FN + FN + FN + #undef FN +} + +__inline void FLIPPED8_SPR_T (uint32 Offset,uint8 *Pixels,uint32 solid,uint32 index_spr) +{ + uint8 *Screen = (uint8 *) GFX.S + Offset - 7; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset - 7; + + #define FN(N) \ + if ((!(solid&(1<<(7-N))))&&(*ZB>index_spr)) { *Screen = *Pixels; *ZB=index_spr; }\ + Screen++; Pixels++; ZB++; + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +} + +__inline void FLIPPED8_SPR_O (uint32 Offset,uint8 *Pixels,uint32 index_spr) +{ + uint8 *Screen = (uint8 *) GFX.S + Offset - 7; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset - 7; + + #define FN \ + if (*ZB>index_spr) {*Screen=*Pixels; *ZB=index_spr;} \ + Screen++; Pixels++; ZB++; + FN + FN + FN + FN + FN + FN + FN + FN + #undef FN +} + + + +void DrawHiResTile8New (uint32 Tile, uint32 Offset, uint32 StartLine, uint32 LineCount) +{ + uint8 *pCache; + uint32 Col; + uint32 TileAddr = BG.TileAddress + ((Tile & 0x3ff) << BG.TileShift); + if ((Tile & 0x1ff) >= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? +/* if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask];*/ + Col = 0; + } + else + { +/* GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette];*/ + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + + if (!BG.Buffered [TileNumber<<1]) + { + BG.Buffered[TileNumber<<1] = ConvertTile8New (pCache, TileAddr); + BG.Buffered[(TileNumber<<1)|1] = Col; + int i; + uint8 *p=pCache+8; + for (i=0;i<64;i++,p++) *p=p[64]|Col; + } + else + if (BG.Buffered [(TileNumber<<1)|1]!=Col) + { + //update cache + int i; + uint8 *p=pCache+8; + for (i=0;i<64;i++,p++) *p=p[64]|Col; + BG.Buffered [(TileNumber<<1)|1]=Col; + } + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8; + + for (l = 4; l != 0; l--, bp += 8*2, Offset+=1) + NORMAL8_O (Offset, (uint8*)bp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8; + Offset += 3; + for (l = 4; l != 0; l--, bp += 8*2, Offset-=1) + NORMAL8_O (Offset, (uint8*)bp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8; + Offset += 3; + + for (l = 4; l != 0; l--, bp += 8*2, Offset-=1) + FLIPPED8_O (Offset, (uint8*)bp); + + } + else + { + //VFLIP + + + bp = pCache+8; + for (l = 4; l != 0; l--, bp += 8*2, Offset+=1) + FLIPPED8_O (Offset, (uint8*)bp); + + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache; + bp = pCache+8; + + for (l = 4; l != 0; l--, bp += 8*2, headerbp+=2, Offset+=1) + NORMAL8_T (Offset, (uint8*)bp,solid_lineclip|*headerbp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache; + bp = pCache+8; + Offset += 3; + for (l = 4; l != 0; l--, bp += 8*2, headerbp+=2, Offset-=1) + NORMAL8_T (Offset, (uint8*)bp,solid_lineclip|*headerbp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? +/* if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask];*/ + Col = 0; + } + else + { +/* GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette];*/ + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + + if (!BG.Buffered [TileNumber<<1]) + { + BG.Buffered[TileNumber<<1] = ConvertTile8New (pCache, TileAddr); + BG.Buffered[(TileNumber<<1)|1] = Col; + int i; + uint8 *p=pCache+8; + for (i=0;i<64;i++,p++) *p=p[64]|Col; + } + else + if (BG.Buffered [(TileNumber<<1)|1]!=Col) + { + //update cache + int i; + uint8 *p=pCache+8; + for (i=0;i<64;i++,p++) *p=p[64]|Col; + BG.Buffered [(TileNumber<<1)|1]=Col; + } + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + bp = pCache+8 + StartPixel*8; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2, Offset+=1) + NORMAL8_O (Offset, (uint8*)bp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + bp = pCache+8+StartPixel*8; + Offset += ((StartPixel+Width-1)>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2, Offset-=1) + NORMAL8_O (Offset, (uint8*)bp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8+StartPixel*8; + Offset += ((StartPixel+Width-1)>>1); + + for (l = Width>>1; l != 0; l--, bp += 8*2, Offset-=1) + FLIPPED8_O (Offset, (uint8*)bp); + + } + else + { + //VFLIP + + bp = pCache+8+StartPixel*8; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2, Offset+=1) + FLIPPED8_O (Offset, (uint8*)bp); + + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*8; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2, headerbp+=2, Offset+=1) + NORMAL8_T (Offset, (uint8*)bp,solid_lineclip|*headerbp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*8; + Offset += ((StartPixel+Width-1)>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2, headerbp+=2, Offset-=1) + NORMAL8_T (Offset, (uint8*)bp,solid_lineclip|*headerbp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<>1); + + for (l = Width>>1; l != 0; l--, bp += 8*2, headerbp+=2, Offset-=1) + FLIPPED8_T (Offset, (uint8*)bp,solid_lineclipI|*headerbp); + + } + else + { + //VFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<>1); + for (l = Width>>1; l != 0; l--, bp += 8*2, headerbp+=2, Offset+=1) + FLIPPED8_T (Offset, (uint8*)bp,solid_lineclipI|*headerbp); + + } + } +} + + + +void DrawTile8New (uint32 Tile, uint32 Offset, uint32 StartLine, uint32 LineCount) +{ + uint8 *pCache; + uint32 Col; + uint32 TileAddr = BG.TileAddress + ((Tile & 0x3ff) << BG.TileShift); + if ((Tile & 0x1ff) >= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? +/* if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask];*/ + Col = 0; + } + else + { +/* GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette];*/ + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + + if (!BG.Buffered [TileNumber<<1]) + { + BG.Buffered[TileNumber<<1] = ConvertTile8New (pCache, TileAddr); + BG.Buffered[(TileNumber<<1)|1] = Col; + int i; + uint8 *p=pCache+8; + for (i=0;i<64;i++,p++) *p=p[64]|Col; + } + else + if (BG.Buffered [(TileNumber<<1)|1]!=Col) + { + //update cache + int i; + uint8 *p=pCache+8; + for (i=0;i<64;i++,p++) *p=p[64]|Col; + BG.Buffered [(TileNumber<<1)|1]=Col; + } + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; +#ifndef asmPPU8 + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; +#endif + + { +#ifndef asmPPU8 + Offset -= (StartLine * 320);; //align to tile multiple +#endif + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU8 + asmDrawTile8((uint32)pCache,StartLine|(LineCount<<16),(uint32)(GFX.S+(Offset)),0); +#else + headerbp = pCache; + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8, headerbp++, Offset+=1) + NORMAL8_T (Offset, (uint8*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU8 + asmDrawTile8((uint32)pCache,StartLine|(LineCount<<16),(uint32)(GFX.S+(Offset)),2); +#else + headerbp = pCache; + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8, headerbp++, Offset-=1) + NORMAL8_T (Offset, (uint8*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + +#ifdef asmPPU8 + asmDrawTile8((uint32)pCache,StartLine|(LineCount<<16),(uint32)(GFX.S+(Offset)),3); +#else + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? +/* if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask];*/ + Col = 0; + } + else + { +/* GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette];*/ + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if (!BG.Buffered [TileNumber<<1]) + { + BG.Buffered[TileNumber<<1] = ConvertTile8New (pCache, TileAddr); + BG.Buffered[(TileNumber<<1)|1] = Col; + int i; + uint8 *p=pCache+8; + for (i=0;i<64;i++,p++) *p=p[64]|Col; + } + else + if (BG.Buffered [(TileNumber<<1)|1]!=Col) + { + //update cache + int i; + uint8 *p=pCache+8; + for (i=0;i<64;i++,p++) *p=p[64]|Col; + BG.Buffered [(TileNumber<<1)|1]=Col; + } + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; +#ifndef asmPPU8 + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; +#endif + + { +#ifndef asmPPU8 + Offset -= (StartLine * 320);; //align to tile multiple +#endif + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU8 + asmDrawTile8((uint32)pCache,StartLine|(LineCount<<16),(uint32)(GFX.S+(Offset)),0); +#else + headerbp = pCache; + bp = pCache+8; + + for (l = 8; l != 0; l--, bp += 8, headerbp++, Offset+=1) + NORMAL8_SPR_T (Offset, (uint8*)bp,solid_lineclip|*headerbp,index_spr); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU8 + asmDrawTile8((uint32)pCache,StartLine|(LineCount<<16),(uint32)(GFX.S+(Offset)),2); +#else + headerbp = pCache; + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8, headerbp++, Offset-=1) + NORMAL8_SPR_T (Offset, (uint8*)bp,solid_lineclip|*headerbp,index_spr); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP +#ifdef asmPPU8 + asmDrawTile8((uint32)pCache,StartLine|(LineCount<<16),(uint32)(GFX.S+(Offset)),3); +#else + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + + bp = pCache+8; + // do this one first! + StartLine=0; + Offset-=(StartLine*320); + for (l = 0; l < 1; l++, bp += 8*2, Offset+=320) + NORMAL16_O (Offset, (uint16*)bp); + + return; + + if ( (BG.Buffered [TileNumber<<1] == 2)) + { + + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU16 + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)),0); +#else + bp = pCache+8; + // do this one first! + for (l = 0; l < LineCount; l++, bp += 8*2, Offset+=320) + NORMAL16_O (Offset, (uint16*)bp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU16 + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)+7*2),2); +#else + bp = pCache+8; + Offset += 7; + // do this one when the first one works! + for (l = 0; l < LineCount; l++, bp += 8*2, Offset+=320) + FLIPPED16_O (Offset, (uint16*)bp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP +#ifdef asmPPU16 + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)+7*2),3); +#else + bp = pCache+8; + Offset += (LineCount * 320)+7; + for (l = 0; l < LineCount; l++, bp += 8*2, Offset-=320) + FLIPPED16_O (Offset, (uint16*)bp); +#endif + } + else + { + //VFLIP +#ifdef asmPPU16 + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)),1); +#else + bp = pCache+8; + Offset += (LineCount * 320); + for (l = 0; l < LineCount; l++, bp += 8*2, Offset-=320) + NORMAL16_O (Offset, (uint16*)bp); +#endif + } + } + else + { + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU16 + asmDrawTile16((uint32)pCache,solid_lineclip,(uint32)(GFX.S+(Offset<<1)),0); +#else + headerbp = pCache; + bp = pCache+8; + // do this one when the first one works! + for (l = 0; l < LineCount; l++, bp += 8*2, headerbp++, Offset+=320) + NORMAL16_T (Offset, (uint16*)bp,*headerbp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU16 + asmDrawTile16((uint32)pCache,solid_lineclip,(uint32)(GFX.S+(Offset<<1)+7*2),2); +#else + headerbp = pCache; + bp = pCache+8; + Offset += 7; + // do this one when the first one works! + for (l = 0; l < LineCount; l++, bp += 8*2, headerbp++, Offset+=320) + FLIPPED16_T (Offset, (uint16*)bp,*headerbp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP +#ifdef asmPPU16 + asmDrawTile16((uint32)pCache,solid_lineclipI,(uint32)(GFX.S+(Offset<<1)+7*2),3); +#else + headerbp = pCache; + bp = pCache+8; + Offset += (LineCount * 320)+7; + for (l = 0; l < LineCount; l++, bp += 8*2, headerbp++, Offset-=320) + FLIPPED16_T (Offset, (uint16*)bp,*headerbp); +#endif + } + else + { + //VFLIP +#ifdef asmPPU16 + asmDrawTile16((uint32)pCache,solid_lineclipI,(uint32)(GFX.S+(Offset<<1)),1); +#else + headerbp = pCache; + bp = pCache+8; + Offset += (LineCount * 320); + for (l = 0; l < LineCount; l++, bp += 8*2, headerbp++, Offset-=320) + NORMAL16_T (Offset, (uint16*)bp,*headerbp); +#endif + } + } +#endif +} + +void DrawClippedTile16New (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount) +{ + DrawTile16New (Tile, Offset, StartLine, LineCount); +} + +void DrawTile16NewSprite (uint32 Tile, uint32 Offset, uint32 StartLine, uint32 LineCount, uint32 index_spr) +{ + uint8 *pCache; + uint32 Col; + uint32 TileAddr = BG.TileAddress + ((Tile & 0x3ff) << BG.TileShift); + if ((Tile & 0x1ff) >= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8; + + for (l = 8; l != 0; l--, bp += 8*2, Offset++) + NORMAL16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, Offset--) + NORMAL16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8; + Offset += 7; + + for (l = 8; l != 0; l--, bp += 8*2, Offset--) + FLIPPED16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + else + { + //VFLIP + + + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset++) + FLIPPED16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache; + bp = pCache+8; + + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset++) + NORMAL16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache; + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset--) + NORMAL16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset++) + NORMAL16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, Offset--) + NORMAL16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + + for (l = Width; l != 0; l--, bp += 8*2, Offset--) + FLIPPED16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + else + { + //VFLIP + + bp = pCache+8+StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset++) + FLIPPED16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset++) + NORMAL16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset--) + NORMAL16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8; + + // do this one when the first one works! + for (l = 4; l != 0; l--, bp += 8*2*2, Offset+=1) + NORMAL16_O (Offset, (uint16*)bp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8; + Offset += 3; + for (l = 4; l != 0; l--, bp += 8*2*2, Offset-=1) + NORMAL16_O (Offset, (uint16*)bp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8; + Offset += 3; + + for (l = 4; l != 0; l--, bp += 8*2*2, Offset-=1) + FLIPPED16_O (Offset, (uint16*)bp); + + } + else + { + //VFLIP + + + bp = pCache+8; + for (l = 4; l != 0; l--, bp += 8*2*2, Offset+=1) + FLIPPED16_O (Offset, (uint16*)bp); + + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache; + bp = pCache+8; + + // do this one when the first one works! + for (l = 4; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + NORMAL16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache; + bp = pCache+8; + Offset += 3; + for (l = 4; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + NORMAL16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + bp = pCache+8 + StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset+=1) + NORMAL16_O (Offset, (uint16*)bp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset-=1) + NORMAL16_O (Offset, (uint16*)bp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset-=1) + FLIPPED16_O (Offset, (uint16*)bp); + + } + else + { + //VFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset+=1) + FLIPPED16_O (Offset, (uint16*)bp); + + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + NORMAL16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + NORMAL16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<>1); + + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + FLIPPED16_T (Offset, (uint16*)bp,solid_lineclipI|*headerbp); + + } + else + { + //VFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + FLIPPED16_T (Offset, (uint16*)bp,solid_lineclipI|*headerbp); + + } + } +} + +/****************** ADD ***********************/ +void DrawTile16ADDNew (uint32 Tile, uint32 Offset, uint32 StartLine, uint32 LineCount) +{ + uint8 *pCache; + uint32 Col; + uint32 TileAddr = BG.TileAddress + ((Tile & 0x3ff) << BG.TileShift); + + if ((Tile & 0x1ff) >= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)),0); +#else + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + NORMAL_ADD_16_O (Offset, (uint16*)bp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)+7*2),2); +#else + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + NORMAL_ADD_16_O (Offset, (uint16*)bp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)+7*2),3); +#else + bp = pCache+8; + Offset += 7; + + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + FLIPPED_ADD_16_O (Offset, (uint16*)bp); +#endif + } + else + { + //VFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)),1); +#else + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + FLIPPED_ADD_16_O (Offset, (uint16*)bp); +#endif + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,solid_lineclip,(uint32)(GFX.S+(Offset<<1)),0); +#else + headerbp = pCache; + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + NORMAL_ADD_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,solid_lineclip,(uint32)(GFX.S+(Offset<<1)+7*2),2); +#else + headerbp = pCache; + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + NORMAL_ADD_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+StartPixel*2),0); +#else + + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + NORMAL_ADD_16_O (Offset, (uint16*)bp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),2); +#else + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + NORMAL_ADD_16_O (Offset, (uint16*)bp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),3); +#else + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + FLIPPED_ADD_16_O (Offset, (uint16*)bp); +#endif + } + else + { + //VFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+StartPixel*2),1); +#else + + bp = pCache+8+StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + FLIPPED_ADD_16_O (Offset, (uint16*)bp); +#endif + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8)|solid_lineclip,(uint32)(GFX.S+(Offset<<1)+StartPixel*2),0); +#else + + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + NORMAL_ADD_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8)|solid_lineclip,(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),2); +#else + + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + NORMAL_ADD_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8; + + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + NORMAL_ADD_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + NORMAL_ADD_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8; + Offset += 7; + + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + FLIPPED_ADD_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + else + { + //VFLIP + + + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + FLIPPED_ADD_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache; + bp = pCache+8; + + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + NORMAL_ADD_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache; + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + NORMAL_ADD_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + NORMAL_ADD_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + NORMAL_ADD_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + FLIPPED_ADD_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + else + { + //VFLIP + + bp = pCache+8+StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + FLIPPED_ADD_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + NORMAL_ADD_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + NORMAL_ADD_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8; + + for (l = 4; l != 0; l--, bp += 8*2*2, Offset+=1) + NORMAL_ADD_16_O (Offset, (uint16*)bp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8; + Offset += 3; + for (l = 4; l != 0; l--, bp += 8*2*2, Offset-=1) + NORMAL_ADD_16_O (Offset, (uint16*)bp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8; + Offset += 3; + + for (l = 4; l != 0; l--, bp += 8*2*2, Offset-=1) + FLIPPED_ADD_16_O (Offset, (uint16*)bp); + + } + else + { + //VFLIP + + + bp = pCache+8; + for (l = 4; l != 0; l--, bp += 8*2*2, Offset+=1) + FLIPPED_ADD_16_O (Offset, (uint16*)bp); + + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache; + bp = pCache+8; + + for (l = 4; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + NORMAL_ADD_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache; + bp = pCache+8; + Offset += 3; + for (l = 4; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + NORMAL_ADD_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + bp = pCache+8 + StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset+=1) + NORMAL_ADD_16_O (Offset, (uint16*)bp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset-=1) + NORMAL_ADD_16_O (Offset, (uint16*)bp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset-=1) + FLIPPED_ADD_16_O (Offset, (uint16*)bp); + + } + else + { + //VFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset+=1) + FLIPPED_ADD_16_O (Offset, (uint16*)bp); + + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + NORMAL_ADD_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + NORMAL_ADD_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<>1); + + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + FLIPPED_ADD_16_T (Offset, (uint16*)bp,solid_lineclipI|*headerbp); + + } + else + { + //VFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + FLIPPED_ADD_16_T (Offset, (uint16*)bp,solid_lineclipI|*headerbp); + + } + } +} + +/****************** ADD1_2 ***********************/ +void DrawTile16ADD1_2New (uint32 Tile, uint32 Offset, uint32 StartLine, uint32 LineCount) +{ + uint8 *pCache; + uint32 Col; + uint32 TileAddr = BG.TileAddress + ((Tile & 0x3ff) << BG.TileShift); + if ((Tile & 0x1ff) >= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)),0); +#else + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + NORMAL_ADD1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)+7*2),2); +#else + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + NORMAL_ADD1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)+7*2),3); +#else + bp = pCache+8; + Offset += 7; + + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + FLIPPED_ADD1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + { + //VFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)),1); +#else + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + FLIPPED_ADD1_2_16_O (Offset, (uint16*)bp); +#endif + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,solid_lineclip,(uint32)(GFX.S+(Offset<<1)),0); +#else + headerbp = pCache; + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + NORMAL_ADD1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,solid_lineclip,(uint32)(GFX.S+(Offset<<1)+7*2),2); +#else + headerbp = pCache; + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + NORMAL_ADD1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+StartPixel*2),0); +#else + + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + NORMAL_ADD1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),2); +#else + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + NORMAL_ADD1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),3); +#else + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + FLIPPED_ADD1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + { + //VFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+StartPixel*2),1); +#else + + bp = pCache+8+StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + FLIPPED_ADD1_2_16_O (Offset, (uint16*)bp); +#endif + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8)|solid_lineclip,(uint32)(GFX.S+(Offset<<1)+StartPixel*2),0); +#else + + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + NORMAL_ADD1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8)|solid_lineclip,(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),2); +#else + + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + NORMAL_ADD1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8; + + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + NORMAL_ADD1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + NORMAL_ADD1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8; + Offset += 7; + + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + FLIPPED_ADD1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + else + { + //VFLIP + + + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + FLIPPED_ADD1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache; + bp = pCache+8; + + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + NORMAL_ADD1_2_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache; + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + NORMAL_ADD1_2_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + NORMAL_ADD1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + NORMAL_ADD1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + FLIPPED_ADD1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + else + { + //VFLIP + + bp = pCache+8+StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + FLIPPED_ADD1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + NORMAL_ADD1_2_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + NORMAL_ADD1_2_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8; + + for (l = 4; l != 0; l--, bp += 8*2*2, Offset+=1) + NORMAL_ADD1_2_16_O (Offset, (uint16*)bp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8; + Offset += 3; + for (l = 4; l != 0; l--, bp += 8*2*2, Offset-=1) + NORMAL_ADD1_2_16_O (Offset, (uint16*)bp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8; + Offset += 3; + + for (l = 4; l != 0; l--, bp += 8*2*2, Offset-=1) + FLIPPED_ADD1_2_16_O (Offset, (uint16*)bp); + + } + else + { + //VFLIP + + + bp = pCache+8; + for (l = 4; l != 0; l--, bp += 8*2*2, Offset+=1) + FLIPPED_ADD1_2_16_O (Offset, (uint16*)bp); + + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache; + bp = pCache+8; + + for (l = 4; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + NORMAL_ADD1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache; + bp = pCache+8; + Offset += 3; + for (l = 4; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + NORMAL_ADD1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + bp = pCache+8 + StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset+=1) + NORMAL_ADD1_2_16_O (Offset, (uint16*)bp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset-=1) + NORMAL_ADD1_2_16_O (Offset, (uint16*)bp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset-=1) + FLIPPED_ADD1_2_16_O (Offset, (uint16*)bp); + + } + else + { + //VFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset+=1) + FLIPPED_ADD1_2_16_O (Offset, (uint16*)bp); + + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + NORMAL_ADD1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + NORMAL_ADD1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<>1); + + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + FLIPPED_ADD1_2_16_T (Offset, (uint16*)bp,solid_lineclipI|*headerbp); + + } + else + { + //VFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + FLIPPED_ADD1_2_16_T (Offset, (uint16*)bp,solid_lineclipI|*headerbp); + + } + } +} + + +/****************** SUB ***********************/ +void DrawTile16SUBNew (uint32 Tile, uint32 Offset, uint32 StartLine, uint32 LineCount) +{ + uint8 *pCache; + uint32 Col; + uint32 TileAddr = BG.TileAddress + ((Tile & 0x3ff) << BG.TileShift); + if ((Tile & 0x1ff) >= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)),0); +#else + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + NORMAL_SUB_16_O (Offset, (uint16*)bp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)+7*2),2); +#else + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + NORMAL_SUB_16_O (Offset, (uint16*)bp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)+7*2),3); +#else + bp = pCache+8; + Offset += 7; + + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + FLIPPED_SUB_16_O (Offset, (uint16*)bp); +#endif + } + else + { + //VFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)),1); +#else + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + FLIPPED_SUB_16_O (Offset, (uint16*)bp); +#endif + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,solid_lineclip,(uint32)(GFX.S+(Offset<<1)),0); +#else + headerbp = pCache; + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + NORMAL_SUB_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,solid_lineclip,(uint32)(GFX.S+(Offset<<1)+7*2),2); +#else + headerbp = pCache; + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + NORMAL_SUB_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+StartPixel*2),0); +#else + + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + NORMAL_SUB_16_O (Offset, (uint16*)bp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),2); +#else + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + NORMAL_SUB_16_O (Offset, (uint16*)bp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),3); +#else + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + FLIPPED_SUB_16_O (Offset, (uint16*)bp); +#endif + } + else + { + //VFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+StartPixel*2),1); +#else + + bp = pCache+8+StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + FLIPPED_SUB_16_O (Offset, (uint16*)bp); +#endif + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8)|solid_lineclip,(uint32)(GFX.S+(Offset<<1)+StartPixel*2),0); +#else + + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + NORMAL_SUB_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8)|solid_lineclip,(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),2); +#else + + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + NORMAL_SUB_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8; + + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + NORMAL_SUB_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + NORMAL_SUB_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8; + Offset += 7; + + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + FLIPPED_SUB_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + else + { + //VFLIP + + + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + FLIPPED_SUB_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache; + bp = pCache+8; + + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + NORMAL_SUB_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache; + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + NORMAL_SUB_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + NORMAL_SUB_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + NORMAL_SUB_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + FLIPPED_SUB_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + else + { + //VFLIP + + bp = pCache+8+StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + FLIPPED_SUB_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + NORMAL_SUB_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + NORMAL_SUB_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8; + + for (l = 4; l != 0; l--, bp += 8*2*2, Offset+=1) + NORMAL_SUB_16_O (Offset, (uint16*)bp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8; + Offset += 3; + for (l = 4; l != 0; l--, bp += 8*2*2, Offset-=1) + NORMAL_SUB_16_O (Offset, (uint16*)bp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8; + Offset += 3; + + for (l = 4; l != 0; l--, bp += 8*2*2, Offset-=1) + FLIPPED_SUB_16_O (Offset, (uint16*)bp); + + } + else + { + //VFLIP + + + bp = pCache+8; + for (l = 4; l != 0; l--, bp += 8*2*2, Offset+=1) + FLIPPED_SUB_16_O (Offset, (uint16*)bp); + + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache; + bp = pCache+8; + + for (l = 4; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + NORMAL_SUB_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache; + bp = pCache+8; + Offset += 3; + for (l = 4; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + NORMAL_SUB_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + bp = pCache+8 + StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset+=1) + NORMAL_SUB_16_O (Offset, (uint16*)bp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset-=1) + NORMAL_SUB_16_O (Offset, (uint16*)bp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset-=1) + FLIPPED_SUB_16_O (Offset, (uint16*)bp); + + } + else + { + //VFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset+=1) + FLIPPED_SUB_16_O (Offset, (uint16*)bp); + + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + NORMAL_SUB_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + NORMAL_SUB_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<>1); + + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + FLIPPED_SUB_16_T (Offset, (uint16*)bp,solid_lineclipI|*headerbp); + + } + else + { + //VFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + FLIPPED_SUB_16_T (Offset, (uint16*)bp,solid_lineclipI|*headerbp); + + } + } +} + +/****************** SUB1_2 ***********************/ +void DrawTile16SUB1_2New (uint32 Tile, uint32 Offset, uint32 StartLine, uint32 LineCount) +{ + uint8 *pCache; + uint32 Col; + uint32 TileAddr = BG.TileAddress + ((Tile & 0x3ff) << BG.TileShift); + if ((Tile & 0x1ff) >= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)),0); +#else + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + NORMAL_SUB1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)+7*2),2); +#else + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + NORMAL_SUB1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)+7*2),3); +#else + bp = pCache+8; + Offset += 7; + + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + FLIPPED_SUB1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + { + //VFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)),1); +#else + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + FLIPPED_SUB1_2_16_O (Offset, (uint16*)bp); +#endif + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,solid_lineclip,(uint32)(GFX.S+(Offset<<1)),0); +#else + headerbp = pCache; + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + NORMAL_SUB1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,solid_lineclip,(uint32)(GFX.S+(Offset<<1)+7*2),2); +#else + headerbp = pCache; + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + NORMAL_SUB1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+StartPixel*2),0); +#else + + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + NORMAL_SUB1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),2); +#else + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + NORMAL_SUB1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),3); +#else + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + FLIPPED_SUB1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + { + //VFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+StartPixel*2),1); +#else + + bp = pCache+8+StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + FLIPPED_SUB1_2_16_O (Offset, (uint16*)bp); +#endif + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8)|solid_lineclip,(uint32)(GFX.S+(Offset<<1)+StartPixel*2),0); +#else + + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + NORMAL_SUB1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8)|solid_lineclip,(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),2); +#else + + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + NORMAL_SUB1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8; + + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + NORMAL_SUB1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + NORMAL_SUB1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8; + Offset += 7; + + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + FLIPPED_SUB1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + else + { + //VFLIP + + + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + FLIPPED_SUB1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache; + bp = pCache+8; + + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + NORMAL_SUB1_2_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache; + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + NORMAL_SUB1_2_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + NORMAL_SUB1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + NORMAL_SUB1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + FLIPPED_SUB1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + else + { + //VFLIP + + bp = pCache+8+StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + FLIPPED_SUB1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + NORMAL_SUB1_2_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + NORMAL_SUB1_2_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8; + + for (l = 4; l != 0; l--, bp += 8*2*2, Offset+=1) + NORMAL_SUB1_2_16_O (Offset, (uint16*)bp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8; + Offset += 3; + for (l = 4; l != 0; l--, bp += 8*2*2, Offset-=1) + NORMAL_SUB1_2_16_O (Offset, (uint16*)bp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8; + Offset += 3; + + for (l = 4; l != 0; l--, bp += 8*2*2, Offset-=1) + FLIPPED_SUB1_2_16_O (Offset, (uint16*)bp); + + } + else + { + //VFLIP + + + bp = pCache+8; + for (l = 4; l != 0; l--, bp += 8*2*2, Offset+=1) + FLIPPED_SUB1_2_16_O (Offset, (uint16*)bp); + + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache; + bp = pCache+8; + + for (l = 4; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + NORMAL_SUB1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache; + bp = pCache+8; + Offset += 3; + for (l = 4; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + NORMAL_SUB1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + bp = pCache+8 + StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset+=1) + NORMAL_SUB1_2_16_O (Offset, (uint16*)bp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset-=1) + NORMAL_SUB1_2_16_O (Offset, (uint16*)bp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset-=1) + FLIPPED_SUB1_2_16_O (Offset, (uint16*)bp); + + } + else + { + //VFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset+=1) + FLIPPED_SUB1_2_16_O (Offset, (uint16*)bp); + + } + } + else + { + + Offset -= (StartLine * 320); //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + NORMAL_SUB1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + NORMAL_SUB1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<>1); + + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + FLIPPED_SUB1_2_16_T (Offset, (uint16*)bp,solid_lineclipI|*headerbp); + + } + else + { + //VFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + FLIPPED_SUB1_2_16_T (Offset, (uint16*)bp,solid_lineclipI|*headerbp); + + } + } +} + +void SqTrans_Tile16New (uint32 Tile, uint32 Offset, uint32 StartLine, uint32 LineCount) +{ +#if 1 + uint8 *pCache; + uint32 Col; + uint32 TileAddr = BG.TileAddress + ((Tile & 0x3ff) << BG.TileShift); + if ((Tile & 0x1ff) >= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320); //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU16 + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)),0); +#else + bp = pCache+8; + // do this one first! + for (l = 8; l != 0; l--, bp += 8*2, Offset++) + SqTrans_NORMAL16_O (Offset, (uint16*)bp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU16 + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)+7*2),2); +#else + bp = pCache+8; + Offset += 7; + // do this one when the first one works! + for (l = 8; l != 0; l--, bp += 8*2, Offset--) + SqTrans_NORMAL16_O (Offset, (uint16*)bp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP +#ifdef asmPPU16 + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)+7*2),3); +#else + bp = pCache+8; + Offset += 7; + + for (l = 8; l != 0; l--, bp += 8*2, Offset--) + SqTrans_FLIPPED16_O (Offset, (uint16*)bp); +#endif + } + else + { + //VFLIP +#ifdef asmPPU16 + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)),1); +#else + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset++) + SqTrans_FLIPPED16_O (Offset, (uint16*)bp); +#endif + } + } + else + { + Offset -= (StartLine * 320); //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU16 + asmDrawTile16((uint32)pCache,solid_lineclip,(uint32)(GFX.S+(Offset<<1)),0); +#else + headerbp = pCache; + bp = pCache+8; + // do this one when the first one works! + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset++) + SqTrans_NORMAL16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU16 + asmDrawTile16((uint32)pCache,solid_lineclip,(uint32)(GFX.S+(Offset<<1)+7*2),2); +#else + headerbp = pCache; + bp = pCache+8; + Offset += 7; + // do this one when the first one works! + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset--) + SqTrans_NORMAL16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320); //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU16 + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+StartPixel*2),0); +#else + + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset++) + SqTrans_NORMAL16_O (Offset, (uint16*)bp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU16 + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),2); +#else + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, Offset--) + SqTrans_NORMAL16_O (Offset, (uint16*)bp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP +#ifdef asmPPU16 + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),3); +#else + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + + for (l = Width; l != 0; l--, bp += 8*2, Offset--) + SqTrans_FLIPPED16_O (Offset, (uint16*)bp); +#endif + } + else + { + //VFLIP +#ifdef asmPPU16 + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+StartPixel*2),1); +#else + + bp = pCache+8+StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset++) + SqTrans_FLIPPED16_O (Offset, (uint16*)bp); +#endif + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU16 + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8)|solid_lineclip,(uint32)(GFX.S+(Offset<<1)+StartPixel*2),0); +#else + + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + // do this one when the first one works! + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset++) + SqTrans_NORMAL16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU16 + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8)|solid_lineclip,(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),2); +#else + + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset--) + SqTrans_NORMAL16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8; + + for (l = 8; l != 0; l--, bp += 8*2, Offset++) + SqTrans_NORMAL16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, Offset--) + SqTrans_NORMAL16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8; + Offset += 7; + + for (l = 8; l != 0; l--, bp += 8*2, Offset--) + SqTrans_FLIPPED16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + else + { + //VFLIP + + + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset++) + SqTrans_FLIPPED16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache; + bp = pCache+8; + + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset++) + SqTrans_NORMAL16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache; + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset--) + SqTrans_NORMAL16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset++) + SqTrans_NORMAL16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, Offset--) + SqTrans_NORMAL16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + + for (l = Width; l != 0; l--, bp += 8*2, Offset--) + SqTrans_FLIPPED16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + else + { + //VFLIP + + bp = pCache+8+StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset++) + SqTrans_FLIPPED16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset++) + SqTrans_NORMAL16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset--) + SqTrans_NORMAL16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8; + + // do this one when the first one works! + for (l = 4; l != 0; l--, bp += 8*2*2, Offset+=1) + SqTrans_NORMAL16_O (Offset, (uint16*)bp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8; + Offset += 3; + for (l = 4; l != 0; l--, bp += 8*2*2, Offset-=1) + SqTrans_NORMAL16_O (Offset, (uint16*)bp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8; + Offset += 3; + + for (l = 4; l != 0; l--, bp += 8*2*2, Offset-=1) + SqTrans_FLIPPED16_O (Offset, (uint16*)bp); + + } + else + { + //VFLIP + + + bp = pCache+8; + for (l = 4; l != 0; l--, bp += 8*2*2, Offset+=1) + SqTrans_FLIPPED16_O (Offset, (uint16*)bp); + + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache; + bp = pCache+8; + + // do this one when the first one works! + for (l = 4; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + SqTrans_NORMAL16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache; + bp = pCache+8; + Offset += 3; + for (l = 4; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + SqTrans_NORMAL16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + bp = pCache+8 + StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset+=1) + SqTrans_NORMAL16_O (Offset, (uint16*)bp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset-=1) + SqTrans_NORMAL16_O (Offset, (uint16*)bp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset-=1) + SqTrans_FLIPPED16_O (Offset, (uint16*)bp); + + } + else + { + //VFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset+=1) + SqTrans_FLIPPED16_O (Offset, (uint16*)bp); + + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + SqTrans_NORMAL16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + SqTrans_NORMAL16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<>1); + + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + SqTrans_FLIPPED16_T (Offset, (uint16*)bp,solid_lineclipI|*headerbp); + + } + else + { + //VFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + SqTrans_FLIPPED16_T (Offset, (uint16*)bp,solid_lineclipI|*headerbp); + + } + } +} + + +#if 0 +/****************** ADD ***********************/ +void SqTrans_Tile16ADDNew (uint32 Tile, uint32 Offset, uint32 StartLine, uint32 LineCount) +{ + uint8 *pCache; + uint32 Col; + uint32 TileAddr = BG.TileAddress + ((Tile & 0x3ff) << BG.TileShift); + + if ((Tile & 0x1ff) >= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)),0); +#else + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_NORMALADD_16_O (Offset, (uint16*)bp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)+7*2),2); +#else + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_NORMALADD_16_O (Offset, (uint16*)bp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)+7*2),3); +#else + bp = pCache+8; + Offset += 7; + + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_FLIPPEDADD_16_O (Offset, (uint16*)bp); +#endif + } + else + { + //VFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)),1); +#else + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_FLIPPEDADD_16_O (Offset, (uint16*)bp); +#endif + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,solid_lineclip,(uint32)(GFX.S+(Offset<<1)),0); +#else + headerbp = pCache; + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + SqTrans_NORMALADD_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,solid_lineclip,(uint32)(GFX.S+(Offset<<1)+7*2),2); +#else + headerbp = pCache; + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + SqTrans_NORMALADD_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+StartPixel*2),0); +#else + + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_NORMALADD_16_O (Offset, (uint16*)bp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),2); +#else + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_NORMALADD_16_O (Offset, (uint16*)bp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),3); +#else + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_FLIPPEDADD_16_O (Offset, (uint16*)bp); +#endif + } + else + { + //VFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+StartPixel*2),1); +#else + + bp = pCache+8+StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_FLIPPEDADD_16_O (Offset, (uint16*)bp); +#endif + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8)|solid_lineclip,(uint32)(GFX.S+(Offset<<1)+StartPixel*2),0); +#else + + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + SqTrans_NORMALADD_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8)|solid_lineclip,(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),2); +#else + + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + SqTrans_NORMALADD_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8; + + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_NORMALADD_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_NORMALADD_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8; + Offset += 7; + + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_FLIPPEDADD_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + else + { + //VFLIP + + + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_FLIPPEDADD_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache; + bp = pCache+8; + + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + SqTrans_NORMALADD_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache; + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + SqTrans_NORMALADD_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_NORMALADD_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_NORMALADD_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_FLIPPEDADD_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + else + { + //VFLIP + + bp = pCache+8+StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_FLIPPEDADD_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + SqTrans_NORMALADD_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + SqTrans_NORMALADD_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8; + + for (l = 4; l != 0; l--, bp += 8*2*2, Offset+=1) + SqTrans_NORMALADD_16_O (Offset, (uint16*)bp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8; + Offset += 3; + for (l = 4; l != 0; l--, bp += 8*2*2, Offset-=1) + SqTrans_NORMALADD_16_O (Offset, (uint16*)bp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8; + Offset += 3; + + for (l = 4; l != 0; l--, bp += 8*2*2, Offset-=1) + SqTrans_FLIPPEDADD_16_O (Offset, (uint16*)bp); + + } + else + { + //VFLIP + + + bp = pCache+8; + for (l = 4; l != 0; l--, bp += 8*2*2, Offset+=1) + SqTrans_FLIPPEDADD_16_O (Offset, (uint16*)bp); + + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache; + bp = pCache+8; + + for (l = 4; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + SqTrans_NORMALADD_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache; + bp = pCache+8; + Offset += 3; + for (l = 4; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + SqTrans_NORMALADD_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + bp = pCache+8 + StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset+=1) + SqTrans_NORMALADD_16_O (Offset, (uint16*)bp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset-=1) + SqTrans_NORMALADD_16_O (Offset, (uint16*)bp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset-=1) + SqTrans_FLIPPEDADD_16_O (Offset, (uint16*)bp); + + } + else + { + //VFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset+=1) + SqTrans_FLIPPEDADD_16_O (Offset, (uint16*)bp); + + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + SqTrans_NORMALADD_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + SqTrans_NORMALADD_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<>1); + + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + SqTrans_FLIPPEDADD_16_T (Offset, (uint16*)bp,solid_lineclipI|*headerbp); + + } + else + { + //VFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + SqTrans_FLIPPEDADD_16_T (Offset, (uint16*)bp,solid_lineclipI|*headerbp); + + } + } +} + +/****************** ADD1_2 ***********************/ +void SqTrans_Tile16ADD1_2New (uint32 Tile, uint32 Offset, uint32 StartLine, uint32 LineCount) +{ + uint8 *pCache; + uint32 Col; + uint32 TileAddr = BG.TileAddress + ((Tile & 0x3ff) << BG.TileShift); + if ((Tile & 0x1ff) >= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)),0); +#else + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_NORMALADD1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)+7*2),2); +#else + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_NORMALADD1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)+7*2),3); +#else + bp = pCache+8; + Offset += 7; + + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_FLIPPEDADD1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + { + //VFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)),1); +#else + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_FLIPPEDADD1_2_16_O (Offset, (uint16*)bp); +#endif + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,solid_lineclip,(uint32)(GFX.S+(Offset<<1)),0); +#else + headerbp = pCache; + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + SqTrans_NORMALADD1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,solid_lineclip,(uint32)(GFX.S+(Offset<<1)+7*2),2); +#else + headerbp = pCache; + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + SqTrans_NORMALADD1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+StartPixel*2),0); +#else + + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_NORMALADD1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),2); +#else + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_NORMALADD1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),3); +#else + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_FLIPPEDADD1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + { + //VFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+StartPixel*2),1); +#else + + bp = pCache+8+StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_FLIPPEDADD1_2_16_O (Offset, (uint16*)bp); +#endif + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8)|solid_lineclip,(uint32)(GFX.S+(Offset<<1)+StartPixel*2),0); +#else + + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + SqTrans_NORMALADD1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8)|solid_lineclip,(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),2); +#else + + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + SqTrans_NORMALADD1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8; + + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_NORMALADD1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_NORMALADD1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8; + Offset += 7; + + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_FLIPPEDADD1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + else + { + //VFLIP + + + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_FLIPPEDADD1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache; + bp = pCache+8; + + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + SqTrans_NORMALADD1_2_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache; + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + SqTrans_NORMALADD1_2_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_NORMALADD1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_NORMALADD1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_FLIPPEDADD1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + else + { + //VFLIP + + bp = pCache+8+StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_FLIPPEDADD1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + SqTrans_NORMALADD1_2_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + SqTrans_NORMALADD1_2_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8; + + for (l = 4; l != 0; l--, bp += 8*2*2, Offset+=1) + SqTrans_NORMALADD1_2_16_O (Offset, (uint16*)bp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8; + Offset += 3; + for (l = 4; l != 0; l--, bp += 8*2*2, Offset-=1) + SqTrans_NORMALADD1_2_16_O (Offset, (uint16*)bp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8; + Offset += 3; + + for (l = 4; l != 0; l--, bp += 8*2*2, Offset-=1) + SqTrans_FLIPPEDADD1_2_16_O (Offset, (uint16*)bp); + + } + else + { + //VFLIP + + + bp = pCache+8; + for (l = 4; l != 0; l--, bp += 8*2*2, Offset+=1) + SqTrans_FLIPPEDADD1_2_16_O (Offset, (uint16*)bp); + + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache; + bp = pCache+8; + + for (l = 4; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + SqTrans_NORMALADD1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache; + bp = pCache+8; + Offset += 3; + for (l = 4; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + SqTrans_NORMALADD1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + bp = pCache+8 + StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset+=1) + SqTrans_NORMALADD1_2_16_O (Offset, (uint16*)bp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset-=1) + SqTrans_NORMALADD1_2_16_O (Offset, (uint16*)bp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset-=1) + SqTrans_FLIPPEDADD1_2_16_O (Offset, (uint16*)bp); + + } + else + { + //VFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset+=1) + SqTrans_FLIPPEDADD1_2_16_O (Offset, (uint16*)bp); + + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + SqTrans_NORMALADD1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + SqTrans_NORMALADD1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<>1); + + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + SqTrans_FLIPPEDADD1_2_16_T (Offset, (uint16*)bp,solid_lineclipI|*headerbp); + + } + else + { + //VFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + SqTrans_FLIPPEDADD1_2_16_T (Offset, (uint16*)bp,solid_lineclipI|*headerbp); + + } + } +} + + +/****************** SUB ***********************/ +void SqTrans_Tile16SUBNew (uint32 Tile, uint32 Offset, uint32 StartLine, uint32 LineCount) +{ + uint8 *pCache; + uint32 Col; + uint32 TileAddr = BG.TileAddress + ((Tile & 0x3ff) << BG.TileShift); + if ((Tile & 0x1ff) >= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)),0); +#else + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_NORMALSUB_16_O (Offset, (uint16*)bp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)+7*2),2); +#else + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_NORMALSUB_16_O (Offset, (uint16*)bp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)+7*2),3); +#else + bp = pCache+8; + Offset += 7; + + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_FLIPPEDSUB_16_O (Offset, (uint16*)bp); +#endif + } + else + { + //VFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)),1); +#else + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_FLIPPEDSUB_16_O (Offset, (uint16*)bp); +#endif + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,solid_lineclip,(uint32)(GFX.S+(Offset<<1)),0); +#else + headerbp = pCache; + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + SqTrans_NORMALSUB_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,solid_lineclip,(uint32)(GFX.S+(Offset<<1)+7*2),2); +#else + headerbp = pCache; + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + SqTrans_NORMALSUB_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+StartPixel*2),0); +#else + + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_NORMALSUB_16_O (Offset, (uint16*)bp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),2); +#else + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_NORMALSUB_16_O (Offset, (uint16*)bp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),3); +#else + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_FLIPPEDSUB_16_O (Offset, (uint16*)bp); +#endif + } + else + { + //VFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+StartPixel*2),1); +#else + + bp = pCache+8+StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_FLIPPEDSUB_16_O (Offset, (uint16*)bp); +#endif + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8)|solid_lineclip,(uint32)(GFX.S+(Offset<<1)+StartPixel*2),0); +#else + + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + SqTrans_NORMALSUB_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8)|solid_lineclip,(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),2); +#else + + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + SqTrans_NORMALSUB_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8; + + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_NORMALSUB_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_NORMALSUB_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8; + Offset += 7; + + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_FLIPPEDSUB_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + else + { + //VFLIP + + + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_FLIPPEDSUB_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache; + bp = pCache+8; + + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + SqTrans_NORMALSUB_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache; + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + SqTrans_NORMALSUB_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_NORMALSUB_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_NORMALSUB_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_FLIPPEDSUB_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + else + { + //VFLIP + + bp = pCache+8+StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_FLIPPEDSUB_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + SqTrans_NORMALSUB_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + SqTrans_NORMALSUB_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8; + + for (l = 4; l != 0; l--, bp += 8*2*2, Offset+=1) + SqTrans_NORMALSUB_16_O (Offset, (uint16*)bp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8; + Offset += 3; + for (l = 4; l != 0; l--, bp += 8*2*2, Offset-=1) + SqTrans_NORMALSUB_16_O (Offset, (uint16*)bp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8; + Offset += 3; + + for (l = 4; l != 0; l--, bp += 8*2*2, Offset-=1) + SqTrans_FLIPPEDSUB_16_O (Offset, (uint16*)bp); + + } + else + { + //VFLIP + + + bp = pCache+8; + for (l = 4; l != 0; l--, bp += 8*2*2, Offset+=1) + SqTrans_FLIPPEDSUB_16_O (Offset, (uint16*)bp); + + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache; + bp = pCache+8; + + for (l = 4; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + SqTrans_NORMALSUB_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache; + bp = pCache+8; + Offset += 3; + for (l = 4; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + SqTrans_NORMALSUB_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + bp = pCache+8 + StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset+=1) + SqTrans_NORMALSUB_16_O (Offset, (uint16*)bp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset-=1) + SqTrans_NORMALSUB_16_O (Offset, (uint16*)bp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset-=1) + SqTrans_FLIPPEDSUB_16_O (Offset, (uint16*)bp); + + } + else + { + //VFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset+=1) + SqTrans_FLIPPEDSUB_16_O (Offset, (uint16*)bp); + + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + SqTrans_NORMALSUB_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + SqTrans_NORMALSUB_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<>1); + + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + SqTrans_FLIPPEDSUB_16_T (Offset, (uint16*)bp,solid_lineclipI|*headerbp); + + } + else + { + //VFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + SqTrans_FLIPPEDSUB_16_T (Offset, (uint16*)bp,solid_lineclipI|*headerbp); + + } + } +} + +/****************** SUB1_2 ***********************/ +void SqTrans_Tile16SUB1_2New (uint32 Tile, uint32 Offset, uint32 StartLine, uint32 LineCount) +{ + uint8 *pCache; + uint32 Col; + uint32 TileAddr = BG.TileAddress + ((Tile & 0x3ff) << BG.TileShift); + if ((Tile & 0x1ff) >= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)),0); +#else + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_NORMALSUB1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)+7*2),2); +#else + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_NORMALSUB1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)+7*2),3); +#else + bp = pCache+8; + Offset += 7; + + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_FLIPPEDSUB1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + { + //VFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)),1); +#else + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_FLIPPEDSUB1_2_16_O (Offset, (uint16*)bp); +#endif + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,solid_lineclip,(uint32)(GFX.S+(Offset<<1)),0); +#else + headerbp = pCache; + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + SqTrans_NORMALSUB1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,solid_lineclip,(uint32)(GFX.S+(Offset<<1)+7*2),2); +#else + headerbp = pCache; + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + SqTrans_NORMALSUB1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+StartPixel*2),0); +#else + + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_NORMALSUB1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),2); +#else + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_NORMALSUB1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),3); +#else + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_FLIPPEDSUB1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + { + //VFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+StartPixel*2),1); +#else + + bp = pCache+8+StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_FLIPPEDSUB1_2_16_O (Offset, (uint16*)bp); +#endif + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8)|solid_lineclip,(uint32)(GFX.S+(Offset<<1)+StartPixel*2),0); +#else + + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + SqTrans_NORMALSUB1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8)|solid_lineclip,(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),2); +#else + + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + SqTrans_NORMALSUB1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8; + + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_NORMALSUB1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_NORMALSUB1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8; + Offset += 7; + + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_FLIPPEDSUB1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + else + { + //VFLIP + + + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_FLIPPEDSUB1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache; + bp = pCache+8; + + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + SqTrans_NORMALSUB1_2_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache; + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + SqTrans_NORMALSUB1_2_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_NORMALSUB1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_NORMALSUB1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_FLIPPEDSUB1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + else + { + //VFLIP + + bp = pCache+8+StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_FLIPPEDSUB1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + SqTrans_NORMALSUB1_2_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + SqTrans_NORMALSUB1_2_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8; + + for (l = 4; l != 0; l--, bp += 8*2*2, Offset+=1) + SqTrans_NORMALSUB1_2_16_O (Offset, (uint16*)bp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8; + Offset += 3; + for (l = 4; l != 0; l--, bp += 8*2*2, Offset-=1) + SqTrans_NORMALSUB1_2_16_O (Offset, (uint16*)bp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8; + Offset += 3; + + for (l = 4; l != 0; l--, bp += 8*2*2, Offset-=1) + SqTrans_FLIPPEDSUB1_2_16_O (Offset, (uint16*)bp); + + } + else + { + //VFLIP + + + bp = pCache+8; + for (l = 4; l != 0; l--, bp += 8*2*2, Offset+=1) + SqTrans_FLIPPEDSUB1_2_16_O (Offset, (uint16*)bp); + + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache; + bp = pCache+8; + + for (l = 4; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + SqTrans_NORMALSUB1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache; + bp = pCache+8; + Offset += 3; + for (l = 4; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + SqTrans_NORMALSUB1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + bp = pCache+8 + StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset+=1) + SqTrans_NORMALSUB1_2_16_O (Offset, (uint16*)bp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset-=1) + SqTrans_NORMALSUB1_2_16_O (Offset, (uint16*)bp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset-=1) + SqTrans_FLIPPEDSUB1_2_16_O (Offset, (uint16*)bp); + + } + else + { + //VFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset+=1) + SqTrans_FLIPPEDSUB1_2_16_O (Offset, (uint16*)bp); + + } + } + else + { + + Offset -= (StartLine * 320); //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + SqTrans_NORMALSUB1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + SqTrans_NORMALSUB1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<>1); + + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + SqTrans_FLIPPEDSUB1_2_16_T (Offset, (uint16*)bp,solid_lineclipI|*headerbp); + + } + else + { + //VFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + SqTrans_FLIPPEDSUB1_2_16_T (Offset, (uint16*)bp,solid_lineclipI|*headerbp); + + } + } +} +#endif diff --git a/src/snes4iphone_src/tilenew.cpp b/src/snes4iphone_src/tilenew.cpp new file mode 100755 index 0000000..a71948c --- /dev/null +++ b/src/snes4iphone_src/tilenew.cpp @@ -0,0 +1,12569 @@ +/* + * Snes9x - Portable Super Nintendo Entertainment System (TM) emulator. + * + * (c) Copyright 1996 - 2001 Gary Henderson (gary.henderson@ntlworld.com) and + * Jerremy Koot (jkoot@snes9x.com) + * + * Super FX C emulator code + * (c) Copyright 1997 - 1999 Ivar (ivar@snes9x.com) and + * Gary Henderson. + * Super FX assembler emulator code (c) Copyright 1998 zsKnight and _Demo_. + * + * DSP1 emulator code (c) Copyright 1998 Ivar, _Demo_ and Gary Henderson. + * C4 asm and some C emulation code (c) Copyright 2000 zsKnight and _Demo_. + * C4 C code (c) Copyright 2001 Gary Henderson (gary.henderson@ntlworld.com). + * + * DOS port code contains the works of other authors. See headers in + * individual files. + * + * Snes9x homepage: http://www.snes9x.com + * + * Permission to use, copy, modify and distribute Snes9x in both binary and + * source form, for non-commercial purposes, is hereby granted without fee, + * providing that this license information and copyright notice appear with + * all copies and any derived work. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event shall the authors be held liable for any damages + * arising from the use of this software. + * + * Snes9x is freeware for PERSONAL USE only. Commercial users should + * seek permission of the copyright holders first. Commercial use includes + * charging money for Snes9x or software derived from Snes9x. + * + * The copyright holders request that bug fixes and improvements to the code + * should be forwarded to them so everyone can benefit from the modifications + * in future versions. + * + * Super NES and Super Nintendo Entertainment System are trademarks of + * Nintendo Co., Limited and its subsidiary companies. + */ + +//#ifndef asmPPU +#include "snes9x.h" + +#include "memmap.h" +#include "ppu.h" +#include "cpuexec.h" +#include "display.h" +#include "gfx.h" +#include "apu.h" + + +//#define asmPPU16 +#define asmPPU8 +//#define asmPPU16T + +typedef union +{ + struct { uint8 b0,b1,b2,b3; } B; + uint32 W; +} yo_uint32; + +uint8 *SubScreenTranspBuffer; +uint8 tmpCache[64]; +extern int squidgetranshackenable; + + +#ifdef asmPPU16 +extern "C" void asmDrawTile16(uint32 cache,uint32 solidbuf,uint32 OffsetGP32,uint32 Flip); +extern "C" void asmDrawTileClipped16(uint32 cache,uint32 solidbuf,uint32 OffsetGP32,uint32 Flip); +#endif + +#ifdef asmPPU8 +extern "C" void asmDrawTile8(uint32 cache,uint32 solidbuf,uint32 OffsetGP32,uint32 Flip); +extern "C" void asmDrawTileClipped8(uint32 cache,uint32 solidbuf,uint32 OffsetGP32,uint32 Flip); +#endif + +// RGB565 +#define yoRGB_REMOVE_LOW_BITS_MASK ((30<<11)|(62<<5)|(30)) +#define yoRGB_LOW_BITS_MASK ((1<<11)|(1<<5)|(1<<1)) +#define yoRGB_HI_BITS_MASKx2 (((16<<11)|(32<<5)|(16))<<1) + + +#define COLOR_ADD(C1, C2) \ +GFX.X2 [((((C1) & yoRGB_REMOVE_LOW_BITS_MASK) + \ + ((C2) & yoRGB_REMOVE_LOW_BITS_MASK)) >> 1) + \ + ((C1) & (C2) & yoRGB_LOW_BITS_MASK)] + + +#define COLOR_ADD1_2(C1, C2) \ +(((((C1) & yoRGB_REMOVE_LOW_BITS_MASK) + \ + ((C2) & yoRGB_REMOVE_LOW_BITS_MASK)) >> 1) + \ + ((C1) & (C2) & yoRGB_LOW_BITS_MASK) | ALPHA_BITS_MASK) + +#define COLOR_SUB(C1, C2) \ +GFX.ZERO_OR_X2 [(((C1) | yoRGB_HI_BITS_MASKx2) - \ + ((C2) & yoRGB_REMOVE_LOW_BITS_MASK)) >> 1] + +#define COLOR_SUB1_2(C1, C2) \ +GFX.ZERO [(((C1) | yoRGB_HI_BITS_MASKx2) - \ + ((C2) & yoRGB_REMOVE_LOW_BITS_MASK)) >> 1] + + + +__inline uint8 ConvertTile16New (uint8 *pCache,uint32 TileAddr,uint16 *ScreenColors) +{ +#if 1 + register uint8 *tp = &Memory.VRAM[TileAddr]; + uint32 *p = (uint32*)tmpCache; + uint32 non_zero,tile_opaque,tile_mono; + uint8 line; + uint32 p1; + uint32 p2; + register uint8 pix; + + non_zero=0; + switch (BG.BitShift) + { + case 8: + for (line = 8; line != 0; line--, tp += 2) + { + p1 = 0; + p2 = 0; + if ((pix = *(tp + 0))) + { + p1 |= odd_high[0][pix >> 4]; + p2 |= odd_low[0][pix & 0xf]; + } + if ((pix = *(tp + 1))) + { + p1 |= even_high[0][pix >> 4]; + p2 |= even_low[0][pix & 0xf]; + } + if ((pix = *(tp + 16))) + { + p1 |= odd_high[1][pix >> 4]; + p2 |= odd_low[1][pix & 0xf]; + } + if ((pix = *(tp + 17))) + { + p1 |= even_high[1][pix >> 4]; + p2 |= even_low[1][pix & 0xf]; + } + if ((pix = *(tp + 32))) + { + p1 |= odd_high[2][pix >> 4]; + p2 |= odd_low[2][pix & 0xf]; + } + if ((pix = *(tp + 33))) + { + p1 |= even_high[2][pix >> 4]; + p2 |= even_low[2][pix & 0xf]; + } + if ((pix = *(tp + 48))) + { + p1 |= odd_high[3][pix >> 4]; + p2 |= odd_low[3][pix & 0xf]; + } + if ((pix = *(tp + 49))) + { + p1 |= even_high[3][pix >> 4]; + p2 |= even_low[3][pix & 0xf]; + } + + *p++=p1; + *p++=p2; + non_zero |= p1 | p2; + } + break; + + case 4: + for (line = 8; line != 0; line--, tp += 2) + { + p1 = 0; + p2 = 0; + if ((pix = *(tp + 0))) + { + p1 |= odd_high[0][pix >> 4]; + p2 |= odd_low[0][pix & 0xf]; + } + if ((pix = *(tp + 1))) + { + p1 |= even_high[0][pix >> 4]; + p2 |= even_low[0][pix & 0xf]; + } + if ((pix = *(tp + 16))) + { + p1 |= odd_high[1][pix >> 4]; + p2 |= odd_low[1][pix & 0xf]; + } + if ((pix = *(tp + 17))) + { + p1 |= even_high[1][pix >> 4]; + p2 |= even_low[1][pix & 0xf]; + } + *p++=p1; + *p++=p2; + non_zero |= p1 | p2; + } + break; + + case 2: + for (line = 8; line != 0; line--, tp += 2) + { + p1 = 0; + p2 = 0; + if ((pix = *(tp + 0))) + { + p1 |= odd_high[0][pix >> 4]; + p2 |= odd_low[0][pix & 0xf]; + } + if ((pix = *(tp + 1))) + { + p1 |= even_high[0][pix >> 4]; + p2 |= even_low[0][pix & 0xf]; + } + + *p++=p1; + *p++=p2; + non_zero |= p1 | p2; + } + break; + } + if (non_zero) + { + tile_opaque=1; + uint8 *p3=tmpCache; + uint8 *q = pCache; + uint32 i; + for (line = 8;line != 0; line--,q++,p3+=8) + { + if (!p3[0]) i=0x80; + else i=0; + if (!p3[1]) i|=0x40; + if (!p3[2]) i|=0x20; + if (!p3[3]) i|=0x10; + if (!p3[4]) i|=0x08; + if (!p3[5]) i|=0x04; + if (!p3[6]) i|=0x02; + if (!p3[7]) i|=0x01; + if (i) tile_opaque=0; + *q=i; + } + uint16 *r = (uint16*)(pCache)+4; + for (line = 0;line <64;line++) + r[line]=ScreenColors[tmpCache[line]]; + + + if (tile_opaque) return 2; //Tile is cached and opaque + return 3; //Tile is cached and transp + } + else return 1; //Tile is totally transparent +#else + return 2; +#endif +} + +#if 1 +__inline uint8 ConvertTile8New (uint8 *pCache,uint32 TileAddr) +{ + register uint8 *tp = &Memory.VRAM[TileAddr]; + uint32 *p = (uint32*)pCache+((8+64)>>2); + uint32 non_zero,tile_opaque,tile_mono; + uint8 line; + uint32 p1; + uint32 p2; + register uint8 pix; + + non_zero=0; + switch (BG.BitShift) + { + case 8: + for (line = 8; line != 0; line--, tp += 2) + { + p1 = 0; + p2 = 0; + if ((pix = *(tp + 0))) + { + p1 |= odd_high[0][pix >> 4]; + p2 |= odd_low[0][pix & 0xf]; + } + if ((pix = *(tp + 1))) + { + p1 |= even_high[0][pix >> 4]; + p2 |= even_low[0][pix & 0xf]; + } + if ((pix = *(tp + 16))) + { + p1 |= odd_high[1][pix >> 4]; + p2 |= odd_low[1][pix & 0xf]; + } + if ((pix = *(tp + 17))) + { + p1 |= even_high[1][pix >> 4]; + p2 |= even_low[1][pix & 0xf]; + } + if ((pix = *(tp + 32))) + { + p1 |= odd_high[2][pix >> 4]; + p2 |= odd_low[2][pix & 0xf]; + } + if ((pix = *(tp + 33))) + { + p1 |= even_high[2][pix >> 4]; + p2 |= even_low[2][pix & 0xf]; + } + if ((pix = *(tp + 48))) + { + p1 |= odd_high[3][pix >> 4]; + p2 |= odd_low[3][pix & 0xf]; + } + if ((pix = *(tp + 49))) + { + p1 |= even_high[3][pix >> 4]; + p2 |= even_low[3][pix & 0xf]; + } + + *p++=p1; + *p++=p2; + non_zero |= p1 | p2; + } + break; + + case 4: + for (line = 8; line != 0; line--, tp += 2) + { + p1 = 0; + p2 = 0; + if ((pix = *(tp + 0))) + { + p1 |= odd_high[0][pix >> 4]; + p2 |= odd_low[0][pix & 0xf]; + } + if ((pix = *(tp + 1))) + { + p1 |= even_high[0][pix >> 4]; + p2 |= even_low[0][pix & 0xf]; + } + if ((pix = *(tp + 16))) + { + p1 |= odd_high[1][pix >> 4]; + p2 |= odd_low[1][pix & 0xf]; + } + if ((pix = *(tp + 17))) + { + p1 |= even_high[1][pix >> 4]; + p2 |= even_low[1][pix & 0xf]; + } + *p++=p1; + *p++=p2; + non_zero |= p1 | p2; + } + break; + + case 2: + for (line = 8; line != 0; line--, tp += 2) + { + p1 = 0; + p2 = 0; + if ((pix = *(tp + 0))) + { + p1 |= odd_high[0][pix >> 4]; + p2 |= odd_low[0][pix & 0xf]; + } + if ((pix = *(tp + 1))) + { + p1 |= even_high[0][pix >> 4]; + p2 |= even_low[0][pix & 0xf]; + } + + *p++=p1; + *p++=p2; + non_zero |= p1 | p2; + } + break; + } + if (non_zero) + { + tile_opaque=1; + uint8 *p3=pCache+8+64; + uint8 *q = pCache; + uint32 i; + for (line = 8;line != 0; line--,q++,p+=8) + { + /*if (!p3[0]) i=0x80; + else i=0; + if (!p3[1]) i|=0x40; + if (!p3[2]) i|=0x20; + if (!p3[3]) i|=0x10; + if (!p3[4]) i|=0x08; + if (!p3[5]) i|=0x04; + if (!p3[6]) i|=0x02; + if (!p3[7]) i|=0x01;*/ + + if (p3[0]) i=0x01; + else i=0; + if (p3[1]) i|=0x02; + if (p3[2]) i|=0x04; + if (p3[3]) i|=0x08; + if (p3[4]) i|=0x10; + if (p3[5]) i|=0x20; + if (p3[6]) i|=0x40; + if (p3[7]) i|=0x80; + + //if (i==0) tile_opaque=0; + *q=i; + } + + //if (tile_opaque) return 2; //Tile is cached and opaque + return 3; //Tile is cached and transp + } + else return 1; //Tile is totally transparent +} +#endif + +/********************************/ +__inline void NORMAL16_T (uint32 Offset,uint16 *Pixels,uint32 solid) +{ +#if 1 + uint16 *Screen = (uint16 *) GFX.S + Offset; + + #define FN(N) \ + if (!(solid&(1<<(7-N)))) *Screen = *Pixels; \ + Screen+=320; Pixels++; + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +#endif +} + +__inline void NORMAL16_O (uint32 Offset,uint16 *Pixels) +{ +#if 1 + uint16 *Screen = (uint16 *) GFX.S + Offset; + + *Screen=*Pixels; + Screen+=320; Pixels++; + *Screen=*Pixels; + Screen+=320; Pixels++; + *Screen=*Pixels; + Screen+=320; Pixels++; + *Screen=*Pixels; + Screen+=320; Pixels++; + *Screen=*Pixels; + Screen+=320; Pixels++; + *Screen=*Pixels; + Screen+=320; Pixels++; + *Screen=*Pixels; + Screen+=320; Pixels++; + *Screen=*Pixels; +#endif +} + +__inline void FLIPPED16_T (uint32 Offset,uint16 *Pixels,uint32 solid) +{ + uint16 *Screen = (uint16 *) GFX.S + Offset; + + Screen += 7 * 320; + #define FN(N) \ + if (!(solid&(1<<(7-N)))) *Screen = *Pixels; \ + Screen -= 320; Pixels++; + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +} + +__inline void FLIPPED16_O (uint32 Offset,uint16 *Pixels) +{ + uint16 *Screen = (uint16 *) GFX.S + Offset; + + Screen += 7 * 320; + + *Screen=*Pixels; + Screen-=320; Pixels++; + *Screen=*Pixels; + Screen-=320; Pixels++; + *Screen=*Pixels; + Screen-=320; Pixels++; + *Screen=*Pixels; + Screen-=320; Pixels++; + *Screen=*Pixels; + Screen-=320; Pixels++; + *Screen=*Pixels; + Screen-=320; Pixels++; + *Screen=*Pixels; + Screen-=320; Pixels++; + *Screen=*Pixels; +} + + + +__inline void NORMAL16_SPR_T (uint32 Offset,uint16 *Pixels,uint32 solid,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.S + Offset; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset; + + #define FN(N) \ + if ((!(solid&(1<<(7-N))))&&(*ZB>index_spr)) { *Screen = *Pixels; *ZB=index_spr; } \ + Screen += 320; Pixels++; ZB += 320; + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +} + +__inline void NORMAL16_SPR_O (uint32 Offset,uint16 *Pixels,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.S + Offset; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset; + + #define FN \ + if (*ZB>index_spr) {*Screen=*Pixels; *ZB=index_spr;} \ + Screen += 320; Pixels++; ZB += 320; + FN + FN + FN + FN + FN + FN + FN + FN + #undef FN +} + +__inline void FLIPPED16_SPR_T (uint32 Offset,uint16 *Pixels,uint32 solid,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.S + Offset + (7 * 320); + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset + (7 * 320); + + #define FN(N) \ + if ((!(solid&(1<<(7-N))))&&(*ZB>index_spr)) { *Screen = *Pixels; *ZB=index_spr; }\ + Screen -= 320; Pixels++; ZB -= 320; + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +} + +__inline void FLIPPED16_SPR_O (uint32 Offset,uint16 *Pixels,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.S + Offset + (7 * 320); + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset + (7 * 320); + + #define FN \ + if (*ZB>index_spr) {*Screen=*Pixels; *ZB=index_spr;} \ + Screen -= 320; Pixels++; ZB -= 320; + FN + FN + FN + FN + FN + FN + FN + FN + #undef FN +} + + + + +__inline void NORMAL_ADD_16_T (uint32 Offset,uint16 *Pixels,uint32 solid) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + #define FN(N) \ + if (!(solid&(1<<(7-N)))) {\ + if (*SubScreen) *Screen = COLOR_ADD(*Pixels,*SubScreen); \ + else *Screen=*Pixels;}\ + Screen += 320; SubScreen += 320; Pixels++; + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +} + +__inline void NORMAL_ADD_16_O (uint32 Offset,uint16 *Pixels) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + #define FN \ + if (*SubScreen) *Screen = COLOR_ADD(*Pixels,*SubScreen);\ + else *Screen=*Pixels; \ + Screen += 320; SubScreen += 320; Pixels++; + FN + FN + FN + FN + FN + FN + FN + FN + #undef FN +} + +__inline void FLIPPED_ADD_16_T (uint32 Offset,uint16 *Pixels,uint32 solid) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + Screen += (7 * 320); + SubScreen += (7 * 320); + #define FN(N) \ + if (!(solid&(1<<(7-N)))) {\ + if (*SubScreen) *Screen = COLOR_ADD(*Pixels,*SubScreen); \ + else *Screen=*Pixels;}\ + Screen -= 320; SubScreen -= 320; Pixels++; + + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +} + +__inline void FLIPPED_ADD_16_O (uint32 Offset,uint16 *Pixels) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + Screen += (7 * 320); + SubScreen += (7 * 320); + #define FN \ + if (*SubScreen) *Screen = COLOR_ADD(*Pixels,*SubScreen);\ + else *Screen=*Pixels; \ + Screen -= 320; SubScreen -= 320; Pixels++; + FN + FN + FN + FN + FN + FN + FN + FN + #undef FN +} + + + +__inline void NORMAL_ADD_16_SPR_T (uint32 Offset,uint16 *Pixels,uint32 solid,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset; + + #define FN(N) \ + if ((!(solid&(1<<(7-N))))&&(*ZB>index_spr)) { \ + if (*SubScreen) *Screen = COLOR_ADD(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr; \ + } \ + Screen += 320; SubScreen += 320; Pixels++; ZB += 320; + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +} + +__inline void NORMAL_ADD_16_SPR_O (uint32 Offset,uint16 *Pixels,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset; + + #define FN \ + if (*ZB>index_spr) {\ + if (*SubScreen) *Screen = COLOR_ADD(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr;} \ + Screen += 320; SubScreen += 320; Pixels++; ZB += 320; + FN + FN + FN + FN + FN + FN + FN + FN + #undef FN +} + +__inline void FLIPPED_ADD_16_SPR_T (uint32 Offset,uint16 *Pixels,uint32 solid,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset + (7 * 320); + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset + (7 * 320); + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset + (7 * 320); + + #define FN(N) \ + if ((!(solid&(1<<(7-N))))&&(*ZB>index_spr)) { \ + if (*SubScreen) *Screen = COLOR_ADD(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr; }\ + Screen -= 320; SubScreen -= 320; Pixels++; ZB -= 320; + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +} + +__inline void FLIPPED_ADD_16_SPR_O (uint32 Offset,uint16 *Pixels,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset + (7 * 320); + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset + (7 * 320); + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset + (7 * 320); + + #define FN \ + if (*ZB>index_spr) {\ + if (*SubScreen) *Screen = COLOR_ADD(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr;} \ + Screen -= 320; SubScreen -= 320; Pixels++; ZB -= 320; + FN + FN + FN + FN + FN + FN + FN + FN + #undef FN +} + +//////////////////// fooble +__inline void NORMAL_ADD1_2_16_T (uint32 Offset,uint16 *Pixels,uint32 solid) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + #define FN(N) \ + if (!(solid&(1<<(7-N)))) {\ + if (*SubScreen) *Screen = COLOR_ADD1_2(*Pixels,*SubScreen); \ + else *Screen=*Pixels;}\ + Screen += 320; SubScreen += 320; Pixels++; + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +} + +__inline void NORMAL_ADD1_2_16_O (uint32 Offset,uint16 *Pixels) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + #define FN \ + if (*SubScreen) *Screen = COLOR_ADD1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels; \ + Screen += 320; SubScreen += 320; Pixels++; + FN + FN + FN + FN + FN + FN + FN + FN + #undef FN +} + +__inline void FLIPPED_ADD1_2_16_T (uint32 Offset,uint16 *Pixels,uint32 solid) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + Screen += (7 * 320); + SubScreen += (7 * 320); + #define FN(N) \ + if (!(solid&(1<<(7-N)))) {\ + if (*SubScreen) *Screen = COLOR_ADD1_2(*Pixels,*SubScreen); \ + else *Screen=*Pixels;}\ + Screen -= 320; SubScreen -= 320; Pixels++; + + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +} + +__inline void FLIPPED_ADD1_2_16_O (uint32 Offset,uint16 *Pixels) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + Screen += (7 * 320); + SubScreen += (7 * 320); + #define FN \ + if (*SubScreen) *Screen = COLOR_ADD1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels; \ + Screen -= 320; SubScreen -= 320; Pixels++; + FN + FN + FN + FN + FN + FN + FN + FN + #undef FN +} + + + +__inline void NORMAL_ADD1_2_16_SPR_T (uint32 Offset,uint16 *Pixels,uint32 solid,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset; + + #define FN(N) \ + if ((!(solid&(1<<(7-N))))&&(*ZB>index_spr)) { \ + if (*SubScreen) *Screen = COLOR_ADD1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr; \ + } \ + Screen += 320; SubScreen += 320; Pixels++; ZB += 320; + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +} + +__inline void NORMAL_ADD1_2_16_SPR_O (uint32 Offset,uint16 *Pixels,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset; + + #define FN \ + if (*ZB>index_spr) {\ + if (*SubScreen) *Screen = COLOR_ADD1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr;} \ + Screen += 320; SubScreen += 320; Pixels++; ZB += 320; + FN + FN + FN + FN + FN + FN + FN + FN + #undef FN +} + +__inline void FLIPPED_ADD1_2_16_SPR_T (uint32 Offset,uint16 *Pixels,uint32 solid,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset + (7 * 320); + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset + (7 * 320); + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset + (7 * 320); + + #define FN(N) \ + if ((!(solid&(1<<(7-N))))&&(*ZB>index_spr)) { \ + if (*SubScreen) *Screen = COLOR_ADD1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr; }\ + Screen -= 320; SubScreen -= 320; Pixels++; ZB -= 320; + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +} + +__inline void FLIPPED_ADD1_2_16_SPR_O (uint32 Offset,uint16 *Pixels,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset + (7 * 320); + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset + (7 * 320); + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset + (7 * 320); + + #define FN \ + if (*ZB>index_spr) {\ + if (*SubScreen) *Screen = COLOR_ADD1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr;} \ + Screen -= 320; SubScreen -= 320; Pixels++; ZB -= 320; + FN + FN + FN + FN + FN + FN + FN + FN + #undef FN +} + +__inline void NORMAL_SUB_16_T (uint32 Offset,uint16 *Pixels,uint32 solid) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + #define FN(N) \ + if (!(solid&(1<<(7-N)))) {\ + if (*SubScreen) *Screen = COLOR_SUB(*Pixels,*SubScreen); \ + else *Screen=*Pixels;}\ + Screen += 320; SubScreen += 320; Pixels++; + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +} + +__inline void NORMAL_SUB_16_O (uint32 Offset,uint16 *Pixels) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + #define FN \ + if (*SubScreen) *Screen = COLOR_SUB(*Pixels,*SubScreen);\ + else *Screen=*Pixels; \ + Screen += 320; SubScreen += 320; Pixels++; + FN + FN + FN + FN + FN + FN + FN + FN + #undef FN +} + +__inline void FLIPPED_SUB_16_T (uint32 Offset,uint16 *Pixels,uint32 solid) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + Screen += (7 * 320); + SubScreen += (7 * 320); + #define FN(N) \ + if (!(solid&(1<<(7-N)))) {\ + if (*SubScreen) *Screen = COLOR_SUB(*Pixels,*SubScreen); \ + else *Screen=*Pixels;}\ + Screen -= 320; SubScreen -= 320; Pixels++; + + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +} + +__inline void FLIPPED_SUB_16_O (uint32 Offset,uint16 *Pixels) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + Screen += (7 * 320); + SubScreen += (7 * 320); + #define FN \ + if (*SubScreen) *Screen = COLOR_SUB(*Pixels,*SubScreen);\ + else *Screen=*Pixels; \ + Screen -= 320; SubScreen -= 320; Pixels++; + FN + FN + FN + FN + FN + FN + FN + FN + #undef FN +} + + + +__inline void NORMAL_SUB_16_SPR_T (uint32 Offset,uint16 *Pixels,uint32 solid,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset; + + #define FN(N) \ + if ((!(solid&(1<<(7-N))))&&(*ZB>index_spr)) { \ + if (*SubScreen) *Screen = COLOR_SUB(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr; \ + } \ + Screen += 320; SubScreen += 320; Pixels++; ZB += 320; + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +} + +__inline void NORMAL_SUB_16_SPR_O (uint32 Offset,uint16 *Pixels,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset; + + #define FN \ + if (*ZB>index_spr) {\ + if (*SubScreen) *Screen = COLOR_SUB(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr;} \ + Screen += 320; SubScreen += 320; Pixels++; ZB += 320; + FN + FN + FN + FN + FN + FN + FN + FN + #undef FN +} + +__inline void FLIPPED_SUB_16_SPR_T (uint32 Offset,uint16 *Pixels,uint32 solid,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset + (7 * 320); + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset + (7 * 320); + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset + (7 * 320); + + #define FN(N) \ + if ((!(solid&(1<<(7-N))))&&(*ZB>index_spr)) { \ + if (*SubScreen) *Screen = COLOR_SUB(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr; }\ + Screen -= 320; SubScreen -= 320; Pixels++; ZB -= 320; + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +} + +__inline void FLIPPED_SUB_16_SPR_O (uint32 Offset,uint16 *Pixels,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset + (7 * 320); + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset + (7 * 320); + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset + (7 * 320); + + #define FN \ + if (*ZB>index_spr) {\ + if (*SubScreen) *Screen = COLOR_SUB(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr;} \ + Screen -= 320; SubScreen -= 320; Pixels++; ZB -= 320; + FN + FN + FN + FN + FN + FN + FN + FN + #undef FN +} + +///// +__inline void NORMAL_SUB1_2_16_T (uint32 Offset,uint16 *Pixels,uint32 solid) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + #define FN(N) \ + if (!(solid&(1<<(7-N)))) {\ + if (*SubScreen) *Screen = COLOR_SUB1_2(*Pixels,*SubScreen); \ + else *Screen=*Pixels;}\ + Screen += 320; SubScreen += 320; Pixels++; + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +} + +__inline void NORMAL_SUB1_2_16_O (uint32 Offset,uint16 *Pixels) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + #define FN \ + if (*SubScreen) *Screen = COLOR_SUB1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels; \ + Screen += 320; SubScreen += 320; Pixels++; + FN + FN + FN + FN + FN + FN + FN + FN + #undef FN +} + +__inline void FLIPPED_SUB1_2_16_T (uint32 Offset,uint16 *Pixels,uint32 solid) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + Screen += (7 * 320); + SubScreen += (7 * 320); + #define FN(N) \ + if (!(solid&(1<<(7-N)))) {\ + if (*SubScreen) *Screen = COLOR_SUB1_2(*Pixels,*SubScreen); \ + else *Screen=*Pixels;}\ + Screen -= 320; SubScreen -= 320; Pixels++; + + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +} + +__inline void FLIPPED_SUB1_2_16_O (uint32 Offset,uint16 *Pixels) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + Screen += (7 * 320); + SubScreen += (7 * 320); + #define FN \ + if (*SubScreen) *Screen = COLOR_SUB1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels; \ + Screen -= 320; SubScreen -= 320; Pixels++; + FN + FN + FN + FN + FN + FN + FN + FN + #undef FN +} + + + +__inline void NORMAL_SUB1_2_16_SPR_T (uint32 Offset,uint16 *Pixels,uint32 solid,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset; + + #define FN(N) \ + if ((!(solid&(1<<(7-N))))&&(*ZB>index_spr)) { \ + if (*SubScreen) *Screen = COLOR_SUB1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr; \ + } \ + Screen += 320; SubScreen += 320; Pixels++; ZB += 320; + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +} + +__inline void NORMAL_SUB1_2_16_SPR_O (uint32 Offset,uint16 *Pixels,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset; + + #define FN \ + if (*ZB>index_spr) {\ + if (*SubScreen) *Screen = COLOR_SUB1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr;} \ + Screen += 320; SubScreen += 320; Pixels++; ZB += 320; + FN + FN + FN + FN + FN + FN + FN + FN + #undef FN +} + +__inline void FLIPPED_SUB1_2_16_SPR_T (uint32 Offset,uint16 *Pixels,uint32 solid,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset + (7 * 320); + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset + (7 * 320); + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset + (7 * 320); + + #define FN(N) \ + if ((!(solid&(1<<(7-N))))&&(*ZB>index_spr)) { \ + if (*SubScreen) *Screen = COLOR_SUB1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr; }\ + Screen -= 320; SubScreen -= 320; Pixels++; ZB -= 320; + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +} + +__inline void FLIPPED_SUB1_2_16_SPR_O (uint32 Offset,uint16 *Pixels,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset + (7 * 320); + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset + (7 * 320); + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset + (7 * 320); + + #define FN \ + if (*ZB>index_spr) {\ + if (*SubScreen) *Screen = COLOR_SUB1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr;} \ + Screen -= 320; SubScreen -= 320; Pixels++; ZB -= 320; + FN + FN + FN + FN + FN + FN + FN + FN + #undef FN +} + +// Some of these are pointless, but what the hell... + +__inline void SqTrans_NORMAL16_T (uint32 Offset,uint16 *Pixels,uint32 solid) +{ +#if 1 + uint16 *Screen = (uint16 *) GFX.S + Offset; + + #define FN(N) \ + if (!(solid&(1<<(7-N)))) *Screen = *Pixels; \ + Screen+=640; Pixels+=2; + FN(0) + FN(2) + FN(4) + FN(6) + #undef FN +#endif +} + +__inline void SqTrans_NORMAL16_O (uint32 Offset,uint16 *Pixels) +{ +#if 1 + uint16 *Screen = (uint16 *) GFX.S + Offset; + + *Screen=*Pixels; + Screen+=640; Pixels+=2; + *Screen=*Pixels; + Screen+=640; Pixels+=2; + *Screen=*Pixels; + Screen+=640; Pixels+=2; + *Screen=*Pixels; +#endif +} + +__inline void SqTrans_FLIPPED16_T (uint32 Offset,uint16 *Pixels,uint32 solid) +{ + uint16 *Screen = (uint16 *) GFX.S + Offset; + + Screen += 6 * 320; + #define FN(N) \ + if (!(solid&(1<<(7-N)))) *Screen = *Pixels; \ + Screen -= 640; Pixels+=2; + FN(1) + FN(3) + FN(5) + FN(7) + #undef FN +} + +__inline void SqTrans_FLIPPED16_O (uint32 Offset,uint16 *Pixels) +{ + uint16 *Screen = (uint16 *) GFX.S + Offset; + + Screen += 6 * 320; + + *Screen=*Pixels; + Screen-=640; Pixels+=2; + *Screen=*Pixels; + Screen-=640; Pixels+=2; + *Screen=*Pixels; + Screen-=640; Pixels+=2; + *Screen=*Pixels; +} + + + +__inline void SqTrans_NORMAL16_SPR_T (uint32 Offset,uint16 *Pixels,uint32 solid,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.S + Offset; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset; + + #define FN(N) \ + if ((!(solid&(1<<(7-N))))&&(*ZB>index_spr)) { *Screen = *Pixels; *ZB=index_spr; } \ + Screen += 640; Pixels+=2; ZB += 640; + FN(0) + FN(2) + FN(4) + FN(6) + #undef FN +} + +__inline void SqTrans_NORMAL16_SPR_O (uint32 Offset,uint16 *Pixels,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.S + Offset; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset; + + #define FN \ + if (*ZB>index_spr) {*Screen=*Pixels; *ZB=index_spr;} \ + Screen += 640; Pixels+=2; ZB += 640; + FN + FN + FN + FN + #undef FN +} + +__inline void SqTrans_FLIPPED16_SPR_T (uint32 Offset,uint16 *Pixels,uint32 solid,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.S + Offset + (6 * 640); + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset + (6 * 640); + + #define FN(N) \ + if ((!(solid&(1<<(7-N))))&&(*ZB>index_spr)) { *Screen = *Pixels; *ZB=index_spr; }\ + Screen -= 640; Pixels+=2; ZB -= 640; + FN(1) + FN(3) + FN(5) + FN(7) + #undef FN +} + +__inline void SqTrans_FLIPPED16_SPR_O (uint32 Offset,uint16 *Pixels,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.S + Offset + (6 * 640); + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset + (6 * 640); + + #define FN \ + if (*ZB>index_spr) {*Screen=*Pixels; *ZB=index_spr;} \ + Screen -= 640; Pixels+=2; ZB -= 640; + FN + FN + FN + FN + #undef FN +} + + +__inline void SqTrans_NORMAL_ADD_16_T (uint32 Offset,uint16 *Pixels,uint32 solid) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + #define FN(N) \ + if (!(solid&(1<<(7-N)))) {\ + if (*SubScreen) *Screen = COLOR_ADD(*Pixels,*SubScreen); \ + else *Screen=*Pixels;}\ + Screen += 640; SubScreen += 640; Pixels+=2; + FN(0) + FN(2) + FN(4) + FN(6) + #undef FN +} + +__inline void SqTrans_NORMAL_ADD_16_O (uint32 Offset,uint16 *Pixels) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + #define FN \ + if (*SubScreen) *Screen = COLOR_ADD(*Pixels,*SubScreen);\ + else *Screen=*Pixels; \ + Screen += 640; SubScreen += 640; Pixels+=2; + FN + FN + FN + FN + #undef FN +} + +__inline void SqTrans_FLIPPED_ADD_16_T (uint32 Offset,uint16 *Pixels,uint32 solid) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + Screen += (6 * 640); + SubScreen += (6 * 640); + #define FN(N) \ + if (!(solid&(1<<(7-N)))) {\ + if (*SubScreen) *Screen = COLOR_ADD(*Pixels,*SubScreen); \ + else *Screen=*Pixels;}\ + Screen -= 640; SubScreen -= 640; Pixels+=2; + + FN(1) + FN(3) + FN(5) + FN(7) + #undef FN +} + +__inline void SqTrans_FLIPPED_ADD_16_O (uint32 Offset,uint16 *Pixels) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + Screen += (6 * 640); + SubScreen += (6 * 640); + #define FN \ + if (*SubScreen) *Screen = COLOR_ADD(*Pixels,*SubScreen);\ + else *Screen=*Pixels; \ + Screen -= 640; SubScreen -= 640; Pixels+=2; + FN + FN + FN + FN + #undef FN +} + + + +__inline void SqTrans_NORMAL_ADD_16_SPR_T (uint32 Offset,uint16 *Pixels,uint32 solid,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset; + + #define FN(N) \ + if ((!(solid&(1<<(7-N))))&&(*ZB>index_spr)) { \ + if (*SubScreen) *Screen = COLOR_ADD(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr; \ + } \ + Screen += 640; SubScreen += 640; Pixels+=2; ZB += 640; + FN(0) + FN(2) + FN(4) + FN(6) + #undef FN +} + +__inline void SqTrans_NORMAL_ADD_16_SPR_O (uint32 Offset,uint16 *Pixels,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset; + + #define FN \ + if (*ZB>index_spr) {\ + if (*SubScreen) *Screen = COLOR_ADD(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr;} \ + Screen += 640; SubScreen += 640; Pixels+=2; ZB += 640; + FN + FN + FN + FN + #undef FN +} + +__inline void SqTrans_FLIPPED_ADD_16_SPR_T (uint32 Offset,uint16 *Pixels,uint32 solid,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset + (6 * 640); + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset + (6 * 640); + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset + (6 * 640); + + #define FN(N) \ + if ((!(solid&(1<<(7-N))))&&(*ZB>index_spr)) { \ + if (*SubScreen) *Screen = COLOR_ADD(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr; }\ + Screen -= 640; SubScreen -= 640; Pixels+=2; ZB -= 640; + FN(1) + FN(3) + FN(5) + FN(7) + #undef FN +} + +__inline void SqTrans_FLIPPED_ADD_16_SPR_O (uint32 Offset,uint16 *Pixels,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset + (6 * 640); + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset + (6 * 640); + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset + (6 * 640); + + #define FN \ + if (*ZB>index_spr) {\ + if (*SubScreen) *Screen = COLOR_ADD(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr;} \ + Screen -= 640; SubScreen -= 640; Pixels+=2; ZB -= 640; + FN + FN + FN + FN + #undef FN +} + +//////////////////// fooble +__inline void SqTrans_NORMAL_ADD1_2_16_T (uint32 Offset,uint16 *Pixels,uint32 solid) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + #define FN(N) \ + if (!(solid&(1<<(7-N)))) {\ + if (*SubScreen) *Screen = COLOR_ADD1_2(*Pixels,*SubScreen); \ + else *Screen=*Pixels;}\ + Screen += 640; SubScreen += 640; Pixels+=2; + FN(0) + FN(2) + FN(4) + FN(6) + #undef FN +} + +__inline void SqTrans_NORMAL_ADD1_2_16_O (uint32 Offset,uint16 *Pixels) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + #define FN \ + if (*SubScreen) *Screen = COLOR_ADD1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels; \ + Screen += 640; SubScreen += 640; Pixels+=2; + FN + FN + FN + FN + #undef FN +} + +__inline void SqTrans_FLIPPED_ADD1_2_16_T (uint32 Offset,uint16 *Pixels,uint32 solid) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + Screen += (6 * 640); + SubScreen += (6 * 640); + #define FN(N) \ + if (!(solid&(1<<(7-N)))) {\ + if (*SubScreen) *Screen = COLOR_ADD1_2(*Pixels,*SubScreen); \ + else *Screen=*Pixels;}\ + Screen -= 640; SubScreen -= 640; Pixels+=2; + + FN(1) + FN(3) + FN(5) + FN(7) + #undef FN +} + +__inline void SqTrans_FLIPPED_ADD1_2_16_O (uint32 Offset,uint16 *Pixels) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + Screen += (6 * 640); + SubScreen += (6 * 640); + #define FN \ + if (*SubScreen) *Screen = COLOR_ADD1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels; \ + Screen -= 640; SubScreen -= 640; Pixels+=2; + FN + FN + FN + FN + #undef FN +} + + + +__inline void SqTrans_NORMAL_ADD1_2_16_SPR_T (uint32 Offset,uint16 *Pixels,uint32 solid,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset; + + #define FN(N) \ + if ((!(solid&(1<<(7-N))))&&(*ZB>index_spr)) { \ + if (*SubScreen) *Screen = COLOR_ADD1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr; \ + } \ + Screen += 640; SubScreen += 640; Pixels+=2; ZB += 640; + FN(0) + FN(2) + FN(4) + FN(6) + #undef FN +} + +__inline void SqTrans_NORMAL_ADD1_2_16_SPR_O (uint32 Offset,uint16 *Pixels,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset; + + #define FN \ + if (*ZB>index_spr) {\ + if (*SubScreen) *Screen = COLOR_ADD1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr;} \ + Screen += 640; SubScreen += 640; Pixels+=2; ZB += 640; + FN + FN + FN + FN + #undef FN +} + +__inline void SqTrans_FLIPPED_ADD1_2_16_SPR_T (uint32 Offset,uint16 *Pixels,uint32 solid,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset + (6 * 640); + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset + (6 * 640); + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset + (6 * 640); + + #define FN(N) \ + if ((!(solid&(1<<(7-N))))&&(*ZB>index_spr)) { \ + if (*SubScreen) *Screen = COLOR_ADD1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr; }\ + Screen -= 640; SubScreen -= 640; Pixels+=2; ZB -= 640; + FN(1) + FN(3) + FN(5) + FN(7) + #undef FN +} + +__inline void SqTrans_FLIPPED_ADD1_2_16_SPR_O (uint32 Offset,uint16 *Pixels,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset + (6 * 640); + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset + (6 * 640); + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset + (6 * 640); + + #define FN \ + if (*ZB>index_spr) {\ + if (*SubScreen) *Screen = COLOR_ADD1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr;} \ + Screen -= 640; SubScreen -= 640; Pixels+=2; ZB -= 640; + FN + FN + FN + FN + #undef FN +} + +__inline void SqTrans_NORMAL_SUB_16_T (uint32 Offset,uint16 *Pixels,uint32 solid) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + #define FN(N) \ + if (!(solid&(1<<(7-N)))) {\ + if (*SubScreen) *Screen = COLOR_SUB(*Pixels,*SubScreen); \ + else *Screen=*Pixels;}\ + Screen += 640; SubScreen += 640; Pixels+=2; + FN(0) + FN(2) + FN(4) + FN(6) + #undef FN +} + +__inline void SqTrans_NORMAL_SUB_16_O (uint32 Offset,uint16 *Pixels) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + #define FN \ + if (*SubScreen) *Screen = COLOR_SUB(*Pixels,*SubScreen);\ + else *Screen=*Pixels; \ + Screen += 640; SubScreen += 640; Pixels+=2; + FN + FN + FN + FN + #undef FN +} + +__inline void SqTrans_FLIPPED_SUB_16_T (uint32 Offset,uint16 *Pixels,uint32 solid) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + Screen += (6 * 640); + SubScreen += (6 * 640); + #define FN(N) \ + if (!(solid&(1<<(7-N)))) {\ + if (*SubScreen) *Screen = COLOR_SUB(*Pixels,*SubScreen); \ + else *Screen=*Pixels;}\ + Screen -= 640; SubScreen -= 640; Pixels+=2; + + FN(1) + FN(3) + FN(5) + FN(7) + #undef FN +} + +__inline void SqTrans_FLIPPED_SUB_16_O (uint32 Offset,uint16 *Pixels) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + Screen += (6 * 640); + SubScreen += (6 * 640); + #define FN \ + if (*SubScreen) *Screen = COLOR_SUB(*Pixels,*SubScreen);\ + else *Screen=*Pixels; \ + Screen -= 640; SubScreen -= 640; Pixels+=2; + FN + FN + FN + FN + #undef FN +} + + + +__inline void SqTrans_NORMAL_SUB_16_SPR_T (uint32 Offset,uint16 *Pixels,uint32 solid,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset; + + #define FN(N) \ + if ((!(solid&(1<<(7-N))))&&(*ZB>index_spr)) { \ + if (*SubScreen) *Screen = COLOR_SUB(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr; \ + } \ + Screen += 640; SubScreen += 640; Pixels+=2; ZB += 640; + FN(0) + FN(2) + FN(4) + FN(6) + #undef FN +} + +__inline void SqTrans_NORMAL_SUB_16_SPR_O (uint32 Offset,uint16 *Pixels,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset; + + #define FN \ + if (*ZB>index_spr) {\ + if (*SubScreen) *Screen = COLOR_SUB(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr;} \ + Screen += 640; SubScreen += 640; Pixels+=2; ZB += 640; + FN + FN + FN + FN + #undef FN +} + +__inline void SqTrans_FLIPPED_SUB_16_SPR_T (uint32 Offset,uint16 *Pixels,uint32 solid,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset + (6 * 640); + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset + (6 * 640); + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset + (6 * 640); + + #define FN(N) \ + if ((!(solid&(1<<(7-N))))&&(*ZB>index_spr)) { \ + if (*SubScreen) *Screen = COLOR_SUB(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr; }\ + Screen -= 640; SubScreen -= 640; Pixels+=2; ZB -= 640; + FN(1) + FN(3) + FN(5) + FN(7) + #undef FN +} + +__inline void SqTrans_FLIPPED_SUB_16_SPR_O (uint32 Offset,uint16 *Pixels,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset + (6 * 640); + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset + (6 * 640); + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset + (6 * 640); + + #define FN \ + if (*ZB>index_spr) {\ + if (*SubScreen) *Screen = COLOR_SUB(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr;} \ + Screen -= 640; SubScreen -= 640; Pixels+=2; ZB -= 640; + FN + FN + FN + FN + #undef FN +} + +///// +__inline void SqTrans_NORMAL_SUB1_2_16_T (uint32 Offset,uint16 *Pixels,uint32 solid) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + #define FN(N) \ + if (!(solid&(1<<(7-N)))) {\ + if (*SubScreen) *Screen = COLOR_SUB1_2(*Pixels,*SubScreen); \ + else *Screen=*Pixels;}\ + Screen += 640; SubScreen += 640; Pixels+=2; + FN(0) + FN(2) + FN(4) + FN(6) + #undef FN +} + +__inline void SqTrans_NORMAL_SUB1_2_16_O (uint32 Offset,uint16 *Pixels) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + #define FN \ + if (*SubScreen) *Screen = COLOR_SUB1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels; \ + Screen += 640; SubScreen += 640; Pixels+=2; + FN + FN + FN + FN + #undef FN +} + +__inline void SqTrans_FLIPPED_SUB1_2_16_T (uint32 Offset,uint16 *Pixels,uint32 solid) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + Screen += (6 * 640); + SubScreen += (6 * 640); + #define FN(N) \ + if (!(solid&(1<<(7-N)))) {\ + if (*SubScreen) *Screen = COLOR_SUB1_2(*Pixels,*SubScreen); \ + else *Screen=*Pixels;}\ + Screen -= 640; SubScreen -= 640; Pixels+=2; + + FN(1) + FN(3) + FN(5) + FN(7) + #undef FN +} + +__inline void SqTrans_FLIPPED_SUB1_2_16_O (uint32 Offset,uint16 *Pixels) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + Screen += (6 * 640); + SubScreen += (6 * 640); + #define FN \ + if (*SubScreen) *Screen = COLOR_SUB1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels; \ + Screen -= 640; SubScreen -= 640; Pixels+=2; + FN + FN + FN + FN + #undef FN +} + + + +__inline void SqTrans_NORMAL_SUB1_2_16_SPR_T (uint32 Offset,uint16 *Pixels,uint32 solid,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset; + + #define FN(N) \ + if ((!(solid&(1<<(7-N))))&&(*ZB>index_spr)) { \ + if (*SubScreen) *Screen = COLOR_SUB1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr; \ + } \ + Screen += 640; SubScreen += 640; Pixels+=2; ZB += 640; + FN(0) + FN(2) + FN(4) + FN(6) + #undef FN +} + +__inline void SqTrans_NORMAL_SUB1_2_16_SPR_O (uint32 Offset,uint16 *Pixels,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset; + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset; + + #define FN \ + if (*ZB>index_spr) {\ + if (*SubScreen) *Screen = COLOR_SUB1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr;} \ + Screen += 640; SubScreen += 640; Pixels+=2; ZB += 640; + FN + FN + FN + FN + #undef FN +} + +__inline void SqTrans_FLIPPED_SUB1_2_16_SPR_T (uint32 Offset,uint16 *Pixels,uint32 solid,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset + (6 * 640); + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset + (6 * 640); + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset + (6 * 640); + + #define FN(N) \ + if ((!(solid&(1<<(7-N))))&&(*ZB>index_spr)) { \ + if (*SubScreen) *Screen = COLOR_SUB1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr; }\ + Screen -= 640; SubScreen -= 640; Pixels+=2; ZB -= 640; + FN(1) + FN(3) + FN(5) + FN(7) + #undef FN +} + +__inline void SqTrans_FLIPPED_SUB1_2_16_SPR_O (uint32 Offset,uint16 *Pixels,uint32 index_spr) +{ + uint16 *Screen = (uint16 *) GFX.Screen + Offset + (6 * 640); + uint16 *SubScreen = (uint16 *) GFX.SubScreen + Offset + (6 * 640); + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset + (6 * 640); + + #define FN \ + if (*ZB>index_spr) {\ + if (*SubScreen) *Screen = COLOR_SUB1_2(*Pixels,*SubScreen);\ + else *Screen=*Pixels;\ + *ZB=index_spr;} \ + Screen -= 640; SubScreen -= 640; Pixels+=2; ZB -= 640; + FN + FN + FN + FN + #undef FN +} + + + +/********************************/ + +#if 1 +__inline void NORMAL8_T (uint32 Offset,uint8 *Pixels,uint32 solid) +{ + uint8 *Screen = (uint8 *) GFX.S + Offset; + + #define FN(N) \ + if (!(solid&(1<<(7-N)))) *Screen = *Pixels; \ + Screen--; Pixels++; + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +} +__inline void NORMAL8_O (uint32 Offset,uint8 *Pixels) +{ + uint8 *Screen = (uint8 *) GFX.S + Offset; + + *Screen=*Pixels; + Screen--; Pixels++; + *Screen=*Pixels; + Screen--; Pixels++; + *Screen=*Pixels; + Screen--; Pixels++; + *Screen=*Pixels; + Screen--; Pixels++; + *Screen=*Pixels; + Screen--; Pixels++; + *Screen=*Pixels; + Screen--; Pixels++; + *Screen=*Pixels; + Screen--; Pixels++; + *Screen=*Pixels; + +} + +__inline void FLIPPED8_T (uint32 Offset,uint8 *Pixels,uint32 solid) +{ + uint8 *Screen = (uint8 *) GFX.S + Offset; + + Screen -= 7; + #define FN(N) \ + if (!(solid&(1<<(7-N)))) *Screen = *Pixels; \ + Screen++; Pixels++; + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +} + +__inline void FLIPPED8_O (uint32 Offset,uint8 *Pixels) +{ + uint8 *Screen = (uint8 *) GFX.S + Offset; + + Screen -= 7; + + *Screen=*Pixels; + Screen++; Pixels++; + *Screen=*Pixels; + Screen++; Pixels++; + *Screen=*Pixels; + Screen++; Pixels++; + *Screen=*Pixels; + Screen++; Pixels++; + *Screen=*Pixels; + Screen++; Pixels++; + *Screen=*Pixels; + Screen++; Pixels++; + *Screen=*Pixels; + Screen++; Pixels++; + *Screen=*Pixels; +} + + +__inline void NORMAL8_SPR_T (uint32 Offset,uint8 *Pixels,uint32 solid,uint32 index_spr) +{ + uint8 *Screen = (uint8 *) GFX.S + Offset; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset; + + #define FN(N) \ + if ((!(solid&(1<<(7-N))))&&(*ZB>index_spr)) { *Screen = *Pixels; *ZB=index_spr; } \ + Screen--; Pixels++; ZB--; + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +} + +__inline void NORMAL8_SPR_O (uint32 Offset,uint8 *Pixels,uint32 index_spr) +{ + uint8 *Screen = (uint8 *) GFX.S + Offset; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset; + + #define FN \ + if (*ZB>index_spr) {*Screen=*Pixels; *ZB=index_spr;} \ + Screen--; Pixels++; ZB--; + FN + FN + FN + FN + FN + FN + FN + FN + #undef FN +} + +__inline void FLIPPED8_SPR_T (uint32 Offset,uint8 *Pixels,uint32 solid,uint32 index_spr) +{ + uint8 *Screen = (uint8 *) GFX.S + Offset - 7; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset - 7; + + #define FN(N) \ + if ((!(solid&(1<<(7-N))))&&(*ZB>index_spr)) { *Screen = *Pixels; *ZB=index_spr; }\ + Screen++; Pixels++; ZB++; + FN(0) + FN(1) + FN(2) + FN(3) + FN(4) + FN(5) + FN(6) + FN(7) + #undef FN +} + +__inline void FLIPPED8_SPR_O (uint32 Offset,uint8 *Pixels,uint32 index_spr) +{ + uint8 *Screen = (uint8 *) GFX.S + Offset - 7; + uint8 *ZB = (uint8 *)GFX.ZBuffer + Offset - 7; + + #define FN \ + if (*ZB>index_spr) {*Screen=*Pixels; *ZB=index_spr;} \ + Screen++; Pixels++; ZB++; + FN + FN + FN + FN + FN + FN + FN + FN + #undef FN +} + + + +void DrawHiResTile8New (uint32 Tile, uint32 Offset, uint32 StartLine, uint32 LineCount) +{ + +} + +void DrawHiResClippedTile8New (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount) +{ + +} + + + +void DrawTile8New (uint32 Tile, uint32 Offset, uint32 StartLine, uint32 LineCount) +{ + uint8 *pCache; + uint32 Col; + uint32 TileAddr = BG.TileAddress + ((Tile & 0x3ff) << BG.TileShift); + if ((Tile & 0x1ff) >= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? +/* if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask];*/ + Col = 0; + } + else + { +/* GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette];*/ + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + + if (!BG.Buffered [TileNumber<<1]) + { + BG.Buffered[TileNumber<<1] = ConvertTile8New (pCache, TileAddr); + BG.Buffered[(TileNumber<<1)|1] = Col; + int i; + uint8 *p=pCache+8; + for (i=0;i<64;i++,p++) *p=p[64]|Col; + } + else + if (BG.Buffered [(TileNumber<<1)|1]!=Col) + { + //update cache + int i; + uint8 *p=pCache+8; + for (i=0;i<64;i++,p++) *p=p[64]|Col; + BG.Buffered [(TileNumber<<1)|1]=Col; + } + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + + register uint8 *bp; + + //Tile is not blank, 'have to draw it + Offset-=(320*StartLine); + + /* + Funky inline assembler - keep for ref + asm volatile ( + "add %0,%0,#8\n\t" + "mov r1,#8\n\t" + "ldmia %0!,{r3,r12}\n\t" + "stmia %1,{r3,r12}\n\t" + "add %1,%1,#320\n\t" + "ldmia %0!,{r3,r12}\n\t" + "stmia %1,{r3,r12}\n\t" + "add %1,%1,#320\n\t" + "ldmia %0!,{r3,r12}\n\t" + "stmia %1,{r3,r12}\n\t" + "add %1,%1,#320\n\t" + "ldmia %0!,{r3,r12}\n\t" + "stmia %1,{r3,r12}\n\t" + "add %1,%1,#320\n\t" + "ldmia %0!,{r3,r12}\n\t" + "stmia %1,{r3,r12}\n\t" + "add %1,%1,#320\n\t" + "ldmia %0!,{r3,r12}\n\t" + "stmia %1,{r3,r12}\n\t" + "add %1,%1,#320\n\t" + "ldmia %0!,{r3,r12}\n\t" + "stmia %1,{r3,r12}\n\t" + "add %1,%1,#320\n\t" + "ldmia %0!,{r3,r12}\n\t" + "stmia %1,{r3,r12}\n\t" + "add %1,%1,#320\n\t" + : + : "r" (pCache), "r" (GFX.S+(Offset)) + : "0","1","2","3","12"); + */ + + + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU8 + asmDrawTile8((uint32)pCache,0|(8<<16),(uint32)(GFX.S+(Offset)),0); +#else + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8, Offset+=320) + NORMAL8_O (Offset, (uint8*)bp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU8 + asmDrawTile8((uint32)pCache,0|(8<<16),(uint32)(GFX.S+(Offset)),0); +#else + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8, Offset+=320) + NORMAL8_O (Offset, (uint8*)bp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP +#ifdef asmPPU8 + asmDrawTile8((uint32)pCache,0|(8<<16),(uint32)(GFX.S+(Offset)),0); +#else + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8, Offset+=320) + NORMAL8_O (Offset, (uint8*)bp); +#endif + } + else + { + //VFLIP +#ifdef asmPPU8 + asmDrawTile8((uint32)pCache,0|(8<<16),(uint32)(GFX.S+(Offset)),0); +#else + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8, Offset+=320) + NORMAL8_O (Offset, (uint8*)bp); +#endif + } + +} + +void DrawClippedTile8New (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount) +{ + DrawTile8New (Tile, Offset, StartLine, LineCount); +} + +void DrawTile8NewSprite (uint32 Tile, uint32 Offset, uint32 StartLine, uint32 LineCount, uint32 index_spr) +{ + +} + +void DrawClippedTile8NewSprite (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount, uint32 index_spr) +{ + +} +#endif + +/*********************************************************************/ + +void DrawTile16New (uint32 Tile, uint32 Offset, uint32 StartLine, uint32 LineCount) +{ + uint8 *pCache; + uint32 Col; + uint32 TileAddr = BG.TileAddress + ((Tile & 0x3ff) << BG.TileShift); + if ((Tile & 0x1ff) >= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + //asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)),0); + +} + +void DrawClippedTile16New (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount) +{ + DrawTile16New (Tile, Offset, StartLine, LineCount); +} + +void DrawTile16NewSprite (uint32 Tile, uint32 Offset, uint32 StartLine, uint32 LineCount, uint32 index_spr) +{ + +} + +void DrawClippedTile16NewSprite (uint32 Tile, uint32 Offset, + uint32 StartPixel, uint32 Width, + uint32 StartLine, uint32 LineCount, uint32 index_spr) +{ + +} + +void DrawHiResTile16New (uint32 Tile, uint32 Offset, uint32 StartLine, uint32 LineCount) +{ + uint8 *pCache; + uint32 Col; + uint32 TileAddr = BG.TileAddress + ((Tile & 0x3ff) << BG.TileShift); + if ((Tile & 0x1ff) >= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8; + + // do this one when the first one works! + for (l = 4; l != 0; l--, bp += 8*2*2, Offset+=1) + NORMAL16_O (Offset, (uint16*)bp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8; + Offset += 3; + for (l = 4; l != 0; l--, bp += 8*2*2, Offset-=1) + NORMAL16_O (Offset, (uint16*)bp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8; + Offset += 3; + + for (l = 4; l != 0; l--, bp += 8*2*2, Offset-=1) + FLIPPED16_O (Offset, (uint16*)bp); + + } + else + { + //VFLIP + + + bp = pCache+8; + for (l = 4; l != 0; l--, bp += 8*2*2, Offset+=1) + FLIPPED16_O (Offset, (uint16*)bp); + + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache; + bp = pCache+8; + + // do this one when the first one works! + for (l = 4; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + NORMAL16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache; + bp = pCache+8; + Offset += 3; + for (l = 4; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + NORMAL16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + bp = pCache+8 + StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset+=1) + NORMAL16_O (Offset, (uint16*)bp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset-=1) + NORMAL16_O (Offset, (uint16*)bp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset-=1) + FLIPPED16_O (Offset, (uint16*)bp); + + } + else + { + //VFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset+=1) + FLIPPED16_O (Offset, (uint16*)bp); + + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + NORMAL16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + NORMAL16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<>1); + + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + FLIPPED16_T (Offset, (uint16*)bp,solid_lineclipI|*headerbp); + + } + else + { + //VFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + FLIPPED16_T (Offset, (uint16*)bp,solid_lineclipI|*headerbp); + + } + } +} + +/****************** ADD ***********************/ +void DrawTile16ADDNew (uint32 Tile, uint32 Offset, uint32 StartLine, uint32 LineCount) +{ + uint8 *pCache; + uint32 Col; + uint32 TileAddr = BG.TileAddress + ((Tile & 0x3ff) << BG.TileShift); + + if ((Tile & 0x1ff) >= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)),0); +#else + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + NORMAL_ADD_16_O (Offset, (uint16*)bp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)+7*2),2); +#else + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + NORMAL_ADD_16_O (Offset, (uint16*)bp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)+7*2),3); +#else + bp = pCache+8; + Offset += 7; + + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + FLIPPED_ADD_16_O (Offset, (uint16*)bp); +#endif + } + else + { + //VFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)),1); +#else + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + FLIPPED_ADD_16_O (Offset, (uint16*)bp); +#endif + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,solid_lineclip,(uint32)(GFX.S+(Offset<<1)),0); +#else + headerbp = pCache; + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + NORMAL_ADD_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,solid_lineclip,(uint32)(GFX.S+(Offset<<1)+7*2),2); +#else + headerbp = pCache; + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + NORMAL_ADD_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+StartPixel*2),0); +#else + + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + NORMAL_ADD_16_O (Offset, (uint16*)bp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),2); +#else + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + NORMAL_ADD_16_O (Offset, (uint16*)bp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),3); +#else + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + FLIPPED_ADD_16_O (Offset, (uint16*)bp); +#endif + } + else + { + //VFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+StartPixel*2),1); +#else + + bp = pCache+8+StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + FLIPPED_ADD_16_O (Offset, (uint16*)bp); +#endif + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8)|solid_lineclip,(uint32)(GFX.S+(Offset<<1)+StartPixel*2),0); +#else + + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + NORMAL_ADD_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8)|solid_lineclip,(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),2); +#else + + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + NORMAL_ADD_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8; + + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + NORMAL_ADD_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + NORMAL_ADD_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8; + Offset += 7; + + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + FLIPPED_ADD_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + else + { + //VFLIP + + + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + FLIPPED_ADD_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache; + bp = pCache+8; + + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + NORMAL_ADD_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache; + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + NORMAL_ADD_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + NORMAL_ADD_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + NORMAL_ADD_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + FLIPPED_ADD_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + else + { + //VFLIP + + bp = pCache+8+StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + FLIPPED_ADD_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + NORMAL_ADD_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + NORMAL_ADD_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8; + + for (l = 4; l != 0; l--, bp += 8*2*2, Offset+=1) + NORMAL_ADD_16_O (Offset, (uint16*)bp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8; + Offset += 3; + for (l = 4; l != 0; l--, bp += 8*2*2, Offset-=1) + NORMAL_ADD_16_O (Offset, (uint16*)bp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8; + Offset += 3; + + for (l = 4; l != 0; l--, bp += 8*2*2, Offset-=1) + FLIPPED_ADD_16_O (Offset, (uint16*)bp); + + } + else + { + //VFLIP + + + bp = pCache+8; + for (l = 4; l != 0; l--, bp += 8*2*2, Offset+=1) + FLIPPED_ADD_16_O (Offset, (uint16*)bp); + + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache; + bp = pCache+8; + + for (l = 4; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + NORMAL_ADD_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache; + bp = pCache+8; + Offset += 3; + for (l = 4; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + NORMAL_ADD_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + bp = pCache+8 + StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset+=1) + NORMAL_ADD_16_O (Offset, (uint16*)bp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset-=1) + NORMAL_ADD_16_O (Offset, (uint16*)bp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset-=1) + FLIPPED_ADD_16_O (Offset, (uint16*)bp); + + } + else + { + //VFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset+=1) + FLIPPED_ADD_16_O (Offset, (uint16*)bp); + + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + NORMAL_ADD_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + NORMAL_ADD_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<>1); + + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + FLIPPED_ADD_16_T (Offset, (uint16*)bp,solid_lineclipI|*headerbp); + + } + else + { + //VFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + FLIPPED_ADD_16_T (Offset, (uint16*)bp,solid_lineclipI|*headerbp); + + } + } +} + +/****************** ADD1_2 ***********************/ +void DrawTile16ADD1_2New (uint32 Tile, uint32 Offset, uint32 StartLine, uint32 LineCount) +{ + uint8 *pCache; + uint32 Col; + uint32 TileAddr = BG.TileAddress + ((Tile & 0x3ff) << BG.TileShift); + if ((Tile & 0x1ff) >= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)),0); +#else + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + NORMAL_ADD1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)+7*2),2); +#else + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + NORMAL_ADD1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)+7*2),3); +#else + bp = pCache+8; + Offset += 7; + + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + FLIPPED_ADD1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + { + //VFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)),1); +#else + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + FLIPPED_ADD1_2_16_O (Offset, (uint16*)bp); +#endif + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,solid_lineclip,(uint32)(GFX.S+(Offset<<1)),0); +#else + headerbp = pCache; + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + NORMAL_ADD1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,solid_lineclip,(uint32)(GFX.S+(Offset<<1)+7*2),2); +#else + headerbp = pCache; + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + NORMAL_ADD1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+StartPixel*2),0); +#else + + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + NORMAL_ADD1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),2); +#else + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + NORMAL_ADD1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),3); +#else + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + FLIPPED_ADD1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + { + //VFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+StartPixel*2),1); +#else + + bp = pCache+8+StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + FLIPPED_ADD1_2_16_O (Offset, (uint16*)bp); +#endif + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8)|solid_lineclip,(uint32)(GFX.S+(Offset<<1)+StartPixel*2),0); +#else + + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + NORMAL_ADD1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8)|solid_lineclip,(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),2); +#else + + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + NORMAL_ADD1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8; + + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + NORMAL_ADD1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + NORMAL_ADD1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8; + Offset += 7; + + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + FLIPPED_ADD1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + else + { + //VFLIP + + + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + FLIPPED_ADD1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache; + bp = pCache+8; + + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + NORMAL_ADD1_2_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache; + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + NORMAL_ADD1_2_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + NORMAL_ADD1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + NORMAL_ADD1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + FLIPPED_ADD1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + else + { + //VFLIP + + bp = pCache+8+StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + FLIPPED_ADD1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + NORMAL_ADD1_2_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + NORMAL_ADD1_2_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8; + + for (l = 4; l != 0; l--, bp += 8*2*2, Offset+=1) + NORMAL_ADD1_2_16_O (Offset, (uint16*)bp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8; + Offset += 3; + for (l = 4; l != 0; l--, bp += 8*2*2, Offset-=1) + NORMAL_ADD1_2_16_O (Offset, (uint16*)bp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8; + Offset += 3; + + for (l = 4; l != 0; l--, bp += 8*2*2, Offset-=1) + FLIPPED_ADD1_2_16_O (Offset, (uint16*)bp); + + } + else + { + //VFLIP + + + bp = pCache+8; + for (l = 4; l != 0; l--, bp += 8*2*2, Offset+=1) + FLIPPED_ADD1_2_16_O (Offset, (uint16*)bp); + + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache; + bp = pCache+8; + + for (l = 4; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + NORMAL_ADD1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache; + bp = pCache+8; + Offset += 3; + for (l = 4; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + NORMAL_ADD1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + bp = pCache+8 + StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset+=1) + NORMAL_ADD1_2_16_O (Offset, (uint16*)bp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset-=1) + NORMAL_ADD1_2_16_O (Offset, (uint16*)bp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset-=1) + FLIPPED_ADD1_2_16_O (Offset, (uint16*)bp); + + } + else + { + //VFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset+=1) + FLIPPED_ADD1_2_16_O (Offset, (uint16*)bp); + + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + NORMAL_ADD1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + NORMAL_ADD1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<>1); + + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + FLIPPED_ADD1_2_16_T (Offset, (uint16*)bp,solid_lineclipI|*headerbp); + + } + else + { + //VFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + FLIPPED_ADD1_2_16_T (Offset, (uint16*)bp,solid_lineclipI|*headerbp); + + } + } +} + + +/****************** SUB ***********************/ +void DrawTile16SUBNew (uint32 Tile, uint32 Offset, uint32 StartLine, uint32 LineCount) +{ + uint8 *pCache; + uint32 Col; + uint32 TileAddr = BG.TileAddress + ((Tile & 0x3ff) << BG.TileShift); + if ((Tile & 0x1ff) >= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)),0); +#else + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + NORMAL_SUB_16_O (Offset, (uint16*)bp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)+7*2),2); +#else + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + NORMAL_SUB_16_O (Offset, (uint16*)bp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)+7*2),3); +#else + bp = pCache+8; + Offset += 7; + + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + FLIPPED_SUB_16_O (Offset, (uint16*)bp); +#endif + } + else + { + //VFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)),1); +#else + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + FLIPPED_SUB_16_O (Offset, (uint16*)bp); +#endif + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,solid_lineclip,(uint32)(GFX.S+(Offset<<1)),0); +#else + headerbp = pCache; + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + NORMAL_SUB_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,solid_lineclip,(uint32)(GFX.S+(Offset<<1)+7*2),2); +#else + headerbp = pCache; + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + NORMAL_SUB_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+StartPixel*2),0); +#else + + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + NORMAL_SUB_16_O (Offset, (uint16*)bp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),2); +#else + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + NORMAL_SUB_16_O (Offset, (uint16*)bp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),3); +#else + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + FLIPPED_SUB_16_O (Offset, (uint16*)bp); +#endif + } + else + { + //VFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+StartPixel*2),1); +#else + + bp = pCache+8+StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + FLIPPED_SUB_16_O (Offset, (uint16*)bp); +#endif + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8)|solid_lineclip,(uint32)(GFX.S+(Offset<<1)+StartPixel*2),0); +#else + + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + NORMAL_SUB_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8)|solid_lineclip,(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),2); +#else + + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + NORMAL_SUB_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8; + + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + NORMAL_SUB_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + NORMAL_SUB_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8; + Offset += 7; + + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + FLIPPED_SUB_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + else + { + //VFLIP + + + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + FLIPPED_SUB_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache; + bp = pCache+8; + + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + NORMAL_SUB_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache; + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + NORMAL_SUB_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + NORMAL_SUB_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + NORMAL_SUB_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + FLIPPED_SUB_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + else + { + //VFLIP + + bp = pCache+8+StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + FLIPPED_SUB_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + NORMAL_SUB_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + NORMAL_SUB_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8; + + for (l = 4; l != 0; l--, bp += 8*2*2, Offset+=1) + NORMAL_SUB_16_O (Offset, (uint16*)bp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8; + Offset += 3; + for (l = 4; l != 0; l--, bp += 8*2*2, Offset-=1) + NORMAL_SUB_16_O (Offset, (uint16*)bp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8; + Offset += 3; + + for (l = 4; l != 0; l--, bp += 8*2*2, Offset-=1) + FLIPPED_SUB_16_O (Offset, (uint16*)bp); + + } + else + { + //VFLIP + + + bp = pCache+8; + for (l = 4; l != 0; l--, bp += 8*2*2, Offset+=1) + FLIPPED_SUB_16_O (Offset, (uint16*)bp); + + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache; + bp = pCache+8; + + for (l = 4; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + NORMAL_SUB_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache; + bp = pCache+8; + Offset += 3; + for (l = 4; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + NORMAL_SUB_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + bp = pCache+8 + StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset+=1) + NORMAL_SUB_16_O (Offset, (uint16*)bp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset-=1) + NORMAL_SUB_16_O (Offset, (uint16*)bp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset-=1) + FLIPPED_SUB_16_O (Offset, (uint16*)bp); + + } + else + { + //VFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset+=1) + FLIPPED_SUB_16_O (Offset, (uint16*)bp); + + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + NORMAL_SUB_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + NORMAL_SUB_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<>1); + + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + FLIPPED_SUB_16_T (Offset, (uint16*)bp,solid_lineclipI|*headerbp); + + } + else + { + //VFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + FLIPPED_SUB_16_T (Offset, (uint16*)bp,solid_lineclipI|*headerbp); + + } + } +} + +/****************** SUB1_2 ***********************/ +void DrawTile16SUB1_2New (uint32 Tile, uint32 Offset, uint32 StartLine, uint32 LineCount) +{ + uint8 *pCache; + uint32 Col; + uint32 TileAddr = BG.TileAddress + ((Tile & 0x3ff) << BG.TileShift); + if ((Tile & 0x1ff) >= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)),0); +#else + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + NORMAL_SUB1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)+7*2),2); +#else + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + NORMAL_SUB1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)+7*2),3); +#else + bp = pCache+8; + Offset += 7; + + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + FLIPPED_SUB1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + { + //VFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)),1); +#else + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + FLIPPED_SUB1_2_16_O (Offset, (uint16*)bp); +#endif + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,solid_lineclip,(uint32)(GFX.S+(Offset<<1)),0); +#else + headerbp = pCache; + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + NORMAL_SUB1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,solid_lineclip,(uint32)(GFX.S+(Offset<<1)+7*2),2); +#else + headerbp = pCache; + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + NORMAL_SUB1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+StartPixel*2),0); +#else + + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + NORMAL_SUB1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),2); +#else + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + NORMAL_SUB1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),3); +#else + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + FLIPPED_SUB1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + { + //VFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+StartPixel*2),1); +#else + + bp = pCache+8+StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + FLIPPED_SUB1_2_16_O (Offset, (uint16*)bp); +#endif + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8)|solid_lineclip,(uint32)(GFX.S+(Offset<<1)+StartPixel*2),0); +#else + + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + NORMAL_SUB1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8)|solid_lineclip,(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),2); +#else + + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + NORMAL_SUB1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8; + + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + NORMAL_SUB1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + NORMAL_SUB1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8; + Offset += 7; + + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + FLIPPED_SUB1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + else + { + //VFLIP + + + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + FLIPPED_SUB1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache; + bp = pCache+8; + + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + NORMAL_SUB1_2_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache; + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + NORMAL_SUB1_2_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + NORMAL_SUB1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + NORMAL_SUB1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + FLIPPED_SUB1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + else + { + //VFLIP + + bp = pCache+8+StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + FLIPPED_SUB1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + NORMAL_SUB1_2_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + NORMAL_SUB1_2_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8; + + for (l = 4; l != 0; l--, bp += 8*2*2, Offset+=1) + NORMAL_SUB1_2_16_O (Offset, (uint16*)bp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8; + Offset += 3; + for (l = 4; l != 0; l--, bp += 8*2*2, Offset-=1) + NORMAL_SUB1_2_16_O (Offset, (uint16*)bp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8; + Offset += 3; + + for (l = 4; l != 0; l--, bp += 8*2*2, Offset-=1) + FLIPPED_SUB1_2_16_O (Offset, (uint16*)bp); + + } + else + { + //VFLIP + + + bp = pCache+8; + for (l = 4; l != 0; l--, bp += 8*2*2, Offset+=1) + FLIPPED_SUB1_2_16_O (Offset, (uint16*)bp); + + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache; + bp = pCache+8; + + for (l = 4; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + NORMAL_SUB1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache; + bp = pCache+8; + Offset += 3; + for (l = 4; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + NORMAL_SUB1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + bp = pCache+8 + StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset+=1) + NORMAL_SUB1_2_16_O (Offset, (uint16*)bp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset-=1) + NORMAL_SUB1_2_16_O (Offset, (uint16*)bp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset-=1) + FLIPPED_SUB1_2_16_O (Offset, (uint16*)bp); + + } + else + { + //VFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset+=1) + FLIPPED_SUB1_2_16_O (Offset, (uint16*)bp); + + } + } + else + { + + Offset -= (StartLine * 320); //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + NORMAL_SUB1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + NORMAL_SUB1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<>1); + + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + FLIPPED_SUB1_2_16_T (Offset, (uint16*)bp,solid_lineclipI|*headerbp); + + } + else + { + //VFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + FLIPPED_SUB1_2_16_T (Offset, (uint16*)bp,solid_lineclipI|*headerbp); + + } + } +} + +void SqTrans_Tile16New (uint32 Tile, uint32 Offset, uint32 StartLine, uint32 LineCount) +{ +#if 1 + uint8 *pCache; + uint32 Col; + uint32 TileAddr = BG.TileAddress + ((Tile & 0x3ff) << BG.TileShift); + if ((Tile & 0x1ff) >= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320); //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU16 + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)),0); +#else + bp = pCache+8; + // do this one first! + for (l = 8; l != 0; l--, bp += 8*2, Offset++) + SqTrans_NORMAL16_O (Offset, (uint16*)bp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU16 + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)+7*2),2); +#else + bp = pCache+8; + Offset += 7; + // do this one when the first one works! + for (l = 8; l != 0; l--, bp += 8*2, Offset--) + SqTrans_NORMAL16_O (Offset, (uint16*)bp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP +#ifdef asmPPU16 + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)+7*2),3); +#else + bp = pCache+8; + Offset += 7; + + for (l = 8; l != 0; l--, bp += 8*2, Offset--) + SqTrans_FLIPPED16_O (Offset, (uint16*)bp); +#endif + } + else + { + //VFLIP +#ifdef asmPPU16 + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)),1); +#else + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset++) + SqTrans_FLIPPED16_O (Offset, (uint16*)bp); +#endif + } + } + else + { + Offset -= (StartLine * 320); //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU16 + asmDrawTile16((uint32)pCache,solid_lineclip,(uint32)(GFX.S+(Offset<<1)),0); +#else + headerbp = pCache; + bp = pCache+8; + // do this one when the first one works! + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset++) + SqTrans_NORMAL16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU16 + asmDrawTile16((uint32)pCache,solid_lineclip,(uint32)(GFX.S+(Offset<<1)+7*2),2); +#else + headerbp = pCache; + bp = pCache+8; + Offset += 7; + // do this one when the first one works! + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset--) + SqTrans_NORMAL16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320); //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU16 + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+StartPixel*2),0); +#else + + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset++) + SqTrans_NORMAL16_O (Offset, (uint16*)bp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU16 + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),2); +#else + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, Offset--) + SqTrans_NORMAL16_O (Offset, (uint16*)bp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP +#ifdef asmPPU16 + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),3); +#else + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + + for (l = Width; l != 0; l--, bp += 8*2, Offset--) + SqTrans_FLIPPED16_O (Offset, (uint16*)bp); +#endif + } + else + { + //VFLIP +#ifdef asmPPU16 + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+StartPixel*2),1); +#else + + bp = pCache+8+StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset++) + SqTrans_FLIPPED16_O (Offset, (uint16*)bp); +#endif + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU16 + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8)|solid_lineclip,(uint32)(GFX.S+(Offset<<1)+StartPixel*2),0); +#else + + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + // do this one when the first one works! + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset++) + SqTrans_NORMAL16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU16 + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8)|solid_lineclip,(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),2); +#else + + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset--) + SqTrans_NORMAL16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8; + + for (l = 8; l != 0; l--, bp += 8*2, Offset++) + SqTrans_NORMAL16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, Offset--) + SqTrans_NORMAL16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8; + Offset += 7; + + for (l = 8; l != 0; l--, bp += 8*2, Offset--) + SqTrans_FLIPPED16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + else + { + //VFLIP + + + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset++) + SqTrans_FLIPPED16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache; + bp = pCache+8; + + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset++) + SqTrans_NORMAL16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache; + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset--) + SqTrans_NORMAL16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset++) + SqTrans_NORMAL16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, Offset--) + SqTrans_NORMAL16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + + for (l = Width; l != 0; l--, bp += 8*2, Offset--) + SqTrans_FLIPPED16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + else + { + //VFLIP + + bp = pCache+8+StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset++) + SqTrans_FLIPPED16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset++) + SqTrans_NORMAL16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset--) + SqTrans_NORMAL16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8; + + // do this one when the first one works! + for (l = 4; l != 0; l--, bp += 8*2*2, Offset+=1) + SqTrans_NORMAL16_O (Offset, (uint16*)bp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8; + Offset += 3; + for (l = 4; l != 0; l--, bp += 8*2*2, Offset-=1) + SqTrans_NORMAL16_O (Offset, (uint16*)bp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8; + Offset += 3; + + for (l = 4; l != 0; l--, bp += 8*2*2, Offset-=1) + SqTrans_FLIPPED16_O (Offset, (uint16*)bp); + + } + else + { + //VFLIP + + + bp = pCache+8; + for (l = 4; l != 0; l--, bp += 8*2*2, Offset+=1) + SqTrans_FLIPPED16_O (Offset, (uint16*)bp); + + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache; + bp = pCache+8; + + // do this one when the first one works! + for (l = 4; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + SqTrans_NORMAL16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache; + bp = pCache+8; + Offset += 3; + for (l = 4; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + SqTrans_NORMAL16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + bp = pCache+8 + StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset+=1) + SqTrans_NORMAL16_O (Offset, (uint16*)bp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset-=1) + SqTrans_NORMAL16_O (Offset, (uint16*)bp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset-=1) + SqTrans_FLIPPED16_O (Offset, (uint16*)bp); + + } + else + { + //VFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset+=1) + SqTrans_FLIPPED16_O (Offset, (uint16*)bp); + + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + SqTrans_NORMAL16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + SqTrans_NORMAL16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<>1); + + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + SqTrans_FLIPPED16_T (Offset, (uint16*)bp,solid_lineclipI|*headerbp); + + } + else + { + //VFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + SqTrans_FLIPPED16_T (Offset, (uint16*)bp,solid_lineclipI|*headerbp); + + } + } +} + + +#if 0 +/****************** ADD ***********************/ +void SqTrans_Tile16ADDNew (uint32 Tile, uint32 Offset, uint32 StartLine, uint32 LineCount) +{ + uint8 *pCache; + uint32 Col; + uint32 TileAddr = BG.TileAddress + ((Tile & 0x3ff) << BG.TileShift); + + if ((Tile & 0x1ff) >= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)),0); +#else + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_NORMALADD_16_O (Offset, (uint16*)bp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)+7*2),2); +#else + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_NORMALADD_16_O (Offset, (uint16*)bp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)+7*2),3); +#else + bp = pCache+8; + Offset += 7; + + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_FLIPPEDADD_16_O (Offset, (uint16*)bp); +#endif + } + else + { + //VFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)),1); +#else + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_FLIPPEDADD_16_O (Offset, (uint16*)bp); +#endif + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,solid_lineclip,(uint32)(GFX.S+(Offset<<1)),0); +#else + headerbp = pCache; + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + SqTrans_NORMALADD_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,solid_lineclip,(uint32)(GFX.S+(Offset<<1)+7*2),2); +#else + headerbp = pCache; + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + SqTrans_NORMALADD_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+StartPixel*2),0); +#else + + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_NORMALADD_16_O (Offset, (uint16*)bp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),2); +#else + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_NORMALADD_16_O (Offset, (uint16*)bp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),3); +#else + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_FLIPPEDADD_16_O (Offset, (uint16*)bp); +#endif + } + else + { + //VFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+StartPixel*2),1); +#else + + bp = pCache+8+StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_FLIPPEDADD_16_O (Offset, (uint16*)bp); +#endif + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8)|solid_lineclip,(uint32)(GFX.S+(Offset<<1)+StartPixel*2),0); +#else + + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + SqTrans_NORMALADD_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8)|solid_lineclip,(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),2); +#else + + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + SqTrans_NORMALADD_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8; + + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_NORMALADD_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_NORMALADD_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8; + Offset += 7; + + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_FLIPPEDADD_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + else + { + //VFLIP + + + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_FLIPPEDADD_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache; + bp = pCache+8; + + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + SqTrans_NORMALADD_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache; + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + SqTrans_NORMALADD_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_NORMALADD_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_NORMALADD_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_FLIPPEDADD_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + else + { + //VFLIP + + bp = pCache+8+StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_FLIPPEDADD_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + SqTrans_NORMALADD_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + SqTrans_NORMALADD_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8; + + for (l = 4; l != 0; l--, bp += 8*2*2, Offset+=1) + SqTrans_NORMALADD_16_O (Offset, (uint16*)bp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8; + Offset += 3; + for (l = 4; l != 0; l--, bp += 8*2*2, Offset-=1) + SqTrans_NORMALADD_16_O (Offset, (uint16*)bp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8; + Offset += 3; + + for (l = 4; l != 0; l--, bp += 8*2*2, Offset-=1) + SqTrans_FLIPPEDADD_16_O (Offset, (uint16*)bp); + + } + else + { + //VFLIP + + + bp = pCache+8; + for (l = 4; l != 0; l--, bp += 8*2*2, Offset+=1) + SqTrans_FLIPPEDADD_16_O (Offset, (uint16*)bp); + + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache; + bp = pCache+8; + + for (l = 4; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + SqTrans_NORMALADD_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache; + bp = pCache+8; + Offset += 3; + for (l = 4; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + SqTrans_NORMALADD_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + bp = pCache+8 + StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset+=1) + SqTrans_NORMALADD_16_O (Offset, (uint16*)bp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset-=1) + SqTrans_NORMALADD_16_O (Offset, (uint16*)bp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset-=1) + SqTrans_FLIPPEDADD_16_O (Offset, (uint16*)bp); + + } + else + { + //VFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset+=1) + SqTrans_FLIPPEDADD_16_O (Offset, (uint16*)bp); + + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + SqTrans_NORMALADD_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + SqTrans_NORMALADD_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<>1); + + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + SqTrans_FLIPPEDADD_16_T (Offset, (uint16*)bp,solid_lineclipI|*headerbp); + + } + else + { + //VFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + SqTrans_FLIPPEDADD_16_T (Offset, (uint16*)bp,solid_lineclipI|*headerbp); + + } + } +} + +/****************** ADD1_2 ***********************/ +void SqTrans_Tile16ADD1_2New (uint32 Tile, uint32 Offset, uint32 StartLine, uint32 LineCount) +{ + uint8 *pCache; + uint32 Col; + uint32 TileAddr = BG.TileAddress + ((Tile & 0x3ff) << BG.TileShift); + if ((Tile & 0x1ff) >= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)),0); +#else + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_NORMALADD1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)+7*2),2); +#else + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_NORMALADD1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)+7*2),3); +#else + bp = pCache+8; + Offset += 7; + + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_FLIPPEDADD1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + { + //VFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)),1); +#else + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_FLIPPEDADD1_2_16_O (Offset, (uint16*)bp); +#endif + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,solid_lineclip,(uint32)(GFX.S+(Offset<<1)),0); +#else + headerbp = pCache; + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + SqTrans_NORMALADD1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,solid_lineclip,(uint32)(GFX.S+(Offset<<1)+7*2),2); +#else + headerbp = pCache; + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + SqTrans_NORMALADD1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+StartPixel*2),0); +#else + + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_NORMALADD1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),2); +#else + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_NORMALADD1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),3); +#else + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_FLIPPEDADD1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + { + //VFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+StartPixel*2),1); +#else + + bp = pCache+8+StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_FLIPPEDADD1_2_16_O (Offset, (uint16*)bp); +#endif + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8)|solid_lineclip,(uint32)(GFX.S+(Offset<<1)+StartPixel*2),0); +#else + + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + SqTrans_NORMALADD1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8)|solid_lineclip,(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),2); +#else + + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + SqTrans_NORMALADD1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8; + + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_NORMALADD1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_NORMALADD1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8; + Offset += 7; + + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_FLIPPEDADD1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + else + { + //VFLIP + + + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_FLIPPEDADD1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache; + bp = pCache+8; + + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + SqTrans_NORMALADD1_2_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache; + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + SqTrans_NORMALADD1_2_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_NORMALADD1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_NORMALADD1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_FLIPPEDADD1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + else + { + //VFLIP + + bp = pCache+8+StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_FLIPPEDADD1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + SqTrans_NORMALADD1_2_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + SqTrans_NORMALADD1_2_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8; + + for (l = 4; l != 0; l--, bp += 8*2*2, Offset+=1) + SqTrans_NORMALADD1_2_16_O (Offset, (uint16*)bp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8; + Offset += 3; + for (l = 4; l != 0; l--, bp += 8*2*2, Offset-=1) + SqTrans_NORMALADD1_2_16_O (Offset, (uint16*)bp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8; + Offset += 3; + + for (l = 4; l != 0; l--, bp += 8*2*2, Offset-=1) + SqTrans_FLIPPEDADD1_2_16_O (Offset, (uint16*)bp); + + } + else + { + //VFLIP + + + bp = pCache+8; + for (l = 4; l != 0; l--, bp += 8*2*2, Offset+=1) + SqTrans_FLIPPEDADD1_2_16_O (Offset, (uint16*)bp); + + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache; + bp = pCache+8; + + for (l = 4; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + SqTrans_NORMALADD1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache; + bp = pCache+8; + Offset += 3; + for (l = 4; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + SqTrans_NORMALADD1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + bp = pCache+8 + StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset+=1) + SqTrans_NORMALADD1_2_16_O (Offset, (uint16*)bp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset-=1) + SqTrans_NORMALADD1_2_16_O (Offset, (uint16*)bp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset-=1) + SqTrans_FLIPPEDADD1_2_16_O (Offset, (uint16*)bp); + + } + else + { + //VFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset+=1) + SqTrans_FLIPPEDADD1_2_16_O (Offset, (uint16*)bp); + + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + SqTrans_NORMALADD1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + SqTrans_NORMALADD1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<>1); + + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + SqTrans_FLIPPEDADD1_2_16_T (Offset, (uint16*)bp,solid_lineclipI|*headerbp); + + } + else + { + //VFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + SqTrans_FLIPPEDADD1_2_16_T (Offset, (uint16*)bp,solid_lineclipI|*headerbp); + + } + } +} + + +/****************** SUB ***********************/ +void SqTrans_Tile16SUBNew (uint32 Tile, uint32 Offset, uint32 StartLine, uint32 LineCount) +{ + uint8 *pCache; + uint32 Col; + uint32 TileAddr = BG.TileAddress + ((Tile & 0x3ff) << BG.TileShift); + if ((Tile & 0x1ff) >= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)),0); +#else + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_NORMALSUB_16_O (Offset, (uint16*)bp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)+7*2),2); +#else + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_NORMALSUB_16_O (Offset, (uint16*)bp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)+7*2),3); +#else + bp = pCache+8; + Offset += 7; + + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_FLIPPEDSUB_16_O (Offset, (uint16*)bp); +#endif + } + else + { + //VFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)),1); +#else + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_FLIPPEDSUB_16_O (Offset, (uint16*)bp); +#endif + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,solid_lineclip,(uint32)(GFX.S+(Offset<<1)),0); +#else + headerbp = pCache; + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + SqTrans_NORMALSUB_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,solid_lineclip,(uint32)(GFX.S+(Offset<<1)+7*2),2); +#else + headerbp = pCache; + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + SqTrans_NORMALSUB_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+StartPixel*2),0); +#else + + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_NORMALSUB_16_O (Offset, (uint16*)bp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),2); +#else + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_NORMALSUB_16_O (Offset, (uint16*)bp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),3); +#else + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_FLIPPEDSUB_16_O (Offset, (uint16*)bp); +#endif + } + else + { + //VFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+StartPixel*2),1); +#else + + bp = pCache+8+StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_FLIPPEDSUB_16_O (Offset, (uint16*)bp); +#endif + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8)|solid_lineclip,(uint32)(GFX.S+(Offset<<1)+StartPixel*2),0); +#else + + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + SqTrans_NORMALSUB_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8)|solid_lineclip,(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),2); +#else + + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + SqTrans_NORMALSUB_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8; + + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_NORMALSUB_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_NORMALSUB_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8; + Offset += 7; + + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_FLIPPEDSUB_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + else + { + //VFLIP + + + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_FLIPPEDSUB_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache; + bp = pCache+8; + + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + SqTrans_NORMALSUB_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache; + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + SqTrans_NORMALSUB_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_NORMALSUB_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_NORMALSUB_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_FLIPPEDSUB_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + else + { + //VFLIP + + bp = pCache+8+StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_FLIPPEDSUB_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + SqTrans_NORMALSUB_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + SqTrans_NORMALSUB_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8; + + for (l = 4; l != 0; l--, bp += 8*2*2, Offset+=1) + SqTrans_NORMALSUB_16_O (Offset, (uint16*)bp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8; + Offset += 3; + for (l = 4; l != 0; l--, bp += 8*2*2, Offset-=1) + SqTrans_NORMALSUB_16_O (Offset, (uint16*)bp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8; + Offset += 3; + + for (l = 4; l != 0; l--, bp += 8*2*2, Offset-=1) + SqTrans_FLIPPEDSUB_16_O (Offset, (uint16*)bp); + + } + else + { + //VFLIP + + + bp = pCache+8; + for (l = 4; l != 0; l--, bp += 8*2*2, Offset+=1) + SqTrans_FLIPPEDSUB_16_O (Offset, (uint16*)bp); + + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache; + bp = pCache+8; + + for (l = 4; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + SqTrans_NORMALSUB_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache; + bp = pCache+8; + Offset += 3; + for (l = 4; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + SqTrans_NORMALSUB_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + bp = pCache+8 + StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset+=1) + SqTrans_NORMALSUB_16_O (Offset, (uint16*)bp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset-=1) + SqTrans_NORMALSUB_16_O (Offset, (uint16*)bp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset-=1) + SqTrans_FLIPPEDSUB_16_O (Offset, (uint16*)bp); + + } + else + { + //VFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset+=1) + SqTrans_FLIPPEDSUB_16_O (Offset, (uint16*)bp); + + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + SqTrans_NORMALSUB_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + SqTrans_NORMALSUB_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<>1); + + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + SqTrans_FLIPPEDSUB_16_T (Offset, (uint16*)bp,solid_lineclipI|*headerbp); + + } + else + { + //VFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + SqTrans_FLIPPEDSUB_16_T (Offset, (uint16*)bp,solid_lineclipI|*headerbp); + + } + } +} + +/****************** SUB1_2 ***********************/ +void SqTrans_Tile16SUB1_2New (uint32 Tile, uint32 Offset, uint32 StartLine, uint32 LineCount) +{ + uint8 *pCache; + uint32 Col; + uint32 TileAddr = BG.TileAddress + ((Tile & 0x3ff) << BG.TileShift); + if ((Tile & 0x1ff) >= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)),0); +#else + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_NORMALSUB1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)+7*2),2); +#else + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_NORMALSUB1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)+7*2),3); +#else + bp = pCache+8; + Offset += 7; + + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_FLIPPEDSUB1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + { + //VFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,0,(uint32)(GFX.S+(Offset<<1)),1); +#else + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_FLIPPEDSUB1_2_16_O (Offset, (uint16*)bp); +#endif + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,solid_lineclip,(uint32)(GFX.S+(Offset<<1)),0); +#else + headerbp = pCache; + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + SqTrans_NORMALSUB1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTile16((uint32)pCache,solid_lineclip,(uint32)(GFX.S+(Offset<<1)+7*2),2); +#else + headerbp = pCache; + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + SqTrans_NORMALSUB1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+StartPixel*2),0); +#else + + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_NORMALSUB1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),2); +#else + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_NORMALSUB1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),3); +#else + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_FLIPPEDSUB1_2_16_O (Offset, (uint16*)bp); +#endif + } + else + { + //VFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8),(uint32)(GFX.S+(Offset<<1)+StartPixel*2),1); +#else + + bp = pCache+8+StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_FLIPPEDSUB1_2_16_O (Offset, (uint16*)bp); +#endif + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8)|solid_lineclip,(uint32)(GFX.S+(Offset<<1)+StartPixel*2),0); +#else + + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + SqTrans_NORMALSUB1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP +#ifdef asmPPU + asmDrawTileClipped16((uint32)pCache,(StartPixel<<16)|(Width<<8)|solid_lineclip,(uint32)(GFX.S+(Offset<<1)+(StartPixel+Width-1)*2),2); +#else + + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + SqTrans_NORMALSUB1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); +#endif + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8; + + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_NORMALSUB1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_NORMALSUB1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8; + Offset += 7; + + for (l = 8; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_FLIPPEDSUB1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + else + { + //VFLIP + + + bp = pCache+8; + for (l = 8; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_FLIPPEDSUB1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache; + bp = pCache+8; + + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + SqTrans_NORMALSUB1_2_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache; + bp = pCache+8; + Offset += 7; + for (l = 8; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + SqTrans_NORMALSUB1_2_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_NORMALSUB1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_NORMALSUB1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + + for (l = Width; l != 0; l--, bp += 8*2, Offset-=1) + SqTrans_FLIPPEDSUB1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + else + { + //VFLIP + + bp = pCache+8+StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, Offset+=1) + SqTrans_FLIPPEDSUB1_2_16_SPR_O (Offset, (uint16*)bp,index_spr); + + } + } + else + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += StartPixel; + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset+=1) + SqTrans_NORMALSUB1_2_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += (StartPixel+Width-1); + for (l = Width; l != 0; l--, bp += 8*2, headerbp++, Offset-=1) + SqTrans_NORMALSUB1_2_16_SPR_T (Offset, (uint16*)bp,solid_lineclip|*headerbp,index_spr); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + + bp = pCache+8; + + for (l = 4; l != 0; l--, bp += 8*2*2, Offset+=1) + SqTrans_NORMALSUB1_2_16_O (Offset, (uint16*)bp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + + bp = pCache+8; + Offset += 3; + for (l = 4; l != 0; l--, bp += 8*2*2, Offset-=1) + SqTrans_NORMALSUB1_2_16_O (Offset, (uint16*)bp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8; + Offset += 3; + + for (l = 4; l != 0; l--, bp += 8*2*2, Offset-=1) + SqTrans_FLIPPEDSUB1_2_16_O (Offset, (uint16*)bp); + + } + else + { + //VFLIP + + + bp = pCache+8; + for (l = 4; l != 0; l--, bp += 8*2*2, Offset+=1) + SqTrans_FLIPPEDSUB1_2_16_O (Offset, (uint16*)bp); + + } + } + else + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache; + bp = pCache+8; + + for (l = 4; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + SqTrans_NORMALSUB1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache; + bp = pCache+8; + Offset += 3; + for (l = 4; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + SqTrans_NORMALSUB1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<= 256) TileAddr += BG.NameSelect; + TileAddr &= 0xffff; + + register uint32 l; + if (BG.DirectColourMode) + { + //Did the palette changed ? + if (IPPU.DirectColourMapsNeedRebuild) S9xBuildDirectColourMaps (); + GFX.ScreenColors = DirectColourMaps [(Tile >> 10) & BG.PaletteMask]; + Col = 0; + } + else + { + GFX.ScreenColors = &IPPU.ScreenColors [(((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette]; + Col = (((Tile >> 10) & BG.PaletteMask) << BG.PaletteShift) + BG.StartPalette; + } + + uint32 TileNumber; + pCache = &BG.Buffer[(TileNumber = (TileAddr >> BG.TileShift)) *(128+8)]; + + + + if ((!BG.Buffered [TileNumber<<1])|(BG.Buffered [(TileNumber<<1)|1]!=Col)) + { + BG.Buffered[TileNumber<<1] = ConvertTile16New (pCache, TileAddr,GFX.ScreenColors); + BG.Buffered[(TileNumber<<1)|1] = Col; + } + + + if (BG.Buffered [TileNumber<<1] == 1) //BLANK_TILE + return; + //Tile is not blank, 'have to draw it + + + register uint8 *bp,*headerbp; + uint32 solid_lineclip; + switch (StartLine) + { + case 0:solid_lineclip=0x00;break; + case 1:solid_lineclip=0x80;break; + case 2:solid_lineclip=0xC0;break; + case 3:solid_lineclip=0xE0;break; + case 4:solid_lineclip=0xF0;break; + case 5:solid_lineclip=0xF8;break; + case 6:solid_lineclip=0xFC;break; + case 7:solid_lineclip=0xFE;break; + } + switch (StartLine+LineCount) //EndLine + { + case 1:solid_lineclip|=0x7F;break; + case 2:solid_lineclip|=0x3F;break; + case 3:solid_lineclip|=0x1F;break; + case 4: solid_lineclip|=0x0F;break; + case 5: solid_lineclip|=0x07;break; + case 6: solid_lineclip|=0x03;break; + case 7: solid_lineclip|=0x01;break; + + } + + if (solid_lineclip==0xFF) return; + + if ( (BG.Buffered [TileNumber<<1] == 2)&&(!solid_lineclip)) + { + Offset -= (StartLine * 320);; //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + bp = pCache+8 + StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset+=1) + SqTrans_NORMALSUB1_2_16_O (Offset, (uint16*)bp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset-=1) + SqTrans_NORMALSUB1_2_16_O (Offset, (uint16*)bp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset-=1) + SqTrans_FLIPPEDSUB1_2_16_O (Offset, (uint16*)bp); + + } + else + { + //VFLIP + + bp = pCache+8+StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, Offset+=1) + SqTrans_FLIPPEDSUB1_2_16_O (Offset, (uint16*)bp); + + } + } + else + { + + Offset -= (StartLine * 320); //align to tile multiple + if (!(Tile & (V_FLIP | H_FLIP))) + { + //NO FLIP + headerbp = pCache+StartPixel; + bp = pCache+8 + StartPixel*16; + Offset += (StartPixel>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + SqTrans_NORMALSUB1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (!(Tile & V_FLIP)) + { + //HFLIP + headerbp = pCache+StartPixel; + bp = pCache+8+StartPixel*16; + Offset += ((StartPixel+Width-1)>>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + SqTrans_NORMALSUB1_2_16_T (Offset, (uint16*)bp,solid_lineclip|*headerbp); + } + else + if (Tile & H_FLIP) + { + //VFLIP & HFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<>1); + + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset-=1) + SqTrans_FLIPPEDSUB1_2_16_T (Offset, (uint16*)bp,solid_lineclipI|*headerbp); + + } + else + { + //VFLIP + uint8 solid_lineclipI; + solid_lineclipI=0; + for (int i=0;i<8;i++) + { + solid_lineclipI<<=1; + if (solid_lineclip & (1<>1); + for (l = Width>>1; l != 0; l--, bp += 8*2*2, headerbp+=2, Offset+=1) + SqTrans_FLIPPEDSUB1_2_16_T (Offset, (uint16*)bp,solid_lineclipI|*headerbp); + + } + } +} +#endif diff --git a/src/snes4iphone_src/unzip.c b/src/snes4iphone_src/unzip.c new file mode 100755 index 0000000..3a70629 --- /dev/null +++ b/src/snes4iphone_src/unzip.c @@ -0,0 +1,1598 @@ +/* unzip.c -- IO for uncompress .zip files using zlib + Version 1.01e, February 12th, 2005 + + Copyright (C) 1998-2005 Gilles Vollant + + Read unzip.h for more info +*/ + +/* Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of +compatibility with older software. The following is from the original crypt.c. Code +woven in by Terry Thorsen 1/2003. +*/ +/* + Copyright (c) 1990-2000 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 2000-Apr-09 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, all these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html +*/ +/* + crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h] + + The encryption/decryption parts of this source code (as opposed to the + non-echoing password parts) were originally written in Europe. The + whole source package can be freely distributed, including from the USA. + (Prior to January 2000, re-export from the US was a violation of US law.) + */ + +/* + This encryption code is a direct transcription of the algorithm from + Roger Schlafly, described by Phil Katz in the file appnote.txt. This + file (appnote.txt) is distributed with the PKZIP program (even in the + version without encryption capabilities). + */ + + +#include +#include +#include +#include "zlib.h" +#include "unzip.h" + +#ifdef STDC +# include +# include +# include +#endif +#ifdef NO_ERRNO_H + extern int errno; +#else +# include +#endif + + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + + +#ifndef CASESENSITIVITYDEFAULT_NO +# if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) +# define CASESENSITIVITYDEFAULT_NO +# endif +#endif + + +#ifndef UNZ_BUFSIZE +#define UNZ_BUFSIZE (16384) +#endif + +#ifndef UNZ_MAXFILENAMEINZIP +#define UNZ_MAXFILENAMEINZIP (256) +#endif + +#ifndef ALLOC +# define ALLOC(size) (malloc(size)) +#endif +#ifndef TRYFREE +# define TRYFREE(p) {if (p) free(p);} +#endif + +#define SIZECENTRALDIRITEM (0x2e) +#define SIZEZIPLOCALHEADER (0x1e) + + + + +const char unz_copyright[] = + " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; + +/* unz_file_info_interntal contain internal info about a file in zipfile*/ +typedef struct unz_file_info_internal_s +{ + uLong offset_curfile;/* relative offset of local header 4 bytes */ +} unz_file_info_internal; + + +/* file_in_zip_read_info_s contain internal information about a file in zipfile, + when reading and decompress it */ +typedef struct +{ + char *read_buffer; /* internal buffer for compressed data */ + z_stream stream; /* zLib stream structure for inflate */ + + uLong pos_in_zipfile; /* position in byte on the zipfile, for fseek*/ + uLong stream_initialised; /* flag set if stream structure is initialised*/ + + uLong offset_local_extrafield;/* offset of the local extra field */ + uInt size_local_extrafield;/* size of the local extra field */ + uLong pos_local_extrafield; /* position in the local extra field in read*/ + + uLong crc32; /* crc32 of all data uncompressed */ + uLong crc32_wait; /* crc32 we must obtain after decompress all */ + uLong rest_read_compressed; /* number of byte to be decompressed */ + uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/ + zlib_filefunc_def z_filefunc; + voidpf filestream; /* io structore of the zipfile */ + uLong compression_method; /* compression method (0==store) */ + uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ + int raw; +} file_in_zip_read_info_s; + + +/* unz_s contain internal information about the zipfile +*/ +typedef struct +{ + zlib_filefunc_def z_filefunc; + voidpf filestream; /* io structore of the zipfile */ + unz_global_info gi; /* public global information */ + uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ + uLong num_file; /* number of the current file in the zipfile*/ + uLong pos_in_central_dir; /* pos of the current file in the central dir*/ + uLong current_file_ok; /* flag about the usability of the current file*/ + uLong central_pos; /* position of the beginning of the central dir*/ + + uLong size_central_dir; /* size of the central directory */ + uLong offset_central_dir; /* offset of start of central directory with + respect to the starting disk number */ + + unz_file_info cur_file_info; /* public info about the current file in zip*/ + unz_file_info_internal cur_file_info_internal; /* private info about it*/ + file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current + file if we are decompressing it */ + int encrypted; +# ifndef NOUNCRYPT + unsigned long keys[3]; /* keys defining the pseudo-random sequence */ + const unsigned long* pcrc_32_tab; +# endif +} unz_s; + + +#ifndef NOUNCRYPT +#include "crypt.h" +#endif + +/* =========================================================================== + Read a byte from a gz_stream; update next_in and avail_in. Return EOF + for end of file. + IN assertion: the stream s has been sucessfully opened for reading. +*/ + + +local int unzlocal_getByte OF(( + const zlib_filefunc_def* pzlib_filefunc_def, + voidpf filestream, + int *pi)); + +local int unzlocal_getByte(pzlib_filefunc_def,filestream,pi) + const zlib_filefunc_def* pzlib_filefunc_def; + voidpf filestream; + int *pi; +{ + unsigned char c; + int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1); + if (err==1) + { + *pi = (int)c; + return UNZ_OK; + } + else + { + if (ZERROR(*pzlib_filefunc_def,filestream)) + return UNZ_ERRNO; + else + return UNZ_EOF; + } +} + + +/* =========================================================================== + Reads a long in LSB order from the given gz_stream. Sets +*/ +local int unzlocal_getShort OF(( + const zlib_filefunc_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX)); + +local int unzlocal_getShort (pzlib_filefunc_def,filestream,pX) + const zlib_filefunc_def* pzlib_filefunc_def; + voidpf filestream; + uLong *pX; +{ + uLong x ; + int i; + int err; + + err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==UNZ_OK) + err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<8; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + +local int unzlocal_getLong OF(( + const zlib_filefunc_def* pzlib_filefunc_def, + voidpf filestream, + uLong *pX)); + +local int unzlocal_getLong (pzlib_filefunc_def,filestream,pX) + const zlib_filefunc_def* pzlib_filefunc_def; + voidpf filestream; + uLong *pX; +{ + uLong x ; + int i; + int err; + + err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==UNZ_OK) + err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<8; + + if (err==UNZ_OK) + err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<16; + + if (err==UNZ_OK) + err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<24; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + + +/* My own strcmpi / strcasecmp */ +local int strcmpcasenosensitive_internal (fileName1,fileName2) + const char* fileName1; + const char* fileName2; +{ + for (;;) + { + char c1=*(fileName1++); + char c2=*(fileName2++); + if ((c1>='a') && (c1<='z')) + c1 -= 0x20; + if ((c2>='a') && (c2<='z')) + c2 -= 0x20; + if (c1=='\0') + return ((c2=='\0') ? 0 : -1); + if (c2=='\0') + return 1; + if (c1c2) + return 1; + } +} + + +#ifdef CASESENSITIVITYDEFAULT_NO +#define CASESENSITIVITYDEFAULTVALUE 2 +#else +#define CASESENSITIVITYDEFAULTVALUE 1 +#endif + +#ifndef STRCMPCASENOSENTIVEFUNCTION +#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal +#endif + +/* + Compare two filename (fileName1,fileName2). + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + or strcasecmp) + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + (like 1 on Unix, 2 on Windows) + +*/ +extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity) + const char* fileName1; + const char* fileName2; + int iCaseSensitivity; +{ + if (iCaseSensitivity==0) + iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; + + if (iCaseSensitivity==1) + return strcmp(fileName1,fileName2); + + return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2); +} + +#ifndef BUFREADCOMMENT +#define BUFREADCOMMENT (0x400) +#endif + +/* + Locate the Central directory of a zipfile (at the end, just before + the global comment) +*/ +local uLong unzlocal_SearchCentralDir OF(( + const zlib_filefunc_def* pzlib_filefunc_def, + voidpf filestream)); + +local uLong unzlocal_SearchCentralDir(pzlib_filefunc_def,filestream) + const zlib_filefunc_def* pzlib_filefunc_def; + voidpf filestream; +{ + unsigned char* buf; + uLong uSizeFile; + uLong uBackRead; + uLong uMaxBack=0xffff; /* maximum size of global comment */ + uLong uPosFound=0; + + if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) + return 0; + + + uSizeFile = ZTELL(*pzlib_filefunc_def,filestream); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return 0; + + uBackRead = 4; + while (uBackReaduMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uSizeFile-uReadPos); + if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) + break; + + if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) + break; + + for (i=(int)uReadSize-3; (i--)>0;) + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && + ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) + { + uPosFound = uReadPos+i; + break; + } + + if (uPosFound!=0) + break; + } + TRYFREE(buf); + return uPosFound; +} + +/* + Open a Zip file. path contain the full pathname (by example, + on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer + "zlib/zlib114.zip". + If the zipfile cannot be opened (file doesn't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. +*/ +extern unzFile ZEXPORT unzOpen2 (path, pzlib_filefunc_def) + const char *path; + zlib_filefunc_def* pzlib_filefunc_def; +{ + unz_s us; + unz_s *s; + uLong central_pos,uL; + + uLong number_disk; /* number of the current dist, used for + spaning ZIP, unsupported, always 0*/ + uLong number_disk_with_CD; /* number the the disk with central dir, used + for spaning ZIP, unsupported, always 0*/ + uLong number_entry_CD; /* total number of entries in + the central dir + (same than number_entry on nospan) */ + + int err=UNZ_OK; + + if (unz_copyright[0]!=' ') + return NULL; + + if (pzlib_filefunc_def==NULL) + fill_fopen_filefunc(&us.z_filefunc); + else + us.z_filefunc = *pzlib_filefunc_def; + + us.filestream= (*(us.z_filefunc.zopen_file))(us.z_filefunc.opaque, + path, + ZLIB_FILEFUNC_MODE_READ | + ZLIB_FILEFUNC_MODE_EXISTING); + if (us.filestream==NULL) + return NULL; + + central_pos = unzlocal_SearchCentralDir(&us.z_filefunc,us.filestream); + if (central_pos==0) + err=UNZ_ERRNO; + + if (ZSEEK(us.z_filefunc, us.filestream, + central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) + err=UNZ_ERRNO; + + /* the signature, already checked */ + if (unzlocal_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of this disk */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of the disk with the start of the central directory */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central dir on this disk */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central dir */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + if ((number_entry_CD!=us.gi.number_entry) || + (number_disk_with_CD!=0) || + (number_disk!=0)) + err=UNZ_BADZIPFILE; + + /* size of the central directory */ + if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK) + err=UNZ_ERRNO; + + /* offset of start of central directory with respect to the + starting disk number */ + if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK) + err=UNZ_ERRNO; + + /* zipfile comment length */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK) + err=UNZ_ERRNO; + + if ((central_pospfile_in_zip_read!=NULL) + unzCloseCurrentFile(file); + + ZCLOSE(s->z_filefunc, s->filestream); + TRYFREE(s); + return UNZ_OK; +} + + +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ +extern int ZEXPORT unzGetGlobalInfo (file,pglobal_info) + unzFile file; + unz_global_info *pglobal_info; +{ + unz_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + *pglobal_info=s->gi; + return UNZ_OK; +} + + +/* + Translate date/time from Dos format to tm_unz (readable more easilty) +*/ +local void unzlocal_DosDateToTmuDate (ulDosDate, ptm) + uLong ulDosDate; + tm_unz* ptm; +{ + uLong uDate; + uDate = (uLong)(ulDosDate>>16); + ptm->tm_mday = (uInt)(uDate&0x1f) ; + ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ; + ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ; + + ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800); + ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ; + ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ; +} + +/* + Get Info about the current file in the zipfile, with internal only info +*/ +local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file, + unz_file_info *pfile_info, + unz_file_info_internal + *pfile_info_internal, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); + +local int unzlocal_GetCurrentFileInfoInternal (file, + pfile_info, + pfile_info_internal, + szFileName, fileNameBufferSize, + extraField, extraFieldBufferSize, + szComment, commentBufferSize) + unzFile file; + unz_file_info *pfile_info; + unz_file_info_internal *pfile_info_internal; + char *szFileName; + uLong fileNameBufferSize; + void *extraField; + uLong extraFieldBufferSize; + char *szComment; + uLong commentBufferSize; +{ + unz_s* s; + unz_file_info file_info; + unz_file_info_internal file_info_internal; + int err=UNZ_OK; + uLong uMagic; + long lSeek=0; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + if (ZSEEK(s->z_filefunc, s->filestream, + s->pos_in_central_dir+s->byte_before_the_zipfile, + ZLIB_FILEFUNC_SEEK_SET)!=0) + err=UNZ_ERRNO; + + + /* we check the magic */ + if (err==UNZ_OK) + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) + err=UNZ_ERRNO; + else if (uMagic!=0x02014b50) + err=UNZ_BADZIPFILE; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK) + err=UNZ_ERRNO; + + unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK) + err=UNZ_ERRNO; + + lSeek+=file_info.size_filename; + if ((err==UNZ_OK) && (szFileName!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_filename0) && (fileNameBufferSize>0)) + if (ZREAD(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead) + err=UNZ_ERRNO; + lSeek -= uSizeRead; + } + + + if ((err==UNZ_OK) && (extraField!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_file_extraz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) + if (ZREAD(s->z_filefunc, s->filestream,extraField,uSizeRead)!=uSizeRead) + err=UNZ_ERRNO; + lSeek += file_info.size_file_extra - uSizeRead; + } + else + lSeek+=file_info.size_file_extra; + + + if ((err==UNZ_OK) && (szComment!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_file_commentz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + if ((file_info.size_file_comment>0) && (commentBufferSize>0)) + if (ZREAD(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead) + err=UNZ_ERRNO; + lSeek+=file_info.size_file_comment - uSizeRead; + } + else + lSeek+=file_info.size_file_comment; + + if ((err==UNZ_OK) && (pfile_info!=NULL)) + *pfile_info=file_info; + + if ((err==UNZ_OK) && (pfile_info_internal!=NULL)) + *pfile_info_internal=file_info_internal; + + return err; +} + + + +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. +*/ +extern int ZEXPORT unzGetCurrentFileInfo (file, + pfile_info, + szFileName, fileNameBufferSize, + extraField, extraFieldBufferSize, + szComment, commentBufferSize) + unzFile file; + unz_file_info *pfile_info; + char *szFileName; + uLong fileNameBufferSize; + void *extraField; + uLong extraFieldBufferSize; + char *szComment; + uLong commentBufferSize; +{ + return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL, + szFileName,fileNameBufferSize, + extraField,extraFieldBufferSize, + szComment,commentBufferSize); +} + +/* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem +*/ +extern int ZEXPORT unzGoToFirstFile (file) + unzFile file; +{ + int err=UNZ_OK; + unz_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + s->pos_in_central_dir=s->offset_central_dir; + s->num_file=0; + err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + +/* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ +extern int ZEXPORT unzGoToNextFile (file) + unzFile file; +{ + unz_s* s; + int err; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */ + if (s->num_file+1==s->gi.number_entry) + return UNZ_END_OF_LIST_OF_FILE; + + s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + + s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; + s->num_file++; + err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + + +/* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzipStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found +*/ +extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity) + unzFile file; + const char *szFileName; + int iCaseSensitivity; +{ + unz_s* s; + int err; + + /* We remember the 'current' position in the file so that we can jump + * back there if we fail. + */ + unz_file_info cur_file_infoSaved; + unz_file_info_internal cur_file_info_internalSaved; + uLong num_fileSaved; + uLong pos_in_central_dirSaved; + + + if (file==NULL) + return UNZ_PARAMERROR; + + if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP) + return UNZ_PARAMERROR; + + s=(unz_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + + /* Save the current state */ + num_fileSaved = s->num_file; + pos_in_central_dirSaved = s->pos_in_central_dir; + cur_file_infoSaved = s->cur_file_info; + cur_file_info_internalSaved = s->cur_file_info_internal; + + err = unzGoToFirstFile(file); + + while (err == UNZ_OK) + { + char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; + err = unzGetCurrentFileInfo(file,NULL, + szCurrentFileName,sizeof(szCurrentFileName)-1, + NULL,0,NULL,0); + if (err == UNZ_OK) + { + if (unzStringFileNameCompare(szCurrentFileName, + szFileName,iCaseSensitivity)==0) + return UNZ_OK; + err = unzGoToNextFile(file); + } + } + + /* We failed, so restore the state of the 'current file' to where we + * were. + */ + s->num_file = num_fileSaved ; + s->pos_in_central_dir = pos_in_central_dirSaved ; + s->cur_file_info = cur_file_infoSaved; + s->cur_file_info_internal = cur_file_info_internalSaved; + return err; +} + + +/* +/////////////////////////////////////////// +// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net) +// I need random access +// +// Further optimization could be realized by adding an ability +// to cache the directory in memory. The goal being a single +// comprehensive file read to put the file I need in a memory. +*/ + +/* +typedef struct unz_file_pos_s +{ + uLong pos_in_zip_directory; // offset in file + uLong num_of_file; // # of file +} unz_file_pos; +*/ + +extern int ZEXPORT unzGetFilePos(file, file_pos) + unzFile file; + unz_file_pos* file_pos; +{ + unz_s* s; + + if (file==NULL || file_pos==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + + file_pos->pos_in_zip_directory = s->pos_in_central_dir; + file_pos->num_of_file = s->num_file; + + return UNZ_OK; +} + +extern int ZEXPORT unzGoToFilePos(file, file_pos) + unzFile file; + unz_file_pos* file_pos; +{ + unz_s* s; + int err; + + if (file==NULL || file_pos==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + + /* jump to the right spot */ + s->pos_in_central_dir = file_pos->pos_in_zip_directory; + s->num_file = file_pos->num_of_file; + + /* set the current file */ + err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + /* return results */ + s->current_file_ok = (err == UNZ_OK); + return err; +} + +/* +// Unzip Helper Functions - should be here? +/////////////////////////////////////////// +*/ + +/* + Read the local header of the current zipfile + Check the coherency of the local header and info in the end of central + directory about this file + store in *piSizeVar the size of extra info in local header + (filename and size of extra field data) +*/ +local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar, + poffset_local_extrafield, + psize_local_extrafield) + unz_s* s; + uInt* piSizeVar; + uLong *poffset_local_extrafield; + uInt *psize_local_extrafield; +{ + uLong uMagic,uData,uFlags; + uLong size_filename; + uLong size_extra_field; + int err=UNZ_OK; + + *piSizeVar = 0; + *poffset_local_extrafield = 0; + *psize_local_extrafield = 0; + + if (ZSEEK(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile + + s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + + + if (err==UNZ_OK) + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) + err=UNZ_ERRNO; + else if (uMagic!=0x04034b50) + err=UNZ_BADZIPFILE; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) + err=UNZ_ERRNO; +/* + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) + err=UNZ_BADZIPFILE; +*/ + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method)) + err=UNZ_BADZIPFILE; + + if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) && + (s->cur_file_info.compression_method!=Z_DEFLATED)) + err=UNZ_BADZIPFILE; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */ + err=UNZ_ERRNO; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */ + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && + ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */ + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && + ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */ + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && + ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK) + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) + err=UNZ_BADZIPFILE; + + *piSizeVar += (uInt)size_filename; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK) + err=UNZ_ERRNO; + *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + + SIZEZIPLOCALHEADER + size_filename; + *psize_local_extrafield = (uInt)size_extra_field; + + *piSizeVar += (uInt)size_extra_field; + + return err; +} + +/* + Open for reading data the current file in the zipfile. + If there is no error and the file is opened, the return value is UNZ_OK. +*/ +extern int ZEXPORT unzOpenCurrentFile3 (file, method, level, raw, password) + unzFile file; + int* method; + int* level; + int raw; + const char* password; +{ + int err=UNZ_OK; + uInt iSizeVar; + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + uLong offset_local_extrafield; /* offset of the local extra field */ + uInt size_local_extrafield; /* size of the local extra field */ +# ifndef NOUNCRYPT + char source[12]; +# else + if (password != NULL) + return UNZ_PARAMERROR; +# endif + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + if (!s->current_file_ok) + return UNZ_PARAMERROR; + + if (s->pfile_in_zip_read != NULL) + unzCloseCurrentFile(file); + + if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar, + &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK) + return UNZ_BADZIPFILE; + + pfile_in_zip_read_info = (file_in_zip_read_info_s*) + ALLOC(sizeof(file_in_zip_read_info_s)); + if (pfile_in_zip_read_info==NULL) + return UNZ_INTERNALERROR; + + pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE); + pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; + pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; + pfile_in_zip_read_info->pos_local_extrafield=0; + pfile_in_zip_read_info->raw=raw; + + if (pfile_in_zip_read_info->read_buffer==NULL) + { + TRYFREE(pfile_in_zip_read_info); + return UNZ_INTERNALERROR; + } + + pfile_in_zip_read_info->stream_initialised=0; + + if (method!=NULL) + *method = (int)s->cur_file_info.compression_method; + + if (level!=NULL) + { + *level = 6; + switch (s->cur_file_info.flag & 0x06) + { + case 6 : *level = 1; break; + case 4 : *level = 2; break; + case 2 : *level = 9; break; + } + } + + if ((s->cur_file_info.compression_method!=0) && + (s->cur_file_info.compression_method!=Z_DEFLATED)) + err=UNZ_BADZIPFILE; + + pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc; + pfile_in_zip_read_info->crc32=0; + pfile_in_zip_read_info->compression_method = + s->cur_file_info.compression_method; + pfile_in_zip_read_info->filestream=s->filestream; + pfile_in_zip_read_info->z_filefunc=s->z_filefunc; + pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile; + + pfile_in_zip_read_info->stream.total_out = 0; + + if ((s->cur_file_info.compression_method==Z_DEFLATED) && + (!raw)) + { + pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; + pfile_in_zip_read_info->stream.zfree = (free_func)0; + pfile_in_zip_read_info->stream.opaque = (voidpf)0; + pfile_in_zip_read_info->stream.next_in = (voidpf)0; + pfile_in_zip_read_info->stream.avail_in = 0; + + err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); + if (err == Z_OK) + pfile_in_zip_read_info->stream_initialised=1; + else + { + TRYFREE(pfile_in_zip_read_info); + return err; + } + /* windowBits is passed < 0 to tell that there is no zlib header. + * Note that in this case inflate *requires* an extra "dummy" byte + * after the compressed stream in order to complete decompression and + * return Z_STREAM_END. + * In unzip, i don't wait absolutely Z_STREAM_END because I known the + * size of both compressed and uncompressed data + */ + } + pfile_in_zip_read_info->rest_read_compressed = + s->cur_file_info.compressed_size ; + pfile_in_zip_read_info->rest_read_uncompressed = + s->cur_file_info.uncompressed_size ; + + + pfile_in_zip_read_info->pos_in_zipfile = + s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + + iSizeVar; + + pfile_in_zip_read_info->stream.avail_in = (uInt)0; + + s->pfile_in_zip_read = pfile_in_zip_read_info; + +# ifndef NOUNCRYPT + if (password != NULL) + { + int i; + s->pcrc_32_tab = get_crc_table(); + init_keys(password,s->keys,s->pcrc_32_tab); + if (ZSEEK(s->z_filefunc, s->filestream, + s->pfile_in_zip_read->pos_in_zipfile + + s->pfile_in_zip_read->byte_before_the_zipfile, + SEEK_SET)!=0) + return UNZ_INTERNALERROR; + if(ZREAD(s->z_filefunc, s->filestream,source, 12)<12) + return UNZ_INTERNALERROR; + + for (i = 0; i<12; i++) + zdecode(s->keys,s->pcrc_32_tab,source[i]); + + s->pfile_in_zip_read->pos_in_zipfile+=12; + s->encrypted=1; + } +# endif + + + return UNZ_OK; +} + +extern int ZEXPORT unzOpenCurrentFile (file) + unzFile file; +{ + return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL); +} + +extern int ZEXPORT unzOpenCurrentFilePassword (file, password) + unzFile file; + const char* password; +{ + return unzOpenCurrentFile3(file, NULL, NULL, 0, password); +} + +extern int ZEXPORT unzOpenCurrentFile2 (file,method,level,raw) + unzFile file; + int* method; + int* level; + int raw; +{ + return unzOpenCurrentFile3(file, method, level, raw, NULL); +} + +/* + Read bytes from the current file. + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) +*/ +extern int ZEXPORT unzReadCurrentFile (file, buf, len) + unzFile file; + voidp buf; + unsigned len; +{ + int err=UNZ_OK; + uInt iRead = 0; + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + + if ((pfile_in_zip_read_info->read_buffer == NULL)) + return UNZ_END_OF_LIST_OF_FILE; + if (len==0) + return 0; + + pfile_in_zip_read_info->stream.next_out = (Bytef*)buf; + + pfile_in_zip_read_info->stream.avail_out = (uInt)len; + + if ((len>pfile_in_zip_read_info->rest_read_uncompressed) && + (!(pfile_in_zip_read_info->raw))) + pfile_in_zip_read_info->stream.avail_out = + (uInt)pfile_in_zip_read_info->rest_read_uncompressed; + + if ((len>pfile_in_zip_read_info->rest_read_compressed+ + pfile_in_zip_read_info->stream.avail_in) && + (pfile_in_zip_read_info->raw)) + pfile_in_zip_read_info->stream.avail_out = + (uInt)pfile_in_zip_read_info->rest_read_compressed+ + pfile_in_zip_read_info->stream.avail_in; + + while (pfile_in_zip_read_info->stream.avail_out>0) + { + if ((pfile_in_zip_read_info->stream.avail_in==0) && + (pfile_in_zip_read_info->rest_read_compressed>0)) + { + uInt uReadThis = UNZ_BUFSIZE; + if (pfile_in_zip_read_info->rest_read_compressedrest_read_compressed; + if (uReadThis == 0) + return UNZ_EOF; + if (ZSEEK(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->pos_in_zipfile + + pfile_in_zip_read_info->byte_before_the_zipfile, + ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + if (ZREAD(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->read_buffer, + uReadThis)!=uReadThis) + return UNZ_ERRNO; + + +# ifndef NOUNCRYPT + if(s->encrypted) + { + uInt i; + for(i=0;iread_buffer[i] = + zdecode(s->keys,s->pcrc_32_tab, + pfile_in_zip_read_info->read_buffer[i]); + } +# endif + + + pfile_in_zip_read_info->pos_in_zipfile += uReadThis; + + pfile_in_zip_read_info->rest_read_compressed-=uReadThis; + + pfile_in_zip_read_info->stream.next_in = + (Bytef*)pfile_in_zip_read_info->read_buffer; + pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; + } + + if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw)) + { + uInt uDoCopy,i ; + + if ((pfile_in_zip_read_info->stream.avail_in == 0) && + (pfile_in_zip_read_info->rest_read_compressed == 0)) + return (iRead==0) ? UNZ_EOF : iRead; + + if (pfile_in_zip_read_info->stream.avail_out < + pfile_in_zip_read_info->stream.avail_in) + uDoCopy = pfile_in_zip_read_info->stream.avail_out ; + else + uDoCopy = pfile_in_zip_read_info->stream.avail_in ; + + for (i=0;istream.next_out+i) = + *(pfile_in_zip_read_info->stream.next_in+i); + + pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, + pfile_in_zip_read_info->stream.next_out, + uDoCopy); + pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; + pfile_in_zip_read_info->stream.avail_in -= uDoCopy; + pfile_in_zip_read_info->stream.avail_out -= uDoCopy; + pfile_in_zip_read_info->stream.next_out += uDoCopy; + pfile_in_zip_read_info->stream.next_in += uDoCopy; + pfile_in_zip_read_info->stream.total_out += uDoCopy; + iRead += uDoCopy; + } + else + { + uLong uTotalOutBefore,uTotalOutAfter; + const Bytef *bufBefore; + uLong uOutThis; + int flush=Z_SYNC_FLUSH; + + uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; + bufBefore = pfile_in_zip_read_info->stream.next_out; + + /* + if ((pfile_in_zip_read_info->rest_read_uncompressed == + pfile_in_zip_read_info->stream.avail_out) && + (pfile_in_zip_read_info->rest_read_compressed == 0)) + flush = Z_FINISH; + */ + err=inflate(&pfile_in_zip_read_info->stream,flush); + + if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL)) + err = Z_DATA_ERROR; + + uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; + uOutThis = uTotalOutAfter-uTotalOutBefore; + + pfile_in_zip_read_info->crc32 = + crc32(pfile_in_zip_read_info->crc32,bufBefore, + (uInt)(uOutThis)); + + pfile_in_zip_read_info->rest_read_uncompressed -= + uOutThis; + + iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); + + if (err==Z_STREAM_END) + return (iRead==0) ? UNZ_EOF : iRead; + if (err!=Z_OK) + break; + } + } + + if (err==Z_OK) + return iRead; + return err; +} + + +/* + Give the current position in uncompressed data +*/ +extern z_off_t ZEXPORT unztell (file) + unzFile file; +{ + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + return (z_off_t)pfile_in_zip_read_info->stream.total_out; +} + + +/* + return 1 if the end of file was reached, 0 elsewhere +*/ +extern int ZEXPORT unzeof (file) + unzFile file; +{ + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + if (pfile_in_zip_read_info->rest_read_uncompressed == 0) + return 1; + else + return 0; +} + + + +/* + Read extra field from the current file (opened by unzOpenCurrentFile) + This is the local-header version of the extra field (sometimes, there is + more info in the local-header version than in the central-header) + + if buf==NULL, it return the size of the local extra field that can be read + + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code +*/ +extern int ZEXPORT unzGetLocalExtrafield (file,buf,len) + unzFile file; + voidp buf; + unsigned len; +{ + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + uInt read_now; + uLong size_to_read; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + size_to_read = (pfile_in_zip_read_info->size_local_extrafield - + pfile_in_zip_read_info->pos_local_extrafield); + + if (buf==NULL) + return (int)size_to_read; + + if (len>size_to_read) + read_now = (uInt)size_to_read; + else + read_now = (uInt)len ; + + if (read_now==0) + return 0; + + if (ZSEEK(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->offset_local_extrafield + + pfile_in_zip_read_info->pos_local_extrafield, + ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + + if (ZREAD(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + buf,read_now)!=read_now) + return UNZ_ERRNO; + + return (int)read_now; +} + +/* + Close the file in zip opened with unzipOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ +extern int ZEXPORT unzCloseCurrentFile (file) + unzFile file; +{ + int err=UNZ_OK; + + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + + if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) && + (!pfile_in_zip_read_info->raw)) + { + if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) + err=UNZ_CRCERROR; + } + + + TRYFREE(pfile_in_zip_read_info->read_buffer); + pfile_in_zip_read_info->read_buffer = NULL; + if (pfile_in_zip_read_info->stream_initialised) + inflateEnd(&pfile_in_zip_read_info->stream); + + pfile_in_zip_read_info->stream_initialised = 0; + TRYFREE(pfile_in_zip_read_info); + + s->pfile_in_zip_read=NULL; + + return err; +} + + +/* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 +*/ +extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf) + unzFile file; + char *szComment; + uLong uSizeBuf; +{ + int err=UNZ_OK; + unz_s* s; + uLong uReadThis ; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + + uReadThis = uSizeBuf; + if (uReadThis>s->gi.size_comment) + uReadThis = s->gi.size_comment; + + if (ZSEEK(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + + if (uReadThis>0) + { + *szComment='\0'; + if (ZREAD(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis) + return UNZ_ERRNO; + } + + if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) + *(szComment+s->gi.size_comment)='\0'; + return (int)uReadThis; +} + +/* Additions by RX '2004 */ +extern uLong ZEXPORT unzGetOffset (file) + unzFile file; +{ + unz_s* s; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + if (!s->current_file_ok) + return 0; + if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff) + if (s->num_file==s->gi.number_entry) + return 0; + return s->pos_in_central_dir; +} + +extern int ZEXPORT unzSetOffset (file, pos) + unzFile file; + uLong pos; +{ + unz_s* s; + int err; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + + s->pos_in_central_dir = pos; + s->num_file = s->gi.number_entry; /* hack */ + err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} diff --git a/src/snes4iphone_src/unzip.h b/src/snes4iphone_src/unzip.h new file mode 100755 index 0000000..14d7a6f --- /dev/null +++ b/src/snes4iphone_src/unzip.h @@ -0,0 +1,356 @@ +/* unzip.h -- IO for uncompress .zip files using zlib + Version 1.01e, February 12th, 2005 + + Copyright (C) 1998-2005 Gilles Vollant + + This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g + WinZip, InfoZip tools and compatible. + + Multi volume ZipFile (span) are not supported. + Encryption compatible with pkzip 2.04g only supported + Old compressions used by old PKZip 1.x are not supported + + + I WAIT FEEDBACK at mail info@winimage.com + Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution + + Condition of use and distribution are the same than zlib : + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + +*/ + +/* for more info about .ZIP format, see + http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip + http://www.info-zip.org/pub/infozip/doc/ + PkWare has also a specification at : + ftp://ftp.pkware.com/probdesc.zip +*/ + +#ifndef _unz_H +#define _unz_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define NOUNCRYPT + +#ifndef _ZLIB_H +#include "zlib.h" +#endif + +#ifndef _ZLIBIOAPI_H +#include "ioapi.h" +#endif + +#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) +/* like the STRICT of WIN32, we define a pointer that cannot be converted + from (void*) without cast */ +typedef struct TagunzFile__ { int unused; } unzFile__; +typedef unzFile__ *unzFile; +#else +typedef voidp unzFile; +#endif + + +#define UNZ_OK (0) +#define UNZ_END_OF_LIST_OF_FILE (-100) +#define UNZ_ERRNO (Z_ERRNO) +#define UNZ_EOF (0) +#define UNZ_PARAMERROR (-102) +#define UNZ_BADZIPFILE (-103) +#define UNZ_INTERNALERROR (-104) +#define UNZ_CRCERROR (-105) + +/* tm_unz contain date/time info */ +typedef struct tm_unz_s +{ + uInt tm_sec; /* seconds after the minute - [0,59] */ + uInt tm_min; /* minutes after the hour - [0,59] */ + uInt tm_hour; /* hours since midnight - [0,23] */ + uInt tm_mday; /* day of the month - [1,31] */ + uInt tm_mon; /* months since January - [0,11] */ + uInt tm_year; /* years - [1980..2044] */ +} tm_unz; + +/* unz_global_info structure contain global data about the ZIPfile + These data comes from the end of central dir */ +typedef struct unz_global_info_s +{ + uLong number_entry; /* total number of entries in + the central dir on this disk */ + uLong size_comment; /* size of the global comment of the zipfile */ +} unz_global_info; + + +/* unz_file_info contain information about a file in the zipfile */ +typedef struct unz_file_info_s +{ + uLong version; /* version made by 2 bytes */ + uLong version_needed; /* version needed to extract 2 bytes */ + uLong flag; /* general purpose bit flag 2 bytes */ + uLong compression_method; /* compression method 2 bytes */ + uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ + uLong crc; /* crc-32 4 bytes */ + uLong compressed_size; /* compressed size 4 bytes */ + uLong uncompressed_size; /* uncompressed size 4 bytes */ + uLong size_filename; /* filename length 2 bytes */ + uLong size_file_extra; /* extra field length 2 bytes */ + uLong size_file_comment; /* file comment length 2 bytes */ + + uLong disk_num_start; /* disk number start 2 bytes */ + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ + + tm_unz tmu_date; +} unz_file_info; + +extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1, + const char* fileName2, + int iCaseSensitivity)); +/* + Compare two filename (fileName1,fileName2). + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + or strcasecmp) + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + (like 1 on Unix, 2 on Windows) +*/ + + +extern unzFile ZEXPORT unzOpen OF((const char *path)); +/* + Open a Zip file. path contain the full pathname (by example, + on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer + "zlib/zlib113.zip". + If the zipfile cannot be opened (file don't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. +*/ + +extern unzFile ZEXPORT unzOpen2 OF((const char *path, + zlib_filefunc_def* pzlib_filefunc_def)); +/* + Open a Zip file, like unzOpen, but provide a set of file low level API + for read/write the zip file (see ioapi.h) +*/ + +extern int ZEXPORT unzClose OF((unzFile file)); +/* + Close a ZipFile opened with unzipOpen. + If there is files inside the .Zip opened with unzOpenCurrentFile (see later), + these files MUST be closed with unzipCloseCurrentFile before call unzipClose. + return UNZ_OK if there is no problem. */ + +extern int ZEXPORT unzGetGlobalInfo OF((unzFile file, + unz_global_info *pglobal_info)); +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ + + +extern int ZEXPORT unzGetGlobalComment OF((unzFile file, + char *szComment, + uLong uSizeBuf)); +/* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 +*/ + + +/***************************************************************************/ +/* Unzip package allow you browse the directory of the zipfile */ + +extern int ZEXPORT unzGoToFirstFile OF((unzFile file)); +/* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem +*/ + +extern int ZEXPORT unzGoToNextFile OF((unzFile file)); +/* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ + +extern int ZEXPORT unzLocateFile OF((unzFile file, + const char *szFileName, + int iCaseSensitivity)); +/* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found +*/ + + +/* ****************************************** */ +/* Ryan supplied functions */ +/* unz_file_info contain information about a file in the zipfile */ +typedef struct unz_file_pos_s +{ + uLong pos_in_zip_directory; /* offset in zip file directory */ + uLong num_of_file; /* # of file */ +} unz_file_pos; + +extern int ZEXPORT unzGetFilePos( + unzFile file, + unz_file_pos* file_pos); + +extern int ZEXPORT unzGoToFilePos( + unzFile file, + unz_file_pos* file_pos); + +/* ****************************************** */ + +extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file, + unz_file_info *pfile_info, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); +/* + Get Info about the current file + if pfile_info!=NULL, the *pfile_info structure will contain somes info about + the current file + if szFileName!=NULL, the filemane string will be copied in szFileName + (fileNameBufferSize is the size of the buffer) + if extraField!=NULL, the extra field information will be copied in extraField + (extraFieldBufferSize is the size of the buffer). + This is the Central-header version of the extra field + if szComment!=NULL, the comment string of the file will be copied in szComment + (commentBufferSize is the size of the buffer) +*/ + +/***************************************************************************/ +/* for reading the content of the current zipfile, you can open it, read data + from it, and close it (you can close it before reading all the file) + */ + +extern int ZEXPORT unzOpenCurrentFile OF((unzFile file)); +/* + Open for reading data the current file in the zipfile. + If there is no error, the return value is UNZ_OK. +*/ + +extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file, + const char* password)); +/* + Open for reading data the current file in the zipfile. + password is a crypting password + If there is no error, the return value is UNZ_OK. +*/ + +extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file, + int* method, + int* level, + int raw)); +/* + Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) + if raw==1 + *method will receive method of compression, *level will receive level of + compression + note : you can set level parameter as NULL (if you did not want known level, + but you CANNOT set method parameter as NULL +*/ + +extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file, + int* method, + int* level, + int raw, + const char* password)); +/* + Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) + if raw==1 + *method will receive method of compression, *level will receive level of + compression + note : you can set level parameter as NULL (if you did not want known level, + but you CANNOT set method parameter as NULL +*/ + + +extern int ZEXPORT unzCloseCurrentFile OF((unzFile file)); +/* + Close the file in zip opened with unzOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ + +extern int ZEXPORT unzReadCurrentFile OF((unzFile file, + voidp buf, + unsigned len)); +/* + Read bytes from the current file (opened by unzOpenCurrentFile) + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) +*/ + +extern z_off_t ZEXPORT unztell OF((unzFile file)); +/* + Give the current position in uncompressed data +*/ + +extern int ZEXPORT unzeof OF((unzFile file)); +/* + return 1 if the end of file was reached, 0 elsewhere +*/ + +extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file, + voidp buf, + unsigned len)); +/* + Read extra field from the current file (opened by unzOpenCurrentFile) + This is the local-header version of the extra field (sometimes, there is + more info in the local-header version than in the central-header) + + if buf==NULL, it return the size of the local extra field + + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code +*/ + +/***************************************************************************/ + +/* Get the current file offset */ +extern uLong ZEXPORT unzGetOffset (unzFile file); + +/* Set the current file offset */ +extern int ZEXPORT unzSetOffset (unzFile file, uLong pos); + + + +#ifdef __cplusplus +} +#endif + +#endif /* _unz_H */ diff --git a/src/snes4iphone_src/usbjoy.c b/src/snes4iphone_src/usbjoy.c new file mode 100755 index 0000000..81d1be4 --- /dev/null +++ b/src/snes4iphone_src/usbjoy.c @@ -0,0 +1,297 @@ +/* Title: USB Joystick library + Version 0.2 + Written by Puck2099 (puck2099@gmail.com), (c) 2006. + + + If you use this library or a part of it, please, let it know. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include +#include /* For the definition of NULL */ +#include // For Device open +#include +#include +#include +#include // For Device read + +#include +#include /* For the definition of PATH_MAX */ +#include + +#include "usbjoy.h" + + +/* + Function: joy_open + + Opens a USB joystick and fills its information. + + Parameters: + + joynumber - Joystick's identifier (0 reserved for GP2X's builtin Joystick). + + Returns: + + Filled usbjoy structure. + +*/ +struct usbjoy * joy_open (int joynumber) { + int fd, i; + char path [128]; + struct usbjoy * joy = NULL; + + system ("insmod joydev"); // Loads joydev module + + if (joynumber == 0) { + } + else if (joynumber > 0) { + sprintf (path, "/dev/input/js%d", joynumber-1); + fd = open(path, O_RDONLY, 0); + if (fd > 0) { + joy = (struct usbjoy *) malloc(sizeof(struct usbjoy)); + + // Joystick's file descriptor + joy->fd = fd; + + // Set the joystick to non-blocking read mode + fcntl(joy->fd, F_SETFL, O_NONBLOCK); + + // Joystick's name + ioctl(joy->fd, JSIOCGNAME(128*sizeof(char)), joy->name); + + // Joystick's device + sprintf (joy->device, path); + + // Joystick's buttons + ioctl(joy->fd, JSIOCGBUTTONS, &joy->numbuttons); + + // Joystick's axes + ioctl(joy->fd, JSIOCGAXES, &joy->numaxes); + + // Clean buttons and axes + for (i=0; i<32; i++) joy->statebuttons[i] = 0; + for (i=0; i<4; i++) joy->stateaxes[i] = 0; + } + else { + printf ("ERROR: No Joystick found\n"); + } + } + return joy; +} + +/* + Function: joy_name + + Returns Joystick's name. + + Parameters: + + joy - Selected joystick. + + Returns: + + Joystick's name or NULL if struct is empty. +*/ +char * joy_name (struct usbjoy * joy) { + if (joy != NULL) return joy->name; + else return NULL; +} + + +/* + Function: joy_device + + Returns Joystick's device. + + Parameters: + + joy - Selected joystick. + + Returns: + + Joystick's device or NULL if struct is empty. +*/ +char * joy_device (struct usbjoy * joy) { + if (joy != NULL) return joy->device; + else return NULL; +} + + +/* + Function: joy_buttons + + Returns Joystick's buttons number. + + Parameters: + + joy - Selected joystick. + + Returns: + + Joystick's buttons or 0 if struct is empty. +*/ +int joy_buttons (struct usbjoy * joy) { + if (joy != NULL) return joy->numbuttons; + else return 0; +} + + +/* + Function: joy_axes + + Returns Joystick's axes number. + + Parameters: + + joy - Selected joystick. + + Returns: + + Joystick's axes or 0 if struct is empty. +*/ +int joy_axes (struct usbjoy * joy) { + if (joy != NULL) return joy->numaxes; + else return 0; +} + + +/* + Function: joy_update + + Updates Joystick's internal information ( and fields). + + Parameters: + + joy - Selected joystick. + + Returns: + + 0 - No events registered (no need to update). + 1 - Events registered (a button or axe has been pushed). + -1 - Error: struct is empty. +*/ +int joy_update (struct usbjoy * joy) { + struct js_event events[0xff]; + int i, len; + int event = 0; + if (joy != NULL) { + if ((len=read(joy->fd, events, (sizeof events))) >0) { + len /= sizeof(events[0]); + for ( i=0; istateaxes[JOYLEFT] = joy->stateaxes[JOYRIGHT] = 0; + if (events[i].value < 0) joy->stateaxes[JOYLEFT] = 1; + else if (events[i].value > 0) joy->stateaxes[JOYRIGHT] = 1; + } + else if (events[i].number == 1) { + joy->stateaxes[JOYUP] = joy->stateaxes[JOYDOWN] = 0; + if (events[i].value < 0) joy->stateaxes[JOYUP] = 1; + else if (events[i].value > 0) joy->stateaxes[JOYDOWN] = 1; + } + event = 1; + break; + case JS_EVENT_BUTTON: + joy->statebuttons[events[i].number] = events[i].value; + event = 1; + break; + default: + break; + } + } + } + } + else { + event = -1; + } + return event; +} + + +/* + Function: joy_getbutton + + Returns Joystick's button information. + + Parameters: + + button - Button which value you want to know (from 0 to 31). + joy - Selected joystick. + + Returns: + + 0 - Button NOT pushed. + 1 - Button pushed. + -1 - Error: struct is empty. +*/ +int joy_getbutton (int button, struct usbjoy * joy) { + if (joy != NULL) { + if (button < joy_buttons(joy)) return joy->statebuttons[button]; + else return 0; + } + else return -1; +} + + +/* + Function: joy_getaxe + + Returns Joystick's axes information. + + Parameters: + + axe - Axe which value you want to know (see ). + joy - Selected joystick. + + Returns: + + 0 - Direction NOT pushed. + 1 - Direction pushed. + -1 - Error: struct is empty. +*/ +int joy_getaxe (int axe, struct usbjoy * joy) { + if (joy != NULL) { + if (axe < 4) return joy->stateaxes[axe]; + else return 0; + } + else return -1; +} + + +/* + Function: joy_close + + Closes selected joystick's file descriptor and detroys it's fields. + + Parameters: + + joy - Selected joystick. + + Returns: + + 0 - Joystick successfully closed. + -1 - Error: struct is empty. +*/ +int joy_close (struct usbjoy * joy) { + if (joy != NULL) { + close (joy->fd); + free (joy); + return 0; + } + else return -1; +} diff --git a/src/snes4iphone_src/usbjoy.h b/src/snes4iphone_src/usbjoy.h new file mode 100755 index 0000000..c324744 --- /dev/null +++ b/src/snes4iphone_src/usbjoy.h @@ -0,0 +1,221 @@ +/* Title: USB Joystick library + Version 0.2 + Written by Puck2099 (puck2099@gmail.com), (c) 2006. + + + If you use this library or a part of it, please, let it know. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef USBJOY_H +#define USBJOY_H + +/* + Enumeration: Axes values + This enumeration contains shortcuts to the values used on axes. + + Constants: + JOYUP - Joystick Up + JOYDOWN - Joystick Down + JOYLEFT - Joystick Left + JOYRIGHT - Joystick Right + + See also: + +*/ +#define JOYUP (0) +#define JOYDOWN (1) +#define JOYLEFT (2) +#define JOYRIGHT (3) + + +/* + Struct: usbjoy + + Contains all Joystick needed information. + + Fields: + fd - File descriptor used. + name - Joystick's name. + device - /dev/input/jsX device. + numbuttons - Joystick's buttons. + numaxes - Joystick's axes. + numhats - Joystick's hats. + statebuttons - Current state of each button. + stateaxes - Current state of each direction. +*/ +struct usbjoy { + int fd; + char name [128]; + char device [128]; + int numbuttons; + int numaxes; + int numhats; + int statebuttons[32]; + int stateaxes[4]; +}; + + +/* + Function: joy_open + + Opens a USB joystick and fills its information. + + Parameters: + + joynumber - Joystick's identifier (0 reserved for GP2X's builtin Joystick). + + Returns: + + Filled usbjoy structure. +*/ +struct usbjoy * joy_open (int joynumber); + + +/* + Function: joy_name + + Returns Joystick's name. + + Parameters: + + joy - Selected joystick. + + Returns: + + Joystick's name or NULL if struct is empty. +*/ +char * joy_name (struct usbjoy * joy); + + +/* + Function: joy_device + + Returns Joystick's device. + + Parameters: + + joy - Selected joystick. + + Returns: + + Joystick's device or NULL if struct is empty. +*/ +char * joy_device (struct usbjoy * joy); + +/* + Function: joy_buttons + + Returns Joystick's buttons number. + + Parameters: + + joy - Selected joystick. + + Returns: + + Joystick's buttons or 0 if struct is empty. +*/ +int joy_buttons (struct usbjoy * joy); + +/* + Function: joy_axes + + Returns Joystick's axes number. + + Parameters: + + joy - Selected joystick. + + Returns: + + Joystick's axes or 0 if struct is empty. +*/ +int joy_axes (struct usbjoy * joy); + + +/* + Function: joy_update + + Updates Joystick's internal information ( and fields). + + Parameters: + + joy - Selected joystick. + + Returns: + + 0 - No events registered (no need to update). + 1 - Events registered (a button or axe has been pushed). + -1 - Error: struct is empty. +*/ +int joy_update (struct usbjoy * joy); + + +/* + Function: joy_getbutton + + Returns Joystick's button information. + + Parameters: + + button - Button which value you want to know (from 0 to 31). + joy - Selected joystick. + + Returns: + + 0 - Button NOT pushed. + 1 - Button pushed. + -1 - Error: struct is empty. +*/ +int joy_getbutton (int button, struct usbjoy * joy); + + +/* + Function: joy_getaxe + + Returns Joystick's axes information. + + Parameters: + + axe - Axe which value you want to know (see ). + joy - Selected joystick. + + Returns: + + 0 - Direction NOT pushed. + 1 - Direction pushed. + -1 - Error: struct is empty. +*/ +int joy_getaxe (int axe, struct usbjoy * joy); + +/* + Function: joy_close + + Closes selected joystick's file descriptor and detroys it's fields. + + Parameters: + + joy - Selected joystick. + + Returns: + + 0 - Joystick successfully closed. + -1 - Error: struct is empty. +*/ +int joy_close (struct usbjoy * joy); + +#endif // USBJOY_H