diff --git a/Availability2.h b/Availability2.h new file mode 100644 index 0000000..3b13f31 --- /dev/null +++ b/Availability2.h @@ -0,0 +1,363 @@ +#ifndef AVAILABILITY2_H +#define AVAILABILITY2_H +#include + +#ifndef __IPHONE_2_1 + #define __IPHONE_2_1 20100 + #define __AVAILABILITY_INTERNAL__IPHONE_2_1 __AVAILABILITY_INTERNAL_UNAVAILABLE + #define __AVAILABILITY_INTERNAL__IPHONE_2_1_DEP__IPHONE_NA __AVAILABILITY_INTERNAL__IPHONE_2_1 + #if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE__IPHONE_2_1 + #define __AVAILABILITY_INTERNAL__IPHONE_2_0_DEP__IPHONE_2_1 + #define __AVAILABILITY_INTERNAL__IPHONE_2_1_DEP__IPHONE_2_1 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_2_2_DEP__IPHONE_2_1 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_0_DEP__IPHONE_2_1 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_1_DEP__IPHONE_2_1 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_2_DEP__IPHONE_2_1 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_3_DEP__IPHONE_2_1 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_4_0_DEP__IPHONE_2_1 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #else + #define __AVAILABILITY_INTERNAL__IPHONE_2_0_DEP__IPHONE_2_1 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_2_1_DEP__IPHONE_2_1 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_2_2_DEP__IPHONE_2_1 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_3_0_DEP__IPHONE_2_1 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_3_1_DEP__IPHONE_2_1 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_3_2_DEP__IPHONE_2_1 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_3_3_DEP__IPHONE_2_1 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_4_0_DEP__IPHONE_2_1 __AVAILABILITY_INTERNAL_DEPRECATED + #endif +#endif +#ifndef __IPHONE_2_2 + #define __IPHONE_2_2 20200 + #define __AVAILABILITY_INTERNAL__IPHONE_2_2 __AVAILABILITY_INTERNAL_UNAVAILABLE + #define __AVAILABILITY_INTERNAL__IPHONE_2_2_DEP__IPHONE_NA __AVAILABILITY_INTERNAL__IPHONE_2_2 + #if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE__IPHONE_2_1 + #define __AVAILABILITY_INTERNAL__IPHONE_2_0_DEP__IPHONE_2_2 + #define __AVAILABILITY_INTERNAL__IPHONE_2_1_DEP__IPHONE_2_2 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_2_2_DEP__IPHONE_2_2 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_0_DEP__IPHONE_2_2 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_1_DEP__IPHONE_2_2 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_2_DEP__IPHONE_2_2 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_3_DEP__IPHONE_2_2 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_4_0_DEP__IPHONE_2_2 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #elif __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE__IPHONE_2_2 + #define __AVAILABILITY_INTERNAL__IPHONE_2_0_DEP__IPHONE_2_2 + #define __AVAILABILITY_INTERNAL__IPHONE_2_1_DEP__IPHONE_2_2 + #define __AVAILABILITY_INTERNAL__IPHONE_2_2_DEP__IPHONE_2_2 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_0_DEP__IPHONE_2_2 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_1_DEP__IPHONE_2_2 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_2_DEP__IPHONE_2_2 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_3_DEP__IPHONE_2_2 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_4_0_DEP__IPHONE_2_2 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #else + #define __AVAILABILITY_INTERNAL__IPHONE_2_0_DEP__IPHONE_2_2 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_2_1_DEP__IPHONE_2_2 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_2_2_DEP__IPHONE_2_2 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_3_0_DEP__IPHONE_2_2 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_3_1_DEP__IPHONE_2_2 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_3_2_DEP__IPHONE_2_2 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_3_3_DEP__IPHONE_2_2 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_4_0_DEP__IPHONE_2_2 __AVAILABILITY_INTERNAL_DEPRECATED + #endif +#endif +#ifndef __IPHONE_3_0 + #define __IPHONE_3_0 30000 + #define __AVAILABILITY_INTERNAL__IPHONE_3_0 __AVAILABILITY_INTERNAL_UNAVAILABLE + #define __AVAILABILITY_INTERNAL__IPHONE_3_0_DEP__IPHONE_NA __AVAILABILITY_INTERNAL__IPHONE_3_0 + #if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE__IPHONE_2_1 + #define __AVAILABILITY_INTERNAL__IPHONE_2_0_DEP__IPHONE_3_0 + #define __AVAILABILITY_INTERNAL__IPHONE_2_1_DEP__IPHONE_3_0 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_2_2_DEP__IPHONE_3_0 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_0_DEP__IPHONE_3_0 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_1_DEP__IPHONE_3_0 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_2_DEP__IPHONE_3_0 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_3_DEP__IPHONE_3_0 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_4_0_DEP__IPHONE_3_0 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #elif __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE__IPHONE_2_2 + #define __AVAILABILITY_INTERNAL__IPHONE_2_0_DEP__IPHONE_3_0 + #define __AVAILABILITY_INTERNAL__IPHONE_2_1_DEP__IPHONE_3_0 + #define __AVAILABILITY_INTERNAL__IPHONE_2_2_DEP__IPHONE_3_0 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_0_DEP__IPHONE_3_0 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_1_DEP__IPHONE_3_0 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_2_DEP__IPHONE_3_0 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_3_DEP__IPHONE_3_0 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_4_0_DEP__IPHONE_3_0 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #elif __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE__IPHONE_3_0 + #define __AVAILABILITY_INTERNAL__IPHONE_2_0_DEP__IPHONE_3_0 + #define __AVAILABILITY_INTERNAL__IPHONE_2_1_DEP__IPHONE_3_0 + #define __AVAILABILITY_INTERNAL__IPHONE_2_2_DEP__IPHONE_3_0 + #define __AVAILABILITY_INTERNAL__IPHONE_3_0_DEP__IPHONE_3_0 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_1_DEP__IPHONE_3_0 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_2_DEP__IPHONE_3_0 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_3_DEP__IPHONE_3_0 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_4_0_DEP__IPHONE_3_0 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #else + #define __AVAILABILITY_INTERNAL__IPHONE_2_0_DEP__IPHONE_3_0 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_2_1_DEP__IPHONE_3_0 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_2_2_DEP__IPHONE_3_0 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_3_0_DEP__IPHONE_3_0 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_3_1_DEP__IPHONE_3_0 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_3_2_DEP__IPHONE_3_0 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_3_3_DEP__IPHONE_3_0 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_4_0_DEP__IPHONE_3_0 __AVAILABILITY_INTERNAL_DEPRECATED + #endif +#endif +#ifndef __IPHONE_3_1 + #define __IPHONE_3_1 30100 + #define __AVAILABILITY_INTERNAL__IPHONE_3_1 __AVAILABILITY_INTERNAL_UNAVAILABLE + #define __AVAILABILITY_INTERNAL__IPHONE_3_1_DEP__IPHONE_NA __AVAILABILITY_INTERNAL__IPHONE_3_1 + #if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE__IPHONE_2_1 + #define __AVAILABILITY_INTERNAL__IPHONE_2_0_DEP__IPHONE_3_1 + #define __AVAILABILITY_INTERNAL__IPHONE_2_1_DEP__IPHONE_3_1 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_2_2_DEP__IPHONE_3_1 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_0_DEP__IPHONE_3_1 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_1_DEP__IPHONE_3_1 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_2_DEP__IPHONE_3_1 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_3_DEP__IPHONE_3_1 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_4_0_DEP__IPHONE_3_1 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #elif __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE__IPHONE_2_2 + #define __AVAILABILITY_INTERNAL__IPHONE_2_0_DEP__IPHONE_3_1 + #define __AVAILABILITY_INTERNAL__IPHONE_2_1_DEP__IPHONE_3_1 + #define __AVAILABILITY_INTERNAL__IPHONE_2_2_DEP__IPHONE_3_1 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_0_DEP__IPHONE_3_1 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_1_DEP__IPHONE_3_1 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_2_DEP__IPHONE_3_1 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_3_DEP__IPHONE_3_1 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_4_0_DEP__IPHONE_3_1 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #elif __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE__IPHONE_3_0 + #define __AVAILABILITY_INTERNAL__IPHONE_2_0_DEP__IPHONE_3_1 + #define __AVAILABILITY_INTERNAL__IPHONE_2_1_DEP__IPHONE_3_1 + #define __AVAILABILITY_INTERNAL__IPHONE_2_2_DEP__IPHONE_3_1 + #define __AVAILABILITY_INTERNAL__IPHONE_3_0_DEP__IPHONE_3_1 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_1_DEP__IPHONE_3_1 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_2_DEP__IPHONE_3_1 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_3_DEP__IPHONE_3_1 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_4_0_DEP__IPHONE_3_1 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #elif __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE__IPHONE_3_1 + #define __AVAILABILITY_INTERNAL__IPHONE_2_0_DEP__IPHONE_3_1 + #define __AVAILABILITY_INTERNAL__IPHONE_2_1_DEP__IPHONE_3_1 + #define __AVAILABILITY_INTERNAL__IPHONE_2_2_DEP__IPHONE_3_1 + #define __AVAILABILITY_INTERNAL__IPHONE_3_0_DEP__IPHONE_3_1 + #define __AVAILABILITY_INTERNAL__IPHONE_3_1_DEP__IPHONE_3_1 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_2_DEP__IPHONE_3_1 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_3_DEP__IPHONE_3_1 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_4_0_DEP__IPHONE_3_1 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #else + #define __AVAILABILITY_INTERNAL__IPHONE_2_0_DEP__IPHONE_3_1 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_2_1_DEP__IPHONE_3_1 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_2_2_DEP__IPHONE_3_1 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_3_0_DEP__IPHONE_3_1 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_3_1_DEP__IPHONE_3_1 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_3_2_DEP__IPHONE_3_1 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_3_3_DEP__IPHONE_3_1 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_4_0_DEP__IPHONE_3_1 __AVAILABILITY_INTERNAL_DEPRECATED + #endif +#endif +#ifndef __IPHONE_3_2 + #define __IPHONE_3_2 30200 + #define __AVAILABILITY_INTERNAL__IPHONE_3_2 __AVAILABILITY_INTERNAL_UNAVAILABLE + #define __AVAILABILITY_INTERNAL__IPHONE_3_2_DEP__IPHONE_NA __AVAILABILITY_INTERNAL__IPHONE_3_2 + #if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE__IPHONE_2_1 + #define __AVAILABILITY_INTERNAL__IPHONE_2_0_DEP__IPHONE_3_2 + #define __AVAILABILITY_INTERNAL__IPHONE_2_1_DEP__IPHONE_3_2 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_2_2_DEP__IPHONE_3_2 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_0_DEP__IPHONE_3_2 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_1_DEP__IPHONE_3_2 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_2_DEP__IPHONE_3_2 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_3_DEP__IPHONE_3_2 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_4_0_DEP__IPHONE_3_2 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #elif __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE__IPHONE_2_2 + #define __AVAILABILITY_INTERNAL__IPHONE_2_0_DEP__IPHONE_3_2 + #define __AVAILABILITY_INTERNAL__IPHONE_2_1_DEP__IPHONE_3_2 + #define __AVAILABILITY_INTERNAL__IPHONE_2_2_DEP__IPHONE_3_2 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_0_DEP__IPHONE_3_2 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_1_DEP__IPHONE_3_2 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_2_DEP__IPHONE_3_2 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_3_DEP__IPHONE_3_2 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_4_0_DEP__IPHONE_3_2 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #elif __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE__IPHONE_3_0 + #define __AVAILABILITY_INTERNAL__IPHONE_2_0_DEP__IPHONE_3_2 + #define __AVAILABILITY_INTERNAL__IPHONE_2_1_DEP__IPHONE_3_2 + #define __AVAILABILITY_INTERNAL__IPHONE_2_2_DEP__IPHONE_3_2 + #define __AVAILABILITY_INTERNAL__IPHONE_3_0_DEP__IPHONE_3_2 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_1_DEP__IPHONE_3_2 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_2_DEP__IPHONE_3_2 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_3_DEP__IPHONE_3_2 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_4_0_DEP__IPHONE_3_2 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #elif __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE__IPHONE_3_1 + #define __AVAILABILITY_INTERNAL__IPHONE_2_0_DEP__IPHONE_3_2 + #define __AVAILABILITY_INTERNAL__IPHONE_2_1_DEP__IPHONE_3_2 + #define __AVAILABILITY_INTERNAL__IPHONE_2_2_DEP__IPHONE_3_2 + #define __AVAILABILITY_INTERNAL__IPHONE_3_0_DEP__IPHONE_3_2 + #define __AVAILABILITY_INTERNAL__IPHONE_3_1_DEP__IPHONE_3_2 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_2_DEP__IPHONE_3_2 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_3_DEP__IPHONE_3_2 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_4_0_DEP__IPHONE_3_2 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #elif __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE__IPHONE_3_2 + #define __AVAILABILITY_INTERNAL__IPHONE_2_0_DEP__IPHONE_3_2 + #define __AVAILABILITY_INTERNAL__IPHONE_2_1_DEP__IPHONE_3_2 + #define __AVAILABILITY_INTERNAL__IPHONE_2_2_DEP__IPHONE_3_2 + #define __AVAILABILITY_INTERNAL__IPHONE_3_0_DEP__IPHONE_3_2 + #define __AVAILABILITY_INTERNAL__IPHONE_3_1_DEP__IPHONE_3_2 + #define __AVAILABILITY_INTERNAL__IPHONE_3_2_DEP__IPHONE_3_2 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_3_DEP__IPHONE_3_2 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_4_0_DEP__IPHONE_3_2 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #else + #define __AVAILABILITY_INTERNAL__IPHONE_2_0_DEP__IPHONE_3_2 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_2_1_DEP__IPHONE_3_2 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_2_2_DEP__IPHONE_3_2 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_3_0_DEP__IPHONE_3_2 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_3_1_DEP__IPHONE_3_2 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_3_2_DEP__IPHONE_3_2 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_3_3_DEP__IPHONE_3_2 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_4_0_DEP__IPHONE_3_2 __AVAILABILITY_INTERNAL_DEPRECATED + #endif +#endif +#ifndef __IPHONE_3_3 + #define __IPHONE_3_3 30300 + #define __AVAILABILITY_INTERNAL__IPHONE_3_3 __AVAILABILITY_INTERNAL_UNAVAILABLE + #define __AVAILABILITY_INTERNAL__IPHONE_3_3_DEP__IPHONE_NA __AVAILABILITY_INTERNAL__IPHONE_3_3 + #if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE__IPHONE_2_1 + #define __AVAILABILITY_INTERNAL__IPHONE_2_0_DEP__IPHONE_3_3 + #define __AVAILABILITY_INTERNAL__IPHONE_2_1_DEP__IPHONE_3_3 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_2_2_DEP__IPHONE_3_3 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_0_DEP__IPHONE_3_3 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_1_DEP__IPHONE_3_3 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_2_DEP__IPHONE_3_3 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_3_DEP__IPHONE_3_3 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_4_0_DEP__IPHONE_3_3 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #elif __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE__IPHONE_2_2 + #define __AVAILABILITY_INTERNAL__IPHONE_2_0_DEP__IPHONE_3_3 + #define __AVAILABILITY_INTERNAL__IPHONE_2_1_DEP__IPHONE_3_3 + #define __AVAILABILITY_INTERNAL__IPHONE_2_2_DEP__IPHONE_3_3 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_0_DEP__IPHONE_3_3 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_1_DEP__IPHONE_3_3 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_2_DEP__IPHONE_3_3 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_3_DEP__IPHONE_3_3 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_4_0_DEP__IPHONE_3_3 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #elif __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE__IPHONE_3_0 + #define __AVAILABILITY_INTERNAL__IPHONE_2_0_DEP__IPHONE_3_3 + #define __AVAILABILITY_INTERNAL__IPHONE_2_1_DEP__IPHONE_3_3 + #define __AVAILABILITY_INTERNAL__IPHONE_2_2_DEP__IPHONE_3_3 + #define __AVAILABILITY_INTERNAL__IPHONE_3_0_DEP__IPHONE_3_3 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_1_DEP__IPHONE_3_3 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_2_DEP__IPHONE_3_3 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_3_DEP__IPHONE_3_3 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_4_0_DEP__IPHONE_3_3 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #elif __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE__IPHONE_3_1 + #define __AVAILABILITY_INTERNAL__IPHONE_2_0_DEP__IPHONE_3_3 + #define __AVAILABILITY_INTERNAL__IPHONE_2_1_DEP__IPHONE_3_3 + #define __AVAILABILITY_INTERNAL__IPHONE_2_2_DEP__IPHONE_3_3 + #define __AVAILABILITY_INTERNAL__IPHONE_3_0_DEP__IPHONE_3_3 + #define __AVAILABILITY_INTERNAL__IPHONE_3_1_DEP__IPHONE_3_3 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_2_DEP__IPHONE_3_3 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_3_DEP__IPHONE_3_3 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_4_0_DEP__IPHONE_3_3 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #elif __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE__IPHONE_3_2 + #define __AVAILABILITY_INTERNAL__IPHONE_2_0_DEP__IPHONE_3_3 + #define __AVAILABILITY_INTERNAL__IPHONE_2_1_DEP__IPHONE_3_3 + #define __AVAILABILITY_INTERNAL__IPHONE_2_2_DEP__IPHONE_3_3 + #define __AVAILABILITY_INTERNAL__IPHONE_3_0_DEP__IPHONE_3_3 + #define __AVAILABILITY_INTERNAL__IPHONE_3_1_DEP__IPHONE_3_3 + #define __AVAILABILITY_INTERNAL__IPHONE_3_2_DEP__IPHONE_3_3 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_3_DEP__IPHONE_3_3 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_4_0_DEP__IPHONE_3_3 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #elif __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE__IPHONE_3_3 + #define __AVAILABILITY_INTERNAL__IPHONE_2_0_DEP__IPHONE_3_3 + #define __AVAILABILITY_INTERNAL__IPHONE_2_1_DEP__IPHONE_3_3 + #define __AVAILABILITY_INTERNAL__IPHONE_2_2_DEP__IPHONE_3_3 + #define __AVAILABILITY_INTERNAL__IPHONE_3_0_DEP__IPHONE_3_3 + #define __AVAILABILITY_INTERNAL__IPHONE_3_1_DEP__IPHONE_3_3 + #define __AVAILABILITY_INTERNAL__IPHONE_3_2_DEP__IPHONE_3_3 + #define __AVAILABILITY_INTERNAL__IPHONE_3_3_DEP__IPHONE_3_3 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_4_0_DEP__IPHONE_3_3 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #else + #define __AVAILABILITY_INTERNAL__IPHONE_2_0_DEP__IPHONE_3_3 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_2_1_DEP__IPHONE_3_3 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_2_2_DEP__IPHONE_3_3 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_3_0_DEP__IPHONE_3_3 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_3_1_DEP__IPHONE_3_3 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_3_2_DEP__IPHONE_3_3 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_3_3_DEP__IPHONE_3_3 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_4_0_DEP__IPHONE_3_3 __AVAILABILITY_INTERNAL_DEPRECATED + #endif +#endif +#ifndef __IPHONE_4_0 + #define __IPHONE_4_0 40000 + #define __AVAILABILITY_INTERNAL__IPHONE_4_0 __AVAILABILITY_INTERNAL_UNAVAILABLE + #define __AVAILABILITY_INTERNAL__IPHONE_4_0_DEP__IPHONE_NA __AVAILABILITY_INTERNAL__IPHONE_4_0 + #if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE__IPHONE_2_1 + #define __AVAILABILITY_INTERNAL__IPHONE_2_0_DEP__IPHONE_4_0 + #define __AVAILABILITY_INTERNAL__IPHONE_2_1_DEP__IPHONE_4_0 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_2_2_DEP__IPHONE_4_0 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_0_DEP__IPHONE_4_0 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_1_DEP__IPHONE_4_0 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_2_DEP__IPHONE_4_0 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_3_DEP__IPHONE_4_0 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_4_0_DEP__IPHONE_4_0 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #elif __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE__IPHONE_2_2 + #define __AVAILABILITY_INTERNAL__IPHONE_2_0_DEP__IPHONE_4_0 + #define __AVAILABILITY_INTERNAL__IPHONE_2_1_DEP__IPHONE_4_0 + #define __AVAILABILITY_INTERNAL__IPHONE_2_2_DEP__IPHONE_4_0 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_0_DEP__IPHONE_4_0 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_1_DEP__IPHONE_4_0 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_2_DEP__IPHONE_4_0 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_3_DEP__IPHONE_4_0 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_4_0_DEP__IPHONE_4_0 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #elif __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE__IPHONE_3_0 + #define __AVAILABILITY_INTERNAL__IPHONE_2_0_DEP__IPHONE_4_0 + #define __AVAILABILITY_INTERNAL__IPHONE_2_1_DEP__IPHONE_4_0 + #define __AVAILABILITY_INTERNAL__IPHONE_2_2_DEP__IPHONE_4_0 + #define __AVAILABILITY_INTERNAL__IPHONE_3_0_DEP__IPHONE_4_0 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_1_DEP__IPHONE_4_0 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_2_DEP__IPHONE_4_0 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_3_DEP__IPHONE_4_0 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_4_0_DEP__IPHONE_4_0 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #elif __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE__IPHONE_3_1 + #define __AVAILABILITY_INTERNAL__IPHONE_2_0_DEP__IPHONE_4_0 + #define __AVAILABILITY_INTERNAL__IPHONE_2_1_DEP__IPHONE_4_0 + #define __AVAILABILITY_INTERNAL__IPHONE_2_2_DEP__IPHONE_4_0 + #define __AVAILABILITY_INTERNAL__IPHONE_3_0_DEP__IPHONE_4_0 + #define __AVAILABILITY_INTERNAL__IPHONE_3_1_DEP__IPHONE_4_0 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_2_DEP__IPHONE_4_0 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_3_DEP__IPHONE_4_0 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_4_0_DEP__IPHONE_4_0 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #elif __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE__IPHONE_3_2 + #define __AVAILABILITY_INTERNAL__IPHONE_2_0_DEP__IPHONE_4_0 + #define __AVAILABILITY_INTERNAL__IPHONE_2_1_DEP__IPHONE_4_0 + #define __AVAILABILITY_INTERNAL__IPHONE_2_2_DEP__IPHONE_4_0 + #define __AVAILABILITY_INTERNAL__IPHONE_3_0_DEP__IPHONE_4_0 + #define __AVAILABILITY_INTERNAL__IPHONE_3_1_DEP__IPHONE_4_0 + #define __AVAILABILITY_INTERNAL__IPHONE_3_2_DEP__IPHONE_4_0 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_3_3_DEP__IPHONE_4_0 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_4_0_DEP__IPHONE_4_0 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #elif __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE__IPHONE_3_3 + #define __AVAILABILITY_INTERNAL__IPHONE_2_0_DEP__IPHONE_4_0 + #define __AVAILABILITY_INTERNAL__IPHONE_2_1_DEP__IPHONE_4_0 + #define __AVAILABILITY_INTERNAL__IPHONE_2_2_DEP__IPHONE_4_0 + #define __AVAILABILITY_INTERNAL__IPHONE_3_0_DEP__IPHONE_4_0 + #define __AVAILABILITY_INTERNAL__IPHONE_3_1_DEP__IPHONE_4_0 + #define __AVAILABILITY_INTERNAL__IPHONE_3_2_DEP__IPHONE_4_0 + #define __AVAILABILITY_INTERNAL__IPHONE_3_3_DEP__IPHONE_4_0 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #define __AVAILABILITY_INTERNAL__IPHONE_4_0_DEP__IPHONE_4_0 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #elif __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE__IPHONE_4_0 + #define __AVAILABILITY_INTERNAL__IPHONE_2_0_DEP__IPHONE_4_0 + #define __AVAILABILITY_INTERNAL__IPHONE_2_1_DEP__IPHONE_4_0 + #define __AVAILABILITY_INTERNAL__IPHONE_2_2_DEP__IPHONE_4_0 + #define __AVAILABILITY_INTERNAL__IPHONE_3_0_DEP__IPHONE_4_0 + #define __AVAILABILITY_INTERNAL__IPHONE_3_1_DEP__IPHONE_4_0 + #define __AVAILABILITY_INTERNAL__IPHONE_3_2_DEP__IPHONE_4_0 + #define __AVAILABILITY_INTERNAL__IPHONE_3_3_DEP__IPHONE_4_0 + #define __AVAILABILITY_INTERNAL__IPHONE_4_0_DEP__IPHONE_4_0 __AVAILABILITY_INTERNAL_WEAK_IMPORT + #else + #define __AVAILABILITY_INTERNAL__IPHONE_2_0_DEP__IPHONE_4_0 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_2_1_DEP__IPHONE_4_0 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_2_2_DEP__IPHONE_4_0 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_3_0_DEP__IPHONE_4_0 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_3_1_DEP__IPHONE_4_0 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_3_2_DEP__IPHONE_4_0 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_3_3_DEP__IPHONE_4_0 __AVAILABILITY_INTERNAL_DEPRECATED + #define __AVAILABILITY_INTERNAL__IPHONE_4_0_DEP__IPHONE_4_0 __AVAILABILITY_INTERNAL_DEPRECATED + #endif +#endif + +#endif diff --git a/Classes/ControlPadConnectViewController.h b/Classes/ControlPadConnectViewController.h new file mode 100644 index 0000000..481c9d8 --- /dev/null +++ b/Classes/ControlPadConnectViewController.h @@ -0,0 +1,45 @@ +// +// ControlPadConnectViewController.h +// SNES4iPad +// +// Created by Yusef Napora on 5/10/10. +// Copyright 2010 __MyCompanyName__. All rights reserved. +// + +#import + +typedef enum { + ControlPadConnectionStateConnected, + ControlPadConnectionStateAvailable, + ControlPadConnectionStateSearching +} ControlPadConnectionState; + +@interface ControlPadConnectViewController : UIViewController { + + UILabel *controllerLabel; + UILabel *statusLabel; + + UIActivityIndicatorView *spinner; + UIButton *acceptButton; + UIButton *denyButton; + UIButton *disconnectButton; + + NSUInteger currentPadNumber; + NSArray *numberStrings; + + ControlPadConnectionState state; +} + +@property (nonatomic, retain) IBOutlet UILabel *controllerLabel; +@property (nonatomic, retain) IBOutlet UILabel *statusLabel; +@property (nonatomic, retain) IBOutlet UIActivityIndicatorView *spinner; +@property (nonatomic, retain) IBOutlet UIButton *acceptButton; +@property (nonatomic, retain) IBOutlet UIButton *denyButton; +@property (nonatomic, retain) IBOutlet UIButton *disconnectButton; +@property (nonatomic, assign) NSUInteger currentPadNumber; +@property (nonatomic, assign) ControlPadConnectionState state; + +- (IBAction) buttonPressed:(id)sender; + + +@end diff --git a/Classes/ControlPadConnectViewController.m b/Classes/ControlPadConnectViewController.m new file mode 100644 index 0000000..c36df13 --- /dev/null +++ b/Classes/ControlPadConnectViewController.m @@ -0,0 +1,137 @@ + // +// ControlPadConnectViewController.m +// SNES4iPad +// +// Created by Yusef Napora on 5/10/10. +// Copyright 2010 __MyCompanyName__. All rights reserved. +// + +#import "SNES4iPadAppDelegate.h" +#import "ControlPadConnectViewController.h" +#import "ControlPadManager.h" + + +@implementation ControlPadConnectViewController + +@synthesize state, controllerLabel, statusLabel, spinner, acceptButton, denyButton, disconnectButton, currentPadNumber; + + + +- (void)viewDidLoad { + [super viewDidLoad]; + self.contentSizeForViewInPopover = CGSizeMake(424, 128); + + numberStrings = [[NSArray alloc] initWithObjects:@"One", @"Two", @"Three", @"Four", nil]; + + [self.acceptButton setBackgroundImage:[[UIImage imageNamed:@"greenButton.png"] stretchableImageWithLeftCapWidth:10 topCapHeight:0] + forState:UIControlStateNormal]; + [self.denyButton setBackgroundImage:[[UIImage imageNamed:@"redButton.png"] stretchableImageWithLeftCapWidth:10 topCapHeight:0] + forState:UIControlStateNormal]; + [self.disconnectButton setBackgroundImage:[[UIImage imageNamed:@"redButton.png"] stretchableImageWithLeftCapWidth:10 topCapHeight:0] + forState:UIControlStateNormal]; +} + + + +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { + // Overriden to allow any orientation. + return YES; +} + +- (void) viewWillAppear:(BOOL)animated +{ + controllerLabel.text = [NSString stringWithFormat:@"Player %@", [numberStrings objectAtIndex:currentPadNumber]]; + + NSString *deviceName = [AppDelegate().controlPadManager deviceNameForPadNumber:currentPadNumber]; + if (deviceName == nil) + { + self.state = ControlPadConnectionStateSearching; + } +} + +- (void) viewWillDisappear:(BOOL)animated +{ + [AppDelegate().controlPadManager stopSearchingForConnection]; +} + +- (void) setState:(ControlPadConnectionState)s +{ + if (state != s) + { + state = s; + switch (state) + { + case ControlPadConnectionStateSearching: + acceptButton.hidden = YES; + denyButton.hidden = YES; + disconnectButton.hidden = YES; + [spinner startAnimating]; + statusLabel.text = @"Waiting For Connection..."; + [AppDelegate().controlPadManager searchForConnectionToPadNumber:currentPadNumber]; + break; + case ControlPadConnectionStateAvailable: + acceptButton.hidden = NO; + denyButton.hidden = NO; + disconnectButton.hidden = YES; + [spinner stopAnimating]; + statusLabel.text = [NSString stringWithFormat:@"Found: %@", + [AppDelegate().controlPadManager deviceNameForPendingConnection]]; + break; + case ControlPadConnectionStateConnected: + acceptButton.hidden = YES; + denyButton.hidden = YES; + disconnectButton.hidden = NO; + [spinner stopAnimating]; + statusLabel.text = [NSString stringWithFormat:@"Connected to %@", + [AppDelegate().controlPadManager deviceNameForPadNumber:currentPadNumber]]; + break; + } + } +} + + + +- (IBAction) buttonPressed:(id)sender +{ + NSLog(@"button pressed: %@", [sender description]); + if (sender == acceptButton) + { + [AppDelegate().controlPadManager acceptPendingConnection]; + } else if (sender == denyButton) + { + [AppDelegate().controlPadManager denyPendingConnection]; + self.state = ControlPadConnectionStateSearching; + } else if (sender == disconnectButton) { + [AppDelegate().controlPadManager disconnectPadNumber:currentPadNumber]; + self.state = ControlPadConnectionStateSearching; + } +} + +- (void)didReceiveMemoryWarning { + // Releases the view if it doesn't have a superview. + [super didReceiveMemoryWarning]; + + // Release any cached data, images, etc that aren't in use. +} + + +- (void)viewDidUnload { + [super viewDidUnload]; + // Release any retained subviews of the main view. + // e.g. self.myOutlet = nil; +} + + +- (void)dealloc { + [super dealloc]; + [numberStrings release]; + [controllerLabel release]; + [statusLabel release]; + [spinner release]; + [acceptButton release]; + [denyButton release]; + +} + + +@end diff --git a/Classes/ControlPadManager.h b/Classes/ControlPadManager.h new file mode 100644 index 0000000..ff51ff5 --- /dev/null +++ b/Classes/ControlPadManager.h @@ -0,0 +1,44 @@ +// +// ControlPadManager.h +// SNES4iPad +// +// Created by Yusef Napora on 5/10/10. +// Copyright 2010 __MyCompanyName__. All rights reserved. +// + +#import +#import + +#define MAX_CONTROL_PADS 4 + +extern unsigned long padStatusForPadNumber(int which); + +@interface ControlPadManager : NSObject { + GKSession *gkSession; + + NSMutableArray *controlPadPeerIDs; + + NSUInteger padAwaitingConnection; + NSString *pendingConnectionPeerID; + + // these longs hold the current status of all the control pads. + // status == a mask of which buttons are currently pressed + // this is the value returned by statusForPadNumber: + unsigned long padStatus[MAX_CONTROL_PADS]; +} + +@property (nonatomic, assign) NSUInteger padAwaitingConnection; +@property (nonatomic, retain) NSString *pendingConnectionPeerID; + +- (void) searchForConnectionToPadNumber:(NSUInteger)padNumber; +- (void) stopSearchingForConnection; + +- (void) acceptPendingConnection; +- (void) denyPendingConnection; +- (void) disconnectPadNumber:(NSUInteger)padNumber; +- (void) disconnectPeer:(NSString *)peerID; +- (unsigned long) statusForPadNumber:(NSUInteger)padNumber; +- (NSString *) deviceNameForPadNumber:(NSUInteger)padNumber; +- (NSString *) deviceNameForPendingConnection; + +@end diff --git a/Classes/ControlPadManager.m b/Classes/ControlPadManager.m new file mode 100644 index 0000000..62168c9 --- /dev/null +++ b/Classes/ControlPadManager.m @@ -0,0 +1,170 @@ +// +// ControlPadManager.m +// SNES4iPad +// +// Created by Yusef Napora on 5/10/10. +// Copyright 2010 __MyCompanyName__. All rights reserved. +// + +#import "SNES4iPadAppDelegate.h" +#import "ControlPadManager.h" +#import "ControlPadConnectViewController.h" + +#define MAX_CONNECTIONS 4 +#define SESSION_ID @"com.snes-hd.controller" + +unsigned long padStatusForPadNumber(int which) +{ + if (which < MAX_CONTROL_PADS) + return [AppDelegate().controlPadManager statusForPadNumber:which]; + + return 0; +} + +@implementation ControlPadManager +@synthesize padAwaitingConnection, pendingConnectionPeerID; + + +- (id) init +{ + if (self = [super init]) + { + gkSession = [[GKSession alloc] initWithSessionID:SESSION_ID + displayName:nil + sessionMode:GKSessionModeServer]; + gkSession.delegate = self; + [gkSession setDataReceiveHandler:self withContext:NULL]; + controlPadPeerIDs = [[NSMutableArray alloc] initWithObjects: + [NSMutableString string], + [NSMutableString string], + [NSMutableString string], + [NSMutableString string], + nil]; + + } + return self; +} + +- (void) searchForConnectionToPadNumber:(NSUInteger)padNumber +{ + if (padNumber >= MAX_CONTROL_PADS) + return; + + padAwaitingConnection = padNumber; + gkSession.available = YES; +} + +- (void) stopSearchingForConnection +{ + gkSession.available = NO; +} + +- (NSString *) deviceNameForPendingConnection +{ + return [gkSession displayNameForPeer:pendingConnectionPeerID]; +} + +- (NSString *) deviceNameForPadNumber:(NSUInteger)padNumber +{ + if (padNumber >= MAX_CONTROL_PADS) + return nil; + + return [gkSession displayNameForPeer: [controlPadPeerIDs objectAtIndex:padNumber]]; +} + +- (unsigned long) statusForPadNumber:(NSUInteger)padNumber +{ + if (padNumber < MAX_CONTROL_PADS) { + return padStatus[padNumber]; + } + return 0; +} + +- (void) disconnectPadNumber:(NSUInteger)padNumber +{ + if (padNumber >= MAX_CONTROL_PADS) + return; + + NSString *peerID = [controlPadPeerIDs objectAtIndex:padNumber]; + [gkSession disconnectPeerFromAllPeers:peerID]; + [[controlPadPeerIDs objectAtIndex:padNumber] setString:@""]; +} + +- (void) disconnectPeer:(NSString *)peerID +{ + if ([controlPadPeerIDs containsObject:peerID]) + { + [self disconnectPadNumber:[controlPadPeerIDs indexOfObject:peerID]]; + } +} + +- (void) receiveData:(NSData *)data fromPeer:(NSString *)peer inSession: (GKSession *)session context:(void *)context +{ + if (![controlPadPeerIDs containsObject:peer]) + return; + + NSUInteger padNumber = [controlPadPeerIDs indexOfObject:peer]; + [data getBytes:&padStatus[padNumber]]; + //NSLog(@"recieved pad status for player %d: %X", padNumber + 1, padStatus[padNumber]); +} + +- (void) acceptPendingConnection +{ + [gkSession acceptConnectionFromPeer:self.pendingConnectionPeerID error:nil]; + [[controlPadPeerIDs objectAtIndex:padAwaitingConnection] setString:self.pendingConnectionPeerID]; + self.pendingConnectionPeerID = nil; + + [AppDelegate().romDetailViewController updateConnectionButtons]; +} + +- (void) denyPendingConnection +{ + [gkSession denyConnectionFromPeer:self.pendingConnectionPeerID]; + self.pendingConnectionPeerID = nil; +} + +#pragma mark - +#pragma mark GKSession Delegate methods +- (void)session:(GKSession *)session peer:(NSString *)peerID didChangeState:(GKPeerConnectionState)state { + NSLog(@"Session state changed"); + + switch (state) { + case GKPeerStateConnected: + NSLog(@"New Peer connected: %@", peerID); + [[controlPadPeerIDs objectAtIndex:padAwaitingConnection] setString:peerID]; + self.pendingConnectionPeerID = nil; + AppDelegate().controlPadConnectViewController.state = ControlPadConnectionStateConnected; + + break; + case GKPeerStateAvailable: + case GKPeerStateConnecting: + NSLog(@"Peer connecting/available: %@", peerID); + self.pendingConnectionPeerID = peerID; + AppDelegate().controlPadConnectViewController.state = ControlPadConnectionStateAvailable; + break; + case GKPeerStateUnavailable: + NSLog(@"Peer unavailable: %@", peerID); + self.pendingConnectionPeerID = nil; + AppDelegate().controlPadConnectViewController.state = ControlPadConnectionStateSearching; + break; + case GKPeerStateDisconnected: + NSLog(@"Peer disconnected: %@", peerID); + [self disconnectPeer:peerID]; + AppDelegate().controlPadConnectViewController.state = ControlPadConnectionStateSearching; + [AppDelegate().romDetailViewController updateConnectionButtons]; + break; + + default: + break; + } +} + +- (void)session:(GKSession *)session didReceiveConnectionRequestFromPeer:(NSString *)peerID { + NSLog(@"Recieved connection request from %@", peerID); + self.pendingConnectionPeerID = peerID; + AppDelegate().controlPadConnectViewController.state = ControlPadConnectionStateAvailable; +} +- (void)session:(GKSession *)session connectionWithPeerFailed:(NSString *)peerID withError:(NSError *)error { + NSLog(@"Connection with %@ failed", peerID); +} +@end diff --git a/Classes/EmulationViewController.h b/Classes/EmulationViewController.h new file mode 100644 index 0000000..379b32b --- /dev/null +++ b/Classes/EmulationViewController.h @@ -0,0 +1,25 @@ +// +// EmulationViewController.h +// SNES4iPad +// +// Created by Yusef Napora on 5/14/10. +// Copyright 2010 __MyCompanyName__. All rights reserved. +// + +#import + +@interface EmulationViewController : UIViewController { +} + +- (void) startWithRom:(NSString *)romFile; + +/* +- (void) stop; +- (void) pause; +- (void) resume; +- (void) saveCurrentState; +- (void) saveNewState; +*/ + +- (void) refreshScreen; +@end diff --git a/Classes/EmulationViewController.m b/Classes/EmulationViewController.m new file mode 100644 index 0000000..a0ba4cb --- /dev/null +++ b/Classes/EmulationViewController.m @@ -0,0 +1,175 @@ + // +// EmulationViewController.m +// SNES4iPad +// +// Created by Yusef Napora on 5/14/10. +// Copyright 2010 __MyCompanyName__. All rights reserved. +// + +#import "SNES4iPadAppDelegate.h" +#import "EmulationViewController.h" +#import "ScreenView.h" + +#import +#import + + +volatile int __emulation_run; +volatile int __emulation_saving; +volatile int __emulation_paused; + +extern int iphone_main(char *filename); + + +pthread_t main_tid; + + +// C wrapper function for emulation core access +void refreshScreenSurface() +{ + [AppDelegate().emulationViewController performSelectorOnMainThread:@selector(refreshScreen) withObject:nil waitUntilDone:NO]; +} + +// entry point for emulator thread +void *threadedStart(void *arg) +{ + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + char *filename = malloc(strlen((char *)arg) + 1); + strcpy(filename, (char *)arg); + printf("Starting emulator for %s\n", filename); + __emulation_run = 1; + iphone_main(filename); + __emulation_run = 0; + __emulation_saving = 0; + + free(filename); + [pool release]; +} + + + +extern unsigned short *vrambuffer; // this holds the 256x224 framebuffer in L565 format + +void convertBufferToARGB(unsigned int *dest, unsigned short *source, int w, int h) +{ + int x, y; + // convert to ARGB + for (y=0; y < h; y++) { + for (x=0; x < w; x++) { + unsigned int index = (y*w)+x; + unsigned short source_pixel = source[index]; + unsigned char r = (source_pixel & 0xf800) >> 11; + unsigned char g = (source_pixel & 0x07c0) >> 5; + unsigned char b = (source_pixel & 0x003f); + dest[index] = 0xff000000 | + (((r << 3) | (r >> 2)) << 16) | + (((g << 2) | (g >> 4)) << 8) | + ((b << 3) | (b >> 2)); + } + } + +} + +// helper function to save a snapshot of the current framebuffer contents +void saveScreenshotToFile(char *filepath) +{ + NSLog(@"writing screenshot to %s", filepath); + int width = 256; + int height = 224; + + unsigned int *argb_buffer = (unsigned int *)malloc(width * height * 4); + convertBufferToARGB(argb_buffer, vrambuffer, width, height); + + // make data provider from buffer + CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, argb_buffer, (width * height * 4), NULL); + + // set up for CGImage creation + int bitsPerComponent = 8; + int bitsPerPixel = 32; + int bytesPerRow = 4 * width; + CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB(); + CGBitmapInfo bitmapInfo = kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst; + CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault; + CGImageRef imageRef = CGImageCreate(width, height, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent); + + UIImage *uiImage = [[UIImage alloc] initWithCGImage:imageRef]; + + NSData *pngData = UIImagePNGRepresentation(uiImage); + [pngData writeToFile:[NSString stringWithCString:filepath] atomically:YES]; + + [uiImage release]; + CGImageRelease(imageRef); + free(argb_buffer); + +} + +@implementation EmulationViewController + +/* + // The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad. +- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { + if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) { + // Custom initialization + } + return self; +} +*/ + + +- (void)loadView { + self.view = (UIView *)[[ScreenView alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; + +} + + +- (void) refreshScreen +{ + //[(ScreenView *) self.view update]; + [self.view setNeedsDisplay]; + //[self.view.layer setNeedsDisplay]; +} + +- (void) startWithRom:(NSString *)romFile +{ + pthread_create(&main_tid, NULL, threadedStart, (void *) [[romFile lastPathComponent] UTF8String]); + + struct sched_param param; + param.sched_priority = 46; + if(pthread_setschedparam(main_tid, SCHED_OTHER, ¶m) != 0) + { + fprintf(stderr, "Error setting pthread priority\n"); + } +} + + + +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { + // Return YES for supported orientations + return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft || + interfaceOrientation == UIInterfaceOrientationLandscapeRight); +} + + +- (void)didReceiveMemoryWarning { + // Releases the view if it doesn't have a superview. + [super didReceiveMemoryWarning]; + + // Release any cached data, images, etc that aren't in use. +} + + +- (void)viewDidUnload { + [super viewDidUnload]; + // Release any retained subviews of the main view. + // e.g. self.myOutlet = nil; +} + + +- (void)dealloc { + [super dealloc]; +} + + +@end + + diff --git a/Classes/RomDetailViewController.h b/Classes/RomDetailViewController.h new file mode 100644 index 0000000..f28bca7 --- /dev/null +++ b/Classes/RomDetailViewController.h @@ -0,0 +1,67 @@ +// +// RomDetailViewController.h +// SNES4iPad +// +// Created by Yusef Napora on 5/10/10. +// Copyright __MyCompanyName__ 2010. All rights reserved. +// + +#import + +@class SaveStateSelectionViewController; + +@interface RomDetailViewController : UIViewController { + + UIPopoverController *splitViewPopoverController; + UIPopoverController *buttonPopoverController; + UIToolbar *toolbar; + + id detailItem; + UILabel *romTitleLabel; + UIImageView *romImageView; + UIBarButtonItem *romTitleButton; + UIBarButtonItem *settingsButton; + + UIImageView *snapshotImageView; + UIButton *powerButton; + UIButton *loadButton; + UIButton *ejectButton; + + + UIView *multiTapView; + UIButton *playerOneButton; + UIButton *playerTwoButton; + UIButton *playerThreeButton; + UIButton *playerFourButton; + + SaveStateSelectionViewController *saveStateSelectionViewController; +} + +@property (nonatomic, retain) IBOutlet UIToolbar *toolbar; + +@property (nonatomic, retain) id detailItem; +@property (nonatomic, retain) IBOutlet UILabel *romTitleLabel; +@property (nonatomic, retain) IBOutlet UIImageView *romImageView; +@property (nonatomic, retain) IBOutlet UIBarButtonItem *romTitleButton; +@property (nonatomic, retain) IBOutlet UIBarButtonItem *settingsButton; + + +@property (nonatomic, retain) IBOutlet UIButton *powerButton; +@property (nonatomic, retain) IBOutlet UIButton *loadButton; +@property (nonatomic, retain) IBOutlet UIButton *ejectButton; +@property (nonatomic, retain) IBOutlet UIImageView *snapshotImageView; + +@property (nonatomic, retain) IBOutlet UIView *multiTapView; +@property (nonatomic, retain) IBOutlet UIButton *playerOneButton; +@property (nonatomic, retain) IBOutlet UIButton *playerTwoButton; +@property (nonatomic, retain) IBOutlet UIButton *playerThreeButton; +@property (nonatomic, retain) IBOutlet UIButton *playerFourButton; + +@property (nonatomic, retain) IBOutlet SaveStateSelectionViewController *saveStateSelectionViewController; + +- (IBAction) buttonPressed:(id)sender; + +- (void) updateConnectionButtons; +- (void) timerTriggeredConnectionDisplay:(NSTimer *)timer; + +@end diff --git a/Classes/RomDetailViewController.m b/Classes/RomDetailViewController.m new file mode 100644 index 0000000..337a0a5 --- /dev/null +++ b/Classes/RomDetailViewController.m @@ -0,0 +1,314 @@ +// +// DetailViewController.m +// SNES4iPad +// +// Created by Yusef Napora on 5/10/10. +// Copyright __MyCompanyName__ 2010. All rights reserved. +// + +#import "SNES4iPadAppDelegate.h" +#import "RomDetailViewController.h" +#import "RomSelectionViewController.h" +#import "SaveStateSelectionViewController.h" +#import "SettingsViewController.h" +#import "ControlPadConnectViewController.h" +#import "ControlPadManager.h" +#import "EmulationViewController.h" + +@interface RomDetailViewController () +@property (nonatomic, retain) UIPopoverController *splitViewPopoverController; +@property (nonatomic, retain) UIPopoverController *buttonPopoverController; +- (void)configureView; +@end + + + +@implementation RomDetailViewController + +@synthesize toolbar, splitViewPopoverController, buttonPopoverController, detailItem; +@synthesize romTitleLabel, romTitleButton, romImageView, powerButton, loadButton, ejectButton; +@synthesize playerOneButton, playerTwoButton, playerThreeButton, playerFourButton, multiTapView; +@synthesize settingsButton, snapshotImageView; +@synthesize saveStateSelectionViewController; + +- (void) viewDidLoad +{ + [self.saveStateSelectionViewController addObserver:self + forKeyPath:@"selectedSavePath" + options:NSKeyValueObservingOptionNew + context:nil]; + CGRect newFrame = self.saveStateSelectionViewController.view.frame; + newFrame.origin = CGPointMake(0, 560); + self.saveStateSelectionViewController.view.frame = newFrame; + [self.view addSubview: self.saveStateSelectionViewController.view]; + [self configureView]; +} + +- (void) viewDidAppear:(BOOL)animated +{ + if ([SettingsController().autoconnect isOn]) { + if (! [AppDelegate().controlPadManager deviceNameForPadNumber:0]) { + [NSTimer scheduledTimerWithTimeInterval:2.0f + target:self + selector:@selector(timerTriggeredConnectionDisplay:) + userInfo:playerOneButton + repeats:NO]; + } + } +} + +- (void) timerTriggeredConnectionDisplay:(NSTimer *)timer +{ + UIButton *b = (UIButton *)[timer userInfo]; + if (b == nil) { + b = playerOneButton; + } + [self buttonPressed:b]; +} + + +#pragma mark - +#pragma mark KVO observation +- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context +{ + NSLog(@"selected save changed"); + if (object == self.saveStateSelectionViewController) + { + if (self.saveStateSelectionViewController.selectedSavePath != nil) + { + self.loadButton.hidden = NO; + } + if (self.saveStateSelectionViewController.selectedScreenshotPath != nil) + { + UIImage *screenshot = [[UIImage alloc] initWithContentsOfFile: + self.saveStateSelectionViewController.selectedScreenshotPath]; + [self.snapshotImageView setImage:screenshot]; + [screenshot release]; + self.snapshotImageView.hidden = NO; + } else { + [self.snapshotImageView setImage:nil]; + self.snapshotImageView.hidden = YES; + } + + } +} + +#pragma mark - +#pragma mark Button Presses +- (IBAction) buttonPressed:(id)sender +{ + if (sender == settingsButton) + { + if (!buttonPopoverController) { + buttonPopoverController = [[UIPopoverController alloc] initWithContentViewController:AppDelegate().settingsViewController]; + buttonPopoverController.delegate = self; + [buttonPopoverController presentPopoverFromBarButtonItem:settingsButton + permittedArrowDirections:UIPopoverArrowDirectionAny + animated:YES]; + } + } else if (sender == powerButton) { + NSLog(@"power button pressed"); + [AppDelegate().emulationViewController startWithRom:(NSString *)detailItem]; + [AppDelegate() showEmulator:YES]; + } else if (sender == loadButton) { + NSLog(@"load button pressed"); + [AppDelegate().emulationViewController startWithRom: + self.saveStateSelectionViewController.selectedSavePath ]; + [AppDelegate() showEmulator:YES]; + } else if (sender == ejectButton) { + self.detailItem = nil; + } else if (sender == playerOneButton || sender == playerTwoButton || + sender == playerThreeButton || sender == playerFourButton) + { + if (!buttonPopoverController) { + UIButton *b = (UIButton *)sender; + AppDelegate().controlPadConnectViewController.currentPadNumber = b.tag; + buttonPopoverController = [[UIPopoverController alloc] initWithContentViewController:AppDelegate().controlPadConnectViewController]; + buttonPopoverController.delegate = self; + [buttonPopoverController presentPopoverFromRect:b.frame + inView:[b superview] + permittedArrowDirections:UIPopoverArrowDirectionAny + animated:YES]; + } + } +} + +- (void) updateConnectionButtons +{ + NSArray *buttonArray = [NSArray arrayWithObjects: + playerOneButton, playerTwoButton, playerThreeButton, playerFourButton, nil]; + + int i = 0; + for (UIButton *b in buttonArray) + { + NSString *deviceName = [AppDelegate().controlPadManager deviceNameForPadNumber:i]; + if (deviceName && ! [deviceName isEqual:@""]) { + b.titleLabel.text = deviceName; + } else { + b.titleLabel.text = @"Not Connected"; + } + i++; + } +} + +#pragma mark - +#pragma mark PopoverController delegate methods +- (void) popoverControllerDidDismissPopover:(UIPopoverController *)popoverController +{ + if (popoverController == buttonPopoverController) + { + [buttonPopoverController release]; + buttonPopoverController = nil; + } +} + + +#pragma mark - +#pragma mark Managing the detail item + +/* + When setting the detail item, update the view and dismiss the popover controller if it's showing. + */ +- (void)setDetailItem:(id)newDetailItem { + if (detailItem != newDetailItem) { + [detailItem release]; + detailItem = [newDetailItem retain]; + + // Update the view. + + [self configureView]; + } + + if (splitViewPopoverController != nil) { + [splitViewPopoverController dismissPopoverAnimated:YES]; + } +} + + +- (void)configureView { + self.multiTapView.hidden = ! [SettingsController().multiTap isOn]; + // Update the user interface for the detail item. + if (!detailItem) { + self.romTitleButton.title = @"No ROM Selected"; + self.saveStateSelectionViewController.view.hidden = YES; + self.snapshotImageView.hidden = YES; + self.romTitleLabel.hidden = YES; + self.powerButton.hidden = YES; + self.loadButton.hidden = YES; + self.romImageView.hidden = YES; + self.ejectButton.hidden = YES; + return; + } + NSString *romFile = [[detailItem description] lastPathComponent]; + self.romTitleLabel.text = [romFile stringByDeletingPathExtension]; + self.romTitleButton.title = romTitleLabel.text; + self.romTitleLabel.hidden = NO; + + self.saveStateSelectionViewController.romFilter = romFile; + [self.saveStateSelectionViewController scanSaveDirectory]; + self.saveStateSelectionViewController.view.hidden = NO; + self.snapshotImageView.hidden = YES; + self.loadButton.hidden = YES; + self.powerButton.hidden = NO; + self.romImageView.hidden = NO; + self.ejectButton.hidden = NO; +} + + +#pragma mark - +#pragma mark Split view support + +- (void)splitViewController: (UISplitViewController*)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem*)barButtonItem forPopoverController: (UIPopoverController*)pc { + + barButtonItem.title = @"ROMs"; + NSMutableArray *items = [[toolbar items] mutableCopy]; + [items insertObject:barButtonItem atIndex:0]; + [toolbar setItems:items animated:YES]; + [items release]; + self.splitViewPopoverController = pc; +} + + +// Called when the view is shown again in the split view, invalidating the button and popover controller. +- (void)splitViewController: (UISplitViewController*)svc willShowViewController:(UIViewController *)aViewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem { + + NSMutableArray *items = [[toolbar items] mutableCopy]; + [items removeObjectAtIndex:0]; + [toolbar setItems:items animated:YES]; + [items release]; + self.splitViewPopoverController = nil; +} + + +#pragma mark - +#pragma mark Rotation support + +// Ensure that the view controller supports rotation and that the split view can therefore show in both portrait and landscape. +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { + return YES; +} + + +#pragma mark - +#pragma mark View lifecycle + +/* + // Implement viewDidLoad to do additional setup after loading the view, typically from a nib. +- (void)viewDidLoad { + [super viewDidLoad]; +} + */ + +/* +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; +} +*/ +/* +- (void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; +} +*/ +/* +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; +} +*/ +/* +- (void)viewDidDisappear:(BOOL)animated { + [super viewDidDisappear:animated]; +} +*/ + +- (void)viewDidUnload { + // Release any retained subviews of the main view. + // e.g. self.myOutlet = nil; + self.splitViewPopoverController = nil; +} + + +#pragma mark - +#pragma mark Memory management + +/* +- (void)didReceiveMemoryWarning { + // Releases the view if it doesn't have a superview. + [super didReceiveMemoryWarning]; + + // Release any cached data, images, etc that aren't in use. +} +*/ + +- (void)dealloc { + [saveStateSelectionViewController removeObserver:self forKeyPath:@"selectedSavePath"]; + [saveStateSelectionViewController release]; + [splitViewPopoverController release]; + [toolbar release]; + + [detailItem release]; + [romTitleLabel release]; + [romImageView release]; + [super dealloc]; +} + +@end diff --git a/Classes/RomSelectionViewController.h b/Classes/RomSelectionViewController.h new file mode 100644 index 0000000..2a924f5 --- /dev/null +++ b/Classes/RomSelectionViewController.h @@ -0,0 +1,25 @@ +// +// RomSelectionViewController.h +// SNES4iPad +// +// Created by Yusef Napora on 5/10/10. +// Copyright __MyCompanyName__ 2010. All rights reserved. +// + +#import + +@class RomDetailViewController; + +@interface RomSelectionViewController : UITableViewController { + RomDetailViewController *romDetailViewController; + + NSMutableArray *arrayOfCharacters; + NSMutableDictionary *objectsForCharacters; + NSArray *alphabetIndex; +} + +@property (nonatomic, retain) IBOutlet RomDetailViewController *romDetailViewController; + +- (void) scanRomDirectory:(NSString *)path; + +@end diff --git a/Classes/RomSelectionViewController.m b/Classes/RomSelectionViewController.m new file mode 100644 index 0000000..7d855fc --- /dev/null +++ b/Classes/RomSelectionViewController.m @@ -0,0 +1,336 @@ +// +// RomSelectionViewController.m +// SNES4iPad +// +// Created by Yusef Napora on 5/10/10. +// Copyright __MyCompanyName__ 2010. All rights reserved. +// + +#import "SNES4iPadAppDelegate.h" +#import "RomSelectionViewController.h" +#import "RomDetailViewController.h" + + +@implementation RomSelectionViewController + +@synthesize romDetailViewController; + + +#pragma mark - +#pragma mark View lifecycle + +- (void) awakeFromNib { + 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)viewDidLoad { + [super viewDidLoad]; + self.clearsSelectionOnViewWillAppear = NO; + self.contentSizeForViewInPopover = CGSizeMake(320.0, 600.0); + + [self scanRomDirectory:[AppDelegate() romDirectoryPath]]; +} + +/* +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; +} +*/ +/* +- (void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; +} +*/ +/* +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; +} +*/ +/* +- (void)viewDidDisappear:(BOOL)animated { + [super viewDidDisappear:animated]; +} +*/ + +// Ensure that the view controller supports rotation and that the split view can therefore show in both portrait and landscape. +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { + return YES; +} + + +#pragma mark - +#pragma mark ROM loading methods + +- (void)scanRomDirectory:(NSString*)path +{ + unsigned long numFiles = 0; + [arrayOfCharacters removeAllObjects]; + [objectsForCharacters removeAllObjects]; + + // make sure path has trailing '/' character + NSString *romDir; + if([[path substringWithRange:NSMakeRange([path length]-1,1)] compare:@"/"] == NSOrderedSame) + { + romDir = [[NSString alloc] initWithFormat:@"%@",path]; + } + else + { + romDir = [[NSString alloc] initWithFormat:@"%@/",path]; + } + + int i; + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSArray* dirContents = [fileManager directoryContentsAtPath: romDir]; + 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 = (char *)[objectIndexer UTF8String]; + objectIndex = objectLetter[0] - 'A'; + if(objectIndex > 25) + { + objectIndex = 25; + } + } + + if(characterLUT[objectIndex] == 0) + { + characterLUT[objectIndex] = 1; + } + + [arrayOfIndexedFiles[objectIndex] addObject:[dirContents objectAtIndex:i]]; + numFiles++; + } + } + + 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]; + } + + + [(UITableView*)self.view reloadData]; + + self.navigationItem.prompt = romDir; +} + + +#pragma mark - +#pragma mark Table view data source + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + UITableViewCell* cell; + NSMutableDictionary* objects; + + objects = objectsForCharacters; + + cell = [tableView dequeueReusableCellWithIdentifier:@"labelCell"]; + if (cell == nil) + { + cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:@"labelCell"] autorelease]; + cell.textLabel.adjustsFontSizeToFitWidth = YES; + cell.textLabel.numberOfLines = 1; + cell.textLabel.minimumFontSize = 9.0f; + cell.textLabel.lineBreakMode = UILineBreakModeMiddleTruncation; + } + + cell.accessoryType = UITableViewCellAccessoryNone; + if([arrayOfCharacters count] <= 0) + { + cell.textLabel.text = @""; + return cell; + } + + cell.textLabel.text = [[objects objectForKey:[arrayOfCharacters objectAtIndex:indexPath.section]] objectAtIndex:indexPath.row]; + + return cell; +} + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)aTableView { + if([arrayOfCharacters count] <= 0) + { + return 1; + } + return [arrayOfCharacters count]; +} + + +- (NSInteger)tableView:(UITableView *)aTableView numberOfRowsInSection:(NSInteger)section { + if([arrayOfCharacters count] <= 0) + { + return 0; + } + + + return [[objectsForCharacters objectForKey:[arrayOfCharacters objectAtIndex:section]] count]; +} + +- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section +{ + if([arrayOfCharacters count] <= 0) + return @""; + + return [arrayOfCharacters objectAtIndex:section]; +} + + +- (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 +} + + +/* +// Override to support conditional editing of the table view. +- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { + // Return NO if you do not want the specified item to be editable. + return YES; +} +*/ + + +/* +// Override to support editing the table view. +- (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]; + } + else 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 to support rearranging the table view. +- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath { +} +*/ + + +/* +// Override to support conditional rearranging of the table view. +- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath { + // Return NO if you do not want the item to be re-orderable. + return YES; +} +*/ + + +#pragma mark - +#pragma mark Table view delegate + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + if([arrayOfCharacters count] <= 0) + { + return; + } + + NSMutableDictionary* objects; + + objects = objectsForCharacters; + + NSString *listingsPath = AppDelegate().romDirectoryPath; + NSString *romPath; + if([[listingsPath substringWithRange:NSMakeRange([listingsPath length]-1,1)] compare:@"/"] == NSOrderedSame) + { + romPath = [listingsPath stringByAppendingString: + [[objects objectForKey:[arrayOfCharacters objectAtIndex:indexPath.section]] objectAtIndex:indexPath.row]]; + } + else + { + romPath = [listingsPath stringByAppendingPathComponent: + [[objects objectForKey:[arrayOfCharacters objectAtIndex:indexPath.section]] objectAtIndex:indexPath.row]]; + } + + self.romDetailViewController.detailItem = (id) romPath; + +} + + +#pragma mark - +#pragma mark Memory management + +- (void)didReceiveMemoryWarning { + // Releases the view if it doesn't have a superview. + [super didReceiveMemoryWarning]; + + // Relinquish ownership any cached data, images, etc. that aren't in use. +} + +- (void)viewDidUnload { + // Relinquish ownership of anything that can be recreated in viewDidLoad or on demand. + // For example: self.myOutlet = nil; +} + + +- (void)dealloc { + [romDetailViewController release]; + [super dealloc]; +} + + +@end + diff --git a/Classes/SNES4iPadAppDelegate.h b/Classes/SNES4iPadAppDelegate.h new file mode 100644 index 0000000..952e1e7 --- /dev/null +++ b/Classes/SNES4iPadAppDelegate.h @@ -0,0 +1,55 @@ +// +// SNES4iPadAppDelegate.h +// SNES4iPad +// +// Created by Yusef Napora on 5/10/10. +// Copyright __MyCompanyName__ 2010. All rights reserved. +// + +#import + + +@class EmulationViewController; +@class RomSelectionViewController; +@class RomDetailViewController; +@class SettingsViewController; +@class ControlPadConnectViewController; +@class ControlPadManager; + + +@interface SNES4iPadAppDelegate : NSObject { + + UIWindow *window; + + UISplitViewController *splitViewController; + + EmulationViewController *emulationViewController; + RomSelectionViewController *romSelectionViewController; + RomDetailViewController *romDetailViewController; + SettingsViewController *settingsViewController; + ControlPadConnectViewController *controlPadConnectViewController; + ControlPadManager *controlPadManager; + + NSString *romDirectoryPath, *saveDirectoryPath, *snapshotDirectoryPath; +} + +@property (nonatomic, retain) IBOutlet UIWindow *window; + +@property (nonatomic, retain) IBOutlet UISplitViewController *splitViewController; +@property (nonatomic, retain) IBOutlet RomSelectionViewController *romSelectionViewController; +@property (nonatomic, retain) IBOutlet RomDetailViewController *romDetailViewController; +@property (nonatomic, retain) SettingsViewController *settingsViewController; +@property (nonatomic, retain) ControlPadConnectViewController *controlPadConnectViewController; +@property (nonatomic, retain) ControlPadManager *controlPadManager; + +@property (nonatomic, retain) EmulationViewController *emulationViewController; + +@property (nonatomic, readonly) NSString *romDirectoryPath; +@property (nonatomic, readonly) NSString *saveDirectoryPath; +@property (nonatomic, readonly) NSString *snapshotDirectoryPath; + +- (void) showEmulator:(BOOL)showOrHide; +- (void) showEmulationMenu:(BOOL)showOrHide; +@end + +extern SNES4iPadAppDelegate *AppDelegate(); \ No newline at end of file diff --git a/Classes/SNES4iPadAppDelegate.m b/Classes/SNES4iPadAppDelegate.m new file mode 100644 index 0000000..f1eea67 --- /dev/null +++ b/Classes/SNES4iPadAppDelegate.m @@ -0,0 +1,105 @@ +// +// SNES4iPadAppDelegate.m +// SNES4iPad +// +// Created by Yusef Napora on 5/10/10. +// Copyright __MyCompanyName__ 2010. All rights reserved. +// + +#import "SNES4iPadAppDelegate.h" + +#import "EmulationViewController.h" +#import "RomSelectionViewController.h" +#import "RomDetailViewController.h" +#import "SettingsViewController.h" +#import "ControlPadConnectViewController.h" +#import "ControlPadManager.h" + + +SNES4iPadAppDelegate *AppDelegate() +{ + return (SNES4iPadAppDelegate *)[[UIApplication sharedApplication] delegate]; +} + +@implementation SNES4iPadAppDelegate + +@synthesize window, splitViewController, romSelectionViewController, romDetailViewController, settingsViewController; +@synthesize controlPadConnectViewController, controlPadManager; +@synthesize romDirectoryPath, saveDirectoryPath, snapshotDirectoryPath; +@synthesize emulationViewController; + + +#pragma mark - +#pragma mark Application lifecycle + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + + [[UIApplication sharedApplication] setIdleTimerDisabled:YES]; + + settingsViewController = [[SettingsViewController alloc] init]; + // access the view property to force it to load + settingsViewController.view = settingsViewController.view; + + controlPadConnectViewController = [[ControlPadConnectViewController alloc] init]; + controlPadManager = [[ControlPadManager alloc] init]; + + + NSString *documentsPath = @"/var/mobile/Media"; + romDirectoryPath = [[documentsPath stringByAppendingPathComponent:@"ROMs/SNES/"] retain]; + saveDirectoryPath = [[romDirectoryPath stringByAppendingPathComponent:@"saves"] retain]; + snapshotDirectoryPath = [[saveDirectoryPath stringByAppendingPathComponent:@"snapshots"] retain]; + + // Make the main emulator view controller + emulationViewController = [[EmulationViewController alloc] init]; + emulationViewController.view.hidden = YES; + + + // Add the split view controller's view to the window and display. + [window addSubview:splitViewController.view]; + + // Add the emulation view in its hidden state. + [window addSubview:emulationViewController.view]; + + [window makeKeyAndVisible]; + + return YES; +} + + +- (void)applicationWillTerminate:(UIApplication *)application { + // Save data if appropriate +} + +- (void) showEmulator:(BOOL)showOrHide +{ + if (showOrHide) { + self.splitViewController.view.hidden = YES; + self.emulationViewController.view.hidden = NO; + [[UIApplication sharedApplication] setStatusBarHidden:YES animated:NO]; + } else { + self.emulationViewController.view.hidden = YES; + self.splitViewController.view.hidden = NO; + [[UIApplication sharedApplication] setStatusBarHidden:NO animated:NO]; + } +} + + + +#pragma mark - +#pragma mark Memory management + +- (void)dealloc { + [romDirectoryPath release]; + [settingsViewController release]; + [romDetailViewController release]; + [romSelectionViewController release]; + [controlPadManager release]; + [controlPadConnectViewController release]; + [splitViewController release]; + [window release]; + [super dealloc]; +} + + +@end + diff --git a/Classes/SaveStateSelectionViewController.h b/Classes/SaveStateSelectionViewController.h new file mode 100644 index 0000000..14bfb9b --- /dev/null +++ b/Classes/SaveStateSelectionViewController.h @@ -0,0 +1,33 @@ +// +// SaveStateSelectionViewController.h +// SNES4iPad +// +// Created by Yusef Napora on 5/10/10. +// Copyright 2010 __MyCompanyName__. All rights reserved. +// + +#import + + +@interface SaveStateSelectionViewController : UIViewController { + NSArray* saveFiles; + + NSString *romFilter; + NSString *selectedSavePath; + NSString *selectedScreenshotPath; + + UIBarButtonItem *editButton; + + UITableView *saveTableView; +} + +@property (nonatomic, retain) NSString *romFilter; +@property (nonatomic, readonly) NSString *selectedSavePath; +@property (nonatomic, readonly) NSString *selectedScreenshotPath; +@property (nonatomic, retain) IBOutlet UITableView *saveTableView; +@property (nonatomic, retain) IBOutlet UIBarButtonItem *editButton; + +- (void) scanSaveDirectory; +- (IBAction) buttonPressed:(id)sender; +- (void) deleteSaveAtIndex:(NSUInteger)saveIndex; +@end diff --git a/Classes/SaveStateSelectionViewController.m b/Classes/SaveStateSelectionViewController.m new file mode 100644 index 0000000..f18ee96 --- /dev/null +++ b/Classes/SaveStateSelectionViewController.m @@ -0,0 +1,344 @@ +// +// SaveStateSelectionViewController.m +// SNES4iPad +// +// Created by Yusef Napora on 5/10/10. +// Copyright 2010 __MyCompanyName__. All rights reserved. +// + +#import "SNES4iPadAppDelegate.h" +#import "SaveStateSelectionViewController.h" +#import + +@implementation SaveStateSelectionViewController + +@synthesize romFilter, selectedSavePath, selectedScreenshotPath, saveTableView, editButton; + +#pragma mark - +#pragma mark View lifecycle + +- (void) awakeFromNib +{ + saveFiles = [[NSMutableArray alloc] init]; + +} + + +- (void)viewDidLoad { + [super viewDidLoad]; + + CGRect tableFrame = self.view.bounds; + tableFrame.size.height -= 44; + tableFrame.origin.y += 44; + + saveTableView = [[UITableView alloc] initWithFrame:tableFrame style:UITableViewStylePlain]; + saveTableView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; + saveTableView.dataSource = self; + saveTableView.delegate = self; + + [self.view addSubview:saveTableView]; +} + + +/* +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; +} +*/ +/* +- (void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; +} +*/ +/* +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; +} +*/ +/* +- (void)viewDidDisappear:(BOOL)animated { + [super viewDidDisappear:animated]; +} +*/ + + +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { + // Override to allow orientations other than the default portrait orientation. + return YES; +} + + +- (void) scanSaveDirectory +{ + if (!self.romFilter) { + return; + } + + + NSMutableArray *saveArray = [[NSMutableArray alloc] init]; + NSString *saveDir; + NSString *path = AppDelegate().saveDirectoryPath; + if([[path substringWithRange:NSMakeRange([path length]-1,1)] compare:@"/"] == NSOrderedSame) + { + saveDir = path; + } + else + { + saveDir = [path stringByAppendingString:@"/"]; + } + + int i; + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSArray* dirContents = [fileManager directoryContentsAtPath: saveDir]; + NSInteger entries = [dirContents count]; + + + 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 ]; + // only add saves for the rom we care about + if (objectTitle.length > romFilter.length) { + NSString *romComparison = [objectTitle substringToIndex:[romFilter length]]; + if (![romComparison isEqual:romFilter]) { + continue; + } + + [saveArray addObject:objectTitle]; + } + } + } + + // sort the array by decending filename (reverse chronological order, since the date is in the filename) + NSSortDescriptor *sorter = [[NSSortDescriptor alloc] initWithKey:@"description" ascending:NO]; + if (saveFiles) + { + [saveFiles release]; + } + saveFiles = [[saveArray sortedArrayUsingDescriptors:[NSArray arrayWithObject:sorter]] retain]; + [saveArray release]; + + [self.saveTableView reloadData]; + +} + +- (IBAction) buttonPressed:(id)sender +{ + if (sender == editButton) + { + if (saveTableView.editing) + { + editButton.title = @"Edit"; + saveTableView.editing = NO; + } else { + editButton.title = @"Done"; + saveTableView.editing = YES; + } + } +} + +- (void) deleteSaveAtIndex:(NSUInteger)saveIndex +{ + NSString *savePath = [[AppDelegate() saveDirectoryPath] stringByAppendingPathComponent: + [saveFiles objectAtIndex:saveIndex]]; + NSString *screenshotPath = [savePath stringByAppendingPathExtension:@"png"]; + + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSError *error = nil; + if ([fileManager fileExistsAtPath:savePath]) { + [fileManager removeItemAtPath:savePath error:&error]; + } + if ([fileManager fileExistsAtPath:screenshotPath]) { + [fileManager removeItemAtPath:screenshotPath error:&error]; + } + + if (!error) { + NSMutableArray *mutableSaves = [saveFiles mutableCopy]; + + [mutableSaves removeObjectAtIndex:saveIndex]; + [saveFiles release]; + saveFiles = [[NSArray alloc] initWithArray:mutableSaves]; + [mutableSaves release]; + + NSIndexPath *indexPath = [NSIndexPath indexPathForRow:saveIndex inSection:0]; + [saveTableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES]; + } +} + +#pragma mark - +#pragma mark Table view data source + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + return 1; +} + + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + if([saveFiles count] <= 0) + { + return 0; + } + + return [saveFiles count]; +} + + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + UITableViewCell* cell; + + cell = [tableView dequeueReusableCellWithIdentifier:@"labelCell"]; + if (cell == nil) + { + cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:@"labelCell"] autorelease]; + cell.textLabel.numberOfLines = 1; + cell.textLabel.adjustsFontSizeToFitWidth = YES; + cell.textLabel.minimumFontSize = 9.0f; + cell.textLabel.lineBreakMode = UILineBreakModeMiddleTruncation; + } + + cell.accessoryType = UITableViewCellAccessoryNone; + + if([saveFiles count] <= 0) + { + cell.textLabel.text = @""; + return cell; + } + + NSString *saveName = [saveFiles objectAtIndex:indexPath.row]; + NSString *dateString = [saveName substringFromIndex:[self.romFilter length]]; + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; + [dateFormatter setDateFormat:@"'-'yyMMdd-HHmmss'.sv'"]; + NSDate *saveDate = [dateFormatter dateFromString:dateString]; + + [dateFormatter setDateFormat:@"EEE',' MMM d',' yyyy 'at' h:mm:ss a"]; + + + cell.textLabel.text = [dateFormatter stringFromDate:saveDate]; + [dateFormatter release]; + + // Set up the cell + return cell; +} + + + +// Override to support conditional editing of the table view. +- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { + // Return NO if you do not want the specified item to be editable. + return YES; +} + + + + +// Override to support editing the table view. +- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { + + if (editingStyle == UITableViewCellEditingStyleDelete) { + [self deleteSaveAtIndex:indexPath.row]; + } + else 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 to support rearranging the table view. +- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath { +} +*/ + + +/* +// Override to support conditional rearranging of the table view. +- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath { + // Return NO if you do not want the item to be re-orderable. + return YES; +} +*/ + + +#pragma mark - +#pragma mark Table view delegate + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + if([saveFiles count] <= 0) + { + return; + } + + NSString *listingsPath = AppDelegate().saveDirectoryPath; + NSString *saveFile = [saveFiles objectAtIndex:indexPath.row]; + + NSString *savePath = [listingsPath stringByAppendingPathComponent:saveFile]; + + NSFileManager *fileManager = [NSFileManager defaultManager]; + NSString *screenshotFile = [saveFile stringByAppendingPathExtension:@"png"]; + NSString *screenshotPath = [AppDelegate().saveDirectoryPath stringByAppendingPathComponent:screenshotFile]; + + [self willChangeValueForKey:@"selectedScreenshotPath"]; + if (selectedScreenshotPath) + { + [selectedScreenshotPath release]; + selectedScreenshotPath = nil; + } + + NSLog(@"Looking for screenshot at %@", screenshotPath); + if ([fileManager fileExistsAtPath:screenshotPath]) + { + NSLog(@"Found screenshot at %@", screenshotPath); + selectedScreenshotPath = [screenshotPath retain]; + } + [self didChangeValueForKey:@"selectedScreenshotPath"]; + + + if (selectedSavePath) + { + [selectedSavePath release]; + } + [self willChangeValueForKey:@"selectedSavePath"]; + selectedSavePath = [savePath retain]; + [self didChangeValueForKey:@"selectedSavePath"]; + + + + +} + + +#pragma mark - +#pragma mark Memory management + +- (void)didReceiveMemoryWarning { + // Releases the view if it doesn't have a superview. + [super didReceiveMemoryWarning]; + + // Relinquish ownership any cached data, images, etc that aren't in use. +} + +- (void)viewDidUnload { + // Relinquish ownership of anything that can be recreated in viewDidLoad or on demand. + // For example: self.myOutlet = nil; +} + + +- (void)dealloc { + [super dealloc]; + [saveFiles release]; + [romFilter release]; + [selectedSavePath release]; +} + + +@end + diff --git a/Classes/ScreenLayer.h b/Classes/ScreenLayer.h new file mode 100644 index 0000000..6731d34 --- /dev/null +++ b/Classes/ScreenLayer.h @@ -0,0 +1,21 @@ +// +// ScreenLayer.h +// SNES4iPad +// +// Created by Yusef Napora on 5/15/10. +// Copyright 2010 __MyCompanyName__. All rights reserved. +// + +#import +#import +#import "IOSurface/IOSurface.h" + +@interface ScreenLayer : CALayer { + IOSurfaceRef _surface; + uint32_t _seed; + CGAffineTransform rotateTransform; +} + +- (void) orientationChanged:(NSNotification *)notification; + +@end diff --git a/Classes/ScreenLayer.m b/Classes/ScreenLayer.m new file mode 100644 index 0000000..4b9439e --- /dev/null +++ b/Classes/ScreenLayer.m @@ -0,0 +1,105 @@ +// +// ScreenLayer.m +// SNES4iPad +// +// Created by Yusef Napora on 5/15/10. +// Copyright 2010 __MyCompanyName__. All rights reserved. +// + +#import "ScreenLayer.h" +#import "SettingsViewController.h" + +#import +#define RADIANS( degrees ) ( degrees * M_PI / 180 ) + +unsigned int *screenPixels; +@implementation ScreenLayer + ++ (id) defaultActionForKey:(NSString *)key +{ + return nil; +} + +- (id)init { + if (self = [super init]) + { + NSLog(@"creating IOSurface buffer"); + CFMutableDictionaryRef dict; + int w = 256; + int h = 224; + int pitch = w * 2, allocSize = 2 * w * h; + int bytesPerElement = 2; + char pixelFormat[4] = {'5', '6', '5', 'L'}; + + dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, + &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFDictionarySetValue(dict, kIOSurfaceIsGlobal, kCFBooleanTrue); + CFDictionarySetValue(dict, kIOSurfaceBytesPerRow, + CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &pitch)); + CFDictionarySetValue(dict, kIOSurfaceBytesPerElement, + CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &bytesPerElement)); + CFDictionarySetValue(dict, kIOSurfaceWidth, + CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &w)); + CFDictionarySetValue(dict, kIOSurfaceHeight, + CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &h)); + CFDictionarySetValue(dict, kIOSurfacePixelFormat, + CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, pixelFormat)); + CFDictionarySetValue(dict, kIOSurfaceAllocSize, + CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &allocSize)); + + _surface = IOSurfaceCreate(dict); + + NSLog(@"created IOSurface at %p", _surface); + + screenPixels = IOSurfaceGetBaseAddress(_surface); + NSLog(@"Base address: %p", screenPixels); + + rotateTransform = CGAffineTransformMakeRotation(RADIANS(90)); + self.affineTransform = rotateTransform; + if ([SettingsController().smoothScaling isOn]) + { + [self setMagnificationFilter: kCAFilterLinear]; + } else { + [self setMagnificationFilter: kCAFilterNearest]; + } + + if (1) { + [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(orientationChanged:) + name:@"UIDeviceOrientationDidChangeNotification" + object:nil]; + } + } + return self; +} + + +- (void)display { + //NSLog(@"ScreenLayer display"); + IOSurfaceLock(_surface, 1, &_seed); + self.affineTransform = CGAffineTransformIdentity; + self.contents = nil; + self.affineTransform = rotateTransform; + self.contents = (id) _surface; + IOSurfaceUnlock(_surface, 1, &_seed); +} + +- (void) orientationChanged:(NSNotification *)notification +{ + UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation]; + if (orientation == UIDeviceOrientationLandscapeLeft) { + rotateTransform = CGAffineTransformMakeRotation(RADIANS(90)); + } else if (orientation == UIDeviceOrientationLandscapeRight) { + rotateTransform = CGAffineTransformMakeRotation(RADIANS(270)); + } + +} + + +- (void)dealloc { + [super dealloc]; +} + + +@end diff --git a/Classes/ScreenView.h b/Classes/ScreenView.h new file mode 100644 index 0000000..d673b55 --- /dev/null +++ b/Classes/ScreenView.h @@ -0,0 +1,16 @@ +// +// ScreenView.h +// SNES4iPad +// +// Created by Yusef Napora on 5/15/10. +// Copyright 2010 __MyCompanyName__. All rights reserved. +// + +#import + +@interface ScreenView : UIView { + +} + + +@end diff --git a/Classes/ScreenView.m b/Classes/ScreenView.m new file mode 100644 index 0000000..4f6f408 --- /dev/null +++ b/Classes/ScreenView.m @@ -0,0 +1,96 @@ +// +// ScreenView.m +// SNES4iPad +// +// Created by Yusef Napora on 5/15/10. +// Copyright 2010 __MyCompanyName__. All rights reserved. +// + +#import + +#import "ScreenView.h" +#import "ScreenLayer.h" +#import "SettingsViewController.h" +#import "SNES4iPadAppDelegate.h" + +extern volatile int __emulation_run; +extern volatile int __emulation_paused; +extern volatile int __emulation_saving; +extern void clearFramebuffer(void); + +@implementation ScreenView + ++ (Class) layerClass +{ + return [ScreenLayer class]; +} + +- (id) initWithFrame:(CGRect)f +{ + if (self = [super initWithFrame:f]) + { + NSLog(@"ScreenView init"); + self.clearsContextBeforeDrawing = NO; + } + return self; +} + + +// Wierd things happen without this empty drawRect +- (void)drawRect:(CGRect)rect { + // [self update]; + //[self.layer display]; +} + + + +- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event +{ + UITouch *touch = [touches anyObject]; + if (touch.tapCount == 2) { + + UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:@"Select an option" + delegate:self + cancelButtonTitle:nil destructiveButtonTitle:@"Quit Game" + otherButtonTitles:@"Save State", @"Save State to New File", nil]; + + CGPoint touchPoint = [touch locationInView:self]; + CGRect rect = CGRectMake(touchPoint.x, touchPoint.y, 60, 60); + + __emulation_paused = 1; + //clearFramebuffer(); + [sheet showFromRect:rect inView:self animated:YES]; + } +} + +- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex +{ + NSInteger quitIndex = [actionSheet destructiveButtonIndex]; + NSInteger saveCurrentIndex = [actionSheet firstOtherButtonIndex]; + NSInteger saveNewIndex = saveCurrentIndex + 1; + + if (buttonIndex == quitIndex) { + NSLog(@"Quit button clicked"); + __emulation_run = 0; + [AppDelegate() showEmulator:NO]; + } else if (buttonIndex == saveCurrentIndex) { + NSLog(@"save to current file button clicked"); + __emulation_saving = 2; + } else if (buttonIndex == saveNewIndex) { + NSLog(@"save to new file button clicked"); + __emulation_saving = 1; + } + + [actionSheet dismissWithClickedButtonIndex:buttonIndex animated:YES]; + [actionSheet release]; + __emulation_paused = 0; + +} + + +- (void)dealloc { + [super dealloc]; +} + + +@end diff --git a/Classes/SettingsViewController.h b/Classes/SettingsViewController.h new file mode 100644 index 0000000..b80fc26 --- /dev/null +++ b/Classes/SettingsViewController.h @@ -0,0 +1,37 @@ +// +// SettingsViewController.h +// SNES4iPad +// +// Created by Yusef Napora on 5/10/10. +// Copyright 2010 __MyCompanyName__. All rights reserved. +// + +#import + + + +@interface SettingsViewController : UIViewController { + UISwitch* autosave; + UISwitch* smoothScaling; + UISwitch* fpsDisplay; + UISwitch* transparency; + UISwitch* speedHack; + UISwitch* multiTap; + UISwitch* autoconnect; +} + +@property (nonatomic, retain) IBOutlet UISwitch* autosave; +@property (nonatomic, retain) IBOutlet UISwitch* smoothScaling; +@property (nonatomic, retain) IBOutlet UISwitch* fpsDisplay; +@property (nonatomic, retain) IBOutlet UISwitch* transparency; +@property (nonatomic, retain) IBOutlet UISwitch* speedHack; +@property (nonatomic, retain) IBOutlet UISwitch* multiTap; +@property (nonatomic, retain) IBOutlet UISwitch* autoconnect; + +- (IBAction) settingChanged:(id)sender; + + +@end + +// Global accessor +extern SettingsViewController *SettingsController(); \ No newline at end of file diff --git a/Classes/SettingsViewController.m b/Classes/SettingsViewController.m new file mode 100644 index 0000000..682935f --- /dev/null +++ b/Classes/SettingsViewController.m @@ -0,0 +1,136 @@ + // +// SettingsViewController.m +// SNES4iPad +// +// Created by Yusef Napora on 5/10/10. +// Copyright 2010 __MyCompanyName__. All rights reserved. +// + +#import "SNES4iPadAppDelegate.h" +#import "SettingsViewController.h" +#import "RomDetailViewController.h" + +#define USER_DEFAULT_KEY_AUTOSAVE @"Autosave" +#define USER_DEFAULT_KEY_SMOOTH_SCALING @"SmoothScaling" +#define USER_DEFAULT_KEY_FPS_DISPLAY @"FPSDisplay" +#define USER_DEFAULT_KEY_TRANSPARENCY @"Transparency" +#define USER_DEFAULT_KEY_SPEED_HACK @"SpeedHack" +#define USER_DEFAULT_KEY_MULTI_TAP @"MultiTap" +#define USER_DEFAULT_KEY_AUTOCONNECT @"Autoconnect" + +unsigned long __fps_debug = 0; +int iphone_soundon = 1; +int __autosave = 0; +int __transparency = 0; +int __speedhack = 0; +int __smooth_scaling = 0; + +SettingsViewController *SettingsController() +{ + return AppDelegate().settingsViewController; +} + +@implementation SettingsViewController + +@synthesize autosave, smoothScaling, fpsDisplay, transparency, speedHack, multiTap, autoconnect; + + +- (void) viewDidLoad +{ + NSDictionary *firstRunValues = [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithBool:NO], USER_DEFAULT_KEY_AUTOSAVE, + [NSNumber numberWithBool:YES], USER_DEFAULT_KEY_SMOOTH_SCALING, + [NSNumber numberWithBool:NO], USER_DEFAULT_KEY_FPS_DISPLAY, + [NSNumber numberWithBool:YES], USER_DEFAULT_KEY_TRANSPARENCY, + [NSNumber numberWithBool:NO], USER_DEFAULT_KEY_SPEED_HACK, + [NSNumber numberWithBool:NO], USER_DEFAULT_KEY_MULTI_TAP, + [NSNumber numberWithBool:YES], USER_DEFAULT_KEY_AUTOCONNECT, + nil]; + + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + + for (NSString *defaultKey in [firstRunValues allKeys]) + { + NSNumber *value = [defaults objectForKey:defaultKey]; + if (!value) + { + value = [firstRunValues objectForKey:defaultKey]; + [defaults setObject:value forKey:defaultKey]; + } + } + + [autosave setOn:[defaults boolForKey:USER_DEFAULT_KEY_AUTOSAVE]]; + [smoothScaling setOn:[defaults boolForKey:USER_DEFAULT_KEY_SMOOTH_SCALING]]; + [fpsDisplay setOn:[defaults boolForKey:USER_DEFAULT_KEY_FPS_DISPLAY]]; + [transparency setOn:[defaults boolForKey:USER_DEFAULT_KEY_TRANSPARENCY]]; + [speedHack setOn:[defaults boolForKey:USER_DEFAULT_KEY_SPEED_HACK]]; + [multiTap setOn:[defaults boolForKey:USER_DEFAULT_KEY_MULTI_TAP]]; + [autoconnect setOn:[defaults boolForKey:USER_DEFAULT_KEY_AUTOCONNECT]]; + + [self settingChanged:nil]; +} + + + +- (void) viewDidAppear:(BOOL)animated +{ + self.contentSizeForViewInPopover = CGSizeMake(320, 300); +} + +- (IBAction) settingChanged:(id)sender +{ + NSString *defaultKey = nil; + if (sender == autosave) defaultKey = USER_DEFAULT_KEY_AUTOSAVE; + else if (sender == smoothScaling) defaultKey = USER_DEFAULT_KEY_SMOOTH_SCALING; + else if (sender == fpsDisplay) defaultKey = USER_DEFAULT_KEY_FPS_DISPLAY; + else if (sender == transparency) defaultKey = USER_DEFAULT_KEY_TRANSPARENCY; + else if (sender == speedHack) defaultKey = USER_DEFAULT_KEY_SPEED_HACK; + else if (sender == multiTap) defaultKey = USER_DEFAULT_KEY_MULTI_TAP; + else if (sender == autoconnect) defaultKey = USER_DEFAULT_KEY_AUTOCONNECT; + + if (defaultKey) + { + UISwitch *toggle = (UISwitch *)sender; + [[NSUserDefaults standardUserDefaults] setBool:[toggle isOn] forKey:defaultKey]; + } + + __fps_debug = [fpsDisplay isOn]; + __autosave = [autosave isOn]; + __transparency = [transparency isOn]; + __speedhack = [speedHack isOn]; + __smooth_scaling = [smoothScaling isOn]; + + if (sender == multiTap) + { + AppDelegate().romDetailViewController.multiTapView.hidden = ![multiTap isOn]; + } +} + + +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { + // Overriden to allow any orientation. + return YES; +} + + +- (void)didReceiveMemoryWarning { + // Releases the view if it doesn't have a superview. + [super didReceiveMemoryWarning]; + + // Release any cached data, images, etc that aren't in use. +} + + +- (void)viewDidUnload { + [super viewDidUnload]; + // Release any retained subviews of the main view. + // e.g. self.myOutlet = nil; +} + + +- (void)dealloc { + [super dealloc]; +} + + +@end diff --git a/CoreSurface/CoreSurface.h b/CoreSurface/CoreSurface.h new file mode 100755 index 0000000..7527382 --- /dev/null +++ b/CoreSurface/CoreSurface.h @@ -0,0 +1,52 @@ +#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 CoreSurfaceBufferGetWidth(CoreSurfaceBufferRef surface); +unsigned int CoreSurfaceBufferGetBytesPerRow(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/IOKit/IOKitKeys.h b/IOKit/IOKitKeys.h new file mode 100644 index 0000000..62395d5 --- /dev/null +++ b/IOKit/IOKitKeys.h @@ -0,0 +1,164 @@ +/* + * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * + * Common symbol definitions for IOKit. + * + * HISTORY + * + */ + + +#ifndef _IOKIT_IOKITKEYS_H +#define _IOKIT_IOKITKEYS_H + +// properties found in the registry root +#define kIOKitBuildVersionKey "IOKitBuildVersion" +#define kIOKitDiagnosticsKey "IOKitDiagnostics" + // a dictionary keyed by plane name +#define kIORegistryPlanesKey "IORegistryPlanes" +#define kIOCatalogueKey "IOCatalogue" + +// registry plane names +#define kIOServicePlane "IOService" +#define kIOPowerPlane "IOPower" +#define kIODeviceTreePlane "IODeviceTree" +#define kIOAudioPlane "IOAudio" +#define kIOFireWirePlane "IOFireWire" +#define kIOUSBPlane "IOUSB" + +// registry ID number +#define kIORegistryEntryIDKey "IORegistryEntryID" + +// IOService class name +#define kIOServiceClass "IOService" + +// IOResources class name +#define kIOResourcesClass "IOResources" + +// IOService driver probing property names +#define kIOClassKey "IOClass" +#define kIOProbeScoreKey "IOProbeScore" +#define kIOKitDebugKey "IOKitDebug" + +// IOService matching property names +#define kIOProviderClassKey "IOProviderClass" +#define kIONameMatchKey "IONameMatch" +#define kIOPropertyMatchKey "IOPropertyMatch" +#define kIOPathMatchKey "IOPathMatch" +#define kIOLocationMatchKey "IOLocationMatch" +#define kIOParentMatchKey "IOParentMatch" +#define kIOResourceMatchKey "IOResourceMatch" +#define kIOMatchedServiceCountKey "IOMatchedServiceCountMatch" + +#define kIONameMatchedKey "IONameMatched" + +#define kIOMatchCategoryKey "IOMatchCategory" +#define kIODefaultMatchCategoryKey "IODefaultMatchCategory" + +// IOService default user client class, for loadable user clients +#define kIOUserClientClassKey "IOUserClientClass" + +// key to find IOMappers +#define kIOMapperIDKey "IOMapperID" + +#define kIOUserClientCrossEndianKey "IOUserClientCrossEndian" +#define kIOUserClientCrossEndianCompatibleKey "IOUserClientCrossEndianCompatible" +#define kIOUserClientSharedInstanceKey "IOUserClientSharedInstance" +// diagnostic string describing the creating task +#define kIOUserClientCreatorKey "IOUserClientCreator" + +// IOService notification types +#define kIOPublishNotification "IOServicePublish" +#define kIOFirstPublishNotification "IOServiceFirstPublish" +#define kIOMatchedNotification "IOServiceMatched" +#define kIOFirstMatchNotification "IOServiceFirstMatch" +#define kIOTerminatedNotification "IOServiceTerminate" + +// IOService interest notification types +#define kIOGeneralInterest "IOGeneralInterest" +#define kIOBusyInterest "IOBusyInterest" +#define kIOAppPowerStateInterest "IOAppPowerStateInterest" +#define kIOPriorityPowerStateInterest "IOPriorityPowerStateInterest" + +#define kIOPlatformDeviceMessageKey "IOPlatformDeviceMessage" + +// IOService interest notification types +#define kIOCFPlugInTypesKey "IOCFPlugInTypes" + +// properties found in services that implement command pooling +#define kIOCommandPoolSizeKey "IOCommandPoolSize" // (OSNumber) + +// properties found in services that have transfer constraints +#define kIOMaximumBlockCountReadKey "IOMaximumBlockCountRead" // (OSNumber) +#define kIOMaximumBlockCountWriteKey "IOMaximumBlockCountWrite" // (OSNumber) +#define kIOMaximumByteCountReadKey "IOMaximumByteCountRead" // (OSNumber) +#define kIOMaximumByteCountWriteKey "IOMaximumByteCountWrite" // (OSNumber) +#define kIOMaximumSegmentCountReadKey "IOMaximumSegmentCountRead" // (OSNumber) +#define kIOMaximumSegmentCountWriteKey "IOMaximumSegmentCountWrite" // (OSNumber) +#define kIOMaximumSegmentByteCountReadKey "IOMaximumSegmentByteCountRead" // (OSNumber) +#define kIOMaximumSegmentByteCountWriteKey "IOMaximumSegmentByteCountWrite" // (OSNumber) +#define kIOMinimumSegmentAlignmentByteCountKey "IOMinimumSegmentAlignmentByteCount" // (OSNumber) +#define kIOMaximumSegmentAddressableBitCountKey "IOMaximumSegmentAddressableBitCount" // (OSNumber) + +// properties found in services that wish to describe an icon +// +// IOIcon = +// { +// CFBundleIdentifier = "com.example.driver.example"; +// IOBundleResourceFile = "example.icns"; +// }; +// +// where IOBundleResourceFile is the filename of the resource + +#define kIOIconKey "IOIcon" // (OSDictionary) +#define kIOBundleResourceFileKey "IOBundleResourceFile" // (OSString) + +#define kIOBusBadgeKey "IOBusBadge" // (OSDictionary) +#define kIODeviceIconKey "IODeviceIcon" // (OSDictionary) + +// property of root that describes the machine's serial number as a string +#define kIOPlatformSerialNumberKey "IOPlatformSerialNumber" // (OSString) + +// property of root that describes the machine's UUID as a string +#define kIOPlatformUUIDKey "IOPlatformUUID" // (OSString) + +// IODTNVRAM property keys +#define kIONVRAMDeletePropertyKey "IONVRAM-DELETE-PROPERTY" +#define kIODTNVRAMPanicInfoKey "aapl,panic-info" + +// keys for complex boot information +#define kIOBootDeviceKey "IOBootDevice" // dict | array of dicts +#define kIOBootDevicePathKey "IOBootDevicePath" // arch-neutral OSString +#define kIOBootDeviceSizeKey "IOBootDeviceSize" // OSNumber of bytes + +// keys for OS Version information +#define kOSBuildVersionKey "OS Build Version" + +#endif /* ! _IOKIT_IOKITKEYS_H */ diff --git a/IOKit/IOKitLib.h b/IOKit/IOKitLib.h new file mode 100644 index 0000000..9827f42 --- /dev/null +++ b/IOKit/IOKitLib.h @@ -0,0 +1,1424 @@ +/* + * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 1.1 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ +/* + * HISTORY + * + */ + +/* + * IOKit user library + */ + +#ifndef _IOKIT_IOKITLIB_H +#define _IOKIT_IOKITLIB_H + +#ifdef KERNEL +#error This file is not for kernel use +#endif + +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include + +#include + +#include + +__BEGIN_DECLS + +/*! @header IOKitLib +IOKitLib implements non-kernel task access to common IOKit object types - IORegistryEntry, IOService, IOIterator etc. These functions are generic - families may provide API that is more specific.
+IOKitLib represents IOKit objects outside the kernel with the types io_object_t, io_registry_entry_t, io_service_t, & io_connect_t. Function names usually begin with the type of object they are compatible with - eg. IOObjectRelease can be used with any io_object_t. Inside the kernel, the c++ class hierarchy allows the subclasses of each object type to receive the same requests from user level clients, for example in the kernel, IOService is a subclass of IORegistryEntry, which means any of the IORegistryEntryXXX functions in IOKitLib may be used with io_service_t's as well as io_registry_t's. There are functions available to introspect the class of the kernel object which any io_object_t et al. represents. +IOKit objects returned by all functions should be released with IOObjectRelease. +*/ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +typedef struct IONotificationPort * IONotificationPortRef; + + +/*! @typedef IOServiceMatchingCallback + @abstract Callback function to be notified of IOService publication. + @param refcon The refcon passed when the notification was installed. + @param iterator The notification iterator which now has new objects. +*/ +typedef void +(*IOServiceMatchingCallback)( + void * refcon, + io_iterator_t iterator ); + +/*! @typedef IOServiceInterestCallback + @abstract Callback function to be notified of changes in state of an IOService. + @param refcon The refcon passed when the notification was installed. + @param service The IOService whose state has changed. + @param messageType A messageType enum, defined by IOKit/IOMessage.h or by the IOService's family. + @param messageArgument An argument for the message, dependent on the messageType. +*/ + +typedef void +(*IOServiceInterestCallback)( + void * refcon, + io_service_t service, + uint32_t messageType, + void * messageArgument ); + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*! @const kIOMasterPortDefault + @abstract The default mach port used to initiate communication with IOKit. + @discussion When specifying a master port to IOKit functions, the NULL argument indicates "use the default". This is a synonym for NULL, if you'd rather use a named constant. +*/ + +extern +const mach_port_t kIOMasterPortDefault; + +/*! @function IOMasterPort + @abstract Returns the mach port used to initiate communication with IOKit. + @discussion Functions that don't specify an existing object require the IOKit master port to be passed. This function obtains that port. + @param bootstrapPort Pass MACH_PORT_NULL for the default. + @param masterPort The master port is returned. + @result A kern_return_t error code. */ + +kern_return_t +IOMasterPort( mach_port_t bootstrapPort, + mach_port_t * masterPort ); + + +/*! @function IONotificationPortCreate + @abstract Creates and returns a notification object for receiving IOKit notifications of new devices or state changes. + @discussion Creates the notification object to receive notifications from IOKit of new device arrivals or state changes. The notification object can be supply a CFRunLoopSource, or mach_port_t to be used to listen for events. + @param masterPort The master port obtained from IOMasterPort(). Pass kIOMasterPortDefault to look up the default master port. + @result A reference to the notification object. */ + +IONotificationPortRef +IONotificationPortCreate( + mach_port_t masterPort ); + +/*! @function IONotificationPortDestroy + @abstract Destroys a notification object created with IONotificationPortCreate. + @param notify A reference to the notification object. */ + +void +IONotificationPortDestroy( + IONotificationPortRef notify ); + +/*! @function IONotificationPortGetRunLoopSource + @abstract Returns a CFRunLoopSource to be used to listen for notifications. + @discussion A notification object may deliver notifications to a CFRunLoop client by adding the run loop source returned by this function to the run loop. + @param notify The notification object. + @result A CFRunLoopSourceRef for the notification object. */ + +CFRunLoopSourceRef +IONotificationPortGetRunLoopSource( + IONotificationPortRef notify ); + +/*! @function IONotificationPortGetMachPort + @abstract Returns a mach_port to be used to listen for notifications. + @discussion A notification object may deliver notifications to a mach messaging client if they listen for messages on the port obtained from this function. Callbacks associated with the notifications may be delivered by calling IODispatchCalloutFromMessage with messages received + @param notify The notification object. + @result A mach_port for the notification object. */ + +mach_port_t +IONotificationPortGetMachPort( + IONotificationPortRef notify ); + +/*! @function IODispatchCalloutFromMessage + @abstract Dispatches callback notifications from a mach message. + @discussion A notification object may deliver notifications to a mach messaging client, which should call this function to generate the callbacks associated with the notifications arriving on the port. + @param unused Not used, set to zero. + @param msg A pointer to the message received. + @param reference Pass the IONotificationPortRef for the object. */ + +void +IODispatchCalloutFromMessage( + void *unused, + mach_msg_header_t *msg, + void *reference ); + +/*! @function IOCreateReceivePort + @abstract Creates and returns a mach port suitable for receiving IOKit messages of the specified type. + @discussion In the future IOKit may use specialized messages and ports + instead of the standard ports created by mach_port_allocate(). Use this + function instead of mach_port_allocate() to ensure compatibility with future + revisions of IOKit. + @param msgType Type of message to be sent to this port + (kOSNotificationMessageID or kOSAsyncCompleteMessageID) + @param recvPort The created port is returned. + @result A kern_return_t error code. */ + +kern_return_t +IOCreateReceivePort( uint32_t msgType, mach_port_t * recvPort ); + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * IOObject + */ + +/*! @function IOObjectRelease + @abstract Releases an object handle previously returned by IOKitLib. + @discussion All objects returned by IOKitLib should be released with this function when access to them is no longer needed. Using the object after it has been released may or may not return an error, depending on how many references the task has to the same object in the kernel. + @param object The IOKit object to release. + @result A kern_return_t error code. */ + +kern_return_t +IOObjectRelease( + io_object_t object ); + +/*! @function IOObjectRetain + @abstract Retains an object handle previously returned by IOKitLib. + @discussion Gives the caller an additional reference to an existing object handle previously returned by IOKitLib. + @param object The IOKit object to retain. + @result A kern_return_t error code. */ + +kern_return_t +IOObjectRetain( + io_object_t object ); + +/*! @function IOObjectGetClass + @abstract Return the class name of an IOKit object. + @discussion This function uses the OSMetaClass system in the kernel to derive the name of the class the object is an instance of. + @param object The IOKit object. + @param className Caller allocated buffer to receive the name string. + @result A kern_return_t error code. */ + +kern_return_t +IOObjectGetClass( + io_object_t object, + io_name_t className ); + +/*! @function CFStringRef IOObjectCopyClass + @abstract Return the class name of an IOKit object. + @discussion This function does the same thing as IOObjectGetClass, but returns the result as a CFStringRef. + @param object The IOKit object. + @result The resulting CFStringRef. This should be released by the caller. If a valid object is not passed in, then NULL is returned.*/ + +CFStringRef +IOObjectCopyClass(io_object_t object) +AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER; + +/*! @function CFStringRef IOObjectCopySuperclassForClass + @abstract Return the superclass name of the given class. + @discussion This function uses the OSMetaClass system in the kernel to derive the name of the superclass of the class. + @param classname The name of the class as a CFString. + @result The resulting CFStringRef. This should be released by the caller. If there is no superclass, or a valid class name is not passed in, then NULL is returned.*/ + +CFStringRef +IOObjectCopySuperclassForClass(CFStringRef classname) +AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER; + +/*! @function CFStringRef IOObjectCopyBundleIdentifierForClass + @abstract Return the bundle identifier of the given class. + @discussion This function uses the OSMetaClass system in the kernel to derive the name of the kmod, which is the same as the bundle identifier. + @param classname The name of the class as a CFString. + @result The resulting CFStringRef. This should be released by the caller. If a valid class name is not passed in, then NULL is returned.*/ + +CFStringRef +IOObjectCopyBundleIdentifierForClass(CFStringRef classname) +AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER; + +/*! @function IOObjectConformsTo + @abstract Performs an OSDynamicCast operation on an IOKit object. + @discussion This function uses the OSMetaClass system in the kernel to determine if the object will dynamic cast to a class, specified as a C-string. In other words, if the object is of that class or a subclass. + @param object An IOKit object. + @param className The name of the class, as a C-string. + @result If the object handle is valid, and represents an object in the kernel that dynamic casts to the class true is returned, otherwise false. */ + +boolean_t +IOObjectConformsTo( + io_object_t object, + const io_name_t className ); + +/*! @function IOObjectIsEqualTo + @abstract Checks two object handles to see if they represent the same kernel object. + @discussion If two object handles are returned by IOKitLib functions, this function will compare them to see if they represent the same kernel object. + @param object An IOKit object. + @param anObject Another IOKit object. + @result If both object handles are valid, and represent the same object in the kernel true is returned, otherwise false. */ + +boolean_t +IOObjectIsEqualTo( + io_object_t object, + io_object_t anObject ); + +/*! @function IOObjectGetRetainCount + @abstract Returns kernel retain count of an IOKit object. + @discussion This function may be used in diagnostics to determine the current retain count of the kernel object. + @param object An IOKit object. + @result If the object handle is valid, the kernel objects retain count is returned, otherwise zero is returned. */ + +uint32_t +IOObjectGetRetainCount( + io_object_t object ); + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * IOIterator, subclass of IOObject + */ + +/*! @function IOIteratorNext + @abstract Returns the next object in an iteration. + @discussion This function returns the next object in an iteration, or zero if no more remain or the iterator is invalid. + @param iterator An IOKit iterator handle. + @result If the iterator handle is valid, the next element in the iteration is returned, otherwise zero is returned. The element should be released by the caller when it is finished. */ + +io_object_t +IOIteratorNext( + io_iterator_t iterator ); + +/*! @function IOIteratorReset + @abstract Resets an iteration back to the beginning. + @discussion If an iterator is invalid, or if the caller wants to start over, IOIteratorReset will set the iteration back to the beginning. + @param iterator An IOKit iterator handle. */ + +void +IOIteratorReset( + io_iterator_t iterator ); + +/*! @function IOIteratorIsValid + @abstract Checks an iterator is still valid. + @discussion Some iterators will be made invalid if changes are made to the structure they are iterating over. This function checks the iterator is still valid and should be called when IOIteratorNext returns zero. An invalid iterator can be reset and the iteration restarted. + @param iterator An IOKit iterator handle. + @result True if the iterator handle is valid, otherwise false is returned. */ + +boolean_t +IOIteratorIsValid( + io_iterator_t iterator ); + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * IOService, subclass of IORegistryEntry + */ + +/*! + @function IOServiceGetMatchingService + @abstract Look up a registered IOService object that matches a matching dictionary. + @discussion This is the preferred method of finding IOService objects currently registered by IOKit (that is, objects that have had their registerService() methods invoked). To find IOService objects that aren't yet registered, use an iterator as created by IORegistryEntryCreateIterator(). IOServiceAddMatchingNotification can also supply this information and install a notification of new IOServices. The matching information used in the matching dictionary may vary depending on the class of service being looked up. + @param masterPort The master port obtained from IOMasterPort(). Pass kIOMasterPortDefault to look up the default master port. + @param matching A CF dictionary containing matching information, of which one reference is always consumed by this function (Note prior to the Tiger release there was a small chance that the dictionary might not be released if there was an error attempting to serialize the dictionary). IOKitLib can construct matching dictionaries for common criteria with helper functions such as IOServiceMatching, IOServiceNameMatching, IOBSDNameMatching, IOOpenFirmwarePathMatching. + @result The first service matched is returned on success. The service must be released by the caller. + */ + +io_service_t +IOServiceGetMatchingService( + mach_port_t masterPort, + CFDictionaryRef matching ); + +/*! @function IOServiceGetMatchingServices + @abstract Look up registered IOService objects that match a matching dictionary. + @discussion This is the preferred method of finding IOService objects currently registered by IOKit (that is, objects that have had their registerService() methods invoked). To find IOService objects that aren't yet registered, use an iterator as created by IORegistryEntryCreateIterator(). IOServiceAddMatchingNotification can also supply this information and install a notification of new IOServices. The matching information used in the matching dictionary may vary depending on the class of service being looked up. + @param masterPort The master port obtained from IOMasterPort(). Pass kIOMasterPortDefault to look up the default master port. + @param matching A CF dictionary containing matching information, of which one reference is always consumed by this function (Note prior to the Tiger release there was a small chance that the dictionary might not be released if there was an error attempting to serialize the dictionary). IOKitLib can construct matching dictionaries for common criteria with helper functions such as IOServiceMatching, IOServiceNameMatching, IOBSDNameMatching, IOOpenFirmwarePathMatching. + @param existing An iterator handle is returned on success, and should be released by the caller when the iteration is finished. + @result A kern_return_t error code. */ + +kern_return_t +IOServiceGetMatchingServices( + mach_port_t masterPort, + CFDictionaryRef matching, + io_iterator_t * existing ); + + +kern_return_t +IOServiceAddNotification( + mach_port_t masterPort, + const io_name_t notificationType, + CFDictionaryRef matching, + mach_port_t wakePort, + uintptr_t reference, + io_iterator_t * notification ) DEPRECATED_ATTRIBUTE; + +/*! @function IOServiceAddMatchingNotification + @abstract Look up registered IOService objects that match a matching dictionary, and install a notification request of new IOServices that match. + @discussion This is the preferred method of finding IOService objects that may arrive at any time. The type of notification specifies the state change the caller is interested in, on IOService's that match the match dictionary. Notification types are identified by name, and are defined in IOKitKeys.h. The matching information used in the matching dictionary may vary depending on the class of service being looked up. + @param notifyPort A IONotificationPortRef object that controls how messages will be sent when the armed notification is fired. When the notification is delivered, the io_iterator_t representing the notification should be iterated through to pick up all outstanding objects. When the iteration is finished the notification is rearmed. See IONotificationPortCreate. + @param notificationType A notification type from IOKitKeys.h +
kIOPublishNotification Delivered when an IOService is registered. +
kIOFirstPublishNotification Delivered when an IOService is registered, but only once per IOService instance. Some IOService's may be reregistered when their state is changed. +
kIOMatchedNotification Delivered when an IOService has had all matching drivers in the kernel probed and started. +
kIOFirstMatchNotification Delivered when an IOService has had all matching drivers in the kernel probed and started, but only once per IOService instance. Some IOService's may be reregistered when their state is changed. +
kIOTerminatedNotification Delivered after an IOService has been terminated. + @param matching A CF dictionary containing matching information, of which one reference is always consumed by this function (Note prior to the Tiger release there was a small chance that the dictionary might not be released if there was an error attempting to serialize the dictionary). IOKitLib can construct matching dictionaries for common criteria with helper functions such as IOServiceMatching, IOServiceNameMatching, IOBSDNameMatching, IOOpenFirmwarePathMatching. + @param callback A callback function called when the notification fires. + @param refCon A reference constant for the callbacks use. + @param notification An iterator handle is returned on success, and should be released by the caller when the notification is to be destroyed. The notification is armed when the iterator is emptied by calls to IOIteratorNext - when no more objects are returned, the notification is armed. Note the notification is not armed when first created. + @result A kern_return_t error code. */ + +kern_return_t +IOServiceAddMatchingNotification( + IONotificationPortRef notifyPort, + const io_name_t notificationType, + CFDictionaryRef matching, + IOServiceMatchingCallback callback, + void * refCon, + io_iterator_t * notification ); + +/*! @function IOServiceAddInterestNotification + @abstract Register for notification of state changes in an IOService. + @discussion IOService objects deliver notifications of their state changes to their clients via the IOService::message API, and to other interested parties including callers of this function. Message type s are defined IOKit/IOMessage.h. + @param notifyPort A IONotificationPortRef object that controls how messages will be sent when the notification is fired. See IONotificationPortCreate. + @param interestType A notification type from IOKitKeys.h +
kIOGeneralInterest General state changes delivered via the IOService::message API. +
kIOBusyInterest Delivered when the IOService changes its busy state to or from zero. The message argument contains the new busy state causing the notification. + @param callback A callback function called when the notification fires, with messageType and messageArgument for the state change. + @param refCon A reference constant for the callbacks use. + @param notification An object handle is returned on success, and should be released by the caller when the notification is to be destroyed. + @result A kern_return_t error code. */ + +kern_return_t +IOServiceAddInterestNotification( + IONotificationPortRef notifyPort, + io_service_t service, + const io_name_t interestType, + IOServiceInterestCallback callback, + void * refCon, + io_object_t * notification ); + +/*! @function IOServiceMatchPropertyTable + @abstract Match an IOService objects with matching dictionary. + @discussion This function calls the matching method of an IOService object and returns the boolean result. + @param service The IOService object to match. + @param matching A CF dictionary containing matching information. IOKitLib can construct matching dictionaries for common criteria with helper functions such as IOServiceMatching, IOServiceNameMatching, IOBSDNameMatching, IOOpenFirmwarePathMatching. + @param matches The boolean result is returned. + @result A kern_return_t error code. */ + +kern_return_t +IOServiceMatchPropertyTable( + io_service_t service, + CFDictionaryRef matching, + boolean_t * matches ); + +/*! @function IOServiceGetBusyState + @abstract Returns the busyState of an IOService. + @discussion Many activities in IOService are asynchronous. When registration, matching, or termination is in progress on an IOService, its busyState is increased by one. Change in busyState to or from zero also changes the IOService's provider's busyState by one, which means that an IOService is marked busy when any of the above activities is ocurring on it or any of its clients. + @param service The IOService whose busyState to return. + @param busyState The busyState count is returned. + @result A kern_return_t error code. */ + +kern_return_t +IOServiceGetBusyState( + io_service_t service, + uint32_t * busyState ); + +/*! @function IOServiceWaitQuiet + @abstract Wait for an IOService's busyState to be zero. + @discussion Blocks the caller until an IOService is non busy, see IOServiceGetBusyState. + @param service The IOService wait on. + @param waitTime Specifies a maximum time to wait. + @result Returns an error code if mach synchronization primitives fail, kIOReturnTimeout, or kIOReturnSuccess. */ + +kern_return_t +IOServiceWaitQuiet( + io_service_t service, + mach_timespec_t * waitTime ); + +/*! @function IOKitGetBusyState + @abstract Returns the busyState of all IOServices. + @discussion Many activities in IOService are asynchronous. When registration, matching, or termination is in progress on an IOService, its busyState is increased by one. Change in busyState to or from zero also changes the IOService's provider's busyState by one, which means that an IOService is marked busy when any of the above activities is ocurring on it or any of its clients. IOKitGetBusyState returns the busy state of the root of the service plane which reflects the busy state of all IOServices. + @param masterPort The master port obtained from IOMasterPort(). Pass kIOMasterPortDefault to look up the default master port. + @param busyState The busyState count is returned. + @result A kern_return_t error code. */ + +kern_return_t +IOKitGetBusyState( + mach_port_t masterPort, + uint32_t * busyState ); + +/*! @function IOKitWaitQuiet + @abstract Wait for a all IOServices' busyState to be zero. + @discussion Blocks the caller until all IOServices are non busy, see IOKitGetBusyState. + @param masterPort The master port obtained from IOMasterPort(). Pass kIOMasterPortDefault to look up the default master port. + @param waitTime Specifies a maximum time to wait. + @result Returns an error code if mach synchronization primitives fail, kIOReturnTimeout, or kIOReturnSuccess. */ + +kern_return_t +IOKitWaitQuiet( + mach_port_t masterPort, + mach_timespec_t * waitTime ); + +/*! @function IOServiceOpen + @abstract A request to create a connection to an IOService. + @discussion A non kernel client may request a connection be opened via the IOServiceOpen() library function, which will call IOService::newUserClient in the kernel. The rules & capabilities of user level clients are family dependent, the default IOService implementation returns kIOReturnUnsupported. + @param service The IOService object to open a connection to, usually obtained via the IOServiceGetMatchingServices or IOServiceAddNotification APIs. + @param owningTask The mach task requesting the connection. + @param type A constant specifying the type of connection to be created, interpreted only by the IOService's family. + @param connect An io_connect_t handle is returned on success, to be used with the IOConnectXXX APIs. It should be destroyed with IOServiceClose(). + @result A return code generated by IOService::newUserClient. */ + +kern_return_t +IOServiceOpen( + io_service_t service, + task_port_t owningTask, + uint32_t type, + io_connect_t * connect ); + +/*! @function IOServiceRequestProbe + @abstract A request to rescan a bus for device changes. + @discussion A non kernel client may request a bus or controller rescan for added or removed devices, if the bus family does automatically notice such changes. For example, SCSI bus controllers do not notice device changes. The implementation of this routine is family dependent, and the default IOService implementation returns kIOReturnUnsupported. + @param service The IOService object to request a rescan, usually obtained via the IOServiceGetMatchingServices or IOServiceAddNotification APIs. + @param options An options mask, interpreted only by the IOService's family. + @result A return code generated by IOService::requestProbe. */ + +kern_return_t +IOServiceRequestProbe( + io_service_t service, + uint32_t options ); + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * IOService connection + */ + +/*! @function IOServiceClose + @abstract Close a connection to an IOService and destroy the connect handle. + @discussion A connection created with the IOServiceOpen should be closed when the connection is no longer to be used with IOServiceClose. + @param connect The connect handle created by IOServiceOpen. It will be destroyed by this function, and should not be released with IOObjectRelease. + @result A kern_return_t error code. */ + +kern_return_t +IOServiceClose( + io_connect_t connect ); + +/*! @function IOConnectAddRef + @abstract Adds a reference to the connect handle. + @discussion Adds a reference to the connect handle. + @param connect The connect handle created by IOServiceOpen. + @result A kern_return_t error code. */ + +kern_return_t +IOConnectAddRef( + io_connect_t connect ); + +/*! @function IOConnectRelease + @abstract Remove a reference to the connect handle. + @discussion Removes a reference to the connect handle. If the last reference is removed an implicit IOServiceClose is performed. + @param connect The connect handle created by IOServiceOpen. + @result A kern_return_t error code. */ + +kern_return_t +IOConnectRelease( + io_connect_t connect ); + +/*! @function IOConnectGetService + @abstract Returns the IOService a connect handle was opened on. + @discussion Finds the service object a connection was opened on. + @param connect The connect handle created by IOServiceOpen. + @param service On succes, the service handle the connection was opened on, which should be released with IOObjectRelease. + @result A kern_return_t error code. */ + +kern_return_t +IOConnectGetService( + io_connect_t connect, + io_service_t * service ); + +/*! @function IOConnectSetNotificationPort + @abstract Set a port to receive family specific notifications. + @discussion This is a generic method to pass a mach port send right to be be used by family specific notifications. + @param connect The connect handle created by IOServiceOpen. + @param type The type of notification requested, not interpreted by IOKit and family defined. + @param port The port to which to send notifications. + @param reference Some families may support passing a reference parameter for the callers use with the notification. + @result A kern_return_t error code. */ + +kern_return_t +IOConnectSetNotificationPort( + io_connect_t connect, + uint32_t type, + mach_port_t port, + uintptr_t reference ); + +/*! @function IOConnectMapMemory + @abstract Map hardware or shared memory into the caller's task. + @discussion This is a generic method to create a mapping in the callers task. The family will interpret the type parameter to determine what sort of mapping is being requested. Cache modes and placed mappings may be requested by the caller. + @param connect The connect handle created by IOServiceOpen. + @param memoryType What is being requested to be mapped, not interpreted by IOKit and family defined. The family may support physical hardware or shared memory mappings. + @param intoTask The task port for the task in which to create the mapping. This may be different to the task which the opened the connection. + @param atAddress An in/out parameter - if the kIOMapAnywhere option is not set, the caller should pass the address where it requests the mapping be created, otherwise nothing need to set on input. The address of the mapping created is passed back on sucess. + @param ofSize The size of the mapping created is passed back on success. + @result A kern_return_t error code. */ + +#if !__LP64__ +kern_return_t +IOConnectMapMemory( + io_connect_t connect, + uint32_t memoryType, + task_port_t intoTask, + vm_address_t *atAddress, + vm_size_t *ofSize, + IOOptionBits options ); + +kern_return_t IOConnectMapMemory64 +#else +kern_return_t IOConnectMapMemory +#endif + (io_connect_t connect, + uint32_t memoryType, + task_port_t intoTask, + mach_vm_address_t *atAddress, + mach_vm_size_t *ofSize, + IOOptionBits options ); + +/*! @function IOConnectUnmapMemory + @abstract Remove a mapping made with IOConnectMapMemory. + @discussion This is a generic method to remove a mapping in the callers task. + @param connect The connect handle created by IOServiceOpen. + @param memoryType The memory type originally requested in IOConnectMapMemory. + @param intoTask The task port for the task in which to remove the mapping. This may be different to the task which the opened the connection. + @param atAddress The address of the mapping to be removed. + @result A kern_return_t error code. */ + +#if !__LP64__ +kern_return_t +IOConnectUnmapMemory( + io_connect_t connect, + uint32_t memoryType, + task_port_t fromTask, + vm_address_t atAddress ); + +kern_return_t IOConnectUnmapMemory64 +#else +kern_return_t IOConnectUnmapMemory +#endif + (io_connect_t connect, + uint32_t memoryType, + task_port_t fromTask, + mach_vm_address_t atAddress ); + +/*! @function IOConnectSetCFProperties + @abstract Set CF container based properties on a connection. + @discussion This is a generic method to pass a CF container of properties to the connection. The properties are interpreted by the family and commonly represent configuration settings, but may be interpreted as anything. + @param connect The connect handle created by IOServiceOpen. + @param properties A CF container - commonly a CFDictionary but this is not enforced. The container should consist of objects which are understood by IOKit - these are currently : CFDictionary, CFArray, CFSet, CFString, CFData, CFNumber, CFBoolean, and are passed in the kernel as the corresponding OSDictionary etc. objects. + @result A kern_return_t error code returned by the family. */ + +kern_return_t +IOConnectSetCFProperties( + io_connect_t connect, + CFTypeRef properties ); + +/*! @function IOConnectSetCFProperty + @abstract Set a CF container based property on a connection. + @discussion This is a generic method to pass a CF property to the connection. The property is interpreted by the family and commonly represent configuration settings, but may be interpreted as anything. + @param connect The connect handle created by IOServiceOpen. + @param propertyName The name of the property as a CFString. + @param property A CF container - should consist of objects which are understood by IOKit - these are currently : CFDictionary, CFArray, CFSet, CFString, CFData, CFNumber, CFBoolean, and are passed in the kernel as the corresponding OSDictionary etc. objects. + @result A kern_return_t error code returned by the object. */ + +kern_return_t +IOConnectSetCFProperty( + io_connect_t connect, + CFStringRef propertyName, + CFTypeRef property ); + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +// Combined LP64 & ILP32 Extended IOUserClient::externalMethod + +kern_return_t +IOConnectCallMethod( + mach_port_t connection, // In + uint32_t selector, // In + const uint64_t *input, // In + uint32_t inputCnt, // In + const void *inputStruct, // In + size_t inputStructCnt, // In + uint64_t *output, // Out + uint32_t *outputCnt, // In/Out + void *outputStruct, // Out + size_t *outputStructCnt) // In/Out +AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER; + +kern_return_t +IOConnectCallAsyncMethod( + mach_port_t connection, // In + uint32_t selector, // In + mach_port_t wake_port, // In + uint64_t *reference, // In + uint32_t referenceCnt, // In + const uint64_t *input, // In + uint32_t inputCnt, // In + const void *inputStruct, // In + size_t inputStructCnt, // In + uint64_t *output, // Out + uint32_t *outputCnt, // In/Out + void *outputStruct, // Out + size_t *outputStructCnt) // In/Out +AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER; + +kern_return_t +IOConnectCallStructMethod( + mach_port_t connection, // In + uint32_t selector, // In + const void *inputStruct, // In + size_t inputStructCnt, // In + void *outputStruct, // Out + size_t *outputStructCnt) // In/Out +AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER; + +kern_return_t +IOConnectCallAsyncStructMethod( + mach_port_t connection, // In + uint32_t selector, // In + mach_port_t wake_port, // In + uint64_t *reference, // In + uint32_t referenceCnt, // In + const void *inputStruct, // In + size_t inputStructCnt, // In + void *outputStruct, // Out + size_t *outputStructCnt) // In/Out +AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER; + +kern_return_t +IOConnectCallScalarMethod( + mach_port_t connection, // In + uint32_t selector, // In + const uint64_t *input, // In + uint32_t inputCnt, // In + uint64_t *output, // Out + uint32_t *outputCnt) // In/Out +AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER; + +kern_return_t +IOConnectCallAsyncScalarMethod( + mach_port_t connection, // In + uint32_t selector, // In + mach_port_t wake_port, // In + uint64_t *reference, // In + uint32_t referenceCnt, // In + const uint64_t *input, // In + uint32_t inputCnt, // In + uint64_t *output, // Out + uint32_t *outputCnt) // In/Out +AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER; + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +kern_return_t +IOConnectTrap0(io_connect_t connect, + uint32_t index ); + +kern_return_t +IOConnectTrap1(io_connect_t connect, + uint32_t index, + uintptr_t p1 ); + +kern_return_t +IOConnectTrap2(io_connect_t connect, + uint32_t index, + uintptr_t p1, + uintptr_t p2); + +kern_return_t +IOConnectTrap3(io_connect_t connect, + uint32_t index, + uintptr_t p1, + uintptr_t p2, + uintptr_t p3); + +kern_return_t +IOConnectTrap4(io_connect_t connect, + uint32_t index, + uintptr_t p1, + uintptr_t p2, + uintptr_t p3, + uintptr_t p4); + +kern_return_t +IOConnectTrap5(io_connect_t connect, + uint32_t index, + uintptr_t p1, + uintptr_t p2, + uintptr_t p3, + uintptr_t p4, + uintptr_t p5); + +kern_return_t +IOConnectTrap6(io_connect_t connect, + uint32_t index, + uintptr_t p1, + uintptr_t p2, + uintptr_t p3, + uintptr_t p4, + uintptr_t p5, + uintptr_t p6); + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*! @function IOConnectAddClient + @abstract Inform a connection of a second connection. + @discussion This is a generic method to inform a family connection of a second connection, and is rarely used. + @param connect The connect handle created by IOServiceOpen. + @param client Another connect handle created by IOServiceOpen. + @result A kern_return_t error code returned by the family. */ + +kern_return_t +IOConnectAddClient( + io_connect_t connect, + io_connect_t client ); + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * IORegistry accessors + */ + +/*! @function IORegistryGetRootEntry + @abstract Return a handle to the registry root. + @discussion This method provides an accessor to the root of the registry for the machine. The root may be passed to a registry iterator when iterating a plane, and contains properties that describe the available planes, and diagnostic information for IOKit. + @param masterPort The master port obtained from IOMasterPort(). Pass kIOMasterPortDefault to look up the default master port. + @result A handle to the IORegistryEntry root instance, to be released with IOObjectRelease by the caller, or MACH_PORT_NULL on failure. */ + +io_registry_entry_t +IORegistryGetRootEntry( + mach_port_t masterPort ); + +/*! @function IORegistryEntryFromPath + @abstract Looks up a registry entry by path. + @discussion This function parses paths to lookup registry entries. The path should begin with ':' If there are characters remaining unparsed after an entry has been looked up, this is considered an invalid lookup. Paths are further documented in IORegistryEntry.h + @param masterPort The master port obtained from IOMasterPort(). Pass kIOMasterPortDefault to look up the default master port. + @param path A C-string path. + @result A handle to the IORegistryEntry witch was found with the path, to be released with IOObjectRelease by the caller, or MACH_PORT_NULL on failure. */ + +io_registry_entry_t +IORegistryEntryFromPath( + mach_port_t masterPort, + const io_string_t path ); + +// options for IORegistryCreateIterator(), IORegistryEntryCreateIterator, IORegistryEntrySearchCFProperty() +enum { + kIORegistryIterateRecursively = 0x00000001, + kIORegistryIterateParents = 0x00000002 +}; + +/*! @function IORegistryCreateIterator + @abstract Create an iterator rooted at the registry root. + @discussion This method creates an IORegistryIterator in the kernel that is set up with options to iterate children of the registry root entry, and to recurse automatically into entries as they are returned, or only when instructed with calls to IORegistryIteratorEnterEntry. The iterator object keeps track of entries that have been recursed into previously to avoid loops. + @param masterPort The master port obtained from IOMasterPort(). Pass kIOMasterPortDefault to look up the default master port. + @param plane The name of an existing registry plane. Plane names are defined in IOKitKeys.h, eg. kIOServicePlane. + @param options kIORegistryIterateRecursively may be set to recurse automatically into each entry as it is returned from IOIteratorNext calls on the registry iterator. + @param iterator A created iterator handle, to be released by the caller when it has finished with it. + @result A kern_return_t error code. */ + +kern_return_t +IORegistryCreateIterator( + mach_port_t masterPort, + const io_name_t plane, + IOOptionBits options, + io_iterator_t * iterator ); + +/*! @function IORegistryEntryCreateIterator + @abstract Create an iterator rooted at a given registry entry. + @discussion This method creates an IORegistryIterator in the kernel that is set up with options to iterate children or parents of a root entry, and to recurse automatically into entries as they are returned, or only when instructed with calls to IORegistryIteratorEnterEntry. The iterator object keeps track of entries that have been recursed into previously to avoid loops. + @param entry The root entry to begin the iteration at. + @param plane The name of an existing registry plane. Plane names are defined in IOKitKeys.h, eg. kIOServicePlane. + @param options kIORegistryIterateRecursively may be set to recurse automatically into each entry as it is returned from IOIteratorNext calls on the registry iterator. kIORegistryIterateParents may be set to iterate the parents of each entry, by default the children are iterated. + @param iterator A created iterator handle, to be released by the caller when it has finished with it. + @result A kern_return_t error code. */ + +kern_return_t +IORegistryEntryCreateIterator( + io_registry_entry_t entry, + const io_name_t plane, + IOOptionBits options, + io_iterator_t * iterator ); + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * IORegistryIterator, subclass of IOIterator + */ + +/*! @function IORegistryIteratorEnterEntry + @abstract Recurse into the current entry in the registry iteration. + @discussion This method makes the current entry, ie. the last entry returned by IOIteratorNext, the root in a new level of recursion. + @result A kern_return_t error code. */ + +kern_return_t +IORegistryIteratorEnterEntry( + io_iterator_t iterator ); + +/*! @function IORegistryIteratorExitEntry + @abstract Exits a level of recursion, restoring the current entry. + @discussion This method undoes an IORegistryIteratorEnterEntry, restoring the current entry. If there are no more levels of recursion to exit false is returned, otherwise true is returned. + @result kIOReturnSuccess if a level of recursion was undone, kIOReturnNoDevice if no recursive levels are left in the iteration. */ + +kern_return_t +IORegistryIteratorExitEntry( + io_iterator_t iterator ); + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * IORegistryEntry, subclass of IOObject + */ + +/*! @function IORegistryEntryGetName + @abstract Returns a C-string name assigned to a registry entry. + @discussion Registry entries can be named in a particular plane, or globally. This function returns the entry's global name. The global name defaults to the entry's meta class name if it has not been named. + @param entry The registry entry handle whose name to look up. + @param name The caller's buffer to receive the name. + @result A kern_return_t error code. */ + +kern_return_t +IORegistryEntryGetName( + io_registry_entry_t entry, + io_name_t name ); + +/*! @function IORegistryEntryGetNameInPlane + @abstract Returns a C-string name assigned to a registry entry, in a specified plane. + @discussion Registry entries can be named in a particular plane, or globally. This function returns the entry's name in the specified plane or global name if it has not been named in that plane. The global name defaults to the entry's meta class name if it has not been named. + @param entry The registry entry handle whose name to look up. + @param plane The name of an existing registry plane. Plane names are defined in IOKitKeys.h, eg. kIOServicePlane. + @param name The caller's buffer to receive the name. + @result A kern_return_t error code. */ + +kern_return_t +IORegistryEntryGetNameInPlane( + io_registry_entry_t entry, + const io_name_t plane, + io_name_t name ); + +/*! @function IORegistryEntryGetLocationInPlane + @abstract Returns a C-string location assigned to a registry entry, in a specified plane. + @discussion Registry entries can given a location string in a particular plane, or globally. If the entry has had a location set in the specified plane that location string will be returned, otherwise the global location string is returned. If no global location string has been set, an error is returned. + @param entry The registry entry handle whose name to look up. + @param plane The name of an existing registry plane. Plane names are defined in IOKitKeys.h, eg. kIOServicePlane. + @param location The caller's buffer to receive the location string. + @result A kern_return_t error code. */ + +kern_return_t +IORegistryEntryGetLocationInPlane( + io_registry_entry_t entry, + const io_name_t plane, + io_name_t location ); + +/*! @function IORegistryEntryGetPath + @abstract Create a path for a registry entry. + @discussion The path for a registry entry is copied to the caller's buffer. The path describes the entry's attachment in a particular plane, which must be specified. The path begins with the plane name followed by a colon, and then followed by '/' separated path components for each of the entries between the root and the registry entry. An alias may also exist for the entry, and will be returned if available. + @param entry The registry entry handle whose path to look up. + @param plane The name of an existing registry plane. Plane names are defined in IOKitKeys.h, eg. kIOServicePlane. + @param path A char buffer allocated by the caller. + @result IORegistryEntryGetPath will fail if the entry is not attached in the plane, or if the buffer is not large enough to contain the path. */ + +kern_return_t +IORegistryEntryGetPath( + io_registry_entry_t entry, + const io_name_t plane, + io_string_t path ); + +/*! @function IORegistryEntryCreateCFProperties + @abstract Create a CF dictionary representation of a registry entry's property table. + @discussion This function creates an instantaneous snapshot of a registry entry's property table, creating a CFDictionary analogue in the caller's task. Not every object available in the kernel is represented as a CF container; currently OSDictionary, OSArray, OSSet, OSSymbol, OSString, OSData, OSNumber, OSBoolean are created as their CF counterparts. + @param entry The registry entry handle whose property table to copy. + @param properties A CFDictionary is created and returned the caller on success. The caller should release with CFRelease. + @param allocator The CF allocator to use when creating the CF containers. + @param options No options are currently defined. + @result A kern_return_t error code. */ + +kern_return_t +IORegistryEntryCreateCFProperties( + io_registry_entry_t entry, + CFMutableDictionaryRef * properties, + CFAllocatorRef allocator, + IOOptionBits options ); + +/*! @function IORegistryEntryCreateCFProperty + @abstract Create a CF representation of a registry entry's property. + @discussion This function creates an instantaneous snapshot of a registry entry property, creating a CF container analogue in the caller's task. Not every object available in the kernel is represented as a CF container; currently OSDictionary, OSArray, OSSet, OSSymbol, OSString, OSData, OSNumber, OSBoolean are created as their CF counterparts. + @param entry The registry entry handle whose property to copy. + @param key A CFString specifying the property name. + @param allocator The CF allocator to use when creating the CF container. + @param options No options are currently defined. + @result A CF container is created and returned the caller on success. The caller should release with CFRelease. */ + +CFTypeRef +IORegistryEntryCreateCFProperty( + io_registry_entry_t entry, + CFStringRef key, + CFAllocatorRef allocator, + IOOptionBits options ); + +/*! @function IORegistryEntrySearchCFProperty + @abstract Create a CF representation of a registry entry's property. + @discussion This function creates an instantaneous snapshot of a registry entry property, creating a CF container analogue in the caller's task. Not every object available in the kernel is represented as a CF container; currently OSDictionary, OSArray, OSSet, OSSymbol, OSString, OSData, OSNumber, OSBoolean are created as their CF counterparts. +This function will search for a property, starting first with specified registry entry's property table, then iterating recusively through either the parent registry entries or the child registry entries of this entry. Once the first occurrence is found, it will lookup and return the value of the property, using the same semantics as IORegistryEntryCreateCFProperty. The iteration keeps track of entries that have been recursed into previously to avoid loops. + @param entry The registry entry at which to start the search. + @param plane The name of an existing registry plane. Plane names are defined in IOKitKeys.h, eg. kIOServicePlane. + @param key A CFString specifying the property name. + @param allocator The CF allocator to use when creating the CF container. + @param options kIORegistryIterateRecursively may be set to recurse automatically into the registry hierarchy. Without this option, this method degenerates into the standard IORegistryEntryCreateCFProperty() call. kIORegistryIterateParents may be set to iterate the parents of the entry, in place of the children. + @result A CF container is created and returned the caller on success. The caller should release with CFRelease. */ + +CFTypeRef +IORegistryEntrySearchCFProperty( + io_registry_entry_t entry, + const io_name_t plane, + CFStringRef key, + CFAllocatorRef allocator, + IOOptionBits options ); + +/* @function IORegistryEntryGetProperty - deprecated, + use IORegistryEntryCreateCFProperty */ + +kern_return_t +IORegistryEntryGetProperty( + io_registry_entry_t entry, + const io_name_t propertyName, + io_struct_inband_t buffer, + uint32_t * size ); + +/*! @function IORegistryEntrySetCFProperties + @abstract Set CF container based properties in a registry entry. + @discussion This is a generic method to pass a CF container of properties to an object in the registry. Setting properties in a registry entry is not generally supported, it is more common to support IOConnectSetCFProperties for connection based property setting. The properties are interpreted by the object. + @param entry The registry entry whose properties to set. + @param properties A CF container - commonly a CFDictionary but this is not enforced. The container should consist of objects which are understood by IOKit - these are currently : CFDictionary, CFArray, CFSet, CFString, CFData, CFNumber, CFBoolean, and are passed in the kernel as the corresponding OSDictionary etc. objects. + @result A kern_return_t error code returned by the object. */ + +kern_return_t +IORegistryEntrySetCFProperties( + io_registry_entry_t entry, + CFTypeRef properties ); + +/*! @function IORegistryEntrySetCFProperty + @abstract Set a CF container based property in a registry entry. + @discussion This is a generic method to pass a CF container as a property to an object in the registry. Setting properties in a registry entry is not generally supported, it is more common to support IOConnectSetCFProperty for connection based property setting. The property is interpreted by the object. + @param entry The registry entry whose property to set. + @param propertyName The name of the property as a CFString. + @param property A CF container - should consist of objects which are understood by IOKit - these are currently : CFDictionary, CFArray, CFSet, CFString, CFData, CFNumber, CFBoolean, and are passed in the kernel as the corresponding OSDictionary etc. objects. + @result A kern_return_t error code returned by the object. */ + +kern_return_t +IORegistryEntrySetCFProperty( + io_registry_entry_t entry, + CFStringRef propertyName, + CFTypeRef property ); + +/*! @function IORegistryEntryGetChildIterator + @abstract Returns an iterator over an registry entry's child entries in a plane. + @discussion This method creates an iterator which will return each of a registry entry's child entries in a specified plane. + @param entry The registry entry whose children to iterate over. + @param plane The name of an existing registry plane. Plane names are defined in IOKitKeys.h, eg. kIOServicePlane. + @param iterator The created iterator over the children of the entry, on success. The iterator must be released when the iteration is finished. + @result A kern_return_t error code. */ + +kern_return_t +IORegistryEntryGetChildIterator( + io_registry_entry_t entry, + const io_name_t plane, + io_iterator_t * iterator ); + +/*! @function IORegistryEntryGetChildEntry + @abstract Returns the first child of a registry entry in a plane. + @discussion This function will return the child which first attached to a registry entry in a plane. + @param entry The registry entry whose child to look up. + @param plane The name of an existing registry plane. Plane names are defined in IOKitKeys.h, eg. kIOServicePlane. + @param child The first child of the registry entry, on success. The child must be released by the caller. + @result A kern_return_t error code. */ + +kern_return_t +IORegistryEntryGetChildEntry( + io_registry_entry_t entry, + const io_name_t plane, + io_registry_entry_t * child ); + +/*! @function IORegistryEntryGetParentIterator + @abstract Returns an iterator over an registry entry's parent entries in a plane. + @discussion This method creates an iterator which will return each of a registry entry's parent entries in a specified plane. + @param entry The registry entry whose parents to iterate over. + @param plane The name of an existing registry plane. Plane names are defined in IOKitKeys.h, eg. kIOServicePlane. + @param iterator The created iterator over the parents of the entry, on success. The iterator must be released when the iteration is finished. + @result A kern_return_t error. */ + +kern_return_t +IORegistryEntryGetParentIterator( + io_registry_entry_t entry, + const io_name_t plane, + io_iterator_t * iterator ); + +/*! @function IORegistryEntryGetParentEntry + @abstract Returns the first parent of a registry entry in a plane. + @discussion This function will return the parent to which the registry entry was first attached in a plane. + @param entry The registry entry whose parent to look up. + @param plane The name of an existing registry plane. Plane names are defined in IOKitKeys.h, eg. kIOServicePlane. + @param child The first parent of the registry entry, on success. The parent must be released by the caller. + @result A kern_return_t error code. */ + +kern_return_t +IORegistryEntryGetParentEntry( + io_registry_entry_t entry, + const io_name_t plane, + io_registry_entry_t * parent ); + +/*! @function IORegistryEntryInPlane + @abstract Determines if the registry entry is attached in a plane. + @discussion This method determines if the entry is attached in a plane to any other entry. + @param entry The registry entry. + @param plane The name of an existing registry plane. Plane names are defined in IOKitKeys.h, eg. kIOServicePlane. + @result If the entry has a parent in the plane, true is returned, otherwise false is returned. */ + +boolean_t +IORegistryEntryInPlane( + io_registry_entry_t entry, + const io_name_t plane ); + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Matching dictionary creation helpers + */ + +/*! @function IOServiceMatching + @abstract Create a matching dictionary that specifies an IOService class match. + @discussion A very common matching criteria for IOService is based on its class. IOServiceMatching will create a matching dictionary that specifies any IOService of a class, or its subclasses. The class is specified by C-string name. + @param name The class name, as a const C-string. Class matching is successful on IOService's of this class or any subclass. + @result The matching dictionary created, is returned on success, or zero on failure. The dictionary is commonly passed to IOServiceGetMatchingServices or IOServiceAddNotification which will consume a reference, otherwise it should be released with CFRelease by the caller. */ + +CFMutableDictionaryRef +IOServiceMatching( + const char * name ); + +/*! @function IOServiceNameMatching + @abstract Create a matching dictionary that specifies an IOService name match. + @discussion A common matching criteria for IOService is based on its name. IOServiceNameMatching will create a matching dictionary that specifies an IOService with a given name. Some IOServices created from the OpenFirmware device tree will perform name matching on the standard OF compatible, name, model properties. + @param name The IOService name, as a const C-string. + @result The matching dictionary created, is returned on success, or zero on failure. The dictionary is commonly passed to IOServiceGetMatchingServices or IOServiceAddNotification which will consume a reference, otherwise it should be released with CFRelease by the caller. */ + +CFMutableDictionaryRef +IOServiceNameMatching( + const char * name ); + +/*! @function IOBSDNameMatching + @abstract Create a matching dictionary that specifies an IOService match based on BSD device name. + @discussion IOServices that represent BSD devices have an associated BSD name. This function creates a matching dictionary that will match IOService's with a given BSD name. + @param masterPort The master port obtained from IOMasterPort(). Pass kIOMasterPortDefault to look up the default master port. + @param options No options are currently defined. + @param bsdName The BSD name, as a const char *. + @result The matching dictionary created, is returned on success, or zero on failure. The dictionary is commonly passed to IOServiceGetMatchingServices or IOServiceAddNotification which will consume a reference, otherwise it should be released with CFRelease by the caller. */ + +CFMutableDictionaryRef +IOBSDNameMatching( + mach_port_t masterPort, + uint32_t options, + const char * bsdName ); + +/*! @function IOOpenFirmwarePathMatching + @abstract Create a matching dictionary that specifies an IOService match based on an OpenFirmware device path. + @discussion Certain IOServices (currently, block and ethernet boot devices) may be looked up by a path that specifies their location in the OpenFirmware device tree, represented in the registry by the kIODeviceTreePlane plane. This function creates a matching dictionary that will match IOService's found with a given OpenFirmware device path. + @param masterPort The master port obtained from IOMasterPort(). Pass kIOMasterPortDefault to look up the default master port. + @param options No options are currently defined. + @param path The OpenFirmware device path, as a const char *. + @result The matching dictionary created, is returned on success, or zero on failure. The dictionary is commonly passed to IOServiceGetMatchingServices or IOServiceAddNotification which will consume a reference, otherwise it should be released with CFRelease by the caller. */ + +CFMutableDictionaryRef +IOOpenFirmwarePathMatching( + mach_port_t masterPort, + uint32_t options, + const char * path ); + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*! @function IOServiceOFPathToBSDName + @abstract Utility to look up an IOService from its OpenFirmware device path, and return its BSD device name if available. + @discussion Certain IOServices (currently, block and ethernet boot devices) may be looked up by a path that specifies their location in the OpenFirmware device tree, represented in the registry by the kIODeviceTreePlane plane. This function looks up an IOService object with a given OpenFirmware device path, and returns its associated BSD device name. + @param masterPort The master port obtained from IOMasterPort(). Pass kIOMasterPortDefault to look up the default master port. + @param openFirmwarePath The OpenFirmware device path, as a const char *. + @param bsdName The BSD name, as a const char *, is copied to the callers buffer. + @result A kern_return_t error code. */ + +kern_return_t +IOServiceOFPathToBSDName(mach_port_t masterPort, + const io_name_t openFirmwarePath, + io_name_t bsdName); + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*! @typedef IOAsyncCallback0 + @abstract standard callback function for asynchronous I/O requests with + no extra arguments beyond a refcon and result code. + @param refcon The refcon passed into the original I/O request + @param result The result of the I/O operation +*/ +typedef void (*IOAsyncCallback0)(void *refcon, IOReturn result); + +/*! @typedef IOAsyncCallback1 + @abstract standard callback function for asynchronous I/O requests with + one extra argument beyond a refcon and result code. + This is often a count of the number of bytes transferred + @param refcon The refcon passed into the original I/O request + @param result The result of the I/O operation + @param arg0 Extra argument +*/ +typedef void (*IOAsyncCallback1)(void *refcon, IOReturn result, void *arg0); + +/*! @typedef IOAsyncCallback2 + @abstract standard callback function for asynchronous I/O requests with + two extra arguments beyond a refcon and result code. + @param refcon The refcon passed into the original I/O request + @param result The result of the I/O operation + @param arg0 Extra argument + @param arg1 Extra argument +*/ +typedef void (*IOAsyncCallback2)(void *refcon, IOReturn result, void *arg0, void *arg1); + +/*! @typedef IOAsyncCallback + @abstract standard callback function for asynchronous I/O requests with + lots of extra arguments beyond a refcon and result code. + @param refcon The refcon passed into the original I/O request + @param result The result of the I/O operation + @param args Array of extra arguments + @param numArgs Number of extra arguments +*/ +typedef void (*IOAsyncCallback)(void *refcon, IOReturn result, void **args, + uint32_t numArgs); + + +/* Internal use */ + +kern_return_t +OSGetNotificationFromMessage( + mach_msg_header_t * msg, + uint32_t index, + uint32_t * type, + uintptr_t * reference, + void ** content, + vm_size_t * size ); + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* Internal use */ + +kern_return_t +IOCatalogueSendData( + mach_port_t masterPort, + uint32_t flag, + const char *buffer, + uint32_t size ); + +kern_return_t +IOCatalogueTerminate( + mach_port_t masterPort, + uint32_t flag, + io_name_t description ); + +kern_return_t +IOCatalogueGetData( + mach_port_t masterPort, + uint32_t flag, + char **buffer, + uint32_t *size ); + +kern_return_t +IOCatalogueModuleLoaded( + mach_port_t masterPort, + io_name_t name ); + +kern_return_t +IOCatalogueReset( + mach_port_t masterPort, + uint32_t flag ); + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +// obsolete API + +#if !defined(__LP64__) + +// for Power Mgt + +typedef struct IOObject IOObject; + +// for MacOS.app + +kern_return_t +IORegistryDisposeEnumerator( + io_enumerator_t enumerator ) DEPRECATED_ATTRIBUTE; + +kern_return_t +IOMapMemory( + io_connect_t connect, + uint32_t memoryType, + task_port_t intoTask, + vm_address_t * atAddress, + vm_size_t * ofSize, + uint32_t flags ) DEPRECATED_ATTRIBUTE; + +// for CGS + +kern_return_t +IOCompatibiltyNumber( + mach_port_t connect, + uint32_t * objectNumber ) DEPRECATED_ATTRIBUTE; + +// Traditional IOUserClient transport routines +kern_return_t +IOConnectMethodScalarIScalarO( + io_connect_t connect, + uint32_t index, + IOItemCount scalarInputCount, + IOItemCount scalarOutputCount, + ... ) AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_5; + +kern_return_t +IOConnectMethodScalarIStructureO( + io_connect_t connect, + uint32_t index, + IOItemCount scalarInputCount, + IOByteCount * structureSize, + ... ) AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_5; + +kern_return_t +IOConnectMethodScalarIStructureI( + io_connect_t connect, + uint32_t index, + IOItemCount scalarInputCount, + IOByteCount structureSize, + ... ) AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_5; + +kern_return_t +IOConnectMethodStructureIStructureO( + io_connect_t connect, + uint32_t index, + IOItemCount structureInputSize, + IOByteCount * structureOutputSize, + void * inputStructure, + void * ouputStructure ) AVAILABLE_MAC_OS_X_VERSION_10_0_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_5; + +// Compatability with earlier Mig interface routines +#if IOCONNECT_NO_32B_METHODS + +kern_return_t +io_connect_map_memory( + io_connect_t connect, + uint32_t memoryType, + task_port_t intoTask, + vm_address_t *atAddress, + vm_size_t *ofSize, + IOOptionBits options) DEPRECATED_ATTRIBUTE; + +kern_return_t +io_connect_unmap_memory( + io_connect_t connect, + uint32_t memoryType, + task_port_t fromTask, + vm_address_t atAddress) DEPRECATED_ATTRIBUTE; + +kern_return_t +io_connect_method_scalarI_scalarO( + mach_port_t connection, + int selector, + io_scalar_inband_t input, + mach_msg_type_number_t inputCnt, + io_scalar_inband_t output, + mach_msg_type_number_t *outputCnt) DEPRECATED_ATTRIBUTE; + +kern_return_t +io_connect_method_scalarI_structureO( + mach_port_t connection, + int selector, + io_scalar_inband_t input, + mach_msg_type_number_t inputCnt, + io_struct_inband_t output, + mach_msg_type_number_t *outputCnt) DEPRECATED_ATTRIBUTE; + +kern_return_t +io_connect_method_scalarI_structureI( + mach_port_t connection, + int selector, + io_scalar_inband_t input, + mach_msg_type_number_t inputCnt, + io_struct_inband_t inputStruct, + mach_msg_type_number_t inputStructCnt) DEPRECATED_ATTRIBUTE; + +kern_return_t +io_connect_method_structureI_structureO( + mach_port_t connection, + int selector, + io_struct_inband_t input, + mach_msg_type_number_t inputCnt, + io_struct_inband_t output, + mach_msg_type_number_t *outputCnt) DEPRECATED_ATTRIBUTE; + +kern_return_t +io_async_method_scalarI_scalarO( + mach_port_t connection, + mach_port_t wake_port, + io_async_ref_t reference, + mach_msg_type_number_t referenceCnt, + int selector, + io_scalar_inband_t input, + mach_msg_type_number_t inputCnt, + io_scalar_inband_t output, + mach_msg_type_number_t *outputCnt) DEPRECATED_ATTRIBUTE; + +kern_return_t +io_async_method_scalarI_structureO( + mach_port_t connection, + mach_port_t wake_port, + io_async_ref_t reference, + mach_msg_type_number_t referenceCnt, + int selector, + io_scalar_inband_t input, + mach_msg_type_number_t inputCnt, + io_struct_inband_t output, + mach_msg_type_number_t *outputCnt) DEPRECATED_ATTRIBUTE; + +kern_return_t +io_async_method_scalarI_structureI( + mach_port_t connection, + mach_port_t wake_port, + io_async_ref_t reference, + mach_msg_type_number_t referenceCnt, + int selector, + io_scalar_inband_t input, + mach_msg_type_number_t inputCnt, + io_struct_inband_t inputStruct, + mach_msg_type_number_t inputStructCnt) DEPRECATED_ATTRIBUTE; + +kern_return_t +io_async_method_structureI_structureO( + mach_port_t connection, + mach_port_t wake_port, + io_async_ref_t reference, + mach_msg_type_number_t referenceCnt, + int selector, + io_struct_inband_t input, + mach_msg_type_number_t inputCnt, + io_struct_inband_t output, + mach_msg_type_number_t *outputCnt) DEPRECATED_ATTRIBUTE; +#endif // IOCONNECT_NO_32B_METHODS + +#endif /* defined(__LP64__) */ + +__END_DECLS + +#endif /* ! _IOKIT_IOKITLIB_H */ diff --git a/IOKit/IOReturn.h b/IOKit/IOReturn.h new file mode 100644 index 0000000..38811b6 --- /dev/null +++ b/IOKit/IOReturn.h @@ -0,0 +1,137 @@ +/* + * Copyright (c) 1998-2002 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * HISTORY + */ + +/* + * Core IOReturn values. Others may be family defined. + */ + +#ifndef __IOKIT_IORETURN_H +#define __IOKIT_IORETURN_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +typedef kern_return_t IOReturn; + +#ifndef sys_iokit +#define sys_iokit err_system(0x38) +#endif /* sys_iokit */ +#define sub_iokit_common err_sub(0) +#define sub_iokit_usb err_sub(1) +#define sub_iokit_firewire err_sub(2) +#define sub_iokit_block_storage err_sub(4) +#define sub_iokit_graphics err_sub(5) +#define sub_iokit_networking err_sub(6) +#define sub_iokit_bluetooth err_sub(8) +#define sub_iokit_pmu err_sub(9) +#define sub_iokit_acpi err_sub(10) +#define sub_iokit_smbus err_sub(11) +#define sub_iokit_ahci err_sub(12) +#define sub_iokit_powermanagement err_sub(13) +//#define sub_iokit_hidsystem err_sub(14) +#define sub_iokit_scsi err_sub(16) +//#define sub_iokit_pccard err_sub(21) + +#define sub_iokit_vendor_specific err_sub(-2) +#define sub_iokit_reserved err_sub(-1) + +#define iokit_common_err(return) (sys_iokit|sub_iokit_common|return) +#define iokit_family_err(sub,return) (sys_iokit|sub|return) +#define iokit_vendor_specific_err(return) (sys_iokit|sub_iokit_vendor_specific|return) + +#define kIOReturnSuccess KERN_SUCCESS // OK +#define kIOReturnError iokit_common_err(0x2bc) // general error +#define kIOReturnNoMemory iokit_common_err(0x2bd) // can't allocate memory +#define kIOReturnNoResources iokit_common_err(0x2be) // resource shortage +#define kIOReturnIPCError iokit_common_err(0x2bf) // error during IPC +#define kIOReturnNoDevice iokit_common_err(0x2c0) // no such device +#define kIOReturnNotPrivileged iokit_common_err(0x2c1) // privilege violation +#define kIOReturnBadArgument iokit_common_err(0x2c2) // invalid argument +#define kIOReturnLockedRead iokit_common_err(0x2c3) // device read locked +#define kIOReturnLockedWrite iokit_common_err(0x2c4) // device write locked +#define kIOReturnExclusiveAccess iokit_common_err(0x2c5) // exclusive access and + // device already open +#define kIOReturnBadMessageID iokit_common_err(0x2c6) // sent/received messages + // had different msg_id +#define kIOReturnUnsupported iokit_common_err(0x2c7) // unsupported function +#define kIOReturnVMError iokit_common_err(0x2c8) // misc. VM failure +#define kIOReturnInternalError iokit_common_err(0x2c9) // internal error +#define kIOReturnIOError iokit_common_err(0x2ca) // General I/O error +//#define kIOReturn???Error iokit_common_err(0x2cb) // ??? +#define kIOReturnCannotLock iokit_common_err(0x2cc) // can't acquire lock +#define kIOReturnNotOpen iokit_common_err(0x2cd) // device not open +#define kIOReturnNotReadable iokit_common_err(0x2ce) // read not supported +#define kIOReturnNotWritable iokit_common_err(0x2cf) // write not supported +#define kIOReturnNotAligned iokit_common_err(0x2d0) // alignment error +#define kIOReturnBadMedia iokit_common_err(0x2d1) // Media Error +#define kIOReturnStillOpen iokit_common_err(0x2d2) // device(s) still open +#define kIOReturnRLDError iokit_common_err(0x2d3) // rld failure +#define kIOReturnDMAError iokit_common_err(0x2d4) // DMA failure +#define kIOReturnBusy iokit_common_err(0x2d5) // Device Busy +#define kIOReturnTimeout iokit_common_err(0x2d6) // I/O Timeout +#define kIOReturnOffline iokit_common_err(0x2d7) // device offline +#define kIOReturnNotReady iokit_common_err(0x2d8) // not ready +#define kIOReturnNotAttached iokit_common_err(0x2d9) // device not attached +#define kIOReturnNoChannels iokit_common_err(0x2da) // no DMA channels left +#define kIOReturnNoSpace iokit_common_err(0x2db) // no space for data +//#define kIOReturn???Error iokit_common_err(0x2dc) // ??? +#define kIOReturnPortExists iokit_common_err(0x2dd) // port already exists +#define kIOReturnCannotWire iokit_common_err(0x2de) // can't wire down + // physical memory +#define kIOReturnNoInterrupt iokit_common_err(0x2df) // no interrupt attached +#define kIOReturnNoFrames iokit_common_err(0x2e0) // no DMA frames enqueued +#define kIOReturnMessageTooLarge iokit_common_err(0x2e1) // oversized msg received + // on interrupt port +#define kIOReturnNotPermitted iokit_common_err(0x2e2) // not permitted +#define kIOReturnNoPower iokit_common_err(0x2e3) // no power to device +#define kIOReturnNoMedia iokit_common_err(0x2e4) // media not present +#define kIOReturnUnformattedMedia iokit_common_err(0x2e5)// media not formatted +#define kIOReturnUnsupportedMode iokit_common_err(0x2e6) // no such mode +#define kIOReturnUnderrun iokit_common_err(0x2e7) // data underrun +#define kIOReturnOverrun iokit_common_err(0x2e8) // data overrun +#define kIOReturnDeviceError iokit_common_err(0x2e9) // the device is not working properly! +#define kIOReturnNoCompletion iokit_common_err(0x2ea) // a completion routine is required +#define kIOReturnAborted iokit_common_err(0x2eb) // operation aborted +#define kIOReturnNoBandwidth iokit_common_err(0x2ec) // bus bandwidth would be exceeded +#define kIOReturnNotResponding iokit_common_err(0x2ed) // device not responding +#define kIOReturnIsoTooOld iokit_common_err(0x2ee) // isochronous I/O request for distant past! +#define kIOReturnIsoTooNew iokit_common_err(0x2ef) // isochronous I/O request for distant future +#define kIOReturnNotFound iokit_common_err(0x2f0) // data was not found +#define kIOReturnInvalid iokit_common_err(0x1) // should never be seen + +#ifdef __cplusplus +} +#endif + +#endif /* ! __IOKIT_IORETURN_H */ diff --git a/IOKit/IOTypes.h b/IOKit/IOTypes.h new file mode 100644 index 0000000..9f5d5a3 --- /dev/null +++ b/IOKit/IOTypes.h @@ -0,0 +1,250 @@ +/* + * Copyright (c) 1998-2006 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +#ifndef __IOKIT_IOTYPES_H +#define __IOKIT_IOTYPES_H + +#ifndef IOKIT +#define IOKIT 1 +#endif /* !IOKIT */ + +#if KERNEL +#include +#else +#include +#include +#endif + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef NULL +#if defined (__cplusplus) +#define NULL 0 +#else +#define NULL ((void *)0) +#endif +#endif + +/* + * Simple data types. + */ +#ifndef __MACTYPES__ /* CF MacTypes.h */ +#ifndef __TYPES__ /* guess... Mac Types.h */ + +#include +#include + +#endif /* __TYPES__ */ +#endif /* __MACTYPES__ */ + +#if KERNEL +#include +#endif + +typedef UInt32 IOOptionBits; +typedef SInt32 IOFixed; +typedef UInt32 IOVersion; +typedef UInt32 IOItemCount; +typedef UInt32 IOCacheMode; + +typedef UInt32 IOByteCount32; +typedef UInt64 IOByteCount64; + +typedef UInt32 IOPhysicalAddress32; +typedef UInt64 IOPhysicalAddress64; +typedef UInt32 IOPhysicalLength32; +typedef UInt64 IOPhysicalLength64; + +#ifdef __LP64__ +typedef mach_vm_address_t IOVirtualAddress; +#else +typedef vm_address_t IOVirtualAddress; +#endif + +#if defined(__LP64__) && defined(KERNEL) +typedef IOByteCount64 IOByteCount; +#else +typedef IOByteCount32 IOByteCount; +#endif + +typedef IOVirtualAddress IOLogicalAddress; + +#if defined(__LP64__) && defined(KERNEL) + +typedef IOPhysicalAddress64 IOPhysicalAddress; +typedef IOPhysicalLength64 IOPhysicalLength; +#define IOPhysical32( hi, lo ) ((UInt64) lo + ((UInt64)(hi) << 32)) +#define IOPhysSize 64 + +#else + +typedef IOPhysicalAddress32 IOPhysicalAddress; +typedef IOPhysicalLength32 IOPhysicalLength; +#define IOPhysical32( hi, lo ) (lo) +#define IOPhysSize 32 + +#endif + + +typedef struct +{ + IOPhysicalAddress address; + IOByteCount length; +} IOPhysicalRange; + +typedef struct +{ + IOVirtualAddress address; + IOByteCount length; +} IOVirtualRange; + +#ifdef __LP64__ +typedef IOVirtualRange IOAddressRange; +#else /* !__LP64__ */ +typedef struct +{ + mach_vm_address_t address; + mach_vm_size_t length; +} IOAddressRange; +#endif /* !__LP64__ */ + +/* + * Map between #defined or enum'd constants and text description. + */ +typedef struct { + int value; + const char *name; +} IONamedValue; + + +/* + * Memory alignment -- specified as a power of two. + */ +typedef unsigned int IOAlignment; + +#define IO_NULL_VM_TASK ((vm_task_t)0) + + +/* + * Pull in machine specific stuff. + */ + +//#include + +#ifndef MACH_KERNEL + +#ifndef __IOKIT_PORTS_DEFINED__ +#define __IOKIT_PORTS_DEFINED__ +#ifdef KERNEL +typedef struct OSObject * io_object_t; +#else /* KERNEL */ +typedef mach_port_t io_object_t; +#endif /* KERNEL */ +#endif /* __IOKIT_PORTS_DEFINED__ */ + +#include + +typedef io_object_t io_connect_t; +typedef io_object_t io_enumerator_t; +typedef io_object_t io_iterator_t; +typedef io_object_t io_registry_entry_t; +typedef io_object_t io_service_t; + +#define IO_OBJECT_NULL ((io_object_t) 0) + +#endif /* MACH_KERNEL */ + +// IOConnectMapMemory memoryTypes +enum { + kIODefaultMemoryType = 0 +}; + +enum { + kIODefaultCache = 0, + kIOInhibitCache = 1, + kIOWriteThruCache = 2, + kIOCopybackCache = 3, + kIOWriteCombineCache = 4 +}; + +// IOMemory mapping options +enum { + kIOMapAnywhere = 0x00000001, + + kIOMapCacheMask = 0x00000700, + kIOMapCacheShift = 8, + kIOMapDefaultCache = kIODefaultCache << kIOMapCacheShift, + kIOMapInhibitCache = kIOInhibitCache << kIOMapCacheShift, + kIOMapWriteThruCache = kIOWriteThruCache << kIOMapCacheShift, + kIOMapCopybackCache = kIOCopybackCache << kIOMapCacheShift, + kIOMapWriteCombineCache = kIOWriteCombineCache << kIOMapCacheShift, + + kIOMapUserOptionsMask = 0x00000fff, + + kIOMapReadOnly = 0x00001000, + + kIOMapStatic = 0x01000000, + kIOMapReference = 0x02000000, + kIOMapUnique = 0x04000000 +#ifdef XNU_KERNEL_PRIVATE + , kIOMap64Bit = 0x08000000 +#endif +}; + +/*! @enum Scale Factors + @discussion Used when a scale_factor parameter is required to define a unit of time. + @constant kNanosecondScale Scale factor for nanosecond based times. + @constant kMicrosecondScale Scale factor for microsecond based times. + @constant kMillisecondScale Scale factor for millisecond based times. + @constant kTickScale Scale factor for the standard (100Hz) tick. + @constant kSecondScale Scale factor for second based times. */ + +enum { + kNanosecondScale = 1, + kMicrosecondScale = 1000, + kMillisecondScale = 1000 * 1000, + kSecondScale = 1000 * 1000 * 1000, + kTickScale = (kSecondScale / 100) +}; + +/* compatibility types */ + +#ifndef KERNEL + +typedef unsigned int IODeviceNumber; + +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* ! __IOKIT_IOTYPES_H */ diff --git a/IOKit/OSKext.h b/IOKit/OSKext.h new file mode 100644 index 0000000..2da9b41 --- /dev/null +++ b/IOKit/OSKext.h @@ -0,0 +1,2752 @@ +/* + * Copyright (c) 2008 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +#ifndef __OSKEXT_H__ +#define __OSKEXT_H__ + +#include + +__BEGIN_DECLS + +#include +//#include +//#include +//#include +#include +#include + +// xxx - should I use "Clear" everywhere I use "Flush" + +/*! + * @header + * @ignore CF_EXPORT + * @ignore + * + * The OSKext library provides a comprehensive interface for creating, + * examining, and loading kernel extensions (kexts). + * + * NOTICE: This library is neither thread-safe nor garbage-collection + * safe. You must use your own locking with threads sharing access to OSKext. + * You can not use this library in an application with garbage collection. + */ + +#pragma mark Types and Constants +/******************************************************************************* +* Types and Constants +*******************************************************************************/ + +/*! + * @typedef OSKextRef + * @abstract A reference to a kernel extension object. + * + * @discussion + * The OSKextRef type refers to a KXKext object, which represents a kernel + * extension bundle on disk, from an archive, or loaded into the kernel. + * OSKext is an opaque type that defines the characteristics and behavior of + * OSKext objects. + * + * The kernel counterpart of OSKext is the OSKext libkern C++ class. + */ +typedef struct __OSKext * OSKextRef + ; + +#define kOSKextBundleExtension "kext" +#define kOSKextMkextExtension "mkext" + +/*! + * @typedef OSKextDiagnosticsFlags + * @constant kOSKextDiagnosticsFlagAll + * @constant kOSKextDiagnosticsFlagValidation + * @constant kOSKextDiagnosticsFlagAuthentication + * @constant kOSKextDiagnosticsFlagDependencies + * @constant kOSKextDiagnosticsFlagWarnings + */ +enum { + kOSKextDiagnosticsFlagNone = (UInt32) 0x0U, + + kOSKextDiagnosticsFlagValidation = (UInt32) 0x1U, + kOSKextDiagnosticsFlagAuthentication = (UInt32) 0x2U, + kOSKextDiagnosticsFlagDependencies = (UInt32) 0x4U, + kOSKextDiagnosticsFlagWarnings = (UInt32) 0x8U, + + kOSKextDiagnosticsFlagAll = (UInt32)0xFFFFFFFFU, +}; +typedef UInt32 OSKextDiagnosticsFlags; +typedef UInt64 OSKextLogFlags; +typedef SInt64 OSKextVersion; +typedef kern_return_t OSReturn; + +typedef uint8_t OSKextExcludeLevel; +#define kOSKextExcludeNone (0) +#define kOSKextExcludeKext (1) +#define kOSKextExcludeAll (2) + +/* Top-level keys for diagnostics dicts. See @link OSKextCopyDiagnostics@/link. + */ +// xxx - not sure we need to include these, but it's convenient +const CFStringRef kOSKextDiagnosticsValidationKey; +const CFStringRef kOSKextDiagnosticsAuthenticationKey; +const CFStringRef kOSKextDiagnosticsLinkLoadKey; +const CFStringRef kOSKextDiagnosticsDependenciesKey; +const CFStringRef kOSKextDiagnosticsWarningsKey; + +#pragma mark Basic CF Functions +/********************************************************************* +* Basic CF Functions +*********************************************************************/ + +/*! + * @function OSKextGetTypeID + * @abstract Returns the type identifier for the OSKext opaque type. + * + * @result The type identifier for the OSKext opaque type. + */ +CF_EXPORT CFTypeID +OSKextGetTypeID(void) + ; + +#pragma mark Module Configuration +/********************************************************************* +* Module Configuration +*********************************************************************/ + +/*! + * @function OSKextSetArchitecture + * @abstract Sets the architecture used for operations on kexts. + * + * @param anArch + * An NXArchInfo pointer with cputype/subtype or name set. + * Ownership remains with the caller. + * Pass NULL to set the architecture to taht of the running kernel. + * + * @result + * true if the architecture was set as desired, + * false if anArch was not found; + * if false, the architecture will now be that + * of the running kernel. + * xxx - should it just be left unchanged instead? + * + * @discussion + * The kext library uses this architecture for any architecture-specific + * operation, such as property lookups + * (see @link OSKextGetValueForInfoDictionaryKey@/link), + * dependency resolution, executable access during validation and linking. + * The kext architecture is initially that of the running kernel (not of + * the user-space process). + * + * This function looks up the system NXArchInfo struct + * for the struct passed in, first using the cputype/subtype, and if that fails, + * the name. You can therefore use this function to set the architecture + * from an architecture name alone by passing an NXArchInfo struct + * with the desired name, + * but the cputype/subtype set to CPU_TYPE_ANY and CPU_SUBTYPE_ANY. + * + * Changing the kext architecture causes all kexts to flush their load info + * and dependencies with @link OSKextFlushLoadInfo@/link. + */ +// xxx - should this also have a flushDependenciesFlag? +CF_EXPORT Boolean +OSKextSetArchitecture(const NXArchInfo * archInfo) + ; + +/*! + * @function OSKextGetArchitecture + * @abstract Gets the architecutre used for operations on kexts. + * + * @result + * The architecture used for operations on kexts. + * The caller does not own the returned pointer and should not free it. + * + * @discussion + * The kext library uses this architecture for any architecture-specific + * operation, such as property lookups + * (see @link OSKextGetValueForInfoDictionaryKey@/link), + * dependency resolution, executable access during validation and linking. + * The kext architecture is initially that of the running kernel (not of + * the user-space process). + */ +CF_EXPORT const NXArchInfo * +OSKextGetArchitecture(void) + ; + +/*! + * @function OSKextGetRunningKernelArchitecture + * @abstract Returns the architecture of the running kernel. + * + * @result + * The architecture of the running kernel. + * The caller does not own the returned pointer and should not free it. + * + * @discussion + * This function consults the kernel task and returns a pointer to the + * NXArchInfo struct representing its architecture. + * The running kernel's architecture does not necessarily match that + * of user space tasks (for example, a 32-bit user space task could be + * running with a 64-bit kernel, or vice-versa). + */ +CF_EXPORT const NXArchInfo * +OSKextGetRunningKernelArchitecture(void) + ; + +/*! @function OSKextGetLogFlags + @param kext The kext to get the log flags. Pass NULL to get the global flag. */ +CF_EXPORT OSKextLogFlags OSKextGetLogFlags(OSKextRef kext); +/*! @function OSKextSetLogFlags */ +CF_EXPORT void OSKextSetLogFlags(OSKextRef kext, OSKextLogFlags logFlags); + +/*! + * @typedef OSKextLogFunction + * @abstract + * Prototype of a callback function used to log messages from the library. + * + * @param format A printf(3) style format string. + * + * @discussion + * The default log function simply prints to stderrmsgLogSpec has any bits set. + * If you set the log function to NULL, + * no log messages will be printed. + * + * Log messages have no trailing newline, to accommodate system log facilities. + */ +/* xxx - no CF_EXPORT, compiler dies */ +typedef void (*OSKextLogFunction)( + OSKextLogFlags flags, + const char * format, + ...) + ; + +/*! + * @function OSKextSetLogFunction + * @abstract Sets the function called to log messages. + * + * @param funct The log function to set. + * + * @discussion + * The default log function simply prints to stderr. If you set the + * log function to NULL, no log messages will be printed. + * + * Log messages have no trailing newline, to accommodate system log facilities. + */ +CF_EXPORT void +OSKextSetLogFunction(OSKextLogFunction func) + ; + +/*! + * @function OSKextSetSimulatedSafeBoot + * @abstract Sets whether safe boot mode is simulated in the library. + * + * @param flag true to simulate safe boot mode, + * false to not simulate. + * + * @discussion + * Kexts without a valid OSBundleRequired property are not allowed to load + * by the kernel when the system has started in safe boot mode. + * If you turn on simulated safe boot, the kext library can + * catch non-loadable kexts and present appropriate diagnostics. + */ +CF_EXPORT void +OSKextSetSimulatedSafeBoot(Boolean flag) + ; + +/*! + * @function OSKextGetSimulatedSafeBoot + * @abstract Returns whether safe boot mode is simulated in the library. + * + * @result + * true if safe boot mode is being simulated, + * false if not. + * + * @discussion + * Kexts without a valid OSBundleRequired property are not allowed to load + * by the kernel when the system has started in safe boot mode. + * When simulated safe boot is on, the kext library can + * catch non-loadable kexts and present appropriate diagnostics. + */ +CF_EXPORT Boolean +OSKextGetSimulatedSafeBoot(void) + ; + +/*! + * @function OSKextGetActualSafeBoot + * @abstract Returns whether safe boot mode is active. + * + * @result + * true if safe boot mode is active, + * false if not. + * + * @discussion + * Kexts without a valid OSBundleRequired property are not allowed to load + * by the kernel when the system has started in safe boot mode. + * The kext library ignores actual safe boot mode, leaving decisions + * regarding safe boot to the kernel. + * If you want to analyze kexts in safe boot mode using the library, + * call @link OSKextSetSimulatedSafeBoot@/link. + */ +// xxx - we used to disallow kexts w/debug-log flags in safe boot, too +CF_EXPORT Boolean +OSKextGetActualSafeBoot(void) + ; + +/*! + * @function OSKextGetSystemExtensionsFolderURLs + * @abstract Returns the standard system extension folder URLs. + * + * @result + * An array containing the standard system extension folder URLs. + * Ownership follows the + * @link //apple_ref/doc/uid/20001148-SW1 Get Rule@/link. + * + * @discussion + * To open all the kexts normally considered for loading by the system, + * pass the return value of this function to + * @link OSKextCreateKextsFromURLs@/link. + */ +CF_EXPORT CFArrayRef +OSKextGetSystemExtensionsFolderURLs(void) + ; + +/*! + * @function OSKextSetRecordsDiagnostics + * @abstract Sets whether kexts record diagnostic information. + * + * @param flags Indicates which diagnostics to record. + * + * @discussion + * The kext library can record diagnostic information for kexts as + * problems are encountered. These diagnostics can consume a fair + * amount of memory, and should be generated only when desired. + * Recording of diagnostics is set to + * @link kOSKextDiagnosticsFlagNone@/link by default. + * Use this function to turn diagnostics recording off (or back on) + * for particular diagnostic types. + * + * Turning on diagnostics does not calculate or recalculate + * diagnostics. Call the various functions that operate on kexts + * to begin accumulating diagnostics. + * + * Turning diagnostics off does not clear any existing diagnostics. + * Use @link OSKextFlushDiagnostics@/link explicitly to clear + * any diagnostics currently stored. + * + * See also @link OSKextCopyDiagnostics@/link, + * @link OSKextValidate@/link, + * @link OSKextAuthenticate@/link, and + * @link OSKextResolveDependencies@/link. + */ +// Could list a pile of see also's here.... +CF_EXPORT void +OSKextSetRecordsDiagnostics(OSKextDiagnosticsFlags flags) + ; + +/*! + * @function OSKextGetRecordsDiagnostics + * @abstract + * Returns what kinds of diagnostic information kexts record. + * + * @result + * Flags indicating which types of diagnostics are currently + * being recorded. You can bitwise-OR or -AND these with other flags + * to add or remove diagnostics being recorded with + * @link OSKextSetRecordsDiagnostics@/link. + */ +CF_EXPORT OSKextDiagnosticsFlags +OSKextGetRecordsDiagnostics(void) + ; + + +/*! + * @function OSKextSetUsesCaches + * @abstract Sets whether the kext library uses cache files. + * + * @param flag + * true to use caches, + * false to not use caches. + * + * @discussion + * The kext library normally uses caches to speed up reading kexts from + * the system extensions folders. + * Use this function to turn off use of caches; this will cause reading + * of kexts to be dramatically slower. + * + * See also @link OSKextGetUsesCaches@/link. + */ +CF_EXPORT void +OSKextSetUsesCaches(Boolean flag) + ; + +/*! + * @function OSKextGetUsesCaches + * @abstract + * Returns whether the OSKext library uses cache files. + * + * @result + * true if the library uses caches to speed up reading of kexts, + * false if it doesn't. + * + * @discussion + * The kext library normally uses caches to speed up reading kexts from + * the system extensions folders. + * Use this function to check whether the library is using caches. + * + * See also @link OSKextGetUsesCaches@/link. + */ +CF_EXPORT Boolean +OSKextGetUsesCaches(void) + ; + +#pragma mark Instance Management +/********************************************************************* +* Instance Management +*********************************************************************/ + +/*! + * @function OSKextCreate + * @abstract Read a single kext from an on-disk bundle, without plugins. + * + * @param allocator + * The allocator to use to allocate memory for the new object. + * Pass NULL or kCFAllocatorDefault + * to use the current default allocator. + * @param anURL + * The location of the bundle for which to create an OSKext object. + * @result + * An OSKext object created from the bundle at anURL. + * Ownership follows the + * @link //apple_ref/doc/uid/20001148-103029 Create Rule@/link. + * + * Returns NULL if there was a memory allocation problem or + * if the bundle doesn't exist at anURL (see Discussion). + * May return an existing OSKext object with the reference count incremented. + * + * @discussion + * Once a kext has been created, it is cached in memory; the kext bundle cache + * is flushed only periodically. OSKextCreate does not check that a cached kext + * bundle still exists in the filesystem. If a kext bundle is deleted + * from the filesystem, it is therefore possible for OSKextCreate + * to return a cached bundle that has actually been deleted. + * + * OSKext uses a CFBundle briefly during initialization, but in order + * to save memory and allow re-reading of kext bundle contents + * from disk, does not retain it. Applications can save further memory + * by flushing info dictionaries so that they are read from disk again + * when needed; see @link OSKextFlushInfoDictionary@/link. + */ +CF_EXPORT OSKextRef +OSKextCreate( + CFAllocatorRef allocator, + CFURLRef anURL) + ; + +/*! + * @function OSKextCreateKextsFromURL + * @abstract Reads all kexts at an on-disk URL along with their plugins. + * + * @param allocator + * The allocator to use to allocate memory for the new objects. + * Pass NULL or kCFAllocatorDefault + * to use the current default allocator. + * @param anURL The URL to scan for kernel extensions. + * @result + * Returns an array containing the kext objects created, + * or NULL on failure. + * + * @discussion + * This function scans anURL for kexts. + * If anURL represents a kext, + * this function reads that kext and its plugins. + * If anURL represents a non-kext directory, + * this functions scans the directory's immediate contents for kext bundles + * and their plugins. It does not scan recursively; only plugins one level + * deep are read. + * + * If given an URL for a kext that is a plugin of another kext, this + * function does not scan for further plugins. + * + * This function does not scan for or read mkext files. Use + * @link OSKextCreateKextsFromMkextFile@/link to read an mkext file. + * + * See @link OSKextCreate OSKextCreate @/link for information + * about kext object caching. + */ +CFArrayRef OSKextCreateKextsFromURL( + CFAllocatorRef allocator, + CFURLRef anURL) + ; + +/*! + * @function OSKextCreateKextsFromURLs + * @abstract Reads all kexts at an array on-disk URLs along with their plugins. + * + * @param allocator + * The allocator to use to allocate memory for the new objects. + * Pass NULL or kCFAllocatorDefault + * to use the current default allocator. + * @param arrayOfURLs The URLs to scan for kernel extensions. + * @result + * Returns an array containing the kext objects created, + * or NULL on failure. + * + * @discussion + * This function scans each URL in arrayOfURLs for kexts. + * If a given URL represents a kext, + * this function reads that kext and its plugins. + * If the URL represents a non-kext directory, this functions scans the + * directory's immediate contents for kext bundles and their plugins. + * It does not scan recursively; only plugins one level deep are read. + * + * If given an URL for a kext that is a plugin of another kext, this + * function does not scan for further plugins. + * + * This function does not scan for or read mkext files. Use + * @link OSKextCreateKextsFromMkextFile@/link to read an mkext file. + * + * See @link OSKextCreate@/link for discussion about kext object caching. + */ +CF_EXPORT CFArrayRef +OSKextCreateKextsFromURLs( + CFAllocatorRef allocator, + CFArrayRef arrayOfURLs) + ; + +/*! + * @function OSKextGetAllKexts + * @abstract + * Returns an array containing all of the kexts currently open in the application. + * + * @result + * A CFArray object containing OSKext objects for each open kext + * in the application. Ownership follows the + * @link //apple_ref/doc/uid/20001148-SW1 Get Rule@/link. + * + * @discussion + * This function is potentially expensive, so use with care. + */ +CF_EXPORT CFArrayRef +OSKextGetAllKexts(void) + ; + +/*! @function OSKextCopyKextsWithIdentifier */ +CF_EXPORT CFArrayRef OSKextCopyKextsWithIdentifier(CFStringRef bundleID); +/*! @function OSKextGetKextsWithIdentifiers + @discussion Follows Create Rule. + */ +CF_EXPORT CFArrayRef OSKextGetKextsWithIdentifiers(CFArrayRef bundleIDs); + +/*! + * @function OSKextGetKextWithIdentifierAndVersion + * @abstract + * Locate a kext given its program-defined identifier and version. + * + * @param aBundleID + * The identifier of the kext to locate. + * Note that identifier names are case-sensitive. + * @param aVersion + * The version of the kext to locate. + * @result + * An OSKext object, or NULL if the kext was not found. + * Ownership follows the + * @link //apple_ref/doc/uid/20001148-SW1 Get Rule@/link. + * + * @discussion + * For a kext to be located using its identifier and version, + * the kext object must have already been created. + * See @link OSKextGetKextWithIdentifierAndVersion@/link for more. + */ +// xxx - check on same-version ordering with folks +CF_EXPORT OSKextRef +OSKextGetKextWithIdentifierAndVersion( + CFStringRef aBundleID, OSKextVersion aVersion) + ; + +/*! + * @function OSKextGetKextsWithIdentifier + * @abstract Locate all kexts with a given program-defined identifier. + * + * @param aBundleID + * The identifier of the kext to locate. + * Note that identifier names are case-sensitive. + * @result + * An CFArray of kext objects with the given identifier, + * or NULL on error. + * Ownership follows the + * @link //apple_ref/doc/uid/20001148-103029 Create Rule@/link. + * + * @discussion + * This function is useful for locating duplicates of a given kext. + * + * See @link OSKextGetKextWithIdentifier@/link for general information + * on looking up kexts by identifier. + */ +CF_EXPORT CFArrayRef +OSKextCopyKextsWithIdentifier( + CFStringRef aBundleID) + ; + +/*! + * @function OSKextGetLoadedKextWithIdentifier + * @abstract + * Locate the loaded kext with a given program-defined identifier. + * + * @param aBundleID + * The identifier of the kext to locate. + * Note that identifier names are case-sensitive. + * @result + * An OSKext object, or NULL if the kext was not found. + * Ownership follows the + * @link //apple_ref/doc/uid/20001148-SW1 Get Rule@/link. + * + * @discussion + * You must call @link OSKextReadLoadedKextInfo@/link before calling this + * function for it to find anything. + * + * See @link OSKextGetKextWithIdentifier@/link for general information + * on looking up kexts by identifier. + */ +CF_EXPORT OSKextRef +OSKextGetLoadedKextWithIdentifier( + CFStringRef aBundleID) + ; + +/*! + * @function OSKextGetCompatibleKextWithIdentifier + * @abstract + * Locate the kext with a given program-defined identifier + * that is compatible with a requested version. + * + * @param aBundleID + * The identifier of the kext to locate. + * Note that identifier names are case-sensitive. + * @param requestedVersion + * The version that the kext must be compatible with. + * @result + * An OSKext object, or NULL if the kext was not found. + * Ownership follows the + * @link //apple_ref/doc/uid/20001148-SW1 Get Rule@/link. + * + * @discussion + * A kext is compatible with a version if that version lies between + * its CFBundleVersion and its OSBundleCompatibleVersion (inclusive). + * + * See @link OSKextGetKextWithIdentifier@/link for general information + * on looking up kexts by identifier. + */ +CF_EXPORT OSKextRef +OSKextGetCompatibleKextWithIdentifier( + CFStringRef aBundleID, + OSKextVersion requestedVersion) + ; + +#pragma mark Basic Accessors +/********************************************************************* +* Basic Accessors +*********************************************************************/ + +/*! + * @function OSKextGetURL + * @abstract Returns the CFURL of a kext bundle. + * + * @param aKext The kext to get the URL for. + * @result A CFURL object. Ownership follows the + * @link //apple_ref/doc/uid/20001148-SW1 Get Rule@/link. + * + * @discussion + * This function returns the CFURL that aKext + * was originally created with. + * It should be resolved to its base for comparison with other kext + * URLs. + */ +CF_EXPORT CFURLRef +OSKextGetURL(OSKextRef aKext) + ; // always absolute + +/*! + * @function OSKextGetIdentifier + * @abstract Returns the bundle identifier from a kext's information property list. + * + * @param aKext The kext to get the identifier for. + * @result + * A CFString object containing the kext bundle's identifier, + * or NULL if none was specified in the information property list. + * Ownership follows the + * @link //apple_ref/doc/uid/20001148-SW1 Get Rule@/link. + */ +CF_EXPORT CFStringRef +OSKextGetIdentifier(OSKextRef aKext) + ; + +/*! + * @function OSKextGetValueForInfoDictionaryKey + * @abstract + * Returns a (possibly architecture-specific) value + * in a kext's information dictionary. + * + * @param aKext The kext to get the property for. + * @param key The base key identifying the property. + * @result + * A value corresponding to key in aKext's + * information dictionary. + * If available, an architecture-specific value is returned, + * otherwise the global value is returned. Ownership follows the + * @link //apple_ref/doc/uid/20001148-SW1 Get Rule@/link. + * + * @discussion + * This function first looks for a property value specific to the current kext + * architecture, as set with @link OSKextSetArchitecture@/link, + * by appending an underscore plus the architecture name to the base key. + * If such a value is not found, it looks for the property using the base key. + * For example, if the currently set architecture is i386, and + * IOKitPersonalities is requested, this function looks up the key + * IOKitPersonalities_i386; if that doesn't exist, then it uses + * IOKitPersonalities. + * + * Some properties are not allowed to be made architecture-specific; + * if such keys are defined, they are ignored by this function: + * + * * CFBundleIdentifier + * * CFBundleVersion + * * CFBundleExecutable + * * OSBundleIsInterface + * * OSKernelResource + * + * This function looks up architecture-specific values for generic bundle + * properties, such as CFBundlePackageType, but such values are of course + * ignored by CFBundle. + * + * If you want to look up a property with a raw key, get the information + * dictionary directly using @link OSKextCopyInfoDictionary@/link or + * by opening a CFBundle for the kext's URL. + * + * This function reads the info dictionary from disk if necessary. + * See @link OSKextFlushInfoDictionary@/link. + */ +CF_EXPORT CFTypeRef +OSKextGetValueForInfoDictionaryKey( + OSKextRef aKext, + CFStringRef key) + ; + +/*! + * @function OSKextCopyInfoDictionary + * @abstract Returns a copy of a kext's information dictionary. + * + * @param aKext The kext to get the information dictionary for. + * @result + * A CFDictionary object containing the data stored in the kext's + * information property list. + * OSKext may add extra keys to this dictionary for its own use. + * Ownership follows the + * @link //apple_ref/doc/uid/20001148-103029 Create Rule@/link. + * + * @discussion + * This function uses @link IOCFUnserialize@/link to parse the XML + * of the info dictionary, in order to match the parsing used in the kernel. + */ +CF_EXPORT CFMutableDictionaryRef +OSKextCopyInfoDictionary(OSKextRef aKext) + ; + +/*! + * @function OSKextFlushInfoDictionary + * @abstract Releases a kext's info dictionary. + * + * @param aKext The kext that should release its info dictionary. + * If NULL, all open kexts' info dictionaries + * are flushed. + * + * @discussion + * OSKexts accumulate a fair amount of information as they are created + * and used; when many kext objects are created the total memory + * consumption can be significant. If an application won't be using + * kexts for long periods of time, it can flush this information + * to save memory; the information will later be re-read from disk + * or recreated as necessary. + * + * Flushing info dictionaries also allows kext objects to synchronize + * with updates on disk; they will automatically re-sort in the + * internal lookup tables to reflect changed versions, for example. + * (xxx - well they will! that's not fully implemented yet) + * + * See also @link OSKextFlushDependencies@/link, + * @link OSKextFlushLoadInfo@/link, + * and @link OSKextFlushDiagnostics@/link. + * + * Kext objects created from an mkext cannot flush their info + * dictionaries. + */ +CF_EXPORT void +OSKextFlushInfoDictionary(OSKextRef aKext) + ; + +/*! + * @function OSKextGetVersion + * @abstract Returns the version of a kext. + * + * @param aKext The kext to get the version for. + * @result The version of the kext as a 64-bit integer. + * + * @discussion + * xxx - needs more info on version format + * xxx - need to fix definition of OSKextVersion. + */ +CF_EXPORT OSKextVersion +OSKextGetVersion(OSKextRef aKext) + ; + +/*! + * @function OSKextGetCompatibleVersion + * @abstract Returns the compatible version of a kext + * + * @param aKext The kext to get the compatible version for. + * @result The compatible version of the kext as a 64-bit integer. + * + * @discussion + * This function returns the value of a kext's OSBundleCompatibleVersion + * property, parsed into a 64-bit integer that can be compared using + * standard integer comparison operators. + * + * xxx - needs more info on version format, ref to tn: http://developer.apple.com/technotes/tn/tn1132.html + */ +CF_EXPORT OSKextVersion +OSKextGetCompatibleVersion(OSKextRef aKext) + ; + +/*! + * @function OSKextCopyUUIDForArchitecture + * @abstract + * Returns the compiler-generated UUID of a kext for a given architecture. + * + * @param aKext The kext to get the UUID for. + * @param anArch The architecture desired. + * Pass NULL to get the UUID for the + * current architecture. + * @result + * A CFData object containing the UUID of the kext's executable + * for anArch, or the currently set architecture if + * anArch is NULL. + * + * @discussion + * UUIDs are used in addition to bundle versions to check the identify of + * kexts loaded in the kernel. + */ +CF_EXPORT CFDataRef +OSKextCopyUUIDForArchitecture(OSKextRef aKext, + const NXArchInfo * anArch) + ; + +/*! + * @function OSKextIsKernelComponent + * @abstract Returns whether a kext represents a kerne programming interface. + * + * @param aKext The kext to examine. + * @result + * true if aKext represents + * a kerne programming interface, false otherwise. + * + * @discussion + * A small set of kexts represent interfaces built into the kernel that can + * be linked against individually. These are commonly known as + * kernel programming interfaces (KPIs), + * and the kexts containing them as "pseudokexts". + * + * If a kext is a kernel component, then it is also always an interface + * (see @link OSKextIsInterface@/link). + */ +CF_EXPORT Boolean +OSKextIsKernelComponent(OSKextRef aKext) + ; + +/*! + * @function OSKextIsInterface + * @abstract + * Returns whether a kext acts as a linkage subset for another kext, + * also known as a symbol set. + * + * @param aKext The kext to examine. + * @result + * true if aKext is an interface kext, + * false otherwise. + * + * @discussion + * An interface kext has no actual code in its executable, but merely + * re-exports a set of symbols (typically a subset) + * from those of its dependencies. + * + * Currently the only interface kexts are the kernel component kexts + * the define the kernel programming interfaces for Mac OS X. + */ +CF_EXPORT Boolean +OSKextIsInterface(OSKextRef aKext) + ; + +/*! + * @function OSKextIsLibrary + * @abstract Returns whether a kext can be declared as a library. + * + * @param aKext The kext to examine. + * @result + * true if aKext is a library kext, false + * otherwise. + * + * @discussion + * A kext is a library kext if it has a valid OSBundleCompatibleVersion + * property. Another kext can link against a library kext by listing + * the library's identifier and required version in its OSBundleLibraries + * property. + */ +CF_EXPORT Boolean +OSKextIsLibrary(OSKextRef aKext) + ; + +/*! + * @function OSKextDeclaresExecutable + * @abstract Returns whether a kext declares a CFBundleExecutable property. + * + * @param aKext The kext to examine. + * @result + * true if aKext has a nonempty CFBundleExecutable + * property, false otherwise. + * + * @discussion + * A kext with an executable is either a loadable kext with actual executable + * code, or an interface kext whose executable serves to restrict linkage + * to a subset of the symbols of another kext. See @link OSKextIsInterface@/link + * for more on the latter type. + */ +CF_EXPORT Boolean +OSKextDeclaresExecutable(OSKextRef aKext) + ; + +/*! + * @function OSKextHasLogOrDebugFlags + * @abstract + * Returns whether a kext has OSBundleEnableKextLogging set to a true value or + * any of its IOKitPersonalities has a nonzero IOKitDebug property. + * + * @param aKext The kext to examine. + * @result + * true if aKext has a true OSBundleEnableKextLogging + * property or if any personality for the currently set architecture has a + * nonzero IOKitDebug property, false otherwise. + * + * @discussion + * Kexts built for distribution should not have any logging or debug flags set. + */ +CF_EXPORT Boolean +OSKextHasLogOrDebugFlags(OSKextRef aKext) + ; + +/*! + * @function OSKextIsLoadableInSafeBoot + * @abstract Returns whether the kernel will load a kext during safe boot. + * + * @param aKext The kext to examine. + * @result + * true if the kernel will allow aKext during + * safe boot, false otherwise. + * + * @discussion + * A kext is loadable during safe boot if it has an OSBundleRequired + * property for the kernel's architecture with a value of + * "Root", "Local-Root", "Network-Root", "Console", or "Safe Boot". + * + * This function does not generally cover the issue of loadability due + * to problems with validation, authentication, or dependency resolution. + * To determine whether a kext can actually be loaded, use + * @link OSKextIsLoadable@/link. + */ +CF_EXPORT Boolean +OSKextIsLoadableInSafeBoot(OSKextRef aKext) + ; + +/*! + * @function OSKextCopyArchitectures + * @abstract + * Returns a list of NXArchInfo structs for the architectures + * found in a kext's executable. + * + * @param aKext The kext to examine. + * @result + * A NULL-terminated list of NXArchInfo + * struct pointers describing + * the architectures supported by aKext, + * or NULL if aKext has no executable. + * The caller is responsible for freeing the list, but not the individual + * NXArchInfo pointers. + */ +CF_EXPORT const NXArchInfo ** +OSKextCopyArchitectures(OSKextRef aKext) + ; + +/*! + * @function OSKextSupportsArchitecture + * @abstract Returns whether a kext has an executable for a given architecture. + * + * @param aKext The kext to examine. + * @param anArch The NXArchInfo description to check. + * If NULL, uses the currently set architecture. + * @result + * true if aKext's executable contains code for + * anArch. + * + * @discussion + */ +// null for current (NOT host) arch +Boolean OSKextSupportsArchitecture(OSKextRef aKext, + const NXArchInfo * anArch) +; // if NULL, uses current default + +/*! + * @function OSKextCopyPlugins + * @abstract Retrieve the plugins of a kext. + * + * @param aKext The kext to get plugins for. + * @result + * An array containing the kexts that are plugins of aKext. + * + * @discussion + * This function scans the plugins folder of aKext + * and returns an array of the kexts found. + * This may result in the creation of new kext objects. + * + * If aKext is a plugin of another kext + * see @link OSKextIsPlugin@/link), + * this function returns an empty array. + */ +CF_EXPORT CFArrayRef +OSKextCopyPlugins(OSKextRef aKext) + ; + +/*! + * @function OSKextIsPlugin + * @abstract Returns whether a kext is a plugin of some other kext. + * + * @param aKext The kext to examine. + * @result + * true if aKext is a plugin of another kext, + * false otherwise. + * + * @discussion + * This function uses a simple algorithm that just checks for the substring + * ".kext/" in the absolute path leading up to the kext's bundle name. + */ +CF_EXPORT Boolean +OSKextIsPlugin(OSKextRef aKext) + ; + +/*! + * @function OSKextCopyContainerForPluginKext + * @abstract Returns the kext that is the container for a plugin kext. + * + * @param aKext The kext to find a parent for. + * @result + * The kext that contains aKext in its PlugIns folder, + * or NULL if aKext is not a plugin. + * Ownership follows the + * @link //apple_ref/doc/uid/20001148-103029 Create Rule@/link. + * + * @discussion + * This function creates a kext object for the longest portion of the + * path leading to aKext, then checks to see whether + * aKext is a plugin of that kext by CFBundle's + * semantics. If so, that kext is returned. + * This may result in the creation of a new kext. + */ +CF_EXPORT OSKextRef +OSKextCopyContainerForPluginKext(OSKextRef aKext) + ; + +/*! + * @function OSKextCopyPersonalitiesArray + * @abstract Returns the personalities of a kext for the current kext architecture. + * + * @param aKext The kext to retrieve personalities for. + * @result An array of IOKit personality dictionaries. + * + * @discussion + * IOKitPersonalities in kexts require some processing before being sent + * to the kernel, and the functions that send personalities expect an array + * rather than a dictionary. This function facilitates such use. + * + * Use @link OSKextGetValueForInfoDictionaryKey@/link to retrieve the raw + * personalities dictionary for the current architecture. + */ +CF_EXPORT CFArrayRef +OSKextCopyPersonalitiesArray(OSKextRef aKext) + ; + +// xxx - would it be awful to have a function that takes a CFTypeRef that's +// xxx - a single kext, an array of kexts, or NULL for all open kexts? + +/*! + * @function OSKextCopyPersonalitiesOfKexts + * @abstract + * Returns the personalities of multiple kexts for the current kext architecture. + * + * @param kextArray The kexts to retrieve personalities for. + * Pass NULL to retrieve personalities for all open kexts. + * @result An array of IOKit personality dictionaries. + * + * @discussion + * IOKitPersonalities in kexts require some processing before being sent + * to the kernel, and the functions that send personalities expect an array + * rather than a dictionary. This function facilitates such use. + */ +CF_EXPORT CFArrayRef +OSKextCopyPersonalitiesOfKexts(CFArrayRef kextArray) + ; + +/*! + * @function OSKextCopyExecutableForArchitecture + * @abstract + * Returns a kext's Mach-O executable, thinned to a single architecture + * if desired. + * + * @param aKext The kext to retrieve the executable from. + * @param anArch The architecture desired. + * Pass NULL to get the whole, unthinned exectuable. + * @result + * A CFData object containing the code + * for the specified architecture, or NULL if it can't be found. + * + * @discussion + * Note that this function does not use the default kext architecture set by + * @link OSKextSetArchitecture@/link when given no architecture. + */ +CF_EXPORT CFDataRef +OSKextCopyExecutableForArchitecture(OSKextRef aKext, + const NXArchInfo * anArch) + ; + +/*! + * @function OSKextCopyResource + * @abstract Returns a named resource from a kext's bundle. + * + * @param aKext The kext to get a resource from. + * @param resourceName The name of the requested resource. + * @param resourceType The abstract type of the requested resource. + * The type is expressed as a filename extension, + * such as jpg. + * Pass NULL if you don’t need + * to search by type. + * + * @result + * A CFData object containing the resource file's contents, + * or NULL if the resource can't be found. + * + * @discussion + * For a kext created from an on-disk URL, this function uses CFBundle + * semantics to locate the resource file. Note that localized resources + * and resource subdirectories are not available to kexts calling + * @link //apple_ref/c/func/OSKextRequestResource OSKextRequestResource@/link + * from within the kernel (because the process providing them runs as root). + * You can store such resources in a kext bundle and use them in applications, + * but they will not be available to the kext loaded in kernel. + */ +CF_EXPORT CFDataRef +OSKextCopyResource( + OSKextRef aKext, + CFStringRef resourceName, + CFStringRef resourceType) + ; + +#pragma mark Dependency Resolution +/********************************************************************* +* Dependency Resolution +*********************************************************************/ + +/*! + * @function OSKextResolveDependencies + * @abstract Calculate the dependency graph for a kext. + * + * @param aKext The kext to resolve dependencies for. + * @result + * true if all dependencies are successfully resolved, + * false otherwise. + * + * @discussion + * This function examines the OSBundleLibraries property of aKext + * and looks for compatible open kexts. Priority is given to kexts marked as + * loaded (see @link OSKextReadLoadedKextInfo@/link and + * @link OSKextFlushLoadInfo@/link). Otherwise the most recent + * compatible version is used; if multiple kexts with the same identifier and + * version exist, the last one created is used. + * + * Any problems resolving dependencies are stored in a diagnostics dictionary, + * which you can retrieve using @link OSKextCopyDiagnostics@/link. + * + * If a kext's dependencies have already been resolved, this function does + * no work and returns true. + * If you want to recalculate a kext's dependencies, call + * @link OSKextFlushDependencies@/link first. + */ +// xxx - check on same-version ordering with folks +CF_EXPORT Boolean +OSKextResolveDependencies(OSKextRef aKext) + ; + +/*! + * @function OSKextFlushDependencies + * @abstract Clears the dependency graph of a kext. + * + * @param aKext The kext to flush dependencies for. + * Pass NULL to flush dependencies for all kexts. + * + * @discussion + * OSKexts accumulate a fair amount of information as they are created + * and used; when many kext objects are created the total memory + * consumption can be significant. If an application won't be using + * kexts for long periods of time, it can flush this information + * to save memory; the information will later be re-read from disk + * or recreated as necessary. + * + * Flushing dependencies is also useful when readling loaded kext + * information from the kernel with @link OSKextReadLoadedKextInfo@/link + * (in fact, that function takes a flag to do it as part of its work). + * Dependency resolution gives priority to kexts marked as loaded, + * so it's wise to call flush dependencies before reading load info + * and before doing any operation that resolves dependencies. + * Conversely, if you want to resolve dependencies without consideration + * for which kexts are loaded, call @link OSKextFlushLoadInfo@/link + * beforehand (with or without the flag to flush dependencies). + * + * This function also clears any dependency resolution diagnostics. + * See also @link OSKextFlushInfoDictionary@/link, + * @link OSKextFlushLoadInfo@/link, + * and @link OSKextFlushDiagnostics@/link. + */ +CF_EXPORT void +OSKextFlushDependencies(OSKextRef aKext) + ; + +/*! + * @function OSKextCopyDeclaredDependencies + * @abstract Returns the kexts identified in a kext's OSBundleLibraries property. + * + * @param aKext The kext to get dependencies for. + * @param needAllFlag If true, the function returns + * NULL if any dependency isn't found. + * @result + * A CFArray containing the kexts found. + * If needAllFlag is false, the array may be missing + * some kexts. If needAllFlag is true and not all + * dependencies are found, this function returns NULL. + * + * @discussion + * This function calls @link OSKextResolveDependencies@/link to find + * dependencies. + */ +CF_EXPORT CFArrayRef +OSKextCopyDeclaredDependencies( + OSKextRef aKext, + Boolean needAllFlag) + ; + + +/*! + * @function OSKextCopyLinkDependencies + * @abstract Returns the kexts that a kext links directly against. + * + * @param aKext The kext to get dependencies for. + * @param needAllFlag If true, the function returns + * NULL if any dependency isn't found. + * @result + * A CFArray containing the kexts found. + * If needAllFlag is false, the array may be missing + * some kexts. If needAllFlag is true and not all + * dependencies are found, this function returns NULL. + * + * @discussion + * Link dependencies are how loaded kext relationships are tracked + * in the kernel (as shown by the kextstat(8) program). + * Some library kexts contain no executable, merely collecting sets of + * other libraries for convenience or compatiblity purposes. + * This function follows through such indirect libraries to find kexts + * with executables that aKext will actually link against. + * + * This function calls @link OSKextResolveDependencies@/link to find + * dependencies. + */ + // xxx - need to insert a manpage link on kextstat +CF_EXPORT CFArrayRef +OSKextCopyLinkDependencies( + OSKextRef aKext, + Boolean needAllFlag) + ; + +/*! + * @function OSKextCopyLoadList + * @abstract + * Returns the entire list of kexts in the load graph of a kext + * (including that kext). + * + * @param aKext The kext to get the load list for. + * @param needAllFlag If true, the function returns + * NULL if any dependency isn't found. + * @result + * A CFArray containing the kexts found. + * If needAllFlag is false, the array may be missing + * some kexts. If needAllFlag is true and not all + * dependencies are found, this function returns NULL. + * + * @discussion + * The fully-resolved load list represents all the kexts needed to load + * aKext into the kernel, in an order guaranteed to work for + * sequential starting and matching with IOKit personalities. + * + * This function calls @link OSKextResolveDependencies@/link to find + * dependencies. + */ +CF_EXPORT CFMutableArrayRef +OSKextCopyLoadList( + OSKextRef aKext, + Boolean needAllFlag) + ; + +/*! + * @function OSKextCopyLoadListForKexts + * @abstract + * Returns the entire list of kexts in load order of the merged load graph + * of the provided list of kexts (including those kexts). + * + * @param kexts The kexts to get the load list for. + * @param needAllFlag If true, the function returns + * NULL if any dependency isn't found. + * + * @result + * A CFArray containing the kexts found. + * If needAllFlag is false, the array may be missing + * some kexts. If needAllFlag is true and not all + * dependencies are found, this function returns NULL. + * + * @discussion + * The fully-resolved load list represents all of the kexts needed to load + * every kext in kexts into the kernel, in an order guaranteed to + * work for sequential starting and matching with IOKit personalities. + * + * This function calls @link OSKextResolveDependencies@/link to find + * dependencies. + */ +CF_EXPORT CFMutableArrayRef +OSKextCopyLoadListForKexts( + CFArrayRef kexts, + Boolean needAllFlag) + ; + + +/*! + * @function OSKextCopyAllDependencies + * @abstract + * Returns all kexts that a given kexts depends on, directly or indirectly. + * + * @param aKext The kext to get dependencies for. + * @param needAllFlag If true, the function returns + * NULL if any dependency isn't found. + * @result + * A CFArray containing the kexts found. + * If needAllFlag is false, the array may be missing + * some kexts. If needAllFlag is true and not all + * dependencies are found, this function returns NULL. + * + * @discussion + * This function calls @link OSKextResolveDependencies@/link to find + * dependencies. + */ +CF_EXPORT CFMutableArrayRef +OSKextCopyAllDependencies( + OSKextRef aKext, + Boolean needAllFlag) + ; + +/*! + * @function OSKextCopyIndirectDependencies + * @abstract + * Returns all kexts that a given kexts depends on indirectly. + * + * @param aKext The kext to get dependencies for. + * @param needAllFlag If true, the function returns + * NULL if any dependency isn't found. + * @result + * A CFArray containing the kexts found. + * If needAllFlag is false, the array may be missing + * some kexts. If needAllFlag is true and not all + * dependencies are found, this function returns NULL. + * + * @discussion + * Note that the list of indirect dependencies includes all kexts declared + * as dependencies by the direct dependencies of aKext - + * it may therefore include a direct dependency as well if some other + * kext in the load graph declares it. + * + * This function calls @link OSKextResolveDependencies@/link to find + * dependencies. + */ +// xxx - This one isn't really useful, is it? +CFMutableArrayRef OSKextCopyIndirectDependencies( + OSKextRef aKext, + Boolean needAllFlag) +; + +/*! + * @function OSKextDependsOnKext + * @abstract + * Returns whether a kext depends on a given library kext, + * directly or indirectly. + * + * @param aKext The kext to examine. + * @param libraryKext The possible library kext. + * @param directFlag + * If true, only checks for a direct declared dependency; + * if false check for direct or indirect dependencies. + * @result + * true if aKext depends on libraryKext, + * either directly or indirectly per directFlag. + * Returns false otherwise. + * + * @discussion + * This function calls @link OSKextResolveDependencies@/link to find + * dependencies. + * + * This function works with actual dependency resolution, not potential. + * If there are multiple kexts with the same bundle identifier, + * aKext may not be the one chosen during resolution + * and so it might appear that no kexts depend on it, even though they could. + */ +CF_EXPORT Boolean +OSKextDependsOnKext( + OSKextRef aKext, + OSKextRef libraryKext, + Boolean directFlag) + ; + +/*! + * @function OSKextCopyDependents + * @abstract + * Return all kexts that depend on a given kext, directly or indirectly. + * + * @param aKext The kext to get dependents for. + * @param directFlag + * true to get only kexts that declare a direct + * dependency on aKext, + * false to get all dependents, direct or indirect. + * @result + * An array of all kexts that ultimately depend on aKext, + * directly or indirectly according to directFlag. + * + * @discussion + * This function calls @link OSKextResolveDependencies@/link on all open + * kexts to find dependencies. This can be somewhat expensive. + * + * This function works with actual dependency resolution, not potential. + * If there are multiple kexts with the same bundle identifier, + * aKext may not be the one chosen during resolution + * and so it might appear that no kexts depend on it, even though they could. + */ +CF_EXPORT CFMutableArrayRef +OSKextCopyDependents(OSKextRef aKext, + Boolean directFlag) + ; + +/*! + * @function OSKextIsCompatibleWithVersion + * @abstract Returns whether a library kext is compatible with a given version. + * + * @param aKext The kext to examine. + * @param aVersion The kext version to check compatibility with + * + * @result + * truer if aKext has a compatible version and + * if aVersion is between the version and compatible version of + * aKext (inclusive), false otherwise. + * + * @discussion + */ +CF_EXPORT Boolean +OSKextIsCompatibleWithVersion( + OSKextRef aKext, + OSKextVersion aVersion) + ; + +/*! + * @function OSKextLogDependencyGraph + * @abstract Prints the resolved dependency graph of a kext. + * + * @param aKext The kext to log the dependency graph of. + * @param bundleIDFlag true to log kexts by bundle ID, + * false to log them by URL. + * @param linkFlag true to log the link graph only, + * false to log the full dependency graph. + * + * @discussion + * linkFlag allows you to display the dependencies as they will + * be recorded in the kernel when the kext is loaded. + * If it is true, then only kexts with executables are included + * in the logged dependency graph. If it is false, all kexts + * needed to load aKext are included. + * + * This function calls @link OSKextResolveDependencies@/link to find + * dependencies. + */ +CF_EXPORT void +OSKextLogDependencyGraph(OSKextRef aKext, + Boolean bundleIDFlag, + Boolean linkFlag) + ; + +/*! + * @function OSKextFindLinkDependencies + * @abstract Finds kexts that define symbols a kext needs resolved. + * + * @param aKext The kext to examine. + * @param nonKPIFlag + * false to look in com.apple.kpi.* kernel component + * for kernel symbols; + * true to look in com.apple.kernel.* kernel components + * instead (not recommended for later versions of Mac OS X). + * @param allowUnsupportedFlag + * false to skip unsupported libraries in the search; + * true to include them. + * @param onedefSymbolsOut + * A dictionary containing symbols that were found once; + * keys are the symbols, values are the kexts defining the key symbol. + * Ownership follows the Create Rule. + * Pass NULL to not retrieve. + * @param undefinedSymbolsOut + * A dictionary containing symbols that weren't found; + * keys are the symbols, values are undefined. + * Ownership follows the Create Rule. + * Pass NULL to not retrieve. + * @param multiplyDefinedSymbolsOut + * A dictionary containing symbols found in multiple library kexts; + * keys are the symbols, values are the kexts defining the key symbol. + * Ownership follows the Create Rule. + * Pass NULL to not retrieve. + * @param multipleDefinitionLibraries + * A array of all library kexts in which multiply defined symbols + * were found; sorted by CFBundleIdentifier. + + * Ownership follows the Create Rule. + * Pass NULL to not retrieve. + * @result + * An array of kexts that export symbols referenced by aKext, + * sorted by CFBundleIdentifier. + * + * @discussion + * This function searches in all open kexts for symbols referenced by + * aKext, ignoring the OSBundleLibraries property. + * You can use this function to find out what you should list + * in a kext's OSBundleLibraries property. + * + * If undefinedSymbolsOut has a nonzero count, + * the symbols named by its keys could not be found in any open kext. + * + * If multiplyDefinedSymbolsOut has a nonzero count, + * some of the result kexts define the same symbol, + * and if those duplicates are listed + * in OSBundleLibraries a link failure will occur. + * You can inspect the contents of multiplyDefinedSymbolsOut + * and multipleDefinitionLibraries + * by hand to sort out which libraries you should actually declare. + * + * This function is fairly expensive, as it has to search through all open + * kexts' information dictionaries, and all library kexts' executables. + */ +CFArrayRef OSKextFindLinkDependencies( + OSKextRef aKext, + Boolean nonKPIFlag, + Boolean allowUnsupportedFlag, + CFDictionaryRef * undefinedSymbolsOut, + CFDictionaryRef * onedefSymbolsOut, + CFDictionaryRef * multiplyDefinedSymbolsOut, + CFArrayRef * multipleDefinitionLibrariesOut) + ; + +#pragma mark Linking and Loading; Other Kernel Operations +/********************************************************************* +* Linking and Loading; Other Kernel Operations +*********************************************************************/ + +/*! + * @function OSKextLoad + * @abstract Loads a kext and its dependencies into the kernel. + * + * @param aKext The kext to load. + * @result + * kOSReturnSuccess if aKext is successfully loaded + * into the kernel, or was already loaded, or an error result if not. + * + * @discussion + * The calling process must have an effective user ID of 0 (root) + * to load kexts into the kernel. + * + * A kext and all its dependencies must pass all validation and authentication + * tests to be loadable. See @link OSKextIsLoadable@/link for more information. + * + * All kexts loaded into the kernel are started, but IOKit personalities + * are not sent to the IOCatalogue. + * See @link OSKextSendPersonalitiesToKernel@/link. + * + * This function calls @link OSKextFlushLoadInfo@/link and clears dependencies + * for all open kexts. It then calls @link OSKextCopyLoadList@/link + * to find dependencies and @link OSKextReadLoadedKextInfo@/link on the + * resulting load list. + */ +// xxx - need to list errors that may be returned +CF_EXPORT OSReturn +OSKextLoad(OSKextRef aKext) + ; + +/*! + * @function OSKextLoadWithOptions + * @abstract Loads a kext and its dependencies into the kernel. + * + * @param aKext The kext to load. + * @param startExclusion + * kOSKextExcludeAll to omit starting aKext + * and any of its dependencies not already started, + * kOSKextExcludeKext to start the dependencies of + * aKext but not aKext itself, + * or kOSKextExcludeNone to start all loaded kexts. + * @param addPersonalitiesExclusion + * kOSKextExcludeAll to omit sending + * IOKitPersonalities to the IOCatalogue for aKext + * and any of its dependencies + * (though they may already be in the IOCatalogue), + * kOSKextExcludeKext to send personalities for the + * dependencies of aKext but not aKext itself, + * or kOSKextExcludeNone to send all personalities. + * @param personalityNames + * The names of IOKitPersonalities in aKext to send, + * addPersonalitiesExclusion allowing. + * If NULL all personalities are sent. + * This parameter only affects aKext; if dependency + * personalities are sent, they are all sent. + * @param delayAutounloadFlag + * true to cause the kernel's automatic kext unloader + * to skip aKext for one cycle, giving extra time + * to set up a debug session. false for normal behavior. + * + * @result + * Returns kOSReturnSuccess on success, other values on failure. + * + * @discussion + * This function allows a kext to be loaded but not started or matched + * (for IOKit kexts), which is useful in some debug scenarios. + * After calling this function, you may need to call @link OSKextStart@/link + * to start aKext (along with its dependencies). + * You may also need to call @link OSKextSendPersonalitiesToKernel@/link + * for any kexts excluded from matching via + * addPersonalitiesExclusion. + * + * The calling process must have an effective user ID of 0 (root) + * to load kexts into the kernel. + * + * A kext and all its dependencies must pass all validation and authentication + * tests to be loadable. See @link OSKextIsLoadable@/link for more information. + * + * This function calls @link OSKextFlushLoadInfo@/link and clears dependencies + * for all open kexts. It then calls @link OSKextCopyLoadList@/link + * to find dependencies and @link OSKextReadLoadedKextInfo@/link on the + * resulting load list. + */ +// xxx - need to list errors that may be returned +CF_EXPORT OSReturn +OSKextLoadWithOptions( + OSKextRef aKext, + OSKextExcludeLevel startExclusion, + OSKextExcludeLevel addPersonalitiesExclusion, + CFArrayRef personalityNames, + Boolean delayAutounloadFlag) + ; + +/*! + * @function OSKextGenerateDebugSymbols + * @abstract Generate debug symbols for a kext and its dependencies. + * + * @param aKext + * The kext to generate debug symbols for. + * @param kernelImage + * The kernel Mach-O or symbol file to use for linking. + * If NULL, the running kernel is used. + * + * @result + * A dictionary whose keys are the bundle IDs of the kexts for which symbols + * have been generated with ".sym" appended, and whose values are CFData + * objects containing the symbol files. Returns NULL on error. + * + * @discussion + * The result includes only non-interface kexts that have an executable + * and a load address set. + * Load addresses are set by @link OSKextReadLoadedKextInfo@/link or by + * @link OSKextSetLoadAddress@/link. + * + * If using the running kernel for load addresses, the current architecture + * set with @link OSKextSetArchitecture@/link must match that of the running + * kernel or this function returns NULL. + * + * This function calls @link OSKextResolveDependencies@/link to find + * dependencies. + */ +CF_EXPORT CFDictionaryRef +OSKextGenerateDebugSymbols( + OSKextRef aKext, + CFDataRef kernelImage) + ; + +/*! + * @function OSKextNeedsLoadAddressForDebugSymbols + * @abstract + * Returns whether a kext needs a load address set to generate debug symbols. + * + * @param aKext The kext to examine. + * @result + * true if aKext needs a load address set + * in order to generate debug symbols with + * @link OSKextGenerateDebugSymbols@/link, false otherwise. + */ +CF_EXPORT Boolean +OSKextNeedsLoadAddressForDebugSymbols(OSKextRef aKext) + ; + +/*! + * @function OSKextUnload + * @abstract Unloads a kext from the kernel if possible. + * + * @param aKext The kext to unload. + * @param terminateServiceAndRemovePersonalities + * If true, and the kext to unload has no kexts loaded + * against it, all IOService objects defined by that kext will be + * asked to terminate so that the unload can proceed, and the personalities + * for the kext will be removed from the IOCatalogue. + * + * @result + * kOSReturnSuccess on success, an error code + * (typically kOSKextReturnInUse) on failure. + * + * @discussion + * The calling process must have an effective user ID of 0 (root) + * to unload kexts from the kernel. + * A kext cannot be unloaded if it has any loaed dependents. + * + * See also the @link IOCatalogueTerminate@/link function. + */ +// xxx - need to list errors that may be returned +CF_EXPORT OSReturn +OSKextUnload(OSKextRef aKext, + Boolean terminateServiceAndRemovePersonalities) + ; + +/*! + * OSKextUnload + * @abstract Unloads a kext from the kernel if possible, based on its + * CFBundleIdentifier. + * + * @param kextIdentifier The CFBundleIDentifier of the kext to unload. + * @param terminateServiceAndRemovePersonalities + * If true, and the kext to unload has no kexts loaded + * against it, all IOService objects defined by that kext will be + * asked to terminate so that the unload can proceed, and the personalities + * for the kext will be removed from the IOCatalogue. + * + * @result + * kOSReturnSuccess on success, an error code + * (typically kOSKextReturnInUse) on failure. + * + * @discussion + * The calling process must have an effective user ID of 0 (root) + * to unload kexts from the kernel. + * A kext cannot be unloaded if it has any loaed dependents. + * + * See also the @link IOCatalogueTerminate@/link function. + */ +// xxx - need to list errors that may be returned +CF_EXPORT OSReturn +OSKextUnloadKextWithIdentifier(CFStringRef kextIdentifier, + Boolean terminateServiceAndRemovePersonalities) + ; + +/*! + * @function OSKextIsStarted + * @abstract Returns whether a kext loaded in the kernel is started. + * + * @param aKext The kext to examine. + * @result + * true if aKext is active and running in the kernel, + * false if not loaded or loaded and not started. + * + * @discussion + * This function returns the state recorded the last time + * @link OSKextReadLoadedKextInfo@/link was called. + */ +CF_EXPORT Boolean +OSKextIsStarted(OSKextRef aKext) + ; + +/*! + * @function OSKextStart + * @abstract Starts a kext loaded in the kernel if possible. + * + * @param aKext The kext to start. + * @result + * kOSReturnSuccess on success, an error code on failure. + * + * @discussion + * This function allows an application to start a kext that is loaded + * in the kernel (typically via @link OSKextLoadWithOptions@/link), + * and any of its dependencies that aren't also started. + * If the kext is already started, this does nothing. + * + * To start a kext means to call its start function, which is distinct from + * the start method of an IOService object. + * + * The calling process must have an effective user ID of 0 (root) + * to start kexts in the kernel. +// xxx - need to list errors that may be returned + */ +CF_EXPORT OSReturn +OSKextStart(OSKextRef aKext) + ; + +/*! + * @function OSKextStop + * @abstract Stops a kext loaded in the kernel if possible. + * + * @param aKext The kext to stop. + * @result + * kOSReturnSuccess on success, an error code on failure. + * + * @discussion + * This function allows an application to stop a kext that is loaded + * in the kernel without unloading it. This may be useful in certain + * debugging scenarios. + * + * A kext cannot be stopped via this function if it has any dependents + * that reference it, any client references within the kernel, + * or any instances of libkern/IOKit C++ classes. + * + * To stop a kext means to call its stop function, which is distinct from + * the stop method of an IOService object. + * + * The calling process must have an effective user ID of 0 (root) + * to stop kexts in the kernel. + */ +// xxx - should it be allowed to stop a kext with dependents that are +// xxx - themselves not started? +// xxx - need to list errors that may be returned +CF_EXPORT OSReturn +OSKextStop(OSKextRef aKext) + ; + +/*! + * @function OSKextSendPersonalitiesToKernel + * @abstract Sends an array of IOKit personalities to the kernel. + * + * @param personalities The personalities to send. + * @result + * kOSReturnSuccess on success, an error code on failure. + * + * @discussion + * This function simply sends an anonymous array of personalities to the + * I/O Kit's IOCatalogue object in the kernel. + * You can get personalities from kexts using + * @link OSKextCopyPersonalitiesArray@/link or + * @link OSKextCopyPersonalitiesOfKexts@/link. + * + * The calling process must have an effective user ID of 0 (root) + * to send personalities to the kernel. + */ +// xxx - need to list errors that may be returned +CF_EXPORT OSReturn +OSKextSendPersonalitiesToKernel(CFArrayRef personalities) + ; + +/*! + * @function OSKextSendKextPersonalitiesToKernel + * @abstract + * Sends the personalities of a single kext to the kernel, optionally + * filtered by name. + * + * @param aKext The kext whose personalities to send. + * @param personalityNames + * An array of names. Only personalities from aKext + * with these names are sent to the kernel. + * @result + * kOSReturnSuccess on success, an error code on failure. + * + * @discussion + * If any names in personalityNames are not found, + * they are simply skipped rather than causing an error. + * + * This function may be useful in certain debugging scenarios, + * where a particular personality is causing problems. + * + * The calling process must have an effective user ID of 0 (root) + * to send personalities to the kernel. + */ +// xxx - should names not found cause an error? +// xxx - need to list errors that may be returned +CF_EXPORT OSReturn +OSKextSendKextPersonalitiesToKernel( + OSKextRef aKext, + CFArrayRef personalityNames) + ; + +/*! + * @function OSKextSendPersonalitiesOfKextsToKernel + * Sends the personalities of multiple kext to the kernel in a single + * operation. + * + * @param kextArray The kexts whose personalities to send. + * @result + * kOSReturnSuccess on success, an error code on failure. + * + * @discussion + * This function performs one data transfer to the kernel, collecting + * all the personalities of the kexts in kextArray. + * + * The calling process must have an effective user ID of 0 (root) + * to send personalities to the kernel. + */ +// xxx - need to list errors that may be returned +CF_EXPORT OSReturn +OSKextSendPersonalitiesOfKextsToKernel(CFArrayRef kextArray) + ; + +/*! + * @function OSKextRemoveKextPersonalitiesFromKernel + * Removes all personalities for a kext's bundle identifier from the kernel. + * + * @param aKext The kext whose personalities to remove. + * @result + * kOSReturnSuccess on success, an error code on failure. + * + * @discussion + * This function removes from the kernel's IOCatalogue all personalities + * whose CFBundleIdentifiers match that of aKext so that no + * further load requests for aKext will be made. This is + * typically done when it is discovered that aKext cannot + * be loaded from user space (if it fails to load in the kernel, matching + * personalities are automatically removed). + * + * Note that kexts other than aKext might have published + * personalities in the IOCatalogue under aKext's identifier. + * Such personalities will also be removed, since they trigger load requests + * for a kext that cannot be loaded. The OSKext library adds an + * IOPersonalityPublisher property to such personalities, that gives the + * bundle identifier of the originating kext. + * + * This function differs from + * @link OSKextRemovePersonalitiesForIdentifierFromKernel@/link + * by having a kext object to check for logging or other purposes. + * + * The calling process must have an effective user ID of 0 (root) + * to remove personalities from the kernel. + */ +// xxx - need to list errors that may be returned +// xxx - this is a not-so-thin shim over IOCatalogueSendData (kIOCatalogueRemoveDrivers) +// xxx - might we just want the function to take a bundle ID? +// xxx - does IOCatalogueSendData really require root access? +CF_EXPORT OSReturn +OSKextRemoveKextPersonalitiesFromKernel(OSKextRef aKext) + ; + +/*! + * @function OSKextRemovePersonalitiesForIdentifierFromKernel + * Removes all personalities for a given bundle identifier from the kernel. + * + * @param aBundleID The bundle identifier for which to remove personalities. + * @result + * kOSReturnSuccess on success, an error code on failure. + * + * @discussion + * This function removes from the kernel's IOCatalogue all personalities + * whose CFBundleIdentifiers are aBundleID so that no + * further load requests for the kext with that identifier will be made. + * This is typically done when it is discovered no kext can be found for + * aBundleID. + * + * This function differs from + * @link OSKextRemoveKextPersonalitiesFromKernel@/link + * by not having a kext object to check for logging or other purposes. + * + * The calling process must have an effective user ID of 0 (root) + * to remove personalities from the kernel. + */ +// xxx - need to list errors that may be returned +// xxx - this is a not-so-thin shim over IOCatalogueSendData (kIOCatalogueRemoveDrivers) +// xxx - I want 2 separate functions for logging; a kext can have flags in it +// xxx - does IOCatalogueSendData really require root access? +CF_EXPORT OSReturn +OSKextRemovePersonalitiesForIdentifierFromKernel(CFStringRef aBundleID) + ; + +/*! + * @function OSKextCreateLoadedKextInfo + * @abstract Returns information about loaded kexts in a dictionary. + * + * @param kextIdentifiers An array of kext identifiers to read from the kernel. + * Pass NULL to read info for all loaded kexts. + * @result + * An array of dictionaries containing information about loaded kexts. + * + * @discussion + * This function gets information from the kernel without affecting any + * kext objects. If you want to update open kext objects to reflect + * whether they are loaded in the kernel, use @link OSKextReadLoadedKextInfo@/link. + */ +// xxx - need to document the keys from OSKextLib.h. +CF_EXPORT CFArrayRef +OSKextCreateLoadedKextInfo( + CFArrayRef kextIdentifiers) + ; + +/*! + * @function OSKextReadLoadedKextInfo + * @abstract Updates kext objects with load info from the kernel. + * + * @param kextIdentifiers An array of kext identifiers to read + * from the kernel; + * all matching kexts have their load info updated. + * Pass NULL to update load info for all kexts. + * @param flushDependenciesFlag + * true to clear dependency information from kexts, + * false to leave it in place. + * + * @result + * kOSReturnSuccess if all information is successfully updated, + * an error code otherwise. Specifically, if the current architecture set + * by @link OSKextSetArchitecture@/link is not that of the running kernel, + * this function returns kOSKextReturnExecutableArchNotFound. + * + * @discussion + * The load status of kexts primarily affects dependency resolution in the + * kext library, in that kexts marked as loaded are given priority over + * all other kexts of the same identifier. + * See @link OSKextResolveDependencies@/link for more. + * + * This function calls @link OSKextFlushLoadInfo@/link on the kexts, + * which clears any previous load info for them + * (or for all kexts if kextIdentifiers is NULL). + * If flushDependenciesFlag is true, + * resolved dependencies (which may not match the loaded kexts + * in the kernel) are also flushed. + * Load addresses are then set from the kernel, + * but dependencies are resolved as needed. + * + * If flushDependenciesFlag is false, + * existing dependency graphs are maintained, allowing you to + * check whether the dependencies, as resolved before reading + * load information, reflect loaded kexts (by getting the load list + * via @link OSKextCopyLoadList@/link and checking the kexts in it + * with @link OSKextIsLoaded@/link). + */ +// xxx - need to list errors that may be returned +CF_EXPORT OSReturn +OSKextReadLoadedKextInfo( + CFArrayRef kexts, + Boolean flushDependenciesFlag) + ; + +/*! + * @function OSKextIsLoaded + * @abstract Returns whether a kext is loaded in the kernel. + * + * @param aKext The kext to examine. + * @result + * true if a kext with the same identifier, version, and UUID + * as aKext is loaded in the kernel, false otherwise. + * + * @discussion + * You must call @link OSKextReadLoadedKextInfo@/link for this flag to be meaningful, + * which in turn requires the current library architecture to match that + * of the running kernel. + * Use @link OSKextOtherVersionIsLoaded@/link to check whether + * a different version of aKext is loaded. + */ +CF_EXPORT Boolean +OSKextIsLoaded(OSKextRef aKext) + ; + +/*! + * @function OSKextGetLoadAddress + * @abstract Returns the actual or simulated kernel load address of a kext. + * + * @param aKext The kext to examine. + * @result + * The load address of aKext, whether read from the kernel using + * @link OSKextReadLoadedKextInfo@/link or set for symbol generation using + * @link OSKextSetLoadAddress@/link. + * + * @discussion + * Load addresses are accessed as 64-bit numbers even for 32-bit architectures; + * cast or truncate the value as necessary. + * + * You must call @link OSKextReadLoadedKextInfo@/link or + * @link OSKextSetLoadAddress@/link for the load address to be nonzero. + */ +CF_EXPORT uint64_t +OSKextGetLoadAddress(OSKextRef aKext) + ; + +/*! + * @function OSKextSetLoadAddress + * @abstract + * Sets the simulated kernel load address of a kext for symbol generation. + * + * @param aKext The kext to set a load address for. + * @result + * true if the address was set, false if not + * (because it's too large for the current architecture). + * + * @discussion + * Load addresses are accessed as 64-bit numbers even for 32-bit architectures. + * If you attempt to set a load address that is too large for a 32-bit link, + * this function returns false. + * See @link OSKextSetArchitecture@/link. + * + * Setting a load address manually is useful for generating debug symbols + * with @link OSKextGenerateDebugSymbols@/link. + */ +CF_EXPORT Boolean +OSKextSetLoadAddress(OSKextRef aKext, uint64_t anAddress) + ; + +/*! + * @function OSKextGetLoadTag + * @abstract + * Returns the load tag of a kext if it's loaded in the kernel. + * + * @param aKext The kext to examine. + * @result + * The load tag (also known as the index or kmod id) of aKext, + * if it's loaded in the kernel (use @link OSKextIsLoaded@/link to check that). + * Returns 0 if aKext is not loaded or if it can't be determined + * whether it is loaded. + * + * @discussion + * You must call @link OSKextReadLoadedKextInfo@/link for the load tag + * to be meaningful, which in turn requires the current library architecture + * to match that of the running kernel. + * Use @link OSKextIsLoaded@/link to check whether aKext + * is loaded. + */ +CF_EXPORT uint32_t +OSKextGetLoadTag(OSKextRef aKext) + ; + +/*! + * @function OSKextFlushLoadInfo + * @abstract Clears all load and dependency information from a kext. + * + * @param aKext + * The kext to clear. If NULL, all open + * kexts have their load info flushed. + * @param flushDependenciesFlag + * true to clear dependency information from kexts, + * false to leave it in place. + * + * @discussion + * Flushing load information releases the internal load information + * structs of a kext, including load flags, the bundle executable, + * link/load diagnostics, and if flushDependenciesFlag is true, + * the dependencies. + * + * OSKexts accumulate a fair amount of information as they are created + * and used; when many kext objects are created the total memory + * consumption can be significant. If an application won't be using + * kexts for long periods of time, it can flush this information + * to save memory; the information will later be re-read from disk + * or recreated as necessary. + * + * Flushing load info is also useful after readling loaded kext + * information from the kernel with @link OSKextReadLoadedKextInfo@/link + * or after working with executables. Executables in particular + * consume a lot of application memory, often unnecessarily, since + * the code is loaded and running in the kernel. + * + * See also @link OSKextFlushInfoDictionaries@/link, + * @link OSKextFlushDependencies@/link, + * and @link OSKextFlushDiagnostics@/link. + */ +CF_EXPORT void +OSKextFlushLoadInfo( + OSKextRef aKext, + Boolean flushDependenciesFlag) + ; + +/*! + * @function OSKextCopyAllRequestedIdentifiers + * @abstract + * Copies the list of all unique bundle identifiers of kext load requests + * that the kernel has received since power-on. + * + * @result + * A CFArray object, or NULL if the copy failed. + * Ownership follows the + * @link //apple_ref/doc/uid/20001148-103029 Create Rule@/link. + * + */ +CF_EXPORT CFArrayRef +OSKextCopyAllRequestedIdentifiers(void) + ; + +#pragma mark Sanity Checking and Diagnostics +/********************************************************************* +* Sanity Checking and Diagnostics +*********************************************************************/ + +/*! + * @function OSKextParseVersionCFString + * @abstract + * Parses a kext version from a CFString. + * + * @param versionString The kext version string to parse. + * @result + * The numeric rendering of versionString, which can + * compared arithmetically with other valid version numbers. + * Returns -1 if the version couldn't be parsed. + */ +CF_EXPORT OSKextVersion +OSKextParseVersionCFString(CFStringRef versionString) + ; + +/*! @function OSKextParseVersionString */ +CF_EXPORT OSKextVersion OSKextParseVersionString(const char* versionString); +CF_EXPORT void OSKextVersionGetString(OSKextVersion version, char* buffer, size_t bufferLength); + + +/*! + * @function OSKextValidate + * @abstract + * Sanity checks a kext's info dictionary and executable for the currently + * set architecture. + * + * @param aKext The kext to validate. + * @result + * true if aKext passes all validation tests, + * false otherwise. + * + * @discussion + * This function forces full validation of a kext, collecting all + * errors found in the validation diagnostics if recording is turned on + * (with @link OSKextSetRecordsDiagnostics@/link). You can get the diagnostics + * using @link OSKextCopyDiagnostics@/link. + * + * If safe boot is currently simulated (see + * @link OSKextSetSimulatedSafeBoot@/link), + * any kext not loadable during safe boot will fail validation. + */ +// compare with CFBundlePreflightExecutable() +CF_EXPORT Boolean +OSKextValidate(OSKextRef aKext) + ; + +/*! + * @function OSKextIsValid + * @abstract + * Returns whether a kext is valid or not. + * + * @param aKext The kext to examine. + * @result + * true if aKext passes all validation tests, + * false otherwise. + * + * @discussion + * This function avoids doing full validation if any problems have been + * discovered with the kext during other operations. To perform a full + * validation of all possible problems, use @link OSKextValidate@/link. + */ +CF_EXPORT Boolean +OSKextIsValid(OSKextRef aKext) + ; + +/*! + * @function OSKextValidateDependencies + * @abstract Validates all dependencies of a kext. + * + * @param aKext The kexts whose dependencies to validate. + * @result + * true if all dependencies of aKext are valid, + * false if any of them are not. + * + * @discussion + * This function calls @link OSKextValidate@/link on aKext and + * all the current dependencies of aKext. + * Use @link OSKextCopyDiagnostics@/link + * with a flag of @link kOSKextDiagnosticsFlagDependencies@/link + * to get the dependency-resolution failures caused by invalid dependencies. + * + * If safe boot is currently simulated (see + * @link OSKextSetSimulatedSafeBoot@/link), + * any kext not loadable during safe boot will fail validation. + * + * This function calls @link OSKextResolveDependencies@/link to find + * dependencies. + */ +CF_EXPORT Boolean +OSKextValidateDependencies(OSKextRef aKext) + ; + +/*! + * @function OSKextAuthenticate + * @abstract Authenticates file ownership and permissions of a kext. + * + * @param aKext The kext to examine. + * @result + * true if all directories and files in aKext's + * bundle or mkext source have secure ownership and permissions, + * false if they do not, or if authentication could not be done. + * + * @discussion + * This function forces full authentication of a kext, collecting all + * errors found in the authentication diagnostics, collecting all + * errors found in the validation diagnostics if recording is turned on + * (with @link OSKextSetRecordsDiagnostics@/link). You can get the diagnostics + * using @link OSKextCopyDiagnostics@/link. + * + * For a kext to be loadable into the kernel, it must be owned by + * user root, group wheel, and its constituent files and directories + * must be nonwritable by group and other. + * A kext created from an mkext file uses that mkext file for authentication + * (see @link OSKextCreateKextsFromMkextFile@/link. + */ +CF_EXPORT Boolean +OSKextAuthenticate(OSKextRef aKext) + ; + +/*! + * @function OSKextIsAuthentic + * @abstract + * Returns whether a kext is authentic or not. + * + * @param aKext The kext to examine. + * @result + * true if aKext passes all authentication tests, + * false otherwise. + * + * @discussion + * This function avoids doing full authentication if any problems have been + * discovered with the kext during other operations. To perform a full + * validation of all possible problems, use @link OSKextValidate@/link. + */ +CF_EXPORT Boolean +OSKextIsAuthentic(OSKextRef aKext) + ; + +/*! + * @function OSKextAuthenticateDependencies + * @abstract Authenticates all dependencies of a kext. + * + * @param aKext The kexts whose dependencies to authenticate. + * @result + * true if all dependencies of aKext are authentic, + * false if any of them are not. + * + * @discussion + * This function calls @link OSKextAuthenticate@/link on aKext + * and all the current dependencies of aKext. + * Use @link OSKextCopyDiagnostics@/link + * with a flag of @link kOSKextDiagnosticsFlagDependencies@/link + * to get the dependency-resolution failures caused by inauthentic dependencies. + * + * This function calls @link OSKextResolveDependencies@/link to find + * dependencies. + */ +CF_EXPORT Boolean +OSKextAuthenticateDependencies(OSKextRef aKext) + ; + +/*! + * @function OSKextIsLoadable + * @abstract + * Returns whether a kext appears loadable for the current architecture. + * + * @param aKext The kext to examine. + * @result + * true if aKext has no problems with validation, + * authentication, or dependency resolution for the current architecture, + * and if it's eligible for the current safe boot mode. + * Returns false otherwise. + * + * @discussion + * This function resolves dependencies for aKext, + * validates and authenticsates aKext and its dependencies, + * and if safe boot is simulated also checks the OSBundleRequired property + * of aKext and its dependencies. If all these tests pass, + * the kext is considered loadable for the current architecture + * (which need not match that of the running kernel). + * + * See @link OSKextSetArchitecture@/link and + * @link OSKextSetSimulatedSafeBoot@/link. + * + * This function calls @link OSKextResolveDependencies@/link to find + * dependencies. + */ +CF_EXPORT Boolean +OSKextIsLoadable(OSKextRef aKext) + ; + +/*! + * @function OSKextCopyDiagnostics + * @abstract Returns diagnostics information for a kext. + * + * @param aKext The kext to get diagnostics for. + * @param typeFlags Flags indicating which diagnostics to retrieve. + * @result + * A dictionary containing diagnostics for aKext, suitable + * for display in an outline view or printout. + * + * @discussion + * You can use this function after validating, authenticating, resolving + * dependencies, or generating debug symbols to get all the problems encountered + * with those operations. + * + * The exact keys and values used for diagnostics are for informational purposes + * only, are not formally defined, and may change without warning. + * + * You can use @link OSKextLogDiagnostics@/link to print nicely-formatted + * reports of any problems found with kexts. + */ +// xxx - need to tie in with the kernel & linker to get link failures +CFDictionaryRef OSKextCopyDiagnostics(OSKextRef aKext, + OSKextDiagnosticsFlags typeFlags) +; + +/*! + * @function OSKextLogDiagnostics + * @abstract Logs specified diagnostics for a kext. + * + * @param aKext The kext to log diagnostics for. + * @param typeFlags Flags indicating which diagnostics to log. + * + * @discussion + * You can use this function after validating, authenticating, resolving + * dependencies, or generating debug symbols to display all the problems + * encountered with those operations. + */ +CF_EXPORT void +OSKextLogDiagnostics( + OSKextRef aKext, + OSKextDiagnosticsFlags typeFlags) + ; + +/*! + * @function OSKextFlushDiagnostics + * @abstract Clears all diagnostics information from a kext. + * + * @param aKext + * The kext to clear diagnostics from. + * Pass NULL to flush diagnostics from all open kexts. + * @param typeFlags Flags indicating which diagnostics to flush. + * + * @discussion + * OSKexts accumulate a fair amount of information as they are created + * and used; when many kext objects are created the total memory + * consumption can be significant. If an application won't be using + * kexts for long periods of time, it can flush this information + * to save memory; the information will later be re-read from disk + * or recreated as necessary. + * + * See also @link OSKextFlushInfoDictionaries@/link, + * @link OSKextFlushDependencies@/link, + * and @link OSKextFlushLoadInfo@/link. + */ +CF_EXPORT void +OSKextFlushDiagnostics(OSKextRef aKext, OSKextDiagnosticsFlags typeFlags) + ; + +#pragma mark Mkext and Prelinked Kernel Files +/********************************************************************* +* Mkext and Prelinked Kernel Files +*********************************************************************/ +// xxx - Use "Flag" or "Mask"? +typedef uint32_t OSKextRequiredFlags +; +#define kOSKextOSBundleRequiredNone 0x0 +#define kOSKextOSBundleRequiredRootFlag 0x1ULL +#define kOSKextOSBundleRequiredLocalRootFlag 0x1ULL << 1 +#define kOSKextOSBundleRequiredNetworkRootFlag 0x1ULL << 2 +#define kOSKextOSBundleRequiredSafeBootFlag 0x1ULL << 3 +#define kOSKextOSBundleRequiredConsoleFlag 0x1ULL << 4 + +/*! + * @function OSKextIsFromMkext + * @abstract Returns whether a kext was created from an mkext archive. + * + * @param aKext The kext to examine. + * @result + * true if aKext was created from an mkext archive, + * false if it was created from an on-disk bundle. + * + * @discussion + * A kext created from an mkext will have only its info dictionary, executable, + * and any resources listed in its the OSBundleStartupResources property. + */ +CF_EXPORT Boolean +OSKextIsFromMkext(OSKextRef aKext) + ; + +/*! + * @function OSKextMatchesRequiredFlags + * @abstract + * Returns whether a kext matches a given set of flags for inclusion in an + * mkext archive. + * + * @param aKext The kext to examine. + * @param requiredFlags + * Flags indicating which values of OSBundleRequired + * are needed. + * @result + * true if aKext's OSBundleRequired property + * matches one of the specified flags, false otherwise. + * + * @discussion + * This function is used to select kexts for inclusion in an mkext archive. + * See @link OSKextFilterRequiredKexts@/link and + * @link OSKextCreateMkext@/link. + */ +CF_EXPORT Boolean +OSKextMatchesRequiredFlags(OSKextRef aKext, + OSKextRequiredFlags requiredFlags) + ; + +/*! + * @function OSKextFilterRequiredKexts + * @abstract + * Filters an array of kexts based on a set of flags + * for inclusion in an mkext archive. + * + * @param kextArray + * The kexts to filter. + * Pass NULL to filter all open kexts. + * @param requiredFlags + * Flags indicating which values of OSBundleRequired + * are needed. + * @result + * An array of kexts matching requiredFlags. + * + * @discussion + * This function is used to select kexts for inclusion in an mkext archive. + * See @link OSKextCreateMkext@/link. + * + */ +CF_EXPORT CFArrayRef +OSKextFilterRequiredKexts(CFArrayRef kextArray, + OSKextRequiredFlags requiredFlags) + ; + +/*! + * @function OSKextCreateMkext + * @abstract Create an mkext file from an array of kexts and set of flags. + * + * @param allocator + * The allocator to use to allocate memory for the new object. + * Pass NULL or kCFAllocatorDefault + * to use the current default allocator. + * @param kextArray + * The kexts to include in the mkext. + * Pass NULL to use all open kexts. + * @param volumeRootURL + * If non-NULL, kexts with this URL as a prefix + * strip it when saving their paths in the mkext. + * This allows creation of mkexts for volumes + * other than the current startup volume. + * @param requiredFlags + * A set of flags that filters kextArray to a subset + * of kexts required for specific startup scenarios + * (typically local disk vs. network). + * @param compressFlag + * true to compress data in the mkext, + * false to include them at full size. + * COMPRESSED MKEXTS ARE NOT SUPPORTED IN THE KERNEL YET. + * @result + * A CFData object containing the mkext file data on success, + * NULL on failure. + * + * @discussion + * This function creates a single-architecture mkext file for the currently + * set library architecture (see @link OSKextSetArchitecture@/link). Kexts + * with executables lacking code for that architecture are not included. + * + * If you want to create a multi-architecture mkext, create a set of single + * architecture mkext files and use lipo(1) or combine them programmatically. + * + * This function generates mkext files in a new format that only works on + * Mac OS X 10.6 or later. + */ +// xxx - add a version param and generate old-format mkexts? +// xxx - add flag to take only most recent version of a given bundle ID? +CF_EXPORT CFDataRef +OSKextCreateMkext( + CFAllocatorRef allocator, + CFArrayRef kextArray, + CFURLRef volumeRootURL, + OSKextRequiredFlags requiredFlags, + Boolean compressFlag) + ; + +/*! + * @function OSKextCreateKextsFromMkextFile + * @abstract Reads all kexts from an mkext file on disk. + * + * @param alocator + * The allocator to use to allocate memory for the new objects. + * Pass NULL or kCFAllocatorDefault + * to use the current default allocator. + * @param mkextURL + * The mkext file URL from which to create kexts. + * @result + * Returns an array containing the kext objects created, + * or NULL on failure. + * + * @discussion + * This function creates kext objects from an mkext file rather than from + * bundles on disk. Kexts created with this function are authenticated using + * the mkext file at mkextURL. + * + * A kext created from an mkext has only its info dictionary, executable, + * and any resources listed in its the OSBundleStartupResources property. + * + * Kexts created from an mkext are not uniqued using filesystem URLs, + * which belong to bundles actually in the filesystem; + * @link OSKextCreate@/link will never return a kext extracted from an mkext + * that originally had the URL given (even though the new mkext format + * stores that original URL). + * This also means that if you open the same mkext file multiple times, + * you will create distinct, identical copies of the kexts in that mkext file. + */ +CF_EXPORT CFArrayRef +OSKextCreateKextsFromMkextFile(CFAllocatorRef allocator, + CFURLRef mkextURL) + ; + +/*! + * @function OSKextCreateKextsFromMkextData + * @abstract Reads all kexts from an mkext file in memory. + * + * @param alocator + * The allocator to use to allocate memory for the new objects. + * Pass NULL or kCFAllocatorDefault + * to use the current default allocator. + * @param mkextData + * The mkext file data from which to create kexts. + * @result + * Returns an array containing the kext objects created, + * or NULL on failure. + * + * @discussion + * This function creates kext objects from an mkext file in memory + * rather than from bundles on disk. Lacking any file in the filesystem, + * kexts created with this function can not be authenticated. + * + * A kext created from an mkext has only its info dictionary, executable, + * and any resources listed in its the OSBundleStartupResources property. + * + * Kexts created from an mkext are not uniqued using filesystem URLs, + * which belong to bundles actually in the filesystem; + * @link OSKextCreate@/link will never return a kext extracted from an mkext + * that originally had the URL given (even though the new mkext format + * stores that original URL). + * This also means that if you open the same mkext file multiple times, + * you will create distinct, identical copies of the kexts in that mkext file. + */ +CF_EXPORT CFArrayRef +OSKextCreateKextsFromMkextData(CFAllocatorRef allocator, + CFDataRef mkextData) + ; + +/*! + * @function OSKextCreatePrelinkedKernel + * @abstract Creates a prelinked kernel from a kernel file and all open kexts. + * + * @param kernelImage The kernel image to use. + * @param kextArray + * The kexts to include in the prelinked kernel. + * Pass NULL to consult the running kernel + * for kexts to include from those open; + * the current architecture must match the runninng kernel's. + * @param volumeRootURL + * If non-NULL, kexts with this URL as a prefix + * strip it when saving their paths in the prelinked kernel. + * This allows creation of prelinked kernels from folders + * other than /System/Library/Extensions. + * @param needAllFlag + * If true and any kext fails to link, + * the skipAuthenticationFlag returns NULL. + * @param skipAuthenticationFlag + * If true, kexts are not authenticated for inclusion + * in the prelinked kernel. + * @param printDiagnosticsFlag + * If true, problems with the kexts that prevent + * inclusion of a kext in the prelinked kernel are logged via + * @link OSKextLogDiagnostics OSKextLogDiagnostics@/link. + * @param symbolsOut + * If non-NULL debug symbols for kernelImage + * and all kexts included in the result are returned by reference. + * + * @result + * A CFData object containing the prelinked kernel image based + * on the running kernel. + * Returns NULL if needAllFlag is true + * and any kext fails to link. + */ +CF_EXPORT CFDataRef +OSKextCreatePrelinkedKernel( + CFDataRef kernelImage, + CFArrayRef kextArray, + CFURLRef volumeRootURL, + Boolean needAllFlag, + Boolean skipAuthenticationFlag, + Boolean printDiagnosticsFlag, + CFDictionaryRef * symbolsOut) + ; + +/*! + * @function OSKextotherCFBundleVersionIsLoaded + * @abstract + * Returns whether another version of a given kext is loaded in the kernel. + * + * @param aKext The kext to examine. + * @result + * true if a kext with the same identifier, + * but a different version or UUID + * from aKext, is loaded in the kernel. + * Returns false if aKext is loaded or if + * no kext with the same identifier is loaded. + * + * @discussion + * You must call @link OSKextReadLoadedKextInfo@/link for this flag to be meaningful, + * which in turn requires the current library architecture to match that + * of the running kernel. + * Use @link OSKextIsLoaded@/link to check whether aKext + * itself is loaded. + */ +CF_EXPORT Boolean OSKextotherCFBundleVersionIsLoaded(OSKextRef kext, Boolean* uuidFlag); + +__END_DECLS + +#endif /* __OSKEXT_H__ */ diff --git a/IOKit/OSMessageNotification.h b/IOKit/OSMessageNotification.h new file mode 100644 index 0000000..7d7b5e5 --- /dev/null +++ b/IOKit/OSMessageNotification.h @@ -0,0 +1,158 @@ +/* + * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * + * HISTORY + * + */ + +#ifndef __OS_OSMESSAGENOTIFICATION_H +#define __OS_OSMESSAGENOTIFICATION_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +enum { + kFirstIOKitNotificationType = 100, + kIOServicePublishNotificationType = 100, + kIOServiceMatchedNotificationType = 101, + kIOServiceTerminatedNotificationType = 102, + kIOAsyncCompletionNotificationType = 150, + kIOServiceMessageNotificationType = 160, + kLastIOKitNotificationType = 199 +}; + +enum { + kOSNotificationMessageID = 53, + kOSAsyncCompleteMessageID = 57, + kMaxAsyncArgs = 16 +}; + +enum { + kIOAsyncReservedIndex = 0, + kIOAsyncReservedCount, + + kIOAsyncCalloutFuncIndex = kIOAsyncReservedCount, + kIOAsyncCalloutRefconIndex, + kIOAsyncCalloutCount, + + kIOMatchingCalloutFuncIndex = kIOAsyncReservedCount, + kIOMatchingCalloutRefconIndex, + kIOMatchingCalloutCount, + + kIOInterestCalloutFuncIndex = kIOAsyncReservedCount, + kIOInterestCalloutRefconIndex, + kIOInterestCalloutServiceIndex, + kIOInterestCalloutCount +}; + + + +// -------------- +enum { + kOSAsyncRef64Count = 8, + kOSAsyncRef64Size = kOSAsyncRef64Count * ((int) sizeof(io_user_reference_t)) +}; +typedef io_user_reference_t OSAsyncReference64[kOSAsyncRef64Count]; + +struct OSNotificationHeader64 { + mach_msg_size_t size; /* content size */ + natural_t type; + OSAsyncReference64 reference; + +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) + unsigned char content[]; +#else + unsigned char content[0]; +#endif +}; + +#pragma pack(4) +struct IOServiceInterestContent64 { + natural_t messageType; + io_user_reference_t messageArgument[1]; +}; +#pragma pack() +// -------------- + +#if !KERNEL_USER32 + +enum { + kOSAsyncRefCount = 8, + kOSAsyncRefSize = 32 +}; +typedef natural_t OSAsyncReference[kOSAsyncRefCount]; + +struct OSNotificationHeader { + mach_msg_size_t size; /* content size */ + natural_t type; + OSAsyncReference reference; + +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) + unsigned char content[]; +#else + unsigned char content[0]; +#endif +}; + +#pragma pack(4) +struct IOServiceInterestContent { + natural_t messageType; + void * messageArgument[1]; +}; +#pragma pack() + +#endif /* KERNEL_USER32 */ + +struct IOAsyncCompletionContent { + IOReturn result; +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) + void * args[] __attribute__ ((packed)); +#else + void * args[0] __attribute__ ((packed)); +#endif +}; + +#ifndef __cplusplus +typedef struct OSNotificationHeader OSNotificationHeader; +typedef struct IOServiceInterestContent IOServiceInterestContent; +typedef struct IOAsyncCompletionContent IOAsyncCompletionContent; +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* __OS_OSMESSAGENOTIFICATION_H */ + diff --git a/IOKit/hid/IOHIDDisplay.h b/IOKit/hid/IOHIDDisplay.h new file mode 100644 index 0000000..e71efed --- /dev/null +++ b/IOKit/hid/IOHIDDisplay.h @@ -0,0 +1,131 @@ +/* + +IOHIDDisplay.h ... I/O Kit HID Display + +Copyright (c) 2009 KennyTM~ +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +* 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. +* Neither the name of the KennyTM~ 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + +*/ + +#ifndef IOHID_DISPLAY_H +#define IOHID_DISPLAY_H + +#include +#include +#include "IOHIDNotification.h" + +#if __cplusplus +extern "C" { +#endif + + typedef struct __IOHIDDisplay +#if 0 + { + CFRuntimeBase _base; // 0, 4 + void* client; // 8 + io_service_t service; // c + CFRunLoopRef runloop; // 10 + CFStringRef mode; // 14, *not retained* + IONotificationPortRef port; // 18 + io_object_t notification; // 1c + CFMutableSetRef removalNotifications; // 20, set of IOHIDNotification's + CFMutableDictionaryRef properties; // 24 + int logLevel; // 28 + float brightness; // 34 + float brightnessMin; // 38 + float brightnessMax; // 3c + float brightnessFactor; // 40; + float x44; // 44 + float ambient; // 4c + float brightnessAutoWeightMin; // 54 + float brightnessAutoWeightMax; // 58 + float x60; // 60 + float x64; // 64 + float x68; // 68 + float x70; // 70 + float x74; // 74 + int x78; // 78 + int x80; // 80 + CFTimeInterval fadePeriod; // 84 + } +#endif + * IOHIDDisplayRef; + +#pragma mark - +#pragma mark Creators + + CFTypeID IOHIDDisplayGetTypeID(void); + IOHIDDisplayRef _IOHIDDisplayCreate(CFAllocatorRef allocator, io_service_t service); + +#pragma mark - +#pragma mark Accessors + + float _IOHIDDisplayGetAmbient(IOHIDDisplayRef display); + void _IOHIDDisplaySetAmbient(IOHIDDisplayRef display, float ambient); + + float _IOHIDDisplayGetBrightness(IOHIDDisplayRef display); + void _IOHIDDisplaySetBrightness(IOHIDDisplayRef display, float brightness); + void _IOHIDDisplaySetBrightnessMax(IOHIDDisplayRef display, float brightnessMax); + + void _IOHIDDisplaySetBrightnessFactor(IOHIDDisplayRef display, float factor); + float _IOHIDDisplayGetBrightnessFactor(IOHIDDisplayRef display); + + void IOHIDDisplaySetProperty(IOHIDDisplayRef display, CFStringRef property, CFTypeRef value); + CFTypeRef IOHIDDisplayGetProperty(IOHIDDisplayRef display, CFStringRef property); + + CFTypeRef _IOHIDDisplayGetClient(IOHIDDisplayRef display); + +#pragma mark - +#pragma mark Actions + + void _IOHIDDisplayUnscheduleWithRunLoop(IOHIDDisplayRef display, CFRunLoopRef runloop, CFStringRef mode); + void _IOHIDDisplayScheduleWithRunLoop(IOHIDDisplayRef display, CFRunLoopRef runloop, CFStringRef mode); + + IOHIDNotificationRef IOHIDDisplayCreateRemovalNotification(IOHIDDisplayRef display, IOHIDNotificationCallback callback, void* target, void* refcon); + + Boolean _IOHIDDisplayOpen(IOHIDDisplayRef display, CFTypeRef client); + void _IOHIDDisplayClose(IOHIDDisplayRef display, CFTypeRef client); + +#pragma mark - +#pragma mark Constants + + static const CFStringRef kIOHIDDisplayPropertyBrightness = CFSTR("DisplayBrightness"); // float + static const CFStringRef kIOHIDDisplayPropertyBrightnessAuto = CFSTR("DisplayBrightnessAuto"); // boolean + static const CFStringRef kIOHIDDisplayPropertyBrightnessMin = CFSTR("DisplayBrightnessMin"); // float + static const CFStringRef kIOHIDDisplayPropertyBrightnessMax = CFSTR("DisplayBrightnessMax"); // float + static const CFStringRef kIOHIDDisplayPropertyBrightnessAutoWeightMax = CFSTR("DisplayBrightnessAutoWeightMax"); // float + static const CFStringRef kIOHIDDisplayPropertyBrightnessAutoWeightMin = CFSTR("DisplayBrightnessAutoWeightMin"); // float + static const CFStringRef kIOHIDDisplayPropertyBrightnessFactor = CFSTR("DisplayBrightnessFactor"); // float + static const CFStringRef kIOHIDDisplayPropertyBrightnessFactorWithFade = CFSTR("DisplayBrightnessFactorWithFade"); // float + static const CFStringRef kIOHIDDisplayPropertyBrightnessFadePeriod = CFSTR("DisplayBrightnessFadePeriod"); // float + static const CFStringRef kIOHIDDisplayPropertyLogLevel = CFSTR("LogLevel"); // int + +#if __cplusplus +} +#endif + +#endif + diff --git a/IOKit/hid/IOHIDEvent.h b/IOKit/hid/IOHIDEvent.h new file mode 100644 index 0000000..e1438f7 --- /dev/null +++ b/IOKit/hid/IOHIDEvent.h @@ -0,0 +1,220 @@ +/* + +IOHIDEvent.h ... Header for IOHIDEvent*** functions. + +Copyright (c) 2009 KennyTM~ +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +* 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. +* Neither the name of the KennyTM~ 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + +*/ + +// With reference to http://www.opensource.apple.com/source/IOHIDFamily/IOHIDFamily-308/IOHIDFamily/IOHIDEvent.h . + +#ifndef IOKIT_HID_IOHIDEVENT_H +#define IOKIT_HID_IOHIDEVENT_H 1 + +#include +#include +#include +#include +#include + +#if __cplusplus +extern "C" { +#endif + + typedef struct __IOHIDEvent +#if 0 + { + CFRuntimeBase base; // 0, 4 + AbsoluteTime _timeStamp; // 8, c + int x10; // 10 + int x14; // 14 + IOOptionBits _options; // 18 + unsigned _typeMask; // 1c + CFMutableArrayRef _children; // 20 + struct __IOHIDEvent* _parent; // 24 + + size_t recordSize; // 28 + void record[]; + } +#endif + * IOHIDEventRef; + +#pragma mark - +#pragma mark GetTypeID + + /*! @function IOHIDEventGetTypeID */ + CFTypeID IOHIDEventGetTypeID(void); + +#pragma mark - +#pragma mark Generic creation functions + + IOHIDEventRef IOHIDEventCreateCopy(CFAllocatorRef allocator, IOHIDEventRef event); + /*! @function IOHIDEventCreate + @abstract Create an IOHIDEvent. + @discussion All event-specific parameters are zeroed. */ + IOHIDEventRef IOHIDEventCreate(CFAllocatorRef allocator, IOHIDEventType type, AbsoluteTime timeStamp, IOOptionBits options); + + CFMutableDataRef IOHIDEventCreateData(CFAllocatorRef allocator, IOHIDEventRef event); + IOHIDEventRef IOHIDEventCreateWithData(CFAllocatorRef allocator, CFDataRef data); + +#pragma mark - +#pragma mark Predefined creation functions + + IOHIDEventRef IOHIDEventCreateProgressEvent(CFAllocatorRef allocator, AbsoluteTime timeStamp, + uint32_t eventType, IOHIDFloat level, IOOptionBits options); + IOHIDEventRef IOHIDEventCreateVendorDefinedEvent(CFAllocatorRef allocator, AbsoluteTime timeStamp, + uint16_t usagePage, uint16_t usage, uint32_t version, const uint8_t* data, uint32_t length, IOOptionBits options); + IOHIDEventRef IOHIDEventCreateSwipeEvent(CFAllocatorRef allocator, AbsoluteTime timeStamp, IOHIDSwipeMask swipeMask, IOOptionBits options); + + /*! @function IOHIDEventCreateDigitizerEvent + @abstract Create a digitizer event. You should use the more specialized methods instead. */ + IOHIDEventRef IOHIDEventCreateDigitizerEvent(CFAllocatorRef allocator, AbsoluteTime timeStamp, IOHIDDigitizerTransducerType type, + uint32_t index, uint32_t identity, uint32_t eventMask, uint32_t buttonMask, + IOHIDFloat x, IOHIDFloat y, IOHIDFloat z, IOHIDFloat tipPressure, IOHIDFloat barrelPressure, + Boolean range, Boolean touch, IOOptionBits options); + IOHIDEventRef IOHIDEventCreateDigitizerFingerEventWithQuality(CFAllocatorRef allocator, AbsoluteTime timeStamp, + uint32_t index, uint32_t identity, uint32_t eventMask, + IOHIDFloat x, IOHIDFloat y, IOHIDFloat z, IOHIDFloat tipPressure, IOHIDFloat twist, + IOHIDFloat minorRadius, IOHIDFloat majorRadius, IOHIDFloat quality, IOHIDFloat density, IOHIDFloat irregularity, + Boolean range, Boolean touch, IOOptionBits options); + /*! @function IOHIDEventCreateDigitizerFingerEvent + @abstract Create a finger digitizer event with default qualities. + @discussion The default qualities are: + - minorRadius = 5 mm, + - majorRadius = 5 mm, + - quality = 1, + - density = 1, + - irregularity = 1. */ + IOHIDEventRef IOHIDEventCreateDigitizerFingerEvent(CFAllocatorRef allocator, AbsoluteTime timeStamp, + uint32_t index, uint32_t identity, uint32_t eventMask, + IOHIDFloat x, IOHIDFloat y, IOHIDFloat z, IOHIDFloat tipPressure, IOHIDFloat twist, + Boolean range, Boolean touch, IOOptionBits options); + IOHIDEventRef IOHIDEventCreateDigitizerStylusEventWithPolarOrientation(CFAllocatorRef allocator, AbsoluteTime timeStamp, + uint32_t index, uint32_t identity, uint32_t eventMask, uint32_t buttonMask, + IOHIDFloat x, IOHIDFloat y, IOHIDFloat z, IOHIDFloat tipPressure, IOHIDFloat barrelPressure, + IOHIDFloat twist, IOHIDFloat altitude, IOHIDFloat azimuth, + Boolean range, Boolean invert, IOOptionBits options); + /*! @function IOHIDEventCreateDigitizerStylusEvent + @discussion Same as IOHIDEventCreateDigitizerStylusEventWithPolarOrientation? */ + IOHIDEventRef IOHIDEventCreateDigitizerStylusEvent(CFAllocatorRef allocator, AbsoluteTime timeStamp, + uint32_t index, uint32_t identity, uint32_t eventMask, uint32_t buttonMask, + IOHIDFloat x, IOHIDFloat y, IOHIDFloat z, IOHIDFloat tipPressure, IOHIDFloat barrelPressure, + IOHIDFloat twist, IOHIDFloat altitude, IOHIDFloat azimuth, + Boolean range, Boolean invert, IOOptionBits options); + + IOHIDEventRef IOHIDEventCreateProximtyEvent(CFAllocatorRef allocator, AbsoluteTime timeStamp, IOHIDProximityDetectionMask detectionMask, IOOptionBits options); +#define IOHIDEventCreateProximityEvent IOHIDEventCreateProximtyEvent + IOHIDEventRef IOHIDEventCreateAmbientLightSensorEvent(CFAllocatorRef allocator, AbsoluteTime timeStamp, IOHIDFloat level, IOOptionBits options); + + /*! @function IOHIDEventCreateMouseEvent + @abstract Create an mouse event, with pressure of 1.0. */ + IOHIDEventRef IOHIDEventCreateMouseEvent(CFAllocatorRef allocator, AbsoluteTime timeStamp, + IOHIDFloat x, IOHIDFloat y, IOHIDFloat z, uint32_t buttonMask, IOOptionBits options); + /*! @function IOHIDEventCreateMouseEventWithPressure + @abstract Create an mouse event with pressure. + @discussion The mouse is considered clicked when the pressure is > 0.15. */ + IOHIDEventRef IOHIDEventCreateMouseEventWithPressure(CFAllocatorRef allocator, AbsoluteTime timeStamp, + IOHIDFloat x, IOHIDFloat y, IOHIDFloat z, uint32_t buttonMask, IOHIDFloat pressure, IOOptionBits options); + /*! @function IOHIDEventCreateButtonEvent + @abstract Create an button event, with pressure of 1.0. */ + IOHIDEventRef IOHIDEventCreateButtonEvent(CFAllocatorRef allocator, AbsoluteTime timeStamp, uint32_t buttonMask, IOOptionBits options); + /*! @function IOHIDEventCreateButtonEventWithPressure + @abstract Create an button event with pressure. + @discussion The button is considered pressed when the pressure is > 0.15. */ + IOHIDEventRef IOHIDEventCreateButtonEventWithPressure(CFAllocatorRef allocator, AbsoluteTime timeStamp, uint32_t buttonMask, IOHIDFloat pressure, IOOptionBits options); + + IOHIDEventRef IOHIDEventCreateKeyboardEvent(CFAllocatorRef allocator, AbsoluteTime timeStamp, uint16_t usagePage, uint16_t usage, Boolean down, IOHIDEventOptionBits flags); + + IOHIDEventRef IOHIDEventCreateAccelerometerEvent(CFAllocatorRef allocator, AbsoluteTime timeStamp, IOHIDFloat x, IOHIDFloat y, IOHIDFloat z, IOOptionBits options); + IOHIDEventRef IOHIDEventCreatePolarOrientationEvent(CFAllocatorRef allocator, AbsoluteTime timeStamp, IOHIDFloat x, IOHIDFloat y, IOHIDFloat z, IOOptionBits options); + IOHIDEventRef IOHIDEventCreateOrientationEvent(CFAllocatorRef allocator, AbsoluteTime timeStamp, IOHIDFloat x, IOHIDFloat y, IOHIDFloat z, IOOptionBits options); + IOHIDEventRef IOHIDEventCreateVelocityEvent(CFAllocatorRef allocator, AbsoluteTime timeStamp, IOHIDFloat x, IOHIDFloat y, IOHIDFloat z, IOOptionBits options); + IOHIDEventRef IOHIDEventCreateScaleEvent(CFAllocatorRef allocator, AbsoluteTime timeStamp, IOHIDFloat x, IOHIDFloat y, IOHIDFloat z, IOOptionBits options); + IOHIDEventRef IOHIDEventCreateScrollEvent(CFAllocatorRef allocator, AbsoluteTime timeStamp, IOHIDFloat x, IOHIDFloat y, IOHIDFloat z, IOOptionBits options); + IOHIDEventRef IOHIDEventCreateRotationEvent(CFAllocatorRef allocator, AbsoluteTime timeStamp, IOHIDFloat x, IOHIDFloat y, IOHIDFloat z, IOOptionBits options); + IOHIDEventRef IOHIDEventCreateTranslationEvent(CFAllocatorRef allocator, AbsoluteTime timeStamp, IOHIDFloat x, IOHIDFloat y, IOHIDFloat z, IOOptionBits options); + +#pragma mark - +#pragma mark Accessors + + IOHIDEventType IOHIDEventGetType(IOHIDEventRef event); + + AbsoluteTime IOHIDEventGetTimeStamp(IOHIDEventRef event); + void IOHIDEventSetTimeStamp(IOHIDEventRef event, AbsoluteTime timeStamp); + + uint32_t IOHIDEventGetEventFlags(IOHIDEventRef event); + void IOHIDEventSetEventFlags(IOHIDEventRef event, uint32_t eventFlags); + Boolean IOHIDEventIsAbsolute(IOHIDEventRef event); + + IOHIDEventRef IOHIDEventGetParent(IOHIDEventRef event); + CFArrayRef IOHIDEventGetChildren(IOHIDEventRef event); + + void IOHIDEventGetVendorDefinedData(IOHIDEventRef event, uint32_t* length, uint8_t** data); + +#pragma mark - +#pragma mark Subevents + + /*! @function IOHIDEventGetEventWithOptions + @abstract Get the deepest event that bears the specified type and matches the options. + @discussion If any of the top 4 bits of options is set (i.e. (options & 0xF0000000) != 0), the children of this event will not be checked. */ + IOHIDEventRef IOHIDEventGetEventWithOptions(IOHIDEventRef event, IOHIDEventType type, IOOptionBits options); + /*! @function IOHIDEventGetEvent + @abstract Get the event that bears the specified type. + @discussion Equivalent to IOHIDEventGetEventWithOptions(event, type, 0xF0000000); */ + IOHIDEventRef IOHIDEventGetEvent(IOHIDEventRef event, IOHIDEventType type); + + void IOHIDEventSetFloatValueWithOptions(IOHIDEventRef event, IOHIDEventField field, IOHIDFloat value, IOOptionBits options); + void IOHIDEventSetFloatValue(IOHIDEventRef event, IOHIDEventField field, IOHIDFloat value); + void IOHIDEventSetIntegerValueWithOptions(IOHIDEventRef event, IOHIDEventField field, int value, IOOptionBits options); + void IOHIDEventSetIntegerValue(IOHIDEventRef event, IOHIDEventField field, int value); + void IOHIDEventSetPositionWithOptions(IOHIDEventRef event, IOHIDEventField field, IOHID3DPoint position, IOOptionBits options); + void IOHIDEventSetPosition(IOHIDEventRef event, IOHIDEventField field, IOHID3DPoint position); + + IOHIDFloat IOHIDEventGetFloatValueWithOptions(IOHIDEventRef event, IOHIDEventField field, IOOptionBits options); + IOHIDFloat IOHIDEventGetFloatValue(IOHIDEventRef event, IOHIDEventField field); + int IOHIDEventGetIntegerValueWithOptions(IOHIDEventRef event, IOHIDEventField field, IOOptionBits options); + int IOHIDEventGetIntegerValue(IOHIDEventRef event, IOHIDEventField field); + IOHID3DPoint IOHIDEventGetPositionWithOptions(IOHIDEventRef event, IOHIDEventField field, IOOptionBits options); + IOHID3DPoint IOHIDEventGetPosition(IOHIDEventRef event, IOHIDEventField field); + + /*! @function IOHIDEventConformsToWithOptions + @abstract Returns if the event or any of its children bears the specified type and options. + @discussion If any of the top 4 bits of options is set (i.e. (options & 0xF0000000) != 0), the children of this event will not be checked. */ + Boolean IOHIDEventConformsToWithOptions(IOHIDEventRef event, IOHIDEventType type, IOOptionBits options); + /*! @function IOHIDEventConformsTo + @abstract Returns if the event bears the specified type. + @discussion Equivalent to IOHIDEventConformsToWithOptions(event, type, 0xF0000000); */ + Boolean IOHIDEventConformsTo(IOHIDEventRef event, IOHIDEventType type); + + void IOHIDEventRemoveEvent(IOHIDEventRef event, IOHIDEventRef childEvent); + void IOHIDEventAppendEvent(IOHIDEventRef event, IOHIDEventRef childEvent); + +#if __cplusplus +} +#endif + +#endif diff --git a/IOKit/hid/IOHIDEventData.h b/IOKit/hid/IOHIDEventData.h new file mode 100644 index 0000000..e2f781f --- /dev/null +++ b/IOKit/hid/IOHIDEventData.h @@ -0,0 +1,1020 @@ +/* + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef _IOKIT_HID_IOHIDEVENTDATA_H +#define _IOKIT_HID_IOHIDEVENTDATA_H + +#include +#include + +#ifdef KERNEL + #include + + #define IOHIDEventRef IOHIDEvent * +#else + #include + + typedef struct IOHIDEventData IOHIDEventData; +#endif + +//============================================================================== +// IOHIDEventData Declarations +//============================================================================== + +#define IOHIDEVENT_BASE \ + uint32_t size; \ + IOHIDEventType type; \ + uint64_t timestamp; \ + uint32_t options; + +/*! + @typedef IOHIDEventData + @abstract + @discussion + @field size Size, in bytes, of the memory detailing this + particular event + @field type Type of this particular event + @field options Event specific options +*/ + +struct IOHIDEventData{ + IOHIDEVENT_BASE; +}; + +typedef struct _IOHIDVendorDefinedEventData { + IOHIDEVENT_BASE; + uint16_t usagePage; + uint16_t usage; + uint32_t version; + uint32_t length; + uint8_t data[0]; +} IOHIDVendorDefinedEventData; + +enum { + kIOHIDKeyboardIsRepeat = 0x00010000 +}; + +typedef struct _IOHIDKeyboardEventData { + IOHIDEVENT_BASE; // options = kHIDKeyboardRepeat + uint16_t usagePage; + uint16_t usage; + boolean_t down; +} IOHIDKeyboardEventData; + +enum { + kIOHIDEventOptionIgnore = 0xf0000000 +}; + +enum { + kIOHIDTransducerRange = 0x00010000, + kIOHIDTransducerTouch = 0x00020000, + kIOHIDTransducerInvert = 0x00040000, +}; + +enum { + kIOHIDDigitizerOrientationTypeTilt = 0, + kIOHIDDigitizerOrientationTypePolar, + kIOHIDDigitizerOrientationTypeQuality +}; +typedef uint8_t IOHIDDigitizerOrientationType; + +#define IOHIDAXISEVENT_BASE \ + struct { \ + IOFixed x; \ + IOFixed y; \ + IOFixed z; \ + } position; + +typedef struct _IOHIDAxisEventData { + IOHIDEVENT_BASE; // options = kHIDAxisRelative + IOHIDAXISEVENT_BASE; +} IOHIDAxisEventData, IOHIDTranslationData, IOHIDRotationEventData, IOHIDScrollEventData, IOHIDScaleEventData, IOHIDVelocityData, IOHIDOrientationEventData; + +typedef struct _IOHIDAccelerometerEventData { + IOHIDEVENT_BASE; // options = kHIDAxisRelative + IOHIDAXISEVENT_BASE; + uint32_t acclType; +} IOHIDAccelerometerEventData; + +typedef struct _IOHIDAmbientLightSensorEventData { + IOHIDEVENT_BASE; // options = kHIDAxisRelative + uint32_t level; + uint32_t ch0; + uint32_t ch1; + Boolean brightnessChanged; +} IOHIDAmbientLightSensorEventData; + +typedef struct _IOHIDTemperatureEventData { + IOHIDEVENT_BASE; + IOFixed level; +} IOHIDTemperatureEventData; + +typedef struct _IOHIDProximityEventData { + IOHIDEVENT_BASE; + uint32_t detectionMask; +} IOHIDProximityEventData; + +typedef struct _IOHIDProgressEventData { + IOHIDEVENT_BASE; + uint32_t eventType; + IOFixed level; +} IOHIDProgressEventData; + + +#define IOHIDBUTTONEVENT_BASE \ + struct { \ + uint32_t buttonMask; \ + IOFixed pressure; \ + uint8_t buttonNumber; \ + uint8_t clickState; \ + } button; + +typedef struct _IOHIDButtonEventData { + IOHIDEVENT_BASE; + IOHIDBUTTONEVENT_BASE; +} IOHIDButtonEventData; + +typedef struct _IOHIDMouseEventData { + IOHIDEVENT_BASE; + IOHIDAXISEVENT_BASE; + IOHIDBUTTONEVENT_BASE; +} IOHIDMouseEventData; + + +typedef struct _IOHIDDigitizerEventData { + IOHIDEVENT_BASE; // options = kIOHIDTransducerRange, kHIDTransducerTouch, kHIDTransducerInvert + IOHIDAXISEVENT_BASE; // 3c, 40, 44 + + uint32_t transducerIndex; + uint32_t transducerType; // could overload this to include that both the hand and finger id. + uint32_t identity; // Specifies a unique ID of the current transducer action. + uint32_t eventMask; // the type of event that has occurred: range, touch, position + uint32_t childEventMask; // CHILD: the type of event that has occurred: range, touch, position + + uint32_t buttonMask; // Bit field representing the current button state + // Pressure field are assumed to be scaled from 0.0 to 1.0 + IOFixed tipPressure; // Force exerted against the digitizer surface by the transducer. + IOFixed barrelPressure; // Force exerted directly by the user on a transducer sensor. + + IOFixed twist; // Specifies the clockwise rotation of the cursor around its own major axis. Unsure it the device should declare units via properties or event. My first inclination is force degrees as the is the unit already expected by AppKit, Carbon and OpenGL. + uint32_t orientationType; // Specifies the orientation type used by the transducer. + union { + struct { // X Tilt and Y Tilt are used together to specify the tilt away from normal of a digitizer transducer. In its normal position, the values of X Tilt and Y Tilt for a transducer are both zero. + IOFixed x; // This quantity is used in conjunction with Y Tilt to represent the tilt away from normal of a transducer, such as a stylus. The X Tilt value represents the plane angle between the Y-Z plane and the plane containing the transducer axis and the Y axis. A positive X Tilt is to the right. + IOFixed y; // This value represents the angle between the X-Z and transducer-X planes. A positive Y Tilt is toward the user. + } tilt; + struct { // X Tilt and Y Tilt are used together to specify the tilt away from normal of a digitizer transducer. In its normal position, the values of X Tilt and Y Tilt for a transducer are both zero. + IOFixed altitude; //The angle with the X-Y plane though a signed, semicicular range. Positive values specify an angle downward and toward the positive Z axis. + IOFixed azimuth; // Specifies the counter clockwise rotation of the cursor around the Z axis though a full circular range. + } polar; + struct { + IOFixed quality; // If set, indicates that the transducer is sensed to be in a relatively noise-free region of digitizing. + IOFixed density; + IOFixed irregularity; + IOFixed majorRadius; // units in mm + IOFixed minorRadius; // units in mm + } quality; + }orientation; +} IOHIDDigitizerEventData; + +typedef struct _IOHIDSwipeEventData { + IOHIDEVENT_BASE; + IOHIDSwipeMask swipeMask; +} IOHIDSwipeEventData; + + +/*! + @typedef IOHIDSystemQueueElement + @abstract Memory structure defining the layout of each event queue element + @discussion The IOHIDEventQueueElement represents a portion of mememory in the + new IOHIDEventQueue. It is possible that a event queue element + can contain multiple interpretations of a given event. The first + event is always considered the primary event. + @field version Version of the event queue element + @field size Size, in bytes, of this particular event queue element + @field timeStamp Time at which event was dispatched + @field deviceID ID of the sending device + @field options Options for further developement + @field eventCount The number of events contained in this transaction + @field events Begining offset of contiguous mememory that contains the + pertinent event data +*/ +typedef struct _IOHIDSystemQueueElement { + uint64_t timeStamp; + uint64_t deviceID; + uint32_t options; + uint32_t eventCount; + IOHIDEventData events[]; +} IOHIDSystemQueueElement; + +//****************************************************************************** +// MACROS +//****************************************************************************** + +#define IOHIDEventFieldEventType(field) ((field >> 16) & 0xffff) +#define IOHIDEventFieldOffset(field) (field & 0xffff) +#define IOHIDEventGetSize(type,size) \ +{ \ + switch ( type ) { \ + case kIOHIDEventTypeNULL: \ + size = sizeof(IOHIDEventData);\ + break; \ + case kIOHIDEventTypeVendorDefined:\ + size = sizeof(IOHIDVendorDefinedEventData);\ + break; \ + case kIOHIDEventTypeKeyboard: \ + size = sizeof(IOHIDKeyboardEventData);\ + break; \ + case kIOHIDEventTypeTranslation:\ + case kIOHIDEventTypeRotation: \ + case kIOHIDEventTypeScroll: \ + case kIOHIDEventTypeScale: \ + case kIOHIDEventTypeVelocity: \ + case kIOHIDEventTypeOrientation:\ + size = sizeof(IOHIDAxisEventData);\ + break; \ + case kIOHIDEventTypeAccelerometer:\ + size = sizeof(IOHIDAccelerometerEventData);\ + break;\ + case kIOHIDEventTypeAmbientLightSensor:\ + size = sizeof(IOHIDAmbientLightSensorEventData);\ + break; \ + case kIOHIDEventTypeProximity: \ + size = sizeof(IOHIDProximityEventData);\ + break; \ + case kIOHIDEventTypeButton: \ + size = sizeof(IOHIDButtonEventData);\ + break; \ + case kIOHIDEventTypeDigitizer: \ + size = sizeof(IOHIDDigitizerEventData);\ + break; \ + case kIOHIDEventTypeTemperature:\ + size = sizeof(IOHIDTemperatureEventData);\ + break; \ + case kIOHIDEventTypeSwipe:\ + size = sizeof(IOHIDSwipeEventData);\ + break; \ + case kIOHIDEventTypeMouse:\ + size = sizeof(IOHIDMouseEventData);\ + break; \ + case kIOHIDEventTypeProgress:\ + size = sizeof(IOHIDProgressEventData);\ + break; \ + default: \ + size = 0; \ + break; \ + } \ +} +#define IOHIDEventGetQueueElementSize(type,size)\ +{ \ + IOHIDEventGetSize(type,size); \ + size += sizeof(IOHIDSystemQueueElement); \ +} + +#ifdef KERNEL + #ifdef HIDEVENTFIXED + #define IOHIDEventValueFloat(value) (value) + #define IOHIDEventValueFixed(value) (value) + #else + #define IOHIDEventValueFloat(value) (value >> 16) + #define IOHIDEventValueFixed(value) (value << 16) + #endif + #define IOHIDEventGetEventWithOptions(event, type, options) event->getEvent(type, options) + #define GET_EVENTDATA(event) event->_data +#else + #define IOHIDEventValueFloat(value) (value / 65536.0) + #define IOHIDEventValueFixed(value) (value * 65536) + #define GET_EVENTDATA(event) event->eventData +#endif + +//============================================================================== +// IOHIDEventGetValue MACRO +//============================================================================== +#define GET_EVENTDATA_VALUE(eventData, fieldEvType, fieldOffset, value)\ +{ \ + switch ( fieldEvType ) { \ + case kIOHIDEventTypeNULL: \ + switch ( fieldOffset ) { \ + case IOHIDEventFieldOffset(kIOHIDEventFieldIsRelative): \ + value = (eventData->options & kIOHIDEventOptionIsAbsolute) == 0; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldIsCollection): \ + value = (eventData->options & kIOHIDEventOptionIsCollection) != 0; \ + break; \ + }; break; \ + case kIOHIDEventTypeVendorDefined: \ + { \ + IOHIDVendorDefinedEventData * sysDef = (IOHIDVendorDefinedEventData*)eventData; \ + switch ( fieldOffset ) { \ + case IOHIDEventFieldOffset(kIOHIDEventFieldVendorDefinedUsagePage): \ + value = sysDef->usagePage; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldVendorDefinedUsage): \ + value = sysDef->usage; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldVendorDefinedVersion): \ + value = sysDef->version; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldVendorDefinedDataLength): \ + value = sysDef->length; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldVendorDefinedData): \ + if (sysDef->data) \ + value = *((typeof(value)*) sysDef->data); \ + break; \ + }; \ + } \ + break; \ + case kIOHIDEventTypeProgress: \ + { \ + IOHIDProgressEventData * progress = (IOHIDProgressEventData*)eventData; \ + switch ( fieldOffset ) { \ + case IOHIDEventFieldOffset(kIOHIDEventFieldProgressEventType): \ + value = progress->eventType; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldProgressLevel): \ + value = IOHIDEventValueFloat(progress->level); \ + break; \ + }; \ + } \ + break; \ + case kIOHIDEventTypeButton: \ + { \ + IOHIDButtonEventData * button = (IOHIDButtonEventData*)eventData; \ + switch ( fieldOffset ) { \ + case IOHIDEventFieldOffset(kIOHIDEventFieldButtonMask): \ + value = button->button.buttonMask; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldButtonNumber): \ + value = button->button.buttonNumber; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldButtonClickCount): \ + value = button->button.clickState; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldButtonPressure): \ + value = IOHIDEventValueFloat(button->button.pressure); \ + break; \ + }; \ + } \ + break; \ + case kIOHIDEventTypeAccelerometer: \ + { \ + IOHIDAccelerometerEventData * accl = (IOHIDAccelerometerEventData*)eventData; \ + switch ( fieldOffset ) { \ + case IOHIDEventFieldOffset(kIOHIDEventFieldAccelerometerX): \ + value = IOHIDEventValueFloat(accl->position.x); \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldAccelerometerY): \ + value = IOHIDEventValueFloat(accl->position.y); \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldAccelerometerZ): \ + value = IOHIDEventValueFloat(accl->position.z); \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldAccelerometerType): \ + value = accl->acclType; \ + break; \ + }; \ + } \ + break; \ + case kIOHIDEventTypeMouse: \ + { \ + IOHIDMouseEventData * mouse = (IOHIDMouseEventData*)eventData; \ + switch ( fieldOffset ) { \ + case IOHIDEventFieldOffset(kIOHIDEventFieldMouseX): \ + value = IOHIDEventValueFloat(mouse->position.x); \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldMouseY): \ + value = IOHIDEventValueFloat(mouse->position.y); \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldMouseZ): \ + value = IOHIDEventValueFloat(mouse->position.z); \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldMouseButtonMask): \ + value = mouse->button.buttonMask; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldMouseNumber): \ + value = mouse->button.buttonNumber; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldMouseClickCount): \ + value = mouse->button.clickState; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldMousePressure): \ + value = IOHIDEventValueFloat(mouse->button.pressure); \ + break; \ + }; \ + } \ + break; \ + case kIOHIDEventTypeSwipe: \ + { \ + IOHIDSwipeEventData * swipe = (IOHIDSwipeEventData *)eventData; \ + switch ( fieldOffset ) { \ + case IOHIDEventFieldOffset(kIOHIDEventFieldSwipeMask): \ + value = swipe->swipeMask; \ + break; \ + }; \ + } \ + break; \ + case kIOHIDEventTypeTemperature: \ + { \ + IOHIDTemperatureEventData * temp = (IOHIDTemperatureEventData *)eventData; \ + switch ( fieldOffset ) { \ + case IOHIDEventFieldOffset(kIOHIDEventFieldTemperatureLevel): \ + value = IOHIDEventValueFloat(temp->level);\ + break; \ + }; \ + } \ + break; \ + case kIOHIDEventTypeTranslation: \ + case kIOHIDEventTypeRotation: \ + case kIOHIDEventTypeScroll: \ + case kIOHIDEventTypeScale: \ + case kIOHIDEventTypeVelocity: \ + case kIOHIDEventTypeOrientation: \ + { \ + IOHIDAxisEventData * axis = (IOHIDAxisEventData *)eventData; \ + switch ( fieldOffset ) { \ + case IOHIDEventFieldOffset(kIOHIDEventFieldTranslationX): \ + /* \ + case IOHIDEventFieldOffset(kIOHIDEventFieldRotationX): \ + case IOHIDEventFieldOffset(kIOHIDEventFieldScrollX): \ + case IOHIDEventFieldOffset(kIOHIDEventFieldScaleX): \ + case IOHIDEventFieldOffset(kIOHIDEventFieldVelocityX): \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerX); \ + case IOHIDEventFieldOffset(kIOHIDEventFieldOrientationRadius): \ + case IOHIDEventFieldOffset(kIOHIDEventFieldAccelerometerX): \ + */ \ + value = IOHIDEventValueFloat(axis->position.x); \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldTranslationY): \ + /* \ + case IOHIDEventFieldOffset(kIOHIDEventFieldRotationY): \ + case IOHIDEventFieldOffset(kIOHIDEventFieldScrollY): \ + case IOHIDEventFieldOffset(kIOHIDEventFieldScaleY): \ + case IOHIDEventFieldOffset(kIOHIDEventFieldVelocityY): \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerY); \ + case IOHIDEventFieldOffset(kIOHIDEventFieldOrientationAzimuth): \ + case IOHIDEventFieldOffset(kIOHIDEventFieldAccelerometerY): \ + */ \ + value = IOHIDEventValueFloat(axis->position.y); \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldTranslationZ): \ + /* \ + case IOHIDEventFieldOffset(kIOHIDEventFieldRotationZ): \ + case IOHIDEventFieldOffset(kIOHIDEventFieldScrollZ): \ + case IOHIDEventFieldOffset(kIOHIDEventFieldScaleZ): \ + case IOHIDEventFieldOffset(kIOHIDEventFieldVelocityZ): \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerZ); \ + case IOHIDEventFieldOffset(kIOHIDEventFieldOrientationAltitude):\ + case IOHIDEventFieldOffset(kIOHIDEventFieldAccelerometerZ): \ + */ \ + value = IOHIDEventValueFloat(axis->position.z); \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldScrollIsPixels): \ + value = ((axis->options & kIOHIDEventOptionPixelUnits) != 0);\ + break; \ + }; \ + } \ + break; \ + case kIOHIDEventTypeAmbientLightSensor: \ + { \ + IOHIDAmbientLightSensorEventData * alsEvent = (IOHIDAmbientLightSensorEventData *)eventData;\ + switch ( fieldOffset ) { \ + case IOHIDEventFieldOffset(kIOHIDEventFieldAmbientLightSensorLevel): \ + value = alsEvent->level; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldAmbientLightSensorRawChannel0): \ + value = alsEvent->ch0; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldAmbientLightSensorRawChannel1): \ + value = alsEvent->ch1; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldAmbientLightDisplayBrightnessChanged): \ + value = alsEvent->brightnessChanged; \ + break; \ + }; \ + } \ + break; \ + case kIOHIDEventTypeProximity: \ + { \ + IOHIDProximityEventData * proxEvent = (IOHIDProximityEventData *)eventData;\ + switch ( fieldOffset ) { \ + case IOHIDEventFieldOffset(kIOHIDEventFieldProximityDetectionMask): \ + value = proxEvent->detectionMask; \ + break; \ + }; \ + } \ + break; \ + case kIOHIDEventTypeKeyboard: \ + { \ + IOHIDKeyboardEventData * keyEvent = (IOHIDKeyboardEventData *)eventData;\ + switch ( fieldOffset ) { \ + case IOHIDEventFieldOffset(kIOHIDEventFieldKeyboardUsagePage): \ + value = keyEvent->usagePage; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldKeyboardUsage): \ + value = keyEvent->usage; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldKeyboardDown): \ + value = keyEvent->down; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldKeyboardRepeat): \ + value = (keyEvent->options & kIOHIDKeyboardIsRepeat);\ + break; \ + }; \ + } \ + break; \ + case kIOHIDEventTypeDigitizer: \ + { \ + IOHIDDigitizerEventData * digEvent = (IOHIDDigitizerEventData *)eventData; \ + switch ( fieldOffset ) { \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerX): \ + value = IOHIDEventValueFloat(digEvent->position.x); \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerY): \ + value = IOHIDEventValueFloat(digEvent->position.y); \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerZ): \ + value = IOHIDEventValueFloat(digEvent->position.z); \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerButtonMask): \ + value = digEvent->buttonMask; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerIndex): \ + value = digEvent->transducerIndex; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerIdentity): \ + value = digEvent->identity; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerEventMask): \ + value = digEvent->eventMask; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerChildEventMask): \ + value = digEvent->childEventMask; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerRange): \ + value = (digEvent->options & kIOHIDTransducerRange) != 0;\ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerTouch): \ + value = (digEvent->options & kIOHIDTransducerTouch) != 0;\ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerCollection): \ + value = (digEvent->options & kIOHIDEventOptionIsCollection) != 0;\ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerPressure): \ + value = IOHIDEventValueFloat(digEvent->tipPressure); \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerBarrelPressure): \ + value = IOHIDEventValueFloat(digEvent->barrelPressure); \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerTwist): \ + value = IOHIDEventValueFloat(digEvent->twist); \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerTiltX): \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerTiltY): \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerQuality): \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerDensity): \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerIrregularity): \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerMajorRadius): \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerMinorRadius): \ + switch ( digEvent->orientationType ) {\ + case kIOHIDDigitizerOrientationTypeTilt:\ + switch ( fieldOffset ) {\ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerTiltX): \ + value = IOHIDEventValueFloat(digEvent->orientation.tilt.x); \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerTiltY): \ + value = IOHIDEventValueFloat(digEvent->orientation.tilt.y); \ + break; \ + }; \ + break; \ + case kIOHIDDigitizerOrientationTypePolar:\ + switch ( fieldOffset ) {\ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerAltitude): \ + value = IOHIDEventValueFloat(digEvent->orientation.polar.altitude); \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerAzimuth): \ + value = IOHIDEventValueFloat(digEvent->orientation.polar.azimuth); \ + break; \ + }; \ + break; \ + case kIOHIDDigitizerOrientationTypeQuality:\ + switch ( fieldOffset ) {\ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerQuality): \ + value = IOHIDEventValueFloat(digEvent->orientation.quality.quality); \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerDensity): \ + value = IOHIDEventValueFloat(digEvent->orientation.quality.density); \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerIrregularity): \ + value = IOHIDEventValueFloat(digEvent->orientation.quality.irregularity); \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerMajorRadius): \ + value = IOHIDEventValueFloat(digEvent->orientation.quality.majorRadius); \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerMinorRadius): \ + value = IOHIDEventValueFloat(digEvent->orientation.quality.minorRadius); \ + break; \ + }; \ + break; \ + }; \ + break; \ + }; \ + } \ + break; \ + }; \ +} + +#define GET_EVENT_VALUE(event, field, value, options) \ +{ IOHIDEventType fieldEvType = IOHIDEventFieldEventType(field); \ + uint32_t fieldOffset = IOHIDEventFieldOffset(field); \ + IOHIDEventRef ev = NULL; \ + if ( (ev = IOHIDEventGetEventWithOptions(event, fieldEvType, options)) ) {\ + GET_EVENTDATA_VALUE(GET_EVENTDATA(ev),fieldEvType,fieldOffset,value);\ + } \ +} + +//============================================================================== +// IOHIDEventSetValue MACRO +//============================================================================== +#define SET_EVENTDATA_VALUE(eventData, fieldEvType, fieldOffset, value) \ +{ switch ( fieldEvType ) { \ + case kIOHIDEventTypeNULL: \ + switch ( fieldOffset ) { \ + case IOHIDEventFieldOffset(kIOHIDEventFieldIsRelative): \ + if ( value ) \ + eventData->options &= ~kIOHIDEventOptionIsAbsolute; \ + else \ + eventData->options |= kIOHIDEventOptionIsAbsolute; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldIsCollection): \ + if ( value ) \ + eventData->options |= kIOHIDEventOptionIsCollection; \ + else \ + eventData->options &= ~kIOHIDEventOptionIsCollection; \ + break; \ + }; break; \ + case kIOHIDEventTypeVendorDefined: \ + { \ + IOHIDVendorDefinedEventData * sysDef = (IOHIDVendorDefinedEventData*)eventData; \ + switch ( fieldOffset ) { \ + case IOHIDEventFieldOffset(kIOHIDEventFieldVendorDefinedUsagePage): \ + sysDef->usagePage = value; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldVendorDefinedUsage): \ + sysDef->usage = value; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldVendorDefinedVersion): \ + sysDef->version = value; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldVendorDefinedData): \ + if (sysDef->data) \ + *((typeof(value)*) sysDef->data) = value; \ + break; \ + }; \ + } \ + break; \ + case kIOHIDEventTypeProgress: \ + { \ + IOHIDProgressEventData * progress = (IOHIDProgressEventData*)eventData; \ + switch ( fieldOffset ) { \ + case IOHIDEventFieldOffset(kIOHIDEventFieldProgressEventType): \ + progress->eventType = value; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldProgressLevel): \ + progress->level = IOHIDEventValueFixed(value); \ + break; \ + }; \ + } \ + break; \ + case kIOHIDEventTypeButton: \ + { \ + IOHIDButtonEventData * button = (IOHIDButtonEventData*)eventData; \ + switch ( fieldOffset ) { \ + case IOHIDEventFieldOffset(kIOHIDEventFieldButtonMask): \ + button->button.buttonMask = value; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldButtonNumber): \ + button->button.buttonNumber = value; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldButtonClickCount): \ + button->button.clickState = value; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldButtonPressure): \ + button->button.pressure = IOHIDEventValueFixed(value); \ + break; \ + }; \ + } \ + break; \ + case kIOHIDEventTypeAccelerometer: \ + { \ + IOHIDAccelerometerEventData * accl = (IOHIDAccelerometerEventData*)eventData; \ + switch ( fieldOffset ) { \ + case IOHIDEventFieldOffset(kIOHIDEventFieldAccelerometerX): \ + accl->position.x = IOHIDEventValueFixed(value); \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldAccelerometerY): \ + accl->position.y = IOHIDEventValueFixed(value); \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldAccelerometerZ): \ + accl->position.z = IOHIDEventValueFixed(value); \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldAccelerometerType): \ + accl->acclType = value; \ + break; \ + }; \ + } \ + break; \ + case kIOHIDEventTypeMouse: \ + { \ + IOHIDMouseEventData * mouse = (IOHIDMouseEventData*)eventData; \ + switch ( fieldOffset ) { \ + case IOHIDEventFieldOffset(kIOHIDEventFieldMouseX): \ + mouse->position.x = IOHIDEventValueFixed(value); \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldMouseY): \ + mouse->position.y = IOHIDEventValueFixed(value); \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldMouseZ): \ + mouse->position.z = IOHIDEventValueFixed(value); \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldMouseButtonMask): \ + mouse->button.buttonMask = value; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldMouseNumber): \ + mouse->button.buttonNumber = value; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldMouseClickCount): \ + mouse->button.clickState = value; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldMousePressure): \ + mouse->button.pressure = IOHIDEventValueFixed(value); \ + break; \ + }; \ + } \ + break; \ + case kIOHIDEventTypeSwipe: \ + { \ + IOHIDSwipeEventData * swipe = (IOHIDSwipeEventData *)eventData; \ + switch ( fieldOffset ) { \ + case IOHIDEventFieldOffset(kIOHIDEventFieldSwipeMask): \ + swipe->swipeMask = value;\ + break; \ + }; \ + } \ + break; \ + case kIOHIDEventTypeTemperature: \ + { \ + IOHIDTemperatureEventData * temp = (IOHIDTemperatureEventData *)eventData; \ + switch ( fieldOffset ) { \ + case IOHIDEventFieldOffset(kIOHIDEventFieldTemperatureLevel): \ + temp->level = IOHIDEventValueFixed(value);\ + break; \ + }; \ + } \ + break; \ + case kIOHIDEventTypeTranslation: \ + case kIOHIDEventTypeRotation: \ + case kIOHIDEventTypeScroll: \ + case kIOHIDEventTypeScale: \ + case kIOHIDEventTypeVelocity: \ + case kIOHIDEventTypeOrientation: \ + { \ + IOHIDAxisEventData * axis = (IOHIDAxisEventData *)eventData; \ + switch ( fieldOffset ) { \ + case IOHIDEventFieldOffset(kIOHIDEventFieldTranslationX): \ + /* \ + case IOHIDEventFieldOffset(kIOHIDEventFieldRotationX): \ + case IOHIDEventFieldOffset(kIOHIDEventFieldScrollX): \ + case IOHIDEventFieldOffset(kIOHIDEventFieldScaleX): \ + case IOHIDEventFieldOffset(kIOHIDEventFieldVelocityX): \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerX); \ + case IOHIDEventFieldOffset(kIOHIDEventFieldOrientationRadius): \ + case IOHIDEventFieldOffset(kIOHIDEventFieldAccelerometerX): \ + */ \ + axis->position.x = IOHIDEventValueFixed(value); \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldTranslationY): \ + /* \ + case IOHIDEventFieldOffset(kIOHIDEventFieldRotationY): \ + case IOHIDEventFieldOffset(kIOHIDEventFieldScrollY): \ + case IOHIDEventFieldOffset(kIOHIDEventFieldScaleY): \ + case IOHIDEventFieldOffset(kIOHIDEventFieldVelocityY): \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerY); \ + case IOHIDEventFieldOffset(kIOHIDEventFieldOrientationAzimuth): \ + case IOHIDEventFieldOffset(kIOHIDEventFieldAccelerometerY): \ + */ \ + axis->position.y = IOHIDEventValueFixed(value); \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldTranslationZ): \ + /* \ + case IOHIDEventFieldOffset(kIOHIDEventFieldRotationZ): \ + case IOHIDEventFieldOffset(kIOHIDEventFieldScrollZ): \ + case IOHIDEventFieldOffset(kIOHIDEventFieldScaleZ): \ + case IOHIDEventFieldOffset(kIOHIDEventFieldVelocityZ): \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerZ); \ + case IOHIDEventFieldOffset(kIOHIDEventFieldOrientationAltitude):\ + case IOHIDEventFieldOffset(kIOHIDEventFieldAccelerometerZ): \ + */ \ + axis->position.z = IOHIDEventValueFixed(value); \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldScrollIsPixels): \ + if ( value ) \ + axis->options |= kIOHIDEventOptionPixelUnits; \ + else \ + axis->options &= ~kIOHIDEventOptionPixelUnits; \ + break; \ + }; \ + } \ + break; \ + case kIOHIDEventTypeAmbientLightSensor: \ + { \ + IOHIDAmbientLightSensorEventData * alsEvent = (IOHIDAmbientLightSensorEventData *)eventData;\ + switch ( fieldOffset ) { \ + case IOHIDEventFieldOffset(kIOHIDEventFieldAmbientLightSensorLevel): \ + alsEvent->level = value; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldAmbientLightSensorRawChannel0): \ + alsEvent->ch0 = value; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldAmbientLightSensorRawChannel1): \ + alsEvent->ch1 = value; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldAmbientLightDisplayBrightnessChanged): \ + alsEvent->brightnessChanged = value; \ + break; \ + }; \ + } \ + break; \ + case kIOHIDEventTypeProximity: \ + { \ + IOHIDProximityEventData * proxEvent = (IOHIDProximityEventData *)eventData;\ + switch ( fieldOffset ) { \ + case IOHIDEventFieldOffset(kIOHIDEventFieldProximityDetectionMask): \ + proxEvent->detectionMask = value; \ + break; \ + }; \ + } \ + break; \ + case kIOHIDEventTypeKeyboard: \ + { \ + IOHIDKeyboardEventData * keyEvent = (IOHIDKeyboardEventData *)eventData;\ + switch ( fieldOffset ) { \ + case IOHIDEventFieldOffset(kIOHIDEventFieldKeyboardUsagePage): \ + keyEvent->usagePage = value; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldKeyboardUsage): \ + keyEvent->usage = value; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldKeyboardDown): \ + keyEvent->down = value; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldKeyboardRepeat): \ + if ( value ) \ + keyEvent->options |= kIOHIDKeyboardIsRepeat; \ + else \ + keyEvent->options &= ~kIOHIDKeyboardIsRepeat; \ + break; \ + }; \ + } \ + break; \ + case kIOHIDEventTypeDigitizer: \ + { \ + IOHIDDigitizerEventData * digEvent = (IOHIDDigitizerEventData *)eventData; \ + switch ( fieldOffset ) { \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerX): \ + digEvent->position.x = IOHIDEventValueFixed(value); \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerY): \ + digEvent->position.y = IOHIDEventValueFixed(value); \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerZ): \ + digEvent->position.z = IOHIDEventValueFixed(value); \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerButtonMask): \ + digEvent->buttonMask = value; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerIndex): \ + digEvent->transducerIndex = value; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerIdentity): \ + digEvent->identity = value; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerEventMask): \ + digEvent->eventMask = value; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerChildEventMask): \ + digEvent->childEventMask = value; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerRange): \ + if ( value ) \ + digEvent->options |= kIOHIDTransducerRange; \ + else \ + digEvent->options &= ~kIOHIDTransducerRange; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerTouch): \ + if ( value ) \ + digEvent->options |= kIOHIDTransducerTouch; \ + else \ + digEvent->options &= ~kIOHIDTransducerTouch; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerCollection): \ + if ( value ) \ + digEvent->options |= kIOHIDEventOptionIsCollection; \ + else \ + digEvent->options &= ~kIOHIDEventOptionIsCollection; \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerPressure): \ + digEvent->tipPressure = IOHIDEventValueFixed(value); \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerBarrelPressure): \ + digEvent->barrelPressure = IOHIDEventValueFixed(value); \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerTwist): \ + digEvent->twist = IOHIDEventValueFixed(value); \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerTiltX): \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerTiltY): \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerQuality): \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerDensity): \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerIrregularity): \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerMajorRadius): \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerMinorRadius): \ + switch ( digEvent->orientationType ) {\ + case kIOHIDDigitizerOrientationTypeTilt:\ + switch ( fieldOffset ) {\ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerTiltX): \ + digEvent->orientation.tilt.x = IOHIDEventValueFixed(value); \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerTiltY): \ + digEvent->orientation.tilt.y = IOHIDEventValueFixed(value); \ + break; \ + }; \ + break; \ + case kIOHIDDigitizerOrientationTypePolar:\ + switch ( fieldOffset ) {\ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerAltitude): \ + digEvent->orientation.polar.altitude = IOHIDEventValueFixed(value); \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerAzimuth): \ + digEvent->orientation.polar.azimuth = IOHIDEventValueFixed(value); \ + break; \ + }; \ + break; \ + case kIOHIDDigitizerOrientationTypeQuality:\ + switch ( fieldOffset ) {\ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerQuality): \ + digEvent->orientation.quality.quality = IOHIDEventValueFixed(value); \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerDensity): \ + digEvent->orientation.quality.density = IOHIDEventValueFixed(value); \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerIrregularity): \ + digEvent->orientation.quality.irregularity = IOHIDEventValueFixed(value); \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerMajorRadius): \ + digEvent->orientation.quality.majorRadius = IOHIDEventValueFixed(value); \ + break; \ + case IOHIDEventFieldOffset(kIOHIDEventFieldDigitizerMinorRadius): \ + digEvent->orientation.quality.minorRadius = IOHIDEventValueFixed(value); \ + break; \ + }; \ + break; \ + }; \ + break; \ + }; \ + } \ + break; \ + }; \ +} + +#define SET_EVENT_VALUE(event, field, value, options) \ +{ IOHIDEventType fieldEvType = IOHIDEventFieldEventType(field); \ + uint32_t fieldOffset = IOHIDEventFieldOffset(field); \ + IOHIDEventRef ev = NULL; \ + if ( (ev = IOHIDEventGetEventWithOptions(event, fieldEvType, options)) ) {\ + SET_EVENTDATA_VALUE(GET_EVENTDATA(ev),fieldEvType,fieldOffset,value);\ + } \ +} + +#endif /* _IOKIT_HID_IOHIDEVENTDATA_H */ diff --git a/IOKit/hid/IOHIDEventQueue.h b/IOKit/hid/IOHIDEventQueue.h new file mode 100644 index 0000000..84c9c63 --- /dev/null +++ b/IOKit/hid/IOHIDEventQueue.h @@ -0,0 +1,82 @@ +/* + +IOHIDEventQueue.h ... Header for IOHIDEventQueue*** functions. + +Copyright (c) 2009 KennyTM~ +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +* 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. +* Neither the name of the KennyTM~ 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + +*/ + +#ifndef IOKIT_HID_IOHIDEVENTQUEUE_H +#define IOKIT_HID_IOHIDEVENTQUEUE_H 1 + +#include +#include "IOHIDEvent.h" + +#if __cplusplus +extern "C" { +#endif + + typedef struct __IOHIDEventQueue +#if 0 + { + CFRuntimeBase base; // 0, 4 + IODataQueueMemory* queue; // 8 + size_t queueSize; // c + int notificationPortType; // 10, 0 -> associate to hidSystem, 1 -> associate to data queue. + uint32_t token; // 14 + int topBitOfToken; // 18, = token >> 31 + } +#endif + * IOHIDEventQueueRef; + +#pragma mark - +#pragma mark Creators + + CFTypeID IOHIDEventQueueGetTypeID(void); + + // Token must be nonzero. + IOHIDEventQueueRef IOHIDEventQueueCreateWithToken(CFAllocatorRef allocator, uint32_t token); + IOHIDEventQueueRef IOHIDEventQueueCreate(CFAllocatorRef allocator, int notificationPortType, uint32_t token); + +#pragma mark - +#pragma mark Accessors + + uint32_t IOHIDEventQueueGetToken(IOHIDEventQueueRef queue); + + void IOHIDEventQueueSetNotificationPort(IOHIDEventQueueRef queue, mach_port_t port); + +#pragma mark - +#pragma mark Actions + + IOHIDEventRef IOHIDEventQueueDequeueCopy(IOHIDEventQueueRef queue); + void IOHIDEventQueueEnqueue(IOHIDEventQueueRef queue, IOHIDEventRef event); // will send a message to the "tickle port" as well. + +#if __cplusplus +} +#endif + +#endif diff --git a/IOKit/hid/IOHIDEventSystem.h b/IOKit/hid/IOHIDEventSystem.h new file mode 100644 index 0000000..5b90e24 --- /dev/null +++ b/IOKit/hid/IOHIDEventSystem.h @@ -0,0 +1,104 @@ +/* + +IOHIDEventSystem.h ... I/O Kit HID Event System + +Copyright (c) 2010 KennyTM~ +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +* 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. +* Neither the name of the KennyTM~ 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + +*/ + +// With reference to http://www.opensource.apple.com/source/IOHIDFamily/IOHIDFamily-258.1/IOHIDLib/IOHIDEventServiceClass.h + +#ifndef IOHID_EVENT_SYSTEM_H +#define IOHID_EVENT_SYSTEM_H + +#include +#include "IOHIDNotification.h" +#include "IOHIDService.h" +#include "IOHIDEvent.h" +#include "IOHIDEventQueue.h" + +#if __cplusplus +extern "C" { +#endif + + typedef struct ___IOHIDEventSystem +#if 0 + { + CFRuntimeBase _base; // 0, 4 + CFMutableSetRef services; // 8 + CFMutableSetRef x0c; // c + CFMutableSetRef x10; // 10 + CFMutableSetRef matchNotifications; // 14 + IONotificationPortRef serviceMatchPort; // 18 + IONotificationPortRef x1c; // 1c + void* x20; // 20 + IOHIDEventSystemCallback callback; // 24 + IOHIDSessionRef session; // 28 + pthread_mutex_t mutex; // 2c + CFRunLoopSourceRef migMachSource; // 58 + CFMutableSetRef queues; // 5c + } +#endif + * IOHIDEventSystemRef; + + typedef void(*IOHIDEventSystemCallback)(void* target, void* refcon, IOHIDServiceRef service, IOHIDEventRef event); + + CFTypeID IOHIDEventSystemGetTypeID(void); + IOHIDEventSystemRef IOHIDEventSystemCreate(CFAllocatorRef allocator); + + CFArrayRef IOHIDEventSystemCopyMatchingServices(IOHIDEventSystemRef system, CFDictionaryRef propertyTable, + IOHIDNotificationCallback matchCallback, void* matchTarget, void* matchRefcon, IOHIDNotificationRef* matchNotif); + void IOHIDEventSystemRegisterQueue(IOHIDEventSystemRef system, IOHIDEventQueueRef queue); + void IOHIDEventSystemUnregisterQueue(IOHIDEventSystemRef system, IOHIDEventQueueRef queue); + + IOHIDEventRef IOHIDEventSystemCopyEvent(IOHIDEventSystemRef system, IOHIDEventType type, IOHIDEventRef event, IOOptionBits options); + + CFTypeRef IOHIDEventSystemGetProperty(IOHIDEventSystemRef system, CFStringRef property); + Boolean IOHIDEventSystemSetProperty(IOHIDEventSystemRef system, CFStringRef property, CFTypeRef value); + + Boolean IOHIDEventSystemOpen(IOHIDEventSystemRef system, IOHIDEventSystemCallback callback, void* target, void* refcon, void* unused); + void IOHIDEventSystemClose(IOHIDEventSystemRef system, void* unused); + +#if 0 + dlfun("IOHIDEventSystemGetTypeID", "I"); + dlfun("IOHIDEventSystemCreate", "@@"); + dlfun("IOHIDEventSystemCopyMatchingServices", "@@^v^v^v^@"); + dlfun("IOHIDEventSystemRegisterQueue", "v@@"); + dlfun("IOHIDEventSystemUnregisterQueue", "v@@"); + dlfun("IOHIDEventSystemCopyEvent", "@@I@I"); + dlfun("IOHIDEventSystemGetProperty", "@@@"); + dlfun("IOHIDEventSystemSetProperty", "c@@@"); + dlfun("IOHIDEventSystemOpen", "c@^v^v^v^v"); + dlfun("IOHIDEventSystemClose", "v@^v"); +#endif + +#if __cplusplus +} +#endif + +#endif + diff --git a/IOKit/hid/IOHIDEventSystemClient.h b/IOKit/hid/IOHIDEventSystemClient.h new file mode 100644 index 0000000..76a0bac --- /dev/null +++ b/IOKit/hid/IOHIDEventSystemClient.h @@ -0,0 +1,84 @@ +/* + +IOHIDEventSystemClient.h ... I/O Kit HID Event System Client + +Copyright (c) 2010 KennyTM~ +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +* 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. +* Neither the name of the KennyTM~ 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + +*/ + +// With reference to http://www.opensource.apple.com/source/IOHIDFamily/IOHIDFamily-258.1/IOHIDLib/IOHIDEventServiceClass.h + +#ifndef IOHID_EVENT_SYSTEM_CLIENT_H +#define IOHID_EVENT_SYSTEM_CLIENT_H + +#include +#include "IOHIDEventQueue.h" +#include "IOHIDEvent.h" + +#if __cplusplus +extern "C" { +#endif + + typedef struct __IOHIDEventSystemClient +#if 0 + { + void* x00; + CFMachPortRef serverPort; // 4 + CFRunLoopSourceRef serverSource; // 8 + IOHIDEventSystemClientEventCallback callback; // c + void* target; // 10 + void* refcon; // 14 + CFMachPortRef queuePort; // 18 + CFRunLoopSourceRef queueSource; // 1c + CFRunLoopSourceRef source2; // 24 + CFRunLoopTimerRef timer; // 28 + IOHIDEventQueueRef queue; // 2c + CFRunLoopRef runloop; // 34 + CFStringRef mode; // 38 + } +#endif + * IOHIDEventSystemClientRef; + + typedef void(*IOHIDEventSystemClientEventCallback)(void* target, void* refcon, IOHIDEventQueueRef queue, IOHIDEventRef event); + + void IOHIDEventSystemClientRegisterEventCallback(IOHIDEventSystemClientRef client, IOHIDEventSystemClientEventCallback callback, void* target, void* refcon); + void IOHIDEventSystemClientUnregisterEventCallback(IOHIDEventSystemClientRef client); + + void IOHIDEventSystemClientUnscheduleWithRunLoop(IOHIDEventSystemClientRef client, CFRunLoopRef runloop, CFStringRef mode); + void IOHIDEventSystemClientScheduleWithRunLoop(IOHIDEventSystemClientRef client, CFRunLoopRef runloop, CFStringRef mode); + + CFPropertyListRef IOHIDEventSystemClientCopyProperty(IOHIDEventSystemClientRef client, CFStringRef property); + Boolean IOHIDEventSystemClientSetProperty(IOHIDEventSystemClientRef client, CFStringRef property, CFPropertyListRef value); + + IOHIDEventSystemClientRef IOHIDEventSystemClient(void); + +#if __cplusplus +} +#endif + +#endif + diff --git a/IOKit/hid/IOHIDEventTypes.h b/IOKit/hid/IOHIDEventTypes.h new file mode 100644 index 0000000..7999057 --- /dev/null +++ b/IOKit/hid/IOHIDEventTypes.h @@ -0,0 +1,368 @@ +/* + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef _IOKIT_HID_IOHIDEVENTTYPES_H +#define _IOKIT_HID_IOHIDEVENTTYPES_H + +#include + +#define IOHIDEventTypeMask(type) (1< + Please Note: + If you append a child digitizer event to a parent digitizer event, appropriate state will be transfered on to the parent. + @constant kIOHIDDigitizerEventRange Issued when the range state has changed. + @constant kIOHIDDigitizerEventTouch Issued when the touch state has changed. + @constant kIOHIDDigitizerEventPosition Issued when the position has changed. + @constant kIOHIDDigitizerEventStop Issued when motion has achieved a state of calculated non-movement. + @constant kIOHIDDigitizerEventPeak Issues when new maximum values have been detected. + @constant kIOHIDDigitizerEventIdentity Issued when the identity has changed. + @constant kIOHIDDigitizerEventAttribute Issued when an attribute has changed. + @constant kIOHIDDigitizerEventUpSwipe Issued when an up swipe has been detected. + @constant kIOHIDDigitizerEventDownSwipe Issued when an down swipe has been detected. + @constant kIOHIDDigitizerEventLeftSwipe Issued when an left swipe has been detected. + @constant kIOHIDDigitizerEventRightSwipe Issued when an right swipe has been detected. + @constant kIOHIDDigitizerEventSwipeMask Mask used to gather swipe events. +*/ +enum { + kIOHIDDigitizerEventRange = 0x00000001, + kIOHIDDigitizerEventTouch = 0x00000002, + kIOHIDDigitizerEventPosition = 0x00000004, + kIOHIDDigitizerEventStop = 0x00000008, + kIOHIDDigitizerEventPeak = 0x00000010, + kIOHIDDigitizerEventIdentity = 0x00000020, + kIOHIDDigitizerEventAttribute = 0x00000040, + kIOHIDDigitizerEventCancel = 0x00000080, + kIOHIDDigitizerEventStart = 0x00000100, + kIOHIDDigitizerEventResting = 0x00000200, + kIOHIDDigitizerEventSwipeUp = 0x01000000, + kIOHIDDigitizerEventSwipeDown = 0x02000000, + kIOHIDDigitizerEventSwipeLeft = 0x04000000, + kIOHIDDigitizerEventSwipeRight = 0x08000000, + kIOHIDDigitizerEventSwipeMask = 0xFF000000, +}; +typedef uint32_t IOHIDDigitizerEventMask; + +enum { + kIOHIDEventOptionIsAbsolute = 0x00000001, + kIOHIDEventOptionIsCollection = 0x00000002, + kIOHIDEventOptionPixelUnits = 0x00000004 +}; +typedef uint32_t IOHIDEventOptionBits; + +#ifndef KERNEL +/*! + @typedef IOHIDFloat +*/ +#ifdef __LP64__ +typedef double IOHIDFloat; +#else +typedef float IOHIDFloat; +#endif +/*! + @typedef IOHID3DPoint +*/ +typedef struct _IOHID3DPoint { + IOHIDFloat x; + IOHIDFloat y; + IOHIDFloat z; +} IOHID3DPoint; +#endif + +#endif /* _IOKIT_HID_IOHIDEVENTTYPES_H */ \ No newline at end of file diff --git a/IOKit/hid/IOHIDNotification.h b/IOKit/hid/IOHIDNotification.h new file mode 100644 index 0000000..9b83204 --- /dev/null +++ b/IOKit/hid/IOHIDNotification.h @@ -0,0 +1,82 @@ +/* + +IOHIDNotification ... I/O Kit HID Notifications + +Copyright (c) 2009 KennyTM~ +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +* 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. +* Neither the name of the KennyTM~ 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + +*/ + +#ifndef IOHID_NOTIFICATION_H +#define IOHID_NOTIFICATION_H + +#include + +#if __cplusplus +extern "C" { +#endif + + typedef void(*IOHIDNotificationCallback)(void* target, void* refcon); + + typedef struct __IOHIDNotification +#if 0 + { + CFRuntimeBase _base; // 0, 4 + IOHIDNotificationCallback clientCallback; // 8 + void* clientTarget; // c + void* clientRefcon; // 10 + IOHIDNotificationCallback ownerCallback; // 14 + void* ownerTarget; // 18 + void* ownerRefcon; // 1c + } +#endif + * IOHIDNotificationRef; + +#pragma mark - +#pragma mark Creators + + CFTypeID IOHIDNotificationGetTypeID(); + + IOHIDNotificationRef IOHIDNotificationCreate(CFAllocatorRef allocator, + IOHIDNotificationCallback ownerCallback, void* ownerTarget, void* ownerRefcon, + IOHIDNotificationCallback clientCallback, void* clientTarget, void* clientRefcon); + +#pragma mark - +#pragma mark Accessors + + IOHIDNotificationCallback IOHIDNotificationGetClientCallback(IOHIDNotificationRef notification); + void* IOHIDNotificationGetClientTarget(IOHIDNotificationRef notification); + void* IOHIDNotificationGetClientRefcon(IOHIDNotificationRef notification); + IOHIDNotificationCallback IOHIDNotificationGetOwnerCallback(IOHIDNotificationRef notification); + void* IOHIDNotificationGetOwnerTarget(IOHIDNotificationRef notification); + void* IOHIDNotificationGetOwnerRefcon(IOHIDNotificationRef notification); + +#if __cplusplus +} +#endif + +#endif + diff --git a/IOKit/hid/IOHIDService.h b/IOKit/hid/IOHIDService.h new file mode 100644 index 0000000..e7290d9 --- /dev/null +++ b/IOKit/hid/IOHIDService.h @@ -0,0 +1,122 @@ +/* + +IOHIDService.h ... I/O Kit HID Service + +Copyright (c) 2009 KennyTM~ +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +* 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. +* Neither the name of the KennyTM~ 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + +*/ + +// With reference to http://www.opensource.apple.com/source/IOHIDFamily/IOHIDFamily-258.1/IOHIDLib/IOHIDEventServiceClass.h + +#ifndef IOHID_SERVICE_H +#define IOHID_SERVICE_H + +#include +#include +#include "IOHIDEvent.h" +#include "IOHIDNotification.h" + +#if __cplusplus +extern "C" { +#endif + + typedef struct __IOHIDService +#if 0 + { + CFRuntimeBase _base; // 0, 4 + CFTypeRef client; // 8 + io_service_t service; // c + void** pluginInterface1; // 10; GUID = D12C833F-B15B-11DA-902D-0014519758EF + void** pluginInterface2; // 14; + IOCFPlugInInterface** interface; // 18 + CFRunLoopRef runloop; // 1c + CFStringRef mode; // 20 + IONotificationPortRef notify; // 24 + CFMutableSetRef removalNotifications; // 2c + void* eventTarget; // 30 + void* eventRefcon; // 34 + IOHIDServiceEventCallback eventCallback; // 38 + uint32_t previousButtonMask; // 3c + } +#endif + * IOHIDServiceRef; + + typedef void(*IOHIDServiceEventCallback)(void* target, void* refcon, IOHIDServiceRef service, IOHIDEventRef event); + + /* + metaObject-> + [0] = NULL + [4] = IOHIDIUnknown::genericQueryInterface(void*, CFUUIDBytes, void**) + [8] = IOHIDIUnknown::genericAddRef(void*) + [0x0c] = IOHIDIUnknown::genericRelease(void*) + [0x10] = IOHIDEventServiceClass::_open(void*, unsigned long) + [0x14] = IOHIDEventServiceClass::_close(void*, unsigned long) + [0x18] = IOHIDEventServiceClass::_getProperty(void*, __CFString const*) + [0x1c] = IOHIDEventServiceClass::_setProperty(void*, __CFString const*, void const*) + [0x20] = IOHIDEventServiceClass::_setEventCallback(void*, void (*)(void*, void*, void*, __IOHIDEvent*, unsigned long), void*, void*) + [0x24] = IOHIDEventServiceClass::_scheduleWithRunLoop(void*, __CFRunLoop*, __CFString const*) + [0x28] = IOHIDEventServiceClass::_unscheduleFromRunLoop(void*, __CFRunLoop*, __CFString const*) + [0x2c] = IOHIDEventServiceClass::_copyEvent(void*, unsigned int, __IOHIDEvent*, unsigned long) + */ + +#pragma mark - +#pragma mark Creators + + CFTypeID IOHIDServiceGetTypeID(void); + IOHIDServiceRef _IOHIDServiceCreate(CFAllocatorRef allocator, io_service_t service); + +#pragma mark - +#pragma mark Accessors + + CFTypeRef IOHIDServiceGetProperty(IOHIDServiceRef service, CFStringRef property); + Boolean IOHIDServiceSetProperty(IOHIDServiceRef service, CFStringRef property, CFTypeRef value); + + CFTypeRef _IOHIDServiceGetClient(IOHIDServiceRef service); + Boolean _IOHIDServiceMatchPropertyTable(IOHIDServiceRef service, CFDictionaryRef propertyTable); + + IOHIDEventRef IOHIDServiceCopyEvent(IOHIDServiceRef service, IOHIDEventType type, IOHIDEventRef event, IOOptionBits options); + + void _IOHIDServiceSetEventCallback(IOHIDServiceRef service, IOHIDServiceEventCallback eventCallback, void* target, void* refcon); + +#pragma mark - +#pragma mark Actions + + void _IOHIDServiceScheduleWithRunLoop(IOHIDServiceRef service, CFRunLoopRef runloop, CFStringRef mode); + void _IOHIDServiceUnscheduleWithRunLoop(IOHIDServiceRef service); + + IOHIDNotificationRef IOHIDServiceCreateRemovalNotification(IOHIDServiceRef display, IOHIDNotificationCallback callback, void* target, void* refcon); + + Boolean _IOHIDServiceOpen(IOHIDServiceRef service, CFTypeRef client, IOOptionBits options); + Boolean _IOHIDServiceClose(IOHIDServiceRef service, CFTypeRef client, IOOptionBits options); + + +#if __cplusplus +} +#endif + +#endif + diff --git a/IOKit/hid/IOHIDSession.h b/IOKit/hid/IOHIDSession.h new file mode 100644 index 0000000..441cf16 --- /dev/null +++ b/IOKit/hid/IOHIDSession.h @@ -0,0 +1,152 @@ +/* + +IOHIDSession.h ... I/O Kit HID Session + +Copyright (c) 2010 KennyTM~ +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +* 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. +* Neither the name of the KennyTM~ 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + +*/ + +#ifndef IOHID_NOTIFICATION_H +#define IOHID_NOTIFICATION_H + +#include +#include "IOHIDDisplay.h" +#include "IOHIDService.h" +#include "IOHIDEvent.h" + +#if __cplusplus +extern "C" { +#endif + + typedef struct IOHIDSessionWorkSpace { + uint64_t value; + } IOHIDSessionWorkSpace; + + typedef struct __IOHIDSession +#if 0 + { + CFRuntimeBase _base; // 0, 4 + int isOpen; // 8 + CFTypeRef client; // c + IOHIDSessionCallback callback; // 10 + void* refcon; // 14 + IOHIDSessionWorkSpace workSpace; // 18, 1c + CFRunLoopRef runloop; // 20 + pthread_mutex_t lock; // 24 + pthread_cond_t cond; // 50 + pthread_mutexattr_t attr; // 6c + CFMutableSetRef services; // 78 + CFMutableSetRef displays; // 7c + CFMutableSetRef ALSStates; // 80 + CFMutableDictionaryRef properties; // 84 + Boolean displayStatus; // 88, initially = true + float factor; // brightnessFactor. 8c, initially = 1 + float deviceAmbient; // 94, initially = 0.5 + float interval; // displayInternval. 98, initially = 0.402 + float ALSIntPeriod; // 9c, initially = 5.5 + float xa4; // a4, initially = 0 + float xa8; // a8, initially = 5.5 + float xac; // ac, initially = -1 + float xb0; // b0, initially = 1 + float backlight; // b4, initially = 1 + CFTypeRef xe0; // e0 + int displayOrientation; // e8, initially = 1 + Boolean orientationEnabled; // ec, initially = false + Boolean ALSIntPeriodOrientationEnabled; // ed, initially = false + float ALSIntPeriodOrientationPortrait; // f0, initially = 5.5 + float ALSIntPeriodOrientationPortraitInv; // f4, initially = 0 + float ALSIntPeriodOrientationLandscape; // f8, initially = 0 + int lockStateToken; // fc. (for the "com.apple.springboard.lockstate" Darwin notification) + uint64_t lockState; // 100, 104 + mach_port_t lockStateNotifyPort; // 108 (leads to __IOHIDSessionLockCallback) + int bootedCleanlyToken; // 10c (for the "com.apple.springboard.bootedcleanly" Darwin notification) + mach_port_t bootedCleanlyNotifyPort; // 118 (leads to __IOHIDSessionBootCallback) + int displayStatusToken; // 11c (for the "com.apple.iokit.hid.displayStatus" Darwin notification) + int substantialTransitionToken; // 12c (for the "com.apple.mobile.SubstantialTransition" Darwin notification) + mach_port_t substantialTransitionNotifyPort; // 130 (leads to __IOHIDSessionTransitionCallback) + int thermalNotificationToken; // 134 (for the kOSThermalNotificationName Darwin notification) + mach_port_t thermalNotificationNotifyPort; // 138 (leads to __IOHIDSessionThermalCallback) + int thermalLevel; // 13c, initially = OSThermalNotificationCurrentLevel() + int logLevel; // 144, initially = 6 + } +#endif + * IOHIDSessionRef; + + typedef void(*IOHIDSessionCallback)(CFTypeRef client, void* refcon, IOHIDServiceRef service, IOHIDEventRef event); + +#pragma mark - +#pragma mark Creators + + CFTypeID IOHIDSessionGetTypeID(void); + IOHIDSessionRef IOHIDSessionCreate(CFAllocatorRef allocator); + +#pragma mark - +#pragma mark Accessors + + CFTypeRef IOHIDSessionGetProperty(IOHIDSessionRef session, CFStringRef key); + Boolean IOHIDSessionSetProperty(IOHIDSessionRef session, CFStringRef key, CFTypeRef value); + + IOHIDSessionWorkSpace IOHIDSessionGetWorkSpace(IOHIDSessionRef session); + void IOHIDSessionSetWorkSpace(IOHIDSessionRef session, IOHIDSessionWorkSpace workSpace); + + Boolean IOHIDSessionGetLockState(IOHIDSessionRef session); + void IOHIDSessionSetLockState(IOHIDSessionRef session, Boolean lockState); + +#pragma mark - +#pragma mark Actions + + Boolean IOHIDSessionOpen(IOHIDSessionRef session, CFTypeRef client, IOHIDSessionCallback callback, void* refcon) + void IOHIDSessionClose(IOHIDSessionRef session, CFTypeRef client); + + void IOHIDSessionAddService(IOHIDSessionRef, IOHIDServiceRef service); + void IOHIDSessionRemoveService(IOHIDSessionRef, IOHIDServiceRef service); + + void IOHIDSessionAddDisplay(IOHIDSessionRef, IOHIDDisplayRef display); + void IOHIDSessionRemoveDisplay(IOHIDSessionRef session, IOHIDDisplayRef display); + + IOHIDEventRef IOHIDSessionCopyEvent(IOHIDSessionRef session, IOHIDEventType type, IOHIDEventRef event, IOOptionBits options); + +#pragma mark - +#pragma mark Constants + + static const CFStringRef kIOHIDSessionPropertyDisplayOrientation = CFSTR("DisplayOrientation"); + static const CFStringRef kIOHIDSessionPropertyDisplayBrightnessFactor = CFSTR("DisplayBrightnessFactor"); + static const CFStringRef kIOHIDSessionPropertyDisplayBrightnessFactorWithFade = CFSTR("DisplayBrightnessFactorWithFade"); + static const CFStringRef kIOHIDSessionPropertyDisplayBrightnessFactorPending = CFSTR("DisplayBrightnessFactorPending"); + static const CFStringRef kIOHIDSessionPropertyLogLevel = CFSTR("LogLevel"); + static const CFStringRef kIOHIDSessionPropertyALSIntPeriodOrientationEnabled = CFSTR("ALSIntPeriodOrientationEnabled"); + static const CFStringRef kIOHIDSessionPropertyALSIntPeriod = CFSTR("ALSIntPeriod"); + static const CFStringRef kIOHIDSessionPropertyALSIntPeriodOrientationPortrait = CFSTR("ALSIntPeriodOrientationPortrait"); + static const CFStringRef kIOHIDSessionPropertyALSIntPeriodOrientationPortraitInv = CFSTR("ALSIntPeriodOrientationPortraitInv"); + static const CFStringRef kIOHIDSessionPropertyALSIntPeriodOrientationLandscape = CFSTR("ALSIntPeriodOrientationLandscape"); + +#if __cplusplus +} +#endif + +#endif + diff --git a/IOKit/hid/IOHIDUserDevice.h b/IOKit/hid/IOHIDUserDevice.h new file mode 100644 index 0000000..3f6f8ca --- /dev/null +++ b/IOKit/hid/IOHIDUserDevice.h @@ -0,0 +1,69 @@ +/* + * + * @APPLE_LICENSE_HEADER_START@ + * + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#ifndef _IOKIT_HID_IOHIDUSERDEVICE_USER_H +#define _IOKIT_HID_IOHIDUSERDEVICE_USER_H + +#include +#include + +__BEGIN_DECLS + +typedef struct __IOHIDUserDevice * IOHIDUserDeviceRef; + +/*! + @function IOHIDUserDeviceGetTypeID + @abstract Returns the type identifier of all IOHIDUserDevice instances. +*/ +CF_EXPORT +CFTypeID IOHIDUserDeviceGetTypeID(void); + +/*! + @function IOHIDUserDeviceCreate + @abstract Creates an virtual IOHIDDevice in the kernel. + @discussion The io_service_t passed in this method must reference an object + in the kernel of type IOHIDUserDevice. + @param allocator Allocator to be used during creation. + @param properties CFDictionaryRef containing device properties index by keys defined in IOHIDKeys.h. + @result Returns a new IOHIDUserDeviceRef. +*/ +CF_EXPORT +IOHIDUserDeviceRef IOHIDUserDeviceCreate( + CFAllocatorRef allocator, + CFDictionaryRef properties); + + +/*! + @function IOHIDUserDeviceHandleReport + @abstract Dispatch a report to the IOHIDUserDevice. +*/ +CF_EXPORT +IOReturn IOHIDUserDeviceHandleReport( + IOHIDUserDeviceRef device, + uint8_t * report, + CFIndex reportLength); + +__END_DECLS + +#endif /* _IOKIT_HID_IOHIDUSERDEVICE_USER_H */ diff --git a/IOSurface/IOSurface.h b/IOSurface/IOSurface.h new file mode 100644 index 0000000..3ba9d24 --- /dev/null +++ b/IOSurface/IOSurface.h @@ -0,0 +1,14 @@ + + +#ifndef _IOSURFACE_H +#define _IOSURFACE_H 1 + +#include +#define IOSFC_AVAILABLE_STARTING(mac, iphone) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0) + +#include +#include + +#include "IOSurfaceAPI.h" + +#endif diff --git a/IOSurface/IOSurfaceAPI.h b/IOSurface/IOSurfaceAPI.h new file mode 100644 index 0000000..c1ef04f --- /dev/null +++ b/IOSurface/IOSurfaceAPI.h @@ -0,0 +1,292 @@ +/* + * IOSurface.h + * IOSurface + * + * Copyright 2006-2008 Apple Computer, Inc. All rights reserved. + * + */ + +#ifndef _IOSURFACE_API_H +#define _IOSURFACE_API_H 1 + +#include +#include + +__BEGIN_DECLS + +typedef struct __IOSurface *IOSurfaceRef; + +typedef uint32_t IOSurfaceID; + +/* The following list of properties are used with the CFDictionary passed to IOSurfaceCreate(). */ + +/* kIOSurfaceAllocSize - CFNumber of the total allocation size of the buffer including all planes. + Defaults to BufferHeight * BytesPerRow if not specified. Must be specified for + dimensionless buffers. */ +extern const CFStringRef kIOSurfaceAllocSize IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +/* kIOSurfaceWidth - CFNumber for the width of the IOSurface buffer in pixels. Required for planar IOSurfaces. */ +extern const CFStringRef kIOSurfaceWidth IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +/* kIOSurfaceHeight - CFNumber for the height of the IOSurface buffer in pixels. Required for planar IOSurfaces. */ +extern const CFStringRef kIOSurfaceHeight IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +/* kIOSurfaceBytesPerRow - CFNumber for the bytes per row of the buffer. If not specified, IOSurface will first calculate + the number full elements required on each row (by rounding up), multiplied by the bytes per element + for this buffer. That value will then be appropriately aligned. */ +extern const CFStringRef kIOSurfaceBytesPerRow IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +/* Optional properties for non-planar two dimensional images */ + +/* kIOSurfaceBitsPerElement - CFNumber for the total number of bytes in an element. Default to 1. */ +extern const CFStringRef kIOSurfaceBytesPerElement IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +/* kIOSurfaceElementWidth - CFNumber for how many pixels wide each element is. Defaults to 1. */ +extern const CFStringRef kIOSurfaceElementWidth IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +/* kIOSurfaceElementHeight - CFNumber for how many pixels high each element is. Defaults to 1. */ +extern const CFStringRef kIOSurfaceElementHeight IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +/* kIOSurfaceOffset - CFNumber for the starting offset into the buffer. Defaults to 0. */ +extern const CFStringRef kIOSurfaceOffset IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +/* Properties for planar surface buffers */ + +/* kIOSurfacePlaneInfo - CFArray describing each image plane in the buffer as a CFDictionary. The CFArray must have at least one entry. */ +extern const CFStringRef kIOSurfacePlaneInfo IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +/* kIOSurfacePlaneWidth - CFNumber for the width of this plane in pixels. Required for image planes. */ +extern const CFStringRef kIOSurfacePlaneWidth IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +/* kIOSurfacePlaneHeight - CFNumber for the height of this plane in pixels. Required for image planes. */ +extern const CFStringRef kIOSurfacePlaneHeight IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +/* kIOSurfacePlaneBytesPerRow - CFNumber for the bytes per row of this plane. If not specified, IOSurface will first calculate + the number full elements required on each row (by rounding up), multiplied by the bytes per element + for this plane. That value will then be appropriately aligned. */ +extern const CFStringRef kIOSurfacePlaneBytesPerRow IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +/* kIOSurfacePlaneOffset - CFNumber for the offset into the buffer for this plane. If not specified then IOSurface + will lay out each plane sequentially based on the previous plane's allocation size. */ +extern const CFStringRef kIOSurfacePlaneOffset IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +/* kIOSurfacePlaneSize - CFNumber for the total data size of this plane. Defaults to plane height * plane bytes per row if not specified. */ +extern const CFStringRef kIOSurfacePlaneSize IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +/* Optional properties for planar surface buffers */ + +/* kIOSurfacePlaneBase - CFNumber for the base offset into the buffer for this plane. Optional, defaults to the plane offset */ +extern const CFStringRef kIOSurfacePlaneBase IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +/* kIOSurfacePlaneBytesPerElement - CFNumber for the bytes per element of this plane. Optional, default is 1. */ +extern const CFStringRef kIOSurfacePlaneBytesPerElement IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +/* kIOSurfacePlaneElementWidth - CFNumber for the element width of this plane. Optional, default is 1. */ +extern const CFStringRef kIOSurfacePlaneElementWidth IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +/* kIOSurfacePlaneElementHeight - CFNumber for the element height of this plane. Optional, default is 1. */ +extern const CFStringRef kIOSurfacePlaneElementHeight IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +/* Optional properties global to the entire IOSurface */ + +/* kIOSurfaceCacheMode - CFNumber for the CPU cache mode to be used for the allocation. Default is kIOMapDefaultCache. */ +extern const CFStringRef kIOSurfaceCacheMode IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +/* kIOSurfaceIsGlobal - CFBoolean If true, the IOSurface may be looked up by any task in the system by its ID. */ +extern const CFStringRef kIOSurfaceIsGlobal IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +/* kIOSurfacePixelFormat - CFNumber A 32-bit unsigned integer that stores the traditional Mac OS X buffer format */ +extern const CFStringRef kIOSurfacePixelFormat IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +CFTypeID IOSurfaceGetTypeID(void) + IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +/* Create a brand new IOSurface object */ +IOSurfaceRef IOSurfaceCreate(CFDictionaryRef properties) + IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +/* Perform an atomic lookup and retain of a IOSurface by its IOSurfaceID. + Note: Performing multiple lookups of the same IOSurface will *NOT* return + the same IOSurfaceRef. If you need to compare two IOSurface objects + for equality, you must either do so by comparing their IOSurfaceIDs, or by + using CFEqual(). */ +IOSurfaceRef IOSurfaceLookup(IOSurfaceID csid) + IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +/* Retrieve the unique IOSurfaceID value for a IOSurface */ +IOSurfaceID IOSurfaceGetID(IOSurfaceRef buffer) + IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +enum +{ + // If you are not going to modify the data while you hold the lock, you should set this flag to avoid invalidating + // any existing caches of the buffer contents. This flag should be passed both to the lock and unlock functions. + // Non-symmentrical usage of this flag will result in undefined behavior. + kIOSurfaceLockReadOnly = 0x00000001, + + // If you want to detect/avoid a potentially expensive paging operation (such as readback from a GPU to system memory) + // when you lock the buffer, you may include this flag. If locking the buffer requires a readback, the lock will + // fail with an error return of kIOReturnCannotLock. + kIOSurfaceLockAvoidSync = 0x00000002 +}; + +/* "Lock" or "Unlock" a IOSurface for reading or writing. + + The term "lock" is used loosely in this context, and is simply used along with the + "unlock" information to put a bound on CPU access to the raw IOSurface data. + + If the seed parameter is non-NULL, IOSurfaceLock() will store the buffer's + internal modification seed value at the time you made the lock call. You can compare + this value to a value returned previously to determine of the contents of the buffer + has been changed since the last lock. + + In the case of IOSurfaceUnlock(), the seed value returned will be the internal + seed value at the time of the unlock. If you locked the buffer for writing, this value + will be incremented as the unlock is performed and the new value will be returned. + + See the kIOSurfaceLock enums for more information. + + Note: Locking and unlocking a IOSurface is not a particularly cheap operation, + so care should be taken to avoid the calls whenever possible. The seed values are + particularly useful for keeping a cache of the buffer contents. +*/ +IOReturn IOSurfaceLock(IOSurfaceRef buffer, uint32_t options, uint32_t *seed) + IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); +IOReturn IOSurfaceUnlock(IOSurfaceRef buffer, uint32_t options, uint32_t *seed) + IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +/* These routines are all fairly self explanatory. 0 is returned if buffer is invalid or NULL */ +size_t IOSurfaceGetAllocSize(IOSurfaceRef buffer) + IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +size_t IOSurfaceGetWidth(IOSurfaceRef buffer) + IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +size_t IOSurfaceGetHeight(IOSurfaceRef buffer) + IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +size_t IOSurfaceGetBytesPerElement(IOSurfaceRef buffer) + IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +size_t IOSurfaceGetBytesPerRow(IOSurfaceRef buffer) + IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +void *IOSurfaceGetBaseAddress(IOSurfaceRef buffer) + IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +size_t IOSurfaceGetElementWidth(IOSurfaceRef buffer) + IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +size_t IOSurfaceGetElementHeight(IOSurfaceRef buffer) + IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +OSType IOSurfaceGetPixelFormat(IOSurfaceRef buffer) + IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +/* This will return the current seed value of the buffer and is a cheap call to make to see + if the contents of the buffer have changed since the last lock/unlock. */ +uint32_t IOSurfaceGetSeed(IOSurfaceRef buffer) + IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +/* Return the number of planes in this buffer. May be 0. Returns 0 for an invalid or NULL buffer pointer. */ +size_t IOSurfaceGetPlaneCount(IOSurfaceRef buffer) + IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +/* These routines return information about a particular plane of a IOSurface. + + If the planeIndex is greater than or equal to the plane count of the IOSurface, zero + is returned.... with one exception. If this IOSurface has zero planes and a planeIndex + of zero is passed in, the routines function just like the non-planar APIs. This is to allow + higher level code to treat planar and non-planar buffers is a more uniform fashion. */ + +size_t IOSurfaceGetWidthOfPlane(IOSurfaceRef buffer, size_t planeIndex) + IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +size_t IOSurfaceGetHeightOfPlane(IOSurfaceRef buffer, size_t planeIndex) + IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +size_t IOSurfaceGetBytesPerElementOfPlane(IOSurfaceRef buffer, size_t planeIndex) + IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +size_t IOSurfaceGetBytesPerRowOfPlane(IOSurfaceRef buffer, size_t planeIndex) + IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +void *IOSurfaceGetBaseAddressOfPlane(IOSurfaceRef buffer, size_t planeIndex) + IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +size_t IOSurfaceGetElementWidthOfPlane(IOSurfaceRef buffer, size_t planeIndex) + IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +size_t IOSurfaceGetElementHeightOfPlane(IOSurfaceRef buffer, size_t planeIndex) + IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +/* These calls let you attach CF property list types to a IOSurface buffer. These calls are + expensive (they essentially must serialize the data into the kernel) and thus should be avoided whenever + possible. Note: These functions can not be used to change the underlying surface properties. */ +void IOSurfaceSetValue(IOSurfaceRef buffer, CFStringRef key, CFTypeRef value) + IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +CFTypeRef IOSurfaceCopyValue(IOSurfaceRef buffer, CFStringRef key) + IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +void IOSurfaceRemoveValue(IOSurfaceRef buffer, CFStringRef key) + IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +/* This call lets you get a mach_port_t that holds a reference to the IOSurface. This is useful + if you need to atomically or securely pass an IOSurface to another task without making the surface global to + the entire system. The returned port must be deallocated with mach_port_deallocate or the equivalent. */ +mach_port_t IOSurfaceCreateMachPort(IOSurfaceRef buffer) + IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +/* This call lets you take a mach_port_t created via IOSurfaceCreatePort() and recreate an IOSurfaceRef from it. + Note: This call does NOT destroy the port. */ +IOSurfaceRef IOSurfaceLookupFromMachPort(mach_port_t port) + IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +/* + IOSurfaceGetPropertyMaximum() will return the maximum of a given property that is guaranteed to be + compatible with all of the current devices (GPUs, etc.) in the system. The most important ones being: + + kIOSurfaceBytesPerRow + kIOSurfaceWidth + kIOSurfaceHeight + kIOSurfacePlaneBytesPerRow + kIOSurfacePlaneWidth + kIOSurfacePlaneHeight + + For the width and height properties, the maximum values are the largest that are guaranteed to work + for both reading and writing. In OpenGL terms this translates into the largest size that will work + for both textures and render targets. + + This function returns 0 for properties that have no predefined limit or where the concept of a limit + would be considered invalid (such as kIOSurfacePixelFormat). + +*/ +size_t IOSurfaceGetPropertyMaximum(CFStringRef property) + IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + + +/* + If a property has a particular alignment requirement, then IOSurfaceGetPropertyAlignment() will return it. + If the property has no alignment requirement then 1 will be returned. The following properties + should always be aligned if you choose calculate them yourself: + + kIOSurfaceBytesPerRow + kIOSurfaceOffset + + kIOSurfacePlaneBase + kIOSurfacePlaneOffset + kIOSurfacePlaneBytesPerRow + +*/ +size_t IOSurfaceGetPropertyAlignment(CFStringRef property) + IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +/* This is a convenience function to automatically align property values. For properties with no alignment + requirements, the original value will be returned. */ +size_t IOSurfaceAlignProperty(CFStringRef property, size_t value) + IOSFC_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_NA); + +__END_DECLS + +#endif diff --git a/IOSurface/IOSurfaceBase.h b/IOSurface/IOSurfaceBase.h new file mode 100644 index 0000000..e69de29 diff --git a/IOSurface/IOSurfaceClient.h b/IOSurface/IOSurfaceClient.h new file mode 100644 index 0000000..8805ad5 --- /dev/null +++ b/IOSurface/IOSurfaceClient.h @@ -0,0 +1,120 @@ +/* + +IOSurfaceClient.h ... IOSurface Client + +Copyright (c) 2010 KennyTM~ +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +* 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. +* Neither the name of the KennyTM~ 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. + +*/ + +#ifndef IOSURFACE_IOSURFACECLIENT_H +#define IOSURFACE_IOSURFACECLIENT_H + +#if __cplusplus +extern "C" { +#endif + +#if 0 + struct IOSurfaceClientUnknown { + int x00; + int x04; + size_t seed; + size_t inUse; + }; +#endif + + typedef struct __IOSurfaceClient +#if 0 + { + void* isa; // 0 + size_t useCount; // 4 + void* address; // 8 + IOSurfaceClientID _id; // c + size_t allocSize; // 10 + size_t width; // 14 + size_t height; // 18 + size_t bytesPerRow; // 1c + int offset; // 20 + OSType pixelFormat; // 24 + size_t planeCount; // 2c + uint16_t bytesPerElement; // 34 + uint8_t elementWidth; // 36 + uint8_t elementHeight; // 37 + struct IOSurfaceClientUnknown* unknown; // 3c + struct { + struct IOSurfaceClientUnknown* unknown; // 40 + size_t width; // 44 + size_t height; // 48 + int offset; // 50 + size_t bytesPerRow; // 54 + uint16_t bytesPerElement; // 5c + uint8_t elementWidth; // 5e + uint8_t elementHeight; // 5f + } planes[]; + } +#endif + IOSurfaceClientRef; + + typedef uint32_t IOSurfaceClientID; + +#pragma mark Accessors + IOSurfaceClientID IOSurfaceClientGetID(IOSurfaceClientRef client); + size_t IOSurfaceClientGetAllocSize(IOSurfaceClientRef client); + size_t IOSurfaceClientGetWidth(IOSurfaceClientRef client); + size_t IOSurfaceClientGetHeight(IOSurfaceClientRef client); + size_t IOSurfaceClientGetBytesPerRow(IOSurfaceClientRef client); + uint16_t IOSurfaceClientGetBytesPerElement(IOSurfaceClientRef client); + uint8_t IOSurfaceClientGetElementWidth(IOSurfaceClientRef client); + uint8_t IOSurfaceClientGetElementHeight(IOSurfaceClientRef client); + OSType IOSurfaceClientGetPixelFormat(IOSurfaceClientRef client); + void* IOSurfaceClientGetBaseAddress(IOSurfaceClientRef client); // return address + offset. + uint32_t IOSurfaceClientGetSeed(IOSurfaceClientRef client); + + uint32_t IOSurfaceClientGetUseCount(IOSurfaceClientRef client); + bool IOSurfaceClientIsInUse(IOSurfaceClientRef client); + +#pragma mark Accessors for planes + size_t IOSurfaceClientGetPlaneCount(IOSurfaceClientRef client); + size_t IOSurfaceClientGetWidthOfPlane(IOSurfaceClientRef client, size_t planeIndex); + size_t IOSurfaceClientGetHeightOfPlane(IOSurfaceClientRef client, size_t planeIndex); + size_t IOSurfaceClientGetBytesPerRowOfPlane(IOSurfaceClientRef client, size_t planeIndex); + uint16_t IOSurfaceClientGetBytesPerElementOfPlane(IOSurfaceClientRef client, size_t planeIndex); + uint8_t IOSurfaceClientGetElementWidthOfPlane(IOSurfaceClientRef client, size_t planeIndex); + uint8_t IOSurfaceClientGetElementHeightOfPlane(IOSurfaceClientRef client, size_t planeIndex); + void* IOSurfaceClientGetBaseAddressOfPlane(IOSurfaceClientRef client, size_t planeIndex); + uint32_t IOSurfaceClientGetSeedOfPlane(IOSurfaceClientRef client, size_t planeIndex); + +#pragma mark Actions + void IOSurfaceClientDecrementUseCount(IOSurfaceClientRef client); + void IOSurfaceClientIncrementUseCount(IOSurfaceClientRef client); + + void IOSurfaceClientRemoveSurfaceNotify(IOSurfaceClientRef client); + +#if __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..9184c4e --- /dev/null +++ b/Makefile @@ -0,0 +1,51 @@ +BUNDLE = SNES-HD.app +EMULATOR_SOURCE_DIR = src/snes4iphone_src +BINARY_FILE = $(EMULATOR_SOURCE_DIR)/snes4iphone +APP_BINARY = $(BUNDLE)/SNES-HD +PLIST_FILE = SNES4iPad-Info.plist +APP_PLIST = $(BUNDLE)/Info.plist + +PACKAGE_DIR=package-dir +PACKAGE_CONTROL=package-control.txt +PACKAGE_FILE=SNES-HD.deb + +RESOURCE_DIR = Resources + +NIB_FILES = $(RESOURCE_DIR)/ControlPadConnectViewController.nib $(RESOURCE_DIR)/DetailView.nib $(RESOURCE_DIR)/MainWindow.nib $(RESOURCE_DIR)/SaveStateSelectionViewController.nib $(RESOURCE_DIR)/SettingsViewController.nib + +RESOURCES = $(wildcard $(RESOURCE_DIR)/*.png) $(NIB_FILES) $(RESOURCE_DIR)/snesadvance.dat + +IBTOOL = ibtool +LDID = /usr/local/bin/ldid +DPKG_DEB = /opt/local/bin/dpkg-deb + +SSH_DESTINATION = root@ipad:/Applications + +all: bundle + +binary: + cd $(EMULATOR_SOURCE_DIR) && $(MAKE) all + +nibs: $(NIB_FILES) + +bundle: binary nibs + mkdir -p $(BUNDLE) + cp $(RESOURCES) $(BUNDLE) + cp $(BINARY_FILE) $(APP_BINARY) + cp $(PLIST_FILE) $(APP_PLIST) + $(LDID) -S $(APP_BINARY) + +package: bundle + mkdir -p $(PACKAGE_DIR)/Applications + mkdir -p $(PACKAGE_DIR)/DEBIAN + cp -r $(BUNDLE) $(PACKAGE_DIR)/Applications + cp $(PACKAGE_CONTROL) $(PACKAGE_DIR)/DEBIAN/control + export COPYFILE_DISABLE + export COPY_EXTENDED_ATTRIBUTES_DISABLE + $(DPKG_DEB) -b $(PACKAGE_DIR) $(PACKAGE_FILE) + +%.nib: %.xib + $(IBTOOL) --compile $@ $< + +transfer: bundle + scp -r $(BUNDLE) $(SSH_DESTINATION) \ No newline at end of file diff --git a/Resources/ControlPadConnectViewController.nib b/Resources/ControlPadConnectViewController.nib new file mode 100644 index 0000000..a908045 Binary files /dev/null and b/Resources/ControlPadConnectViewController.nib differ diff --git a/Resources/ControlPadConnectViewController.xib b/Resources/ControlPadConnectViewController.xib new file mode 100644 index 0000000..dfc07af --- /dev/null +++ b/Resources/ControlPadConnectViewController.xib @@ -0,0 +1,675 @@ + + + + 800 + 10C540 + 762 + 1038.25 + 458.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 87 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + IBIPadFramework + + + IBFirstResponder + IBIPadFramework + + + + 292 + + YES + + + 274 + {{0, 28}, {200, 100}} + + NO + IBIPadFramework + + NSImage + controlpad.png + + + + + 292 + {{56, 0}, {87, 21}} + + NO + YES + 7 + NO + IBIPadFramework + Player One + + 1 + MSAxIDEAA + + 1 + + + + 1 + 10 + + + + 292 + {{214, 0}, {180, 21}} + + NO + YES + 7 + NO + IBIPadFramework + Waiting For Connection + + 1 + MSAxIDEAA + + + + 1 + 10 + + + + -2147483356 + {{285, 59}, {37, 37}} + + NO + IBIPadFramework + 0 + + + + 292 + {{213, 59}, {75, 37}} + + NO + IBIPadFramework + 0 + 0 + + Helvetica-Bold + 15 + 16 + + Accept + + 3 + MQA + + + 1 + MSAxIDEAA + + + 3 + MC41AA + + + + + 292 + {{332, 59}, {72, 37}} + + NO + IBIPadFramework + 0 + 0 + + Deny + + + + + + + -2147483356 + {{251, 59}, {105, 37}} + + NO + IBIPadFramework + 0 + 0 + + Disconnect + + + + + + {424, 128} + + + 1 + MCAwIDAAA + + IBIPadFramework + + + + + YES + + + controllerLabel + + + + 12 + + + + statusLabel + + + + 13 + + + + acceptButton + + + + 14 + + + + view + + + + 15 + + + + denyButton + + + + 16 + + + + spinner + + + + 17 + + + + buttonPressed: + + + 7 + + 18 + + + + buttonPressed: + + + 7 + + 19 + + + + disconnectButton + + + + 21 + + + + buttonPressed: + + + 7 + + 22 + + + + + YES + + 0 + + + + + + -1 + + + File's Owner + + + -2 + + + + + 4 + + + YES + + + + + + + + + + + + 5 + + + + + 7 + + + + + 8 + + + + + 9 + + + + + 10 + + + + + 11 + + + + + 20 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 10.IBPluginDependency + 11.IBPluginDependency + 20.IBPluginDependency + 4.IBEditorWindowLastContentRect + 4.IBPluginDependency + 5.IBPluginDependency + 7.IBPluginDependency + 8.IBPluginDependency + 9.IBPluginDependency + + + YES + ControlPadConnectViewController + UIResponder + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{462, 404}, {424, 128}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 22 + + + + YES + + ControlPadConnectViewController + UIViewController + + buttonPressed: + id + + + YES + + YES + acceptButton + controllerLabel + denyButton + disconnectButton + spinner + statusLabel + + + YES + UIButton + UILabel + UIButton + UIButton + UIActivityIndicatorView + UILabel + + + + IBProjectSource + Classes/ControlPadConnectViewController.h + + + + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSNetServices.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSPort.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSStream.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSXMLParser.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIActivityIndicatorView + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIActivityIndicatorView.h + + + + UIButton + UIControl + + IBFrameworkSource + UIKit.framework/Headers/UIButton.h + + + + UIControl + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIControl.h + + + + UIImageView + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIImageView.h + + + + UILabel + UIView + + IBFrameworkSource + UIKit.framework/Headers/UILabel.h + + + + UIResponder + NSObject + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UIPopoverController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UISplitViewController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + + 0 + IBIPadFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + ../SNES4iPad.xcodeproj + 3 + + controlpad.png + {200, 100} + + 87 + + diff --git a/Resources/Default-Landscape.png b/Resources/Default-Landscape.png new file mode 100644 index 0000000..3f6c90c Binary files /dev/null and b/Resources/Default-Landscape.png differ diff --git a/Resources/Default-Portrait.png b/Resources/Default-Portrait.png new file mode 100644 index 0000000..5d8ebcf Binary files /dev/null and b/Resources/Default-Portrait.png differ diff --git a/Resources/DetailView.nib b/Resources/DetailView.nib new file mode 100644 index 0000000..d1963df Binary files /dev/null and b/Resources/DetailView.nib differ diff --git a/Resources/DetailView.xib b/Resources/DetailView.xib new file mode 100644 index 0000000..d6729c0 --- /dev/null +++ b/Resources/DetailView.xib @@ -0,0 +1,1220 @@ + + + + 800 + 10C540 + 762 + 1038.25 + 458.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 87 + + + YES + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + IBIPadFramework + + + IBFirstResponder + IBIPadFramework + + + + 311 + + YES + + + 292 + {{117, 75}, {534, 433}} + + + NO + IBIPadFramework + + NSImage + console.png + + + + + 290 + {768, 44} + + + NO + NO + IBIPadFramework + + YES + + IBIPadFramework + + 5 + + + No ROM Selected + IBIPadFramework + + + + IBIPadFramework + + 5 + + + + NSImage + gear.png + + IBIPadFramework + 1 + + + + + 1 + MCAwIDAAA + + + + + 256 + {{214, 44}, {340, 126}} + + + + 1 + MSAxIDEgMAA + + 1 + NO + IBIPadFramework + + NSImage + cartridge.png + + + + + 292 + {{278, 44}, {199, 87}} + + + NO + YES + NO + IBIPadFramework + No ROM Selected + + Helvetica + 14 + 16 + + + 1 + MSAxIDEAA + + + 1 + 14 + 3 + 1 + 0 + + + + 292 + {{199, 267}, {149, 53}} + + + NO + IBIPadFramework + 0 + 0 + + Helvetica-Bold + 15 + 16 + + YES + NO + NO + + 3 + MQA + + + 1 + MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA + + + 3 + MC41AA + + + NSImage + powerbutton.png + + + + + 292 + {{420, 265}, {149, 53}} + + + NO + IBIPadFramework + 0 + 0 + + YES + NO + NO + + + 1 + MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA + + + + NSImage + loadbutton.png + + + + + 292 + {{208, 452}, {131, 37}} + + + NO + IBIPadFramework + 0 + 0 + + Helvetica-BoldOblique + 15 + 16 + + Not Connected + + + 1 + MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA + + + + + + 292 + {{429, 452}, {131, 37}} + + + NO + 1 + IBIPadFramework + 0 + 0 + + Not Connected + + + 1 + MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA + + + + + + 292 + {{278, 44}, {210, 126}} + + + NO + IBIPadFramework + + + + 292 + {{340, 267}, {88, 139}} + + + NO + IBIPadFramework + 0 + 0 + + + + 1 + MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA + + + + + + 292 + + YES + + + 292 + {{12, 11}, {74, 21}} + + + + 3 + MCAwAA + + NO + YES + 7 + NO + IBIPadFramework + Player 3: + + + 1 + 10 + + + + 292 + {{94, 3}, {131, 37}} + + + + NO + 2 + IBIPadFramework + 0 + 0 + + Not Connected + + + 1 + MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA + + + + + + 292 + {{318, 3}, {131, 37}} + + + + NO + 3 + IBIPadFramework + 0 + 0 + + Not Connected + + + 1 + MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA + + + + + + 292 + {{240, 10}, {69, 21}} + + + + NO + YES + 7 + NO + IBIPadFramework + Player 4: + + + 1 + 10 + + + {{117, 512}, {534, 44}} + + + + 3 + MSAwAA + + 2 + + + NO + IBIPadFramework + + + {768, 1004} + + + + 3 + MC43MDQzNzk1NjIAA + + NO + + 2 + + IBIPadFramework + + + NO + SaveStateSelectionViewController + + 2 + + + 1 + + IBIPadFramework + NO + + + + + YES + + + view + + + + 12 + + + + toolbar + + + + 65 + + + + romImageView + + + + 69 + + + + romTitleLabel + + + + 72 + + + + romTitleButton + + + + 76 + + + + powerButton + + + + 93 + + + + loadButton + + + + 94 + + + + playerOneButton + + + + 104 + + + + playerTwoButton + + + + 105 + + + + snapshotImageView + + + + 116 + + + + buttonPressed: + + + + 118 + + + + buttonPressed: + + + 7 + + 119 + + + + buttonPressed: + + + 7 + + 120 + + + + buttonPressed: + + + 7 + + 121 + + + + buttonPressed: + + + 7 + + 122 + + + + settingsButton + + + + 123 + + + + multiTapView + + + + 158 + + + + playerThreeButton + + + + 159 + + + + playerFourButton + + + + 160 + + + + buttonPressed: + + + 7 + + 161 + + + + buttonPressed: + + + 7 + + 162 + + + + ejectButton + + + + 164 + + + + buttonPressed: + + + 7 + + 166 + + + + saveStateSelectionViewController + + + + 168 + + + + + YES + + 0 + + + + + + -1 + + + File's Owner + + + -2 + + + + + 8 + + + YES + + + + + + + + + + + + + + + + 63 + + + YES + + + + + + + + + 68 + + + + + 71 + + + + + 73 + + + + + 74 + + + + + 75 + + + + + 90 + + + + + 91 + + + + + 92 + + + + + 101 + + + + + 102 + + + + + 103 + + + + + 115 + + + + + 153 + + + YES + + + + + + + + + 154 + + + + + 155 + + + + + 156 + + + + + 157 + + + + + 163 + + + + + 167 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 101.IBPluginDependency + 102.IBPluginDependency + 103.IBPluginDependency + 115.IBPluginDependency + 153.IBPluginDependency + 154.IBPluginDependency + 155.IBPluginDependency + 156.IBPluginDependency + 157.IBPluginDependency + 163.IBPluginDependency + 167.CustomClassName + 167.IBEditorWindowLastContentRect + 167.IBPluginDependency + 63.IBPluginDependency + 68.IBPluginDependency + 71.IBPluginDependency + 73.IBPluginDependency + 74.IBPluginDependency + 75.IBPluginDependency + 8.IBEditorWindowLastContentRect + 8.IBPluginDependency + 90.IBPluginDependency + 91.IBPluginDependency + 92.IBPluginDependency + + + YES + RomDetailViewController + UIResponder + 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 + SaveStateSelectionViewController + {{21, 4}, {783, 752}} + 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 + {{94, 3}, {783, 752}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 168 + + + + YES + + RomDetailViewController + UIViewController + + buttonPressed: + id + + + YES + + YES + detailItem + ejectButton + loadButton + multiTapView + playerFourButton + playerOneButton + playerThreeButton + playerTwoButton + powerButton + romImageView + romTitleButton + romTitleLabel + saveStateSelectionViewController + settingsButton + snapshotImageView + toolbar + + + YES + id + UIButton + UIButton + UIView + UIButton + UIButton + UIButton + UIButton + UIButton + UIImageView + UIBarButtonItem + UILabel + SaveStateSelectionViewController + UIBarButtonItem + UIImageView + UIToolbar + + + + IBProjectSource + Classes/RomDetailViewController.h + + + + SaveStateSelectionViewController + UIViewController + + buttonPressed: + id + + + YES + + YES + editButton + saveTableView + + + YES + UIBarButtonItem + UITableView + + + + IBProjectSource + Classes/SaveStateSelectionViewController.h + + + + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSNetServices.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSPort.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSStream.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSXMLParser.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIBarButtonItem + UIBarItem + + IBFrameworkSource + UIKit.framework/Headers/UIBarButtonItem.h + + + + UIBarItem + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIBarItem.h + + + + UIButton + UIControl + + IBFrameworkSource + UIKit.framework/Headers/UIButton.h + + + + UIControl + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIControl.h + + + + UIImageView + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIImageView.h + + + + UILabel + UIView + + IBFrameworkSource + UIKit.framework/Headers/UILabel.h + + + + UIResponder + NSObject + + + + UIScrollView + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIScrollView.h + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UITableView + UIScrollView + + IBFrameworkSource + UIKit.framework/Headers/UITableView.h + + + + UIToolbar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIToolbar.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UIPopoverController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UISplitViewController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + + 0 + IBIPadFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + SNES4iPad.xcodeproj + 3 + + YES + + YES + cartridge.png + console.png + gear.png + loadbutton.png + powerbutton.png + + + YES + {520, 193} + {521, 433} + {26, 26} + {149, 53} + {149, 53} + + + 87 + + diff --git a/Resources/Icon.png b/Resources/Icon.png new file mode 100644 index 0000000..21d42e4 Binary files /dev/null and b/Resources/Icon.png differ diff --git a/Resources/MainWindow.nib b/Resources/MainWindow.nib new file mode 100644 index 0000000..9fe14fe Binary files /dev/null and b/Resources/MainWindow.nib differ diff --git a/Resources/MainWindow.xib b/Resources/MainWindow.xib new file mode 100644 index 0000000..0610d9a --- /dev/null +++ b/Resources/MainWindow.xib @@ -0,0 +1,665 @@ + + + + 800 + 10C540 + 762 + 1038.25 + 458.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 87 + + + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + + IBFilesOwner + IBIPadFramework + + + IBFirstResponder + IBIPadFramework + + + + 292 + {768, 1024} + + 1 + MSAxIDEAA + + NO + NO + + 2 + + IBIPadFramework + YES + + + IBIPadFramework + + + + + 2 + + + 3 + + IBIPadFramework + YES + + + + 2 + + + 1 + + IBIPadFramework + NO + + + 256 + {0, 0} + YES + YES + IBIPadFramework + + 3 + MC4yMjk5MjcwMDczAA + + + + + + ROMs + IBIPadFramework + + + + 2 + + + 1 + + IBIPadFramework + NO + + + + + + + DetailView + + 1 + + IBIPadFramework + NO + + + + + + + + window + + + + 4 + + + + delegate + + + + 17 + + + + splitViewController + + + + 43 + + + + delegate + + + + 49 + + + + romDetailViewController + + + + 50 + + + + romDetailViewController + + + + 51 + + + + romSelectionViewController + + + + 52 + + + + + + 0 + + + + + + -1 + + + File's Owner + + + -2 + + + + + 2 + + + + + 3 + + + + + 37 + + + + + + + + + 38 + + + + + + + + + 39 + + + + + 40 + + + + + + + + 41 + + + + + 42 + + + + + + + UIApplication + UIResponder + {{190, 57}, {783, 799}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + SNES4iPadAppDelegate + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + {{241, 4}, {1039, 752}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + RomDetailViewController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + RomSelectionViewController + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + + + 52 + + + + + RomDetailViewController + UIViewController + + buttonPressed: + id + + + id + UIButton + UIButton + UIView + UIButton + UIButton + UIButton + UIButton + UIButton + UIImageView + UIBarButtonItem + UILabel + SaveStateSelectionViewController + UIBarButtonItem + UIImageView + UIToolbar + + + IBProjectSource + Classes/RomDetailViewController.h + + + + RomSelectionViewController + UITableViewController + + romDetailViewController + RomDetailViewController + + + IBProjectSource + Classes/RomSelectionViewController.h + + + + SNES4iPadAppDelegate + NSObject + + RomDetailViewController + RomSelectionViewController + UISplitViewController + UIWindow + + + IBProjectSource + Classes/SNES4iPadAppDelegate.h + + + + SaveStateSelectionViewController + UIViewController + + buttonPressed: + id + + + UIBarButtonItem + UITableView + + + IBProjectSource + Classes/SaveStateSelectionViewController.h + + + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSNetServices.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSPort.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSStream.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSXMLParser.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIApplication + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIApplication.h + + + + UIBarButtonItem + UIBarItem + + IBFrameworkSource + UIKit.framework/Headers/UIBarButtonItem.h + + + + UIBarItem + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIBarItem.h + + + + UIButton + UIControl + + IBFrameworkSource + UIKit.framework/Headers/UIButton.h + + + + UIControl + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIControl.h + + + + UIImageView + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIImageView.h + + + + UILabel + UIView + + IBFrameworkSource + UIKit.framework/Headers/UILabel.h + + + + UINavigationBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UINavigationBar.h + + + + UINavigationController + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UINavigationItem + NSObject + + + + UIResponder + NSObject + + + + UIScrollView + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIScrollView.h + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UISplitViewController + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UISplitViewController.h + + + + UITableView + UIScrollView + + IBFrameworkSource + UIKit.framework/Headers/UITableView.h + + + + UITableViewController + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITableViewController.h + + + + UIToolbar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIToolbar.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UIPopoverController.h + + + + UIViewController + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + UIWindow + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIWindow.h + + + + + 0 + IBIPadFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + SNES4iPad.xcodeproj + 3 + 87 + + diff --git a/Resources/SaveStateSelectionViewController.nib b/Resources/SaveStateSelectionViewController.nib new file mode 100644 index 0000000..6f38f6e Binary files /dev/null and b/Resources/SaveStateSelectionViewController.nib differ diff --git a/Resources/SaveStateSelectionViewController.xib b/Resources/SaveStateSelectionViewController.xib new file mode 100644 index 0000000..d7d8905 --- /dev/null +++ b/Resources/SaveStateSelectionViewController.xib @@ -0,0 +1,511 @@ + + + + 800 + 10C540 + 762 + 1038.25 + 458.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 87 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + IBIPadFramework + + + IBFirstResponder + IBIPadFramework + + + + 311 + + YES + + + 290 + {768, 44} + + NO + NO + IBIPadFramework + + YES + + Saved States: + IBIPadFramework + + + + IBIPadFramework + + 5 + + + Edit + IBIPadFramework + 1 + + + + + 1 + MCAwIDAAA + + + + {768, 464} + + + 3 + MQA + + 2 + + + IBIPadFramework + + + + + YES + + + view + + + + 33 + + + + editButton + + + + 35 + + + + buttonPressed: + + + + 36 + + + + + YES + + 0 + + + + + + -1 + + + File's Owner + + + -2 + + + + + 27 + + + YES + + + + + + 28 + + + YES + + + + + + + + 29 + + + + + 30 + + + + + 31 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 27.IBEditorWindowLastContentRect + 27.IBPluginDependency + 28.IBPluginDependency + 29.IBPluginDependency + 30.IBPluginDependency + 31.IBPluginDependency + + + YES + SaveStateSelectionViewController + UIResponder + {{123, 94}, {768, 464}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 38 + + + + YES + + SaveStateSelectionViewController + UIViewController + + buttonPressed: + id + + + YES + + YES + editButton + saveTableView + + + YES + UIBarButtonItem + UITableView + + + + IBProjectSource + Classes/SaveStateSelectionViewController.h + + + + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSNetServices.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSPort.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSStream.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSXMLParser.h + + + + NSObject + + IBFrameworkSource + QuartzCore.framework/Headers/CAAnimation.h + + + + NSObject + + IBFrameworkSource + QuartzCore.framework/Headers/CALayer.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIBarButtonItem + UIBarItem + + IBFrameworkSource + UIKit.framework/Headers/UIBarButtonItem.h + + + + UIBarItem + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIBarItem.h + + + + UIResponder + NSObject + + + + UIScrollView + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIScrollView.h + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UITableView + UIScrollView + + IBFrameworkSource + UIKit.framework/Headers/UITableView.h + + + + UIToolbar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIToolbar.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UIPopoverController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UISplitViewController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + + 0 + IBIPadFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + ../SNES4iPad.xcodeproj + 3 + 87 + + diff --git a/Resources/SettingsViewController.nib b/Resources/SettingsViewController.nib new file mode 100644 index 0000000..3680a5e Binary files /dev/null and b/Resources/SettingsViewController.nib differ diff --git a/Resources/SettingsViewController.xib b/Resources/SettingsViewController.xib new file mode 100644 index 0000000..3e84d11 --- /dev/null +++ b/Resources/SettingsViewController.xib @@ -0,0 +1,862 @@ + + + + 800 + 10C540 + 762 + 1038.25 + 458.00 + + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + 87 + + + YES + + + + YES + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + YES + + YES + + + YES + + + + YES + + IBFilesOwner + IBIPadFramework + + + IBFirstResponder + IBIPadFramework + + + + 292 + + YES + + + 292 + {{20, 91}, {150, 21}} + + NO + YES + 7 + NO + IBIPadFramework + Framerate Counter + + 1 + MSAxIDEAA + + + 1 + 10 + + + + 292 + {{20, 20}, {76, 21}} + + NO + YES + 7 + NO + IBIPadFramework + Autosave + + + 1 + 10 + + + + 292 + {{206, 91}, {94, 27}} + + NO + IBIPadFramework + 0 + 0 + + + + 292 + {{206, 20}, {94, 27}} + + NO + IBIPadFramework + 0 + 0 + + + + 292 + {{20, 56}, {120, 21}} + + NO + YES + 7 + NO + IBIPadFramework + Smooth Scaling + + 1 + MSAxIDEAA + + 1 + + + + 1 + 10 + + + + 292 + {{206, 56}, {94, 27}} + + NO + IBIPadFramework + 0 + 0 + YES + + + + 292 + {{20, 130}, {146, 21}} + + NO + YES + 7 + NO + IBIPadFramework + Transparencies On + + 1 + MSAxIDEAA + + + + 1 + 10 + + + + 292 + {{206, 130}, {94, 27}} + + NO + IBIPadFramework + 0 + 0 + YES + + + + 292 + {{20, 168}, {103, 21}} + + NO + YES + 7 + NO + IBIPadFramework + Speed Hacks + + 1 + MSAxIDEAA + + + + 1 + 10 + + + + 292 + {{206, 165}, {94, 27}} + + NO + IBIPadFramework + 0 + 0 + + + + 292 + {{20, 203}, {151, 21}} + + NO + YES + 7 + NO + IBIPadFramework + Multi Tap (4 Player) + + 1 + MSAxIDEAA + + + + 1 + 10 + + + + 292 + {{206, 203}, {94, 27}} + + NO + IBIPadFramework + 0 + 0 + + + + 292 + {{20, 241}, {138, 39}} + + NO + YES + 7 + NO + IBIPadFramework + Search for 1st Player on startup + + 1 + MSAxIDEAA + + + + 1 + 10 + 2 + 0 + + + + 292 + {{206, 247}, {94, 27}} + + NO + IBIPadFramework + 0 + 0 + YES + + + {320, 300} + + + 1 + MCAwIDAAA + + IBIPadFramework + + + + + YES + + + view + + + + 5 + + + + autosave + + + + 24 + + + + smoothScaling + + + + 25 + + + + fpsDisplay + + + + 26 + + + + transparency + + + + 27 + + + + speedHack + + + + 28 + + + + multiTap + + + + 29 + + + + settingChanged: + + + 13 + + 30 + + + + settingChanged: + + + 13 + + 31 + + + + settingChanged: + + + 13 + + 32 + + + + settingChanged: + + + 13 + + 33 + + + + settingChanged: + + + 13 + + 34 + + + + settingChanged: + + + 13 + + 35 + + + + settingChanged: + + + 13 + + 38 + + + + autoconnect + + + + 39 + + + + + YES + + 0 + + + + + + -1 + + + File's Owner + + + -2 + + + + + 4 + + + YES + + + + + + + + + + + + + + + + + + + 6 + + + + + 7 + + + + + 8 + + + + + 9 + + + + + 10 + + + + + 11 + + + + + 12 + + + + + 13 + + + + + 14 + + + + + 15 + + + + + 21 + + + + + 22 + + + + + 36 + + + + + 37 + + + + + + + YES + + YES + -1.CustomClassName + -2.CustomClassName + 10.IBPluginDependency + 11.IBPluginDependency + 12.IBPluginDependency + 13.IBPluginDependency + 14.IBPluginDependency + 15.IBPluginDependency + 21.IBPluginDependency + 22.IBPluginDependency + 36.IBPluginDependency + 37.IBPluginDependency + 4.IBEditorWindowLastContentRect + 4.IBPluginDependency + 6.IBPluginDependency + 7.IBPluginDependency + 8.IBPluginDependency + 9.IBPluginDependency + + + YES + SettingsViewController + UIResponder + 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 + {{485, 351}, {320, 300}} + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + com.apple.InterfaceBuilder.IBCocoaTouchPlugin + + + + YES + + + YES + + + + + YES + + + YES + + + + 39 + + + + YES + + SettingsViewController + UIViewController + + settingChanged: + id + + + YES + + YES + autoconnect + autosave + fpsDisplay + multiTap + smoothScaling + speedHack + transparency + + + YES + UISwitch + UISwitch + UISwitch + UISwitch + UISwitch + UISwitch + UISwitch + + + + IBProjectSource + Classes/SettingsViewController.h + + + + + YES + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSError.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSFileManager.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueCoding.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyValueObserving.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSKeyedArchiver.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSNetServices.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSObject.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSPort.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSRunLoop.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSStream.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSThread.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURL.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSURLConnection.h + + + + NSObject + + IBFrameworkSource + Foundation.framework/Headers/NSXMLParser.h + + + + NSObject + + IBFrameworkSource + QuartzCore.framework/Headers/CAAnimation.h + + + + NSObject + + IBFrameworkSource + QuartzCore.framework/Headers/CALayer.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIAccessibility.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UINibLoading.h + + + + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UIResponder.h + + + + UIControl + UIView + + IBFrameworkSource + UIKit.framework/Headers/UIControl.h + + + + UILabel + UIView + + IBFrameworkSource + UIKit.framework/Headers/UILabel.h + + + + UIResponder + NSObject + + + + UISearchBar + UIView + + IBFrameworkSource + UIKit.framework/Headers/UISearchBar.h + + + + UISearchDisplayController + NSObject + + IBFrameworkSource + UIKit.framework/Headers/UISearchDisplayController.h + + + + UISwitch + UIControl + + IBFrameworkSource + UIKit.framework/Headers/UISwitch.h + + + + UIView + + IBFrameworkSource + UIKit.framework/Headers/UITextField.h + + + + UIView + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIView.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UINavigationController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UIPopoverController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UISplitViewController.h + + + + UIViewController + + IBFrameworkSource + UIKit.framework/Headers/UITabBarController.h + + + + UIViewController + UIResponder + + IBFrameworkSource + UIKit.framework/Headers/UIViewController.h + + + + + 0 + IBIPadFramework + + com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS + + + + com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 + + + YES + ../SNES4iPad.xcodeproj + 3 + 87 + + diff --git a/Resources/cartridge.png b/Resources/cartridge.png new file mode 100644 index 0000000..2e1b447 Binary files /dev/null and b/Resources/cartridge.png differ diff --git a/Resources/console.png b/Resources/console.png new file mode 100644 index 0000000..9216470 Binary files /dev/null and b/Resources/console.png differ diff --git a/Resources/controlpad.png b/Resources/controlpad.png new file mode 100644 index 0000000..45790a9 Binary files /dev/null and b/Resources/controlpad.png differ diff --git a/Resources/gear.png b/Resources/gear.png new file mode 100644 index 0000000..2790af6 Binary files /dev/null and b/Resources/gear.png differ diff --git a/Resources/greenButton.png b/Resources/greenButton.png new file mode 100644 index 0000000..fb06c06 Binary files /dev/null and b/Resources/greenButton.png differ diff --git a/Resources/loadbutton.png b/Resources/loadbutton.png new file mode 100644 index 0000000..3491fc9 Binary files /dev/null and b/Resources/loadbutton.png differ diff --git a/Resources/powerbutton.png b/Resources/powerbutton.png new file mode 100644 index 0000000..e68f170 Binary files /dev/null and b/Resources/powerbutton.png differ diff --git a/Resources/redButton.png b/Resources/redButton.png new file mode 100644 index 0000000..a1cf553 Binary files /dev/null and b/Resources/redButton.png differ diff --git a/Resources/snapshot-test.png b/Resources/snapshot-test.png new file mode 100644 index 0000000..4c8fc7b Binary files /dev/null and b/Resources/snapshot-test.png differ diff --git a/Resources/snesadvance.dat b/Resources/snesadvance.dat new file mode 100755 index 0000000..e66a250 --- /dev/null +++ b/Resources/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/SNES4iPad-Info.plist b/SNES4iPad-Info.plist new file mode 100644 index 0000000..56f1768 --- /dev/null +++ b/SNES4iPad-Info.plist @@ -0,0 +1,39 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + SNES (HD) + CFBundleExecutable + SNES-HD + CFBundleIconFile + Icon.png + CFBundleIdentifier + com.wherethewoozlewasnt.snes-hd + CFBundleInfoDictionaryVersion + 6.0 + UIDeviceFamily + 2 + CFBundleName + SNES-HD + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/SNES4iPad.xcodeproj/project.pbxproj b/SNES4iPad.xcodeproj/project.pbxproj new file mode 100755 index 0000000..d04ca65 --- /dev/null +++ b/SNES4iPad.xcodeproj/project.pbxproj @@ -0,0 +1,392 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1D3623260D0F684500981E51 /* SNES4iPadAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* SNES4iPadAppDelegate.m */; }; + 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; + 2804200B108E984D000629CD /* RomSelectionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 28042008108E984D000629CD /* RomSelectionViewController.m */; }; + 2804200C108E984D000629CD /* RomDetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2804200A108E984D000629CD /* RomDetailViewController.m */; }; + 2892E4100DC94CBA00A64D0F /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */; }; + CE43A4A5119DEA3C0007E399 /* EmulationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CE43A4A4119DEA3C0007E399 /* EmulationViewController.m */; }; + CE43A4B4119DF2B00007E399 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CE43A4B3119DF2B00007E399 /* QuartzCore.framework */; }; + CE43A4B6119DF2D80007E399 /* CoreSurface.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CE43A4B5119DF2D80007E399 /* CoreSurface.framework */; }; + CE43A4DB119DFEF70007E399 /* cartridge.png in Resources */ = {isa = PBXBuildFile; fileRef = CE43A4CD119DFEF70007E399 /* cartridge.png */; }; + CE43A4DC119DFEF70007E399 /* console.png in Resources */ = {isa = PBXBuildFile; fileRef = CE43A4CE119DFEF70007E399 /* console.png */; }; + CE43A4DD119DFEF70007E399 /* controlpad.png in Resources */ = {isa = PBXBuildFile; fileRef = CE43A4CF119DFEF70007E399 /* controlpad.png */; }; + CE43A4DE119DFEF70007E399 /* ControlPadConnectViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE43A4D0119DFEF70007E399 /* ControlPadConnectViewController.xib */; }; + CE43A4DF119DFEF70007E399 /* DetailView.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE43A4D1119DFEF70007E399 /* DetailView.xib */; }; + CE43A4E0119DFEF70007E399 /* gear.png in Resources */ = {isa = PBXBuildFile; fileRef = CE43A4D2119DFEF70007E399 /* gear.png */; }; + CE43A4E1119DFEF70007E399 /* greenButton.png in Resources */ = {isa = PBXBuildFile; fileRef = CE43A4D3119DFEF70007E399 /* greenButton.png */; }; + CE43A4E2119DFEF70007E399 /* loadbutton.png in Resources */ = {isa = PBXBuildFile; fileRef = CE43A4D4119DFEF70007E399 /* loadbutton.png */; }; + CE43A4E3119DFEF70007E399 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE43A4D5119DFEF70007E399 /* MainWindow.xib */; }; + CE43A4E4119DFEF70007E399 /* powerbutton.png in Resources */ = {isa = PBXBuildFile; fileRef = CE43A4D6119DFEF70007E399 /* powerbutton.png */; }; + CE43A4E5119DFEF70007E399 /* redButton.png in Resources */ = {isa = PBXBuildFile; fileRef = CE43A4D7119DFEF70007E399 /* redButton.png */; }; + CE43A4E6119DFEF70007E399 /* SaveStateSelectionViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE43A4D8119DFEF70007E399 /* SaveStateSelectionViewController.xib */; }; + CE43A4E7119DFEF70007E399 /* SettingsViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = CE43A4D9119DFEF70007E399 /* SettingsViewController.xib */; }; + CE43A4E8119DFEF70007E399 /* snapshot-test.png in Resources */ = {isa = PBXBuildFile; fileRef = CE43A4DA119DFEF70007E399 /* snapshot-test.png */; }; + CE43A517119E087E0007E399 /* SNES4iPad-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = CE43A516119E087E0007E399 /* SNES4iPad-Info.plist */; }; + CEA57D651198B621004DCD60 /* SaveStateSelectionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CEA57D631198B621004DCD60 /* SaveStateSelectionViewController.m */; }; + CEA57E2B1198D3BC004DCD60 /* SettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CEA57E291198D3BC004DCD60 /* SettingsViewController.m */; }; + CEA57F091198E5E8004DCD60 /* ControlPadManager.m in Sources */ = {isa = PBXBuildFile; fileRef = CEA57F081198E5E8004DCD60 /* ControlPadManager.m */; }; + CEA57F0B1198E6F8004DCD60 /* GameKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CEA57F0A1198E6F8004DCD60 /* GameKit.framework */; }; + CEA57F111198ED61004DCD60 /* ControlPadConnectViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CEA57F0F1198ED61004DCD60 /* ControlPadConnectViewController.m */; }; + CEEA77CE119F3F4400440258 /* ScreenView.m in Sources */ = {isa = PBXBuildFile; fileRef = CEEA77CD119F3F4400440258 /* ScreenView.m */; }; + CEEA77D1119F3F6100440258 /* ScreenLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = CEEA77D0119F3F6100440258 /* ScreenLayer.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 1D3623240D0F684500981E51 /* SNES4iPadAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SNES4iPadAppDelegate.h; sourceTree = ""; }; + 1D3623250D0F684500981E51 /* SNES4iPadAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SNES4iPadAppDelegate.m; sourceTree = ""; }; + 1D6058910D05DD3D006BFB54 /* SNES4iPad.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SNES4iPad.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + 28042007108E984D000629CD /* RomSelectionViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RomSelectionViewController.h; sourceTree = ""; }; + 28042008108E984D000629CD /* RomSelectionViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RomSelectionViewController.m; sourceTree = ""; }; + 28042009108E984D000629CD /* RomDetailViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RomDetailViewController.h; sourceTree = ""; }; + 2804200A108E984D000629CD /* RomDetailViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RomDetailViewController.m; sourceTree = ""; }; + 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; + 28A0AAE50D9B0CCF005BE974 /* SNES4iPad_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SNES4iPad_Prefix.pch; sourceTree = ""; }; + 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + CE43A4A3119DEA3C0007E399 /* EmulationViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EmulationViewController.h; sourceTree = ""; }; + CE43A4A4119DEA3C0007E399 /* EmulationViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EmulationViewController.m; sourceTree = ""; }; + CE43A4B3119DF2B00007E399 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; + CE43A4B5119DF2D80007E399 /* CoreSurface.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreSurface.framework; path = System/Library/PrivateFrameworks/CoreSurface.framework; sourceTree = SDKROOT; }; + CE43A4CD119DFEF70007E399 /* cartridge.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = cartridge.png; sourceTree = ""; }; + CE43A4CE119DFEF70007E399 /* console.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = console.png; sourceTree = ""; }; + CE43A4CF119DFEF70007E399 /* controlpad.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = controlpad.png; sourceTree = ""; }; + CE43A4D0119DFEF70007E399 /* ControlPadConnectViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ControlPadConnectViewController.xib; sourceTree = ""; }; + CE43A4D1119DFEF70007E399 /* DetailView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = DetailView.xib; sourceTree = ""; }; + CE43A4D2119DFEF70007E399 /* gear.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = gear.png; sourceTree = ""; }; + CE43A4D3119DFEF70007E399 /* greenButton.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = greenButton.png; sourceTree = ""; }; + CE43A4D4119DFEF70007E399 /* loadbutton.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = loadbutton.png; sourceTree = ""; }; + CE43A4D5119DFEF70007E399 /* MainWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MainWindow.xib; sourceTree = ""; }; + CE43A4D6119DFEF70007E399 /* powerbutton.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = powerbutton.png; sourceTree = ""; }; + CE43A4D7119DFEF70007E399 /* redButton.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = redButton.png; sourceTree = ""; }; + CE43A4D8119DFEF70007E399 /* SaveStateSelectionViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SaveStateSelectionViewController.xib; sourceTree = ""; }; + CE43A4D9119DFEF70007E399 /* SettingsViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SettingsViewController.xib; sourceTree = ""; }; + CE43A4DA119DFEF70007E399 /* snapshot-test.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "snapshot-test.png"; sourceTree = ""; }; + CE43A50D119E01600007E399 /* CoreSurface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CoreSurface.h; sourceTree = ""; }; + CE43A516119E087E0007E399 /* SNES4iPad-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "SNES4iPad-Info.plist"; sourceTree = ""; }; + CEA57D621198B621004DCD60 /* SaveStateSelectionViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SaveStateSelectionViewController.h; sourceTree = ""; }; + CEA57D631198B621004DCD60 /* SaveStateSelectionViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SaveStateSelectionViewController.m; sourceTree = ""; }; + CEA57E281198D3BC004DCD60 /* SettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SettingsViewController.h; sourceTree = ""; }; + CEA57E291198D3BC004DCD60 /* SettingsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SettingsViewController.m; sourceTree = ""; }; + CEA57F071198E5E8004DCD60 /* ControlPadManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ControlPadManager.h; sourceTree = ""; }; + CEA57F081198E5E8004DCD60 /* ControlPadManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ControlPadManager.m; sourceTree = ""; }; + CEA57F0A1198E6F8004DCD60 /* GameKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameKit.framework; path = System/Library/Frameworks/GameKit.framework; sourceTree = SDKROOT; }; + CEA57F0E1198ED61004DCD60 /* ControlPadConnectViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ControlPadConnectViewController.h; sourceTree = ""; }; + CEA57F0F1198ED61004DCD60 /* ControlPadConnectViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ControlPadConnectViewController.m; sourceTree = ""; }; + CEEA77CC119F3F4400440258 /* ScreenView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScreenView.h; sourceTree = ""; }; + CEEA77CD119F3F4400440258 /* ScreenView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ScreenView.m; sourceTree = ""; }; + CEEA77CF119F3F6100440258 /* ScreenLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScreenLayer.h; sourceTree = ""; }; + CEEA77D0119F3F6100440258 /* ScreenLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ScreenLayer.m; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, + 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, + 2892E4100DC94CBA00A64D0F /* CoreGraphics.framework in Frameworks */, + CEA57F0B1198E6F8004DCD60 /* GameKit.framework in Frameworks */, + CE43A4B4119DF2B00007E399 /* QuartzCore.framework in Frameworks */, + CE43A4B6119DF2D80007E399 /* CoreSurface.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 080E96DDFE201D6D7F000001 /* Classes */ = { + isa = PBXGroup; + children = ( + 1D3623240D0F684500981E51 /* SNES4iPadAppDelegate.h */, + 1D3623250D0F684500981E51 /* SNES4iPadAppDelegate.m */, + 28042007108E984D000629CD /* RomSelectionViewController.h */, + 28042008108E984D000629CD /* RomSelectionViewController.m */, + 28042009108E984D000629CD /* RomDetailViewController.h */, + 2804200A108E984D000629CD /* RomDetailViewController.m */, + CEA57D621198B621004DCD60 /* SaveStateSelectionViewController.h */, + CEA57D631198B621004DCD60 /* SaveStateSelectionViewController.m */, + CEA57E281198D3BC004DCD60 /* SettingsViewController.h */, + CEA57E291198D3BC004DCD60 /* SettingsViewController.m */, + CEA57F071198E5E8004DCD60 /* ControlPadManager.h */, + CEA57F081198E5E8004DCD60 /* ControlPadManager.m */, + CEA57F0E1198ED61004DCD60 /* ControlPadConnectViewController.h */, + CEA57F0F1198ED61004DCD60 /* ControlPadConnectViewController.m */, + CE43A4A3119DEA3C0007E399 /* EmulationViewController.h */, + CE43A4A4119DEA3C0007E399 /* EmulationViewController.m */, + CEEA77CC119F3F4400440258 /* ScreenView.h */, + CEEA77CD119F3F4400440258 /* ScreenView.m */, + CEEA77CF119F3F6100440258 /* ScreenLayer.h */, + CEEA77D0119F3F6100440258 /* ScreenLayer.m */, + ); + path = Classes; + sourceTree = ""; + }; + 19C28FACFE9D520D11CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 1D6058910D05DD3D006BFB54 /* SNES4iPad.app */, + ); + name = Products; + sourceTree = ""; + }; + 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { + isa = PBXGroup; + children = ( + 080E96DDFE201D6D7F000001 /* Classes */, + CE43A4CC119DFEF70007E399 /* Resources */, + 29B97315FDCFA39411CA2CEA /* Other Sources */, + 29B97323FDCFA39411CA2CEA /* Frameworks */, + 19C28FACFE9D520D11CA2CBB /* Products */, + CEA57F0A1198E6F8004DCD60 /* GameKit.framework */, + CE43A4B3119DF2B00007E399 /* QuartzCore.framework */, + CE43A4B5119DF2D80007E399 /* CoreSurface.framework */, + ); + name = CustomTemplate; + sourceTree = ""; + }; + 29B97315FDCFA39411CA2CEA /* Other Sources */ = { + isa = PBXGroup; + children = ( + CE43A50C119E01600007E399 /* CoreSurface */, + 28A0AAE50D9B0CCF005BE974 /* SNES4iPad_Prefix.pch */, + CE43A516119E087E0007E399 /* SNES4iPad-Info.plist */, + 29B97316FDCFA39411CA2CEA /* main.m */, + ); + name = "Other Sources"; + sourceTree = ""; + }; + 29B97323FDCFA39411CA2CEA /* Frameworks */ = { + isa = PBXGroup; + children = ( + 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, + 1D30AB110D05D00D00671497 /* Foundation.framework */, + 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + CE43A4CC119DFEF70007E399 /* Resources */ = { + isa = PBXGroup; + children = ( + CE43A4CD119DFEF70007E399 /* cartridge.png */, + CE43A4CE119DFEF70007E399 /* console.png */, + CE43A4CF119DFEF70007E399 /* controlpad.png */, + CE43A4D0119DFEF70007E399 /* ControlPadConnectViewController.xib */, + CE43A4D1119DFEF70007E399 /* DetailView.xib */, + CE43A4D2119DFEF70007E399 /* gear.png */, + CE43A4D3119DFEF70007E399 /* greenButton.png */, + CE43A4D4119DFEF70007E399 /* loadbutton.png */, + CE43A4D5119DFEF70007E399 /* MainWindow.xib */, + CE43A4D6119DFEF70007E399 /* powerbutton.png */, + CE43A4D7119DFEF70007E399 /* redButton.png */, + CE43A4D8119DFEF70007E399 /* SaveStateSelectionViewController.xib */, + CE43A4D9119DFEF70007E399 /* SettingsViewController.xib */, + CE43A4DA119DFEF70007E399 /* snapshot-test.png */, + ); + path = Resources; + sourceTree = ""; + }; + CE43A50C119E01600007E399 /* CoreSurface */ = { + isa = PBXGroup; + children = ( + CE43A50D119E01600007E399 /* CoreSurface.h */, + ); + path = CoreSurface; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 1D6058900D05DD3D006BFB54 /* SNES4iPad */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "SNES4iPad" */; + buildPhases = ( + 1D60588D0D05DD3D006BFB54 /* Resources */, + 1D60588E0D05DD3D006BFB54 /* Sources */, + 1D60588F0D05DD3D006BFB54 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = SNES4iPad; + productName = SNES4iPad; + productReference = 1D6058910D05DD3D006BFB54 /* SNES4iPad.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 29B97313FDCFA39411CA2CEA /* Project object */ = { + isa = PBXProject; + buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "SNES4iPad" */; + compatibilityVersion = "Xcode 3.2"; + hasScannedForEncodings = 1; + knownRegions = ( + English, + Japanese, + French, + German, + en, + ); + mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1D6058900D05DD3D006BFB54 /* SNES4iPad */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1D60588D0D05DD3D006BFB54 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + CE43A4DB119DFEF70007E399 /* cartridge.png in Resources */, + CE43A4DC119DFEF70007E399 /* console.png in Resources */, + CE43A4DD119DFEF70007E399 /* controlpad.png in Resources */, + CE43A4DE119DFEF70007E399 /* ControlPadConnectViewController.xib in Resources */, + CE43A4DF119DFEF70007E399 /* DetailView.xib in Resources */, + CE43A4E0119DFEF70007E399 /* gear.png in Resources */, + CE43A4E1119DFEF70007E399 /* greenButton.png in Resources */, + CE43A4E2119DFEF70007E399 /* loadbutton.png in Resources */, + CE43A4E3119DFEF70007E399 /* MainWindow.xib in Resources */, + CE43A4E4119DFEF70007E399 /* powerbutton.png in Resources */, + CE43A4E5119DFEF70007E399 /* redButton.png in Resources */, + CE43A4E6119DFEF70007E399 /* SaveStateSelectionViewController.xib in Resources */, + CE43A4E7119DFEF70007E399 /* SettingsViewController.xib in Resources */, + CE43A4E8119DFEF70007E399 /* snapshot-test.png in Resources */, + CE43A517119E087E0007E399 /* SNES4iPad-Info.plist in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1D60588E0D05DD3D006BFB54 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1D60589B0D05DD56006BFB54 /* main.m in Sources */, + 1D3623260D0F684500981E51 /* SNES4iPadAppDelegate.m in Sources */, + 2804200B108E984D000629CD /* RomSelectionViewController.m in Sources */, + 2804200C108E984D000629CD /* RomDetailViewController.m in Sources */, + CEA57D651198B621004DCD60 /* SaveStateSelectionViewController.m in Sources */, + CEA57E2B1198D3BC004DCD60 /* SettingsViewController.m in Sources */, + CEA57F091198E5E8004DCD60 /* ControlPadManager.m in Sources */, + CEA57F111198ED61004DCD60 /* ControlPadConnectViewController.m in Sources */, + CE43A4A5119DEA3C0007E399 /* EmulationViewController.m in Sources */, + CEEA77CE119F3F4400440258 /* ScreenView.m in Sources */, + CEEA77D1119F3F6100440258 /* ScreenLayer.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 1D6058940D05DD3E006BFB54 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"", + ); + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = SNES4iPad_Prefix.pch; + INFOPLIST_FILE = "SNES4iPad-Info.plist"; + PRODUCT_NAME = SNES4iPad; + }; + name = Debug; + }; + 1D6058950D05DD3E006BFB54 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks\"", + ); + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREFIX_HEADER = SNES4iPad_Prefix.pch; + INFOPLIST_FILE = "SNES4iPad-Info.plist"; + PRODUCT_NAME = SNES4iPad; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + C01FCF4F08A954540054247B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + "ARCHS[sdk=iphoneos*]" = armv7; + "ARCHS[sdk=iphonesimulator*]" = i386; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + FRAMEWORK_SEARCH_PATHS = /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.2.sdk/System/Library/PrivateFrameworks/; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + SDKROOT = iphoneos3.2; + TARGETED_DEVICE_FAMILY = 2; + }; + name = Debug; + }; + C01FCF5008A954540054247B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + "ARCHS[sdk=iphoneos*]" = armv7; + "ARCHS[sdk=iphonesimulator*]" = i386; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + FRAMEWORK_SEARCH_PATHS = /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.2.sdk/System/Library/PrivateFrameworks/; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; + PREBINDING = NO; + SDKROOT = iphoneos3.2; + TARGETED_DEVICE_FAMILY = 2; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "SNES4iPad" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1D6058940D05DD3E006BFB54 /* Debug */, + 1D6058950D05DD3E006BFB54 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C01FCF4E08A954540054247B /* Build configuration list for PBXProject "SNES4iPad" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C01FCF4F08A954540054247B /* Debug */, + C01FCF5008A954540054247B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; +} diff --git a/SNES4iPad.xcodeproj/yusefnapora.pbxuser b/SNES4iPad.xcodeproj/yusefnapora.pbxuser new file mode 100644 index 0000000..6c43933 --- /dev/null +++ b/SNES4iPad.xcodeproj/yusefnapora.pbxuser @@ -0,0 +1,539 @@ +// !$*UTF8*$! +{ + 1D3623240D0F684500981E51 /* SNES4iPadAppDelegate.h */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {917, 702}}"; + sepNavSelRange = "{372, 0}"; + sepNavVisRange = "{306, 1390}"; + }; + }; + 1D3623250D0F684500981E51 /* SNES4iPadAppDelegate.m */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {917, 1326}}"; + sepNavSelRange = "{2530, 0}"; + sepNavVisRange = "{2122, 841}"; + }; + }; + 1D6058900D05DD3D006BFB54 /* SNES4iPad */ = { + activeExec = 0; + executables = ( + CEA57BFC1198477B004DCD60 /* SNES4iPad */, + ); + }; + 28042007108E984D000629CD /* RomSelectionViewController.h */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {917, 456}}"; + sepNavSelRange = "{213, 0}"; + sepNavVisRange = "{0, 599}"; + }; + }; + 28042008108E984D000629CD /* RomSelectionViewController.m */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {1251, 4329}}"; + sepNavSelRange = "{156, 32}"; + sepNavVisRange = "{0, 914}"; + }; + }; + 28042009108E984D000629CD /* RomDetailViewController.h */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {917, 871}}"; + sepNavSelRange = "{2082, 0}"; + sepNavVisRange = "{802, 1287}"; + }; + }; + 2804200A108E984D000629CD /* RomDetailViewController.m */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {1510, 3822}}"; + sepNavSelRange = "{7623, 0}"; + sepNavVisRange = "{5351, 1274}"; + }; + }; + 28A0AAE50D9B0CCF005BE974 /* SNES4iPad_Prefix.pch */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {1012, 488}}"; + sepNavSelRange = "{349, 0}"; + sepNavVisRange = "{0, 357}"; + }; + }; + 29B97313FDCFA39411CA2CEA /* Project object */ = { + activeBuildConfigurationName = Debug; + activeExecutable = CEA57BFC1198477B004DCD60 /* SNES4iPad */; + activeSDKPreference = iphoneos3.2; + activeTarget = 1D6058900D05DD3D006BFB54 /* SNES4iPad */; + addToTargets = ( + 1D6058900D05DD3D006BFB54 /* SNES4iPad */, + ); + breakpoints = ( + ); + codeSenseManager = CEA57C091198478C004DCD60 /* Code sense */; + executables = ( + CEA57BFC1198477B004DCD60 /* SNES4iPad */, + ); + perUserDictionary = { + PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = { + PBXFileTableDataSourceColumnSortingDirectionKey = "-1"; + PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID; + PBXFileTableDataSourceColumnWidthsKey = ( + 20, + 739, + 20, + 48, + 43, + 43, + 20, + ); + PBXFileTableDataSourceColumnsKey = ( + PBXFileDataSource_FiletypeID, + PBXFileDataSource_Filename_ColumnID, + PBXFileDataSource_Built_ColumnID, + PBXFileDataSource_ObjectSize_ColumnID, + PBXFileDataSource_Errors_ColumnID, + PBXFileDataSource_Warnings_ColumnID, + PBXFileDataSource_Target_ColumnID, + ); + }; + PBXPerProjectTemplateStateSaveDate = 296352179; + PBXWorkspaceStateSaveDate = 296352179; + }; + perUserProjectItems = { + CE1819BE11A1E86200B7A5B0 = CE1819BE11A1E86200B7A5B0 /* PBXTextBookmark */; + CE1819C011A1E86200B7A5B0 = CE1819C011A1E86200B7A5B0 /* PBXTextBookmark */; + CE1819C111A1E86200B7A5B0 = CE1819C111A1E86200B7A5B0 /* PBXTextBookmark */; + CE235A1811A23FFA00593C86 = CE235A1811A23FFA00593C86 /* PBXTextBookmark */; + CE235A1911A23FFA00593C86 = CE235A1911A23FFA00593C86 /* PBXTextBookmark */; + CE235A1A11A23FFA00593C86 = CE235A1A11A23FFA00593C86 /* PBXTextBookmark */; + CE235A1B11A23FFA00593C86 = CE235A1B11A23FFA00593C86 /* PBXTextBookmark */; + CE235A1C11A23FFA00593C86 = CE235A1C11A23FFA00593C86 /* PBXTextBookmark */; + CE235A1D11A23FFA00593C86 = CE235A1D11A23FFA00593C86 /* PBXTextBookmark */; + CE235A1E11A23FFA00593C86 = CE235A1E11A23FFA00593C86 /* PBXTextBookmark */; + CE43A4ED119DFFD90007E399 = CE43A4ED119DFFD90007E399 /* PBXBookmark */; + CE43A4EF119DFFD90007E399 = CE43A4EF119DFFD90007E399 /* PBXTextBookmark */; + CE43A501119DFFFD0007E399 = CE43A501119DFFFD0007E399 /* PBXTextBookmark */; + CE43A553119E17760007E399 = CE43A553119E17760007E399 /* PBXTextBookmark */; + CE43A568119E35470007E399 = CE43A568119E35470007E399 /* PlistBookmark */; + CEA57E3D1198D831004DCD60 = CEA57E3D1198D831004DCD60 /* PBXTextBookmark */; + CEDE3D11119A2C00002889C8 = CEDE3D11119A2C00002889C8 /* PBXTextBookmark */; + CEE856CE11A9F9C300784F8D /* PBXTextBookmark */ = CEE856CE11A9F9C300784F8D /* PBXTextBookmark */; + CEEA77D2119F426600440258 = CEEA77D2119F426600440258 /* PBXTextBookmark */; + CEEA77EF119F42DA00440258 = CEEA77EF119F42DA00440258 /* PBXTextBookmark */; + CEEA77F0119F42DA00440258 = CEEA77F0119F42DA00440258 /* PBXTextBookmark */; + CEEA7801119F43ED00440258 = CEEA7801119F43ED00440258 /* PBXTextBookmark */; + CEEA7824119F47EF00440258 = CEEA7824119F47EF00440258 /* PBXTextBookmark */; + CEEA7832119F4F0D00440258 = CEEA7832119F4F0D00440258 /* PBXTextBookmark */; + CEEA7833119F4F0D00440258 = CEEA7833119F4F0D00440258 /* PBXTextBookmark */; + CEEA7847119F56AF00440258 = CEEA7847119F56AF00440258 /* PBXTextBookmark */; + }; + sourceControlManager = CEA57C081198478C004DCD60 /* Source Control */; + userBuildSettings = { + }; + }; + CE1819BE11A1E86200B7A5B0 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = CEEA77CD119F3F4400440258 /* ScreenView.m */; + name = "ScreenView.m: 61"; + rLen = 0; + rLoc = 1618; + rType = 0; + vrLen = 1203; + vrLoc = 839; + }; + CE1819C011A1E86200B7A5B0 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 2804200A108E984D000629CD /* RomDetailViewController.m */; + name = "RomDetailViewController.m: 228"; + rLen = 0; + rLoc = 7623; + rType = 0; + vrLen = 1274; + vrLoc = 5351; + }; + CE1819C111A1E86200B7A5B0 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = CEA57D621198B621004DCD60 /* SaveStateSelectionViewController.h */; + name = "SaveStateSelectionViewController.h: 32"; + rLen = 0; + rLoc = 909; + rType = 0; + vrLen = 915; + vrLoc = 0; + }; + CE235A1811A23FFA00593C86 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = CEA57F081198E5E8004DCD60 /* ControlPadManager.m */; + name = "ControlPadManager.m: 128"; + rLen = 0; + rLoc = 3183; + rType = 0; + vrLen = 1307; + vrLoc = 2985; + }; + CE235A1911A23FFA00593C86 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = CE43A4A4119DEA3C0007E399 /* EmulationViewController.m */; + name = "EmulationViewController.m: 65"; + rLen = 0; + rLoc = 1749; + rType = 0; + vrLen = 994; + vrLoc = 674; + }; + CE235A1A11A23FFA00593C86 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = CEA57F0F1198ED61004DCD60 /* ControlPadConnectViewController.m */; + name = "ControlPadConnectViewController.m: 30"; + rLen = 151; + rLoc = 1013; + rType = 0; + vrLen = 1333; + vrLoc = 273; + }; + CE235A1B11A23FFA00593C86 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = CEA57F071198E5E8004DCD60 /* ControlPadManager.h */; + name = "ControlPadManager.h: 31"; + rLen = 0; + rLoc = 846; + rType = 0; + vrLen = 948; + vrLoc = 0; + }; + CE235A1C11A23FFA00593C86 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = CEA57F0E1198ED61004DCD60 /* ControlPadConnectViewController.h */; + name = "ControlPadConnectViewController.h: 38"; + rLen = 0; + rLoc = 1054; + rType = 0; + vrLen = 997; + vrLoc = 58; + }; + CE235A1D11A23FFA00593C86 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = CEA57D631198B621004DCD60 /* SaveStateSelectionViewController.m */; + name = "SaveStateSelectionViewController.m: 293"; + rLen = 0; + rLoc = 7946; + rType = 0; + vrLen = 1086; + vrLoc = 7156; + }; + CE235A1E11A23FFA00593C86 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = CEA57D631198B621004DCD60 /* SaveStateSelectionViewController.m */; + name = "SaveStateSelectionViewController.m: 293"; + rLen = 0; + rLoc = 7946; + rType = 0; + vrLen = 1086; + vrLoc = 7156; + }; + CE43A4A3119DEA3C0007E399 /* EmulationViewController.h */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {917, 450}}"; + sepNavSelRange = "{212, 0}"; + sepNavVisRange = "{0, 488}"; + }; + }; + CE43A4A4119DEA3C0007E399 /* EmulationViewController.m */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {1160, 2301}}"; + sepNavSelRange = "{1749, 0}"; + sepNavVisRange = "{674, 994}"; + }; + }; + CE43A4ED119DFFD90007E399 /* PBXBookmark */ = { + isa = PBXBookmark; + fRef = CE43A4CE119DFEF70007E399 /* console.png */; + }; + CE43A4EF119DFFD90007E399 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 28042008108E984D000629CD /* RomSelectionViewController.m */; + name = "RomSelectionViewController.m: 9"; + rLen = 32; + rLoc = 156; + rType = 0; + vrLen = 914; + vrLoc = 0; + }; + CE43A501119DFFFD0007E399 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 28042007108E984D000629CD /* RomSelectionViewController.h */; + name = "RomSelectionViewController.h: 12"; + rLen = 0; + rLoc = 213; + rType = 0; + vrLen = 599; + vrLoc = 0; + }; + CE43A553119E17760007E399 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 28042009108E984D000629CD /* RomDetailViewController.h */; + name = "RomDetailViewController.h: 64"; + rLen = 0; + rLoc = 2082; + rType = 0; + vrLen = 1287; + vrLoc = 802; + }; + CE43A568119E35470007E399 /* PlistBookmark */ = { + isa = PlistBookmark; + fRef = CE43A516119E087E0007E399 /* SNES4iPad-Info.plist */; + fallbackIsa = PBXBookmark; + isK = 0; + kPath = ( + ); + name = "/Users/yusefnapora/Documents/Code/SNES4iPad/SNES4iPad-Info.plist"; + rLen = 0; + rLoc = 9223372036854775808; + }; + CEA57BFC1198477B004DCD60 /* SNES4iPad */ = { + isa = PBXExecutable; + activeArgIndices = ( + ); + argumentStrings = ( + ); + autoAttachOnCrash = 1; + breakpointsEnabled = 1; + configStateDict = { + }; + customDataFormattersEnabled = 1; + dataTipCustomDataFormattersEnabled = 1; + dataTipShowTypeColumn = 1; + dataTipSortType = 0; + debuggerPlugin = GDBDebugging; + disassemblyDisplayState = 0; + dylibVariantSuffix = ""; + enableDebugStr = 1; + environmentEntries = ( + ); + executableSystemSymbolLevel = 0; + executableUserSymbolLevel = 0; + libgmallocEnabled = 0; + name = SNES4iPad; + savedGlobals = { + }; + showTypeColumn = 0; + sourceDirectories = ( + ); + variableFormatDictionary = { + }; + }; + CEA57C081198478C004DCD60 /* Source Control */ = { + isa = PBXSourceControlManager; + fallbackIsa = XCSourceControlManager; + isSCMEnabled = 0; + scmConfiguration = { + repositoryNamesForRoots = { + "" = ""; + }; + }; + }; + CEA57C091198478C004DCD60 /* Code sense */ = { + isa = PBXCodeSenseManager; + indexTemplatePath = ""; + }; + CEA57D621198B621004DCD60 /* SaveStateSelectionViewController.h */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {917, 442}}"; + sepNavSelRange = "{909, 0}"; + sepNavVisRange = "{0, 915}"; + sepNavWindowFrame = "{{38, 194}, {750, 558}}"; + }; + }; + CEA57D631198B621004DCD60 /* SaveStateSelectionViewController.m */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {1048, 4420}}"; + sepNavSelRange = "{7946, 0}"; + sepNavVisRange = "{6712, 901}"; + }; + }; + CEA57E281198D3BC004DCD60 /* SettingsViewController.h */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {917, 455}}"; + sepNavSelRange = "{876, 0}"; + sepNavVisRange = "{0, 879}"; + sepNavWindowFrame = "{{15, 215}, {750, 558}}"; + }; + }; + CEA57E291198D3BC004DCD60 /* SettingsViewController.m */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {917, 1794}}"; + sepNavSelRange = "{755, 0}"; + sepNavVisRange = "{0, 934}"; + }; + }; + CEA57E3D1198D831004DCD60 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 28A0AAE50D9B0CCF005BE974 /* SNES4iPad_Prefix.pch */; + name = "SNES4iPad_Prefix.pch: 14"; + rLen = 0; + rLoc = 349; + rType = 0; + vrLen = 357; + vrLoc = 0; + }; + CEA57F071198E5E8004DCD60 /* ControlPadManager.h */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {917, 585}}"; + sepNavSelRange = "{846, 0}"; + sepNavVisRange = "{0, 948}"; + sepNavWindowFrame = "{{15, 215}, {750, 558}}"; + }; + }; + CEA57F081198E5E8004DCD60 /* ControlPadManager.m */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {917, 2262}}"; + sepNavSelRange = "{3183, 0}"; + sepNavVisRange = "{2985, 1307}"; + }; + }; + CEA57F0E1198ED61004DCD60 /* ControlPadConnectViewController.h */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {917, 598}}"; + sepNavSelRange = "{1054, 0}"; + sepNavVisRange = "{58, 997}"; + }; + }; + CEA57F0F1198ED61004DCD60 /* ControlPadConnectViewController.m */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {964, 1690}}"; + sepNavSelRange = "{1013, 151}"; + sepNavVisRange = "{273, 1333}"; + }; + }; + CEDE3D11119A2C00002889C8 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = CEDE3D12119A2C00002889C8 /* NSString.h */; + name = "NSString.h: 305"; + rLen = 38; + rLoc = 18084; + rType = 0; + vrLen = 1550; + vrLoc = 17247; + }; + CEDE3D12119A2C00002889C8 /* NSString.h */ = { + isa = PBXFileReference; + lastKnownFileType = sourcecode.c.h; + name = NSString.h; + path = /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.2.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSString.h; + sourceTree = ""; + }; + CEE856CE11A9F9C300784F8D /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = CEA57D631198B621004DCD60 /* SaveStateSelectionViewController.m */; + name = "SaveStateSelectionViewController.m: 293"; + rLen = 0; + rLoc = 7946; + rType = 0; + vrLen = 901; + vrLoc = 6712; + }; + CEEA77CC119F3F4400440258 /* ScreenView.h */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {917, 419}}"; + sepNavSelRange = "{227, 0}"; + sepNavVisRange = "{0, 233}"; + }; + }; + CEEA77CD119F3F4400440258 /* ScreenView.m */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {917, 1105}}"; + sepNavSelRange = "{1618, 0}"; + sepNavVisRange = "{839, 1203}"; + }; + }; + CEEA77CF119F3F6100440258 /* ScreenLayer.h */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {917, 444}}"; + sepNavSelRange = "{302, 0}"; + sepNavVisRange = "{0, 311}"; + }; + }; + CEEA77D0119F3F6100440258 /* ScreenLayer.m */ = { + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {917, 1001}}"; + sepNavSelRange = "{1922, 0}"; + sepNavVisRange = "{1223, 958}"; + }; + }; + CEEA77D2119F426600440258 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = CE43A4A3119DEA3C0007E399 /* EmulationViewController.h */; + name = "EmulationViewController.h: 10"; + rLen = 0; + rLoc = 212; + rType = 0; + vrLen = 488; + vrLoc = 0; + }; + CEEA77EF119F42DA00440258 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = CEA57E281198D3BC004DCD60 /* SettingsViewController.h */; + name = "SettingsViewController.h: 35"; + rLen = 0; + rLoc = 876; + rType = 0; + vrLen = 879; + vrLoc = 0; + }; + CEEA77F0119F42DA00440258 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = CEA57E291198D3BC004DCD60 /* SettingsViewController.m */; + name = "SettingsViewController.m: 27"; + rLen = 0; + rLoc = 755; + rType = 0; + vrLen = 934; + vrLoc = 0; + }; + CEEA7801119F43ED00440258 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = CEEA77CF119F3F6100440258 /* ScreenLayer.h */; + name = "ScreenLayer.h: 14"; + rLen = 0; + rLoc = 302; + rType = 0; + vrLen = 311; + vrLoc = 0; + }; + CEEA7824119F47EF00440258 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = CEEA77D0119F3F6100440258 /* ScreenLayer.m */; + name = "ScreenLayer.m: 57"; + rLen = 0; + rLoc = 1922; + rType = 0; + vrLen = 958; + vrLoc = 1223; + }; + CEEA7832119F4F0D00440258 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 1D3623240D0F684500981E51 /* SNES4iPadAppDelegate.h */; + name = "SNES4iPadAppDelegate.h: 18"; + rLen = 0; + rLoc = 372; + rType = 0; + vrLen = 1390; + vrLoc = 306; + }; + CEEA7833119F4F0D00440258 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = CEEA77CC119F3F4400440258 /* ScreenView.h */; + name = "ScreenView.h: 16"; + rLen = 0; + rLoc = 227; + rType = 0; + vrLen = 233; + vrLoc = 0; + }; + CEEA7847119F56AF00440258 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = 1D3623250D0F684500981E51 /* SNES4iPadAppDelegate.m */; + name = "SNES4iPadAppDelegate.m: 79"; + rLen = 0; + rLoc = 2530; + rType = 0; + vrLen = 841; + vrLoc = 2122; + }; +} diff --git a/SNES4iPad.xcodeproj/yusefnapora.perspectivev3 b/SNES4iPad.xcodeproj/yusefnapora.perspectivev3 new file mode 100644 index 0000000..014cc17 --- /dev/null +++ b/SNES4iPad.xcodeproj/yusefnapora.perspectivev3 @@ -0,0 +1,1503 @@ + + + + + ActivePerspectiveName + Project + AllowedModules + + + BundleLoadPath + + MaxInstances + n + Module + PBXSmartGroupTreeModule + Name + Groups and Files Outline View + + + BundleLoadPath + + MaxInstances + n + Module + PBXNavigatorGroup + Name + Editor + + + BundleLoadPath + + MaxInstances + n + Module + XCTaskListModule + Name + Task List + + + BundleLoadPath + + MaxInstances + n + Module + XCDetailModule + Name + File and Smart Group Detail Viewer + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXBuildResultsModule + Name + Detailed Build Results Viewer + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXProjectFindModule + Name + Project Batch Find Tool + + + BundleLoadPath + + MaxInstances + n + Module + XCProjectFormatConflictsModule + Name + Project Format Conflicts List + + + BundleLoadPath + + MaxInstances + n + Module + PBXBookmarksModule + Name + Bookmarks Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXClassBrowserModule + Name + Class Browser + + + BundleLoadPath + + MaxInstances + n + Module + PBXCVSModule + Name + Source Code Control Tool + + + BundleLoadPath + + MaxInstances + n + Module + PBXDebugBreakpointsModule + Name + Debug Breakpoints Tool + + + BundleLoadPath + + MaxInstances + n + Module + XCDockableInspector + Name + Inspector + + + BundleLoadPath + + MaxInstances + n + Module + PBXOpenQuicklyModule + Name + Open Quickly Tool + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXDebugSessionModule + Name + Debugger + + + BundleLoadPath + + MaxInstances + 1 + Module + PBXDebugCLIModule + Name + Debug Console + + + BundleLoadPath + + MaxInstances + n + Module + XCSnapshotModule + Name + Snapshots Tool + + + BundlePath + /Developer/Library/PrivateFrameworks/DevToolsInterface.framework/Resources + Description + AIODescriptionKey + DockingSystemVisible + + Extension + perspectivev3 + FavBarConfig + + PBXProjectModuleGUID + CEA57C071198478C004DCD60 + XCBarModuleItemNames + + XCBarModuleItems + + + FirstTimeWindowDisplayed + + Identifier + com.apple.perspectives.project.defaultV3 + MajorVersion + 34 + MinorVersion + 0 + Name + All-In-One + Notifications + + OpenEditors + + PerspectiveWidths + + 1280 + 1280 + + Perspectives + + + ChosenToolbarItems + + XCToolbarPerspectiveControl + NSToolbarSeparatorItem + active-combo-popup + action + NSToolbarFlexibleSpaceItem + debugger-enable-breakpoints + build-and-go + com.apple.ide.PBXToolbarStopButton + get-info + NSToolbarFlexibleSpaceItem + com.apple.pbx.toolbar.searchfield + + ControllerClassBaseName + + IconName + WindowOfProject + Identifier + perspective.project + IsVertical + + Layout + + + BecomeActive + + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C37FBAC04509CD000000102 + 1C37FAAC04509CD000000102 + 1C37FABC05509CD000000102 + 1C37FABC05539CD112110102 + E2644B35053B69B200211256 + 1C37FABC04509CD000100104 + 1CC0EA4004350EF90044410B + 1CC0EA4004350EF90041110B + 1C77FABC04509CD000000102 + + PBXProjectModuleGUID + 1CA23ED40692098700951B8B + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + yes + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 280 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 29B97314FDCFA39411CA2CEA + 080E96DDFE201D6D7F000001 + CE43A4CC119DFEF70007E399 + 29B97315FDCFA39411CA2CEA + CE43A50C119E01600007E399 + 29B97323FDCFA39411CA2CEA + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 35 + 22 + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {280, 660}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + + + GeometryConfiguration + + Frame + {{0, 0}, {297, 678}} + GroupTreeTableConfiguration + + MainColumn + 280 + + RubberWindowFrame + 0 59 1280 719 0 0 1280 778 + + Module + PBXSmartGroupTreeModule + Proportion + 297pt + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + CEA57C021198478C004DCD60 + PBXProjectModuleLabel + SaveStateSelectionViewController.m + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + CEA57C031198478C004DCD60 + PBXProjectModuleLabel + SaveStateSelectionViewController.m + _historyCapacity + 0 + bookmark + CEE856CE11A9F9C300784F8D + history + + CEA57E3D1198D831004DCD60 + CEDE3D11119A2C00002889C8 + CE43A4ED119DFFD90007E399 + CE43A4EF119DFFD90007E399 + CE43A501119DFFFD0007E399 + CE43A553119E17760007E399 + CE43A568119E35470007E399 + CEEA77D2119F426600440258 + CEEA77EF119F42DA00440258 + CEEA77F0119F42DA00440258 + CEEA7801119F43ED00440258 + CEEA7824119F47EF00440258 + CEEA7832119F4F0D00440258 + CEEA7833119F4F0D00440258 + CEEA7847119F56AF00440258 + CE1819BE11A1E86200B7A5B0 + CE1819C011A1E86200B7A5B0 + CE1819C111A1E86200B7A5B0 + CE235A1811A23FFA00593C86 + CE235A1911A23FFA00593C86 + CE235A1A11A23FFA00593C86 + CE235A1B11A23FFA00593C86 + CE235A1C11A23FFA00593C86 + CE235A1E11A23FFA00593C86 + + + SplitCount + 1 + + StatusBarVisibility + + XCSharingToken + com.apple.Xcode.CommonNavigatorGroupSharingToken + + GeometryConfiguration + + Frame + {{0, 0}, {978, 457}} + RubberWindowFrame + 0 59 1280 719 0 0 1280 778 + + Module + PBXNavigatorGroup + Proportion + 457pt + + + Proportion + 216pt + Tabs + + + ContentConfiguration + + PBXProjectModuleGUID + 1CA23EDF0692099D00951B8B + PBXProjectModuleLabel + Detail + + GeometryConfiguration + + Frame + {{10, 27}, {978, 189}} + RubberWindowFrame + 0 59 1280 719 0 0 1280 778 + + Module + XCDetailModule + + + ContentConfiguration + + PBXProjectModuleGUID + 1CA23EE00692099D00951B8B + PBXProjectModuleLabel + Project Find + + GeometryConfiguration + + Frame + {{10, 27}, {978, 176}} + + Module + PBXProjectFindModule + + + ContentConfiguration + + PBXCVSModuleFilterTypeKey + 1032 + PBXProjectModuleGUID + 1CA23EE10692099D00951B8B + PBXProjectModuleLabel + SCM Results + + GeometryConfiguration + + Frame + {{10, 31}, {603, 297}} + + Module + PBXCVSModule + + + ContentConfiguration + + PBXProjectModuleGUID + XCMainBuildResultsModuleGUID + PBXProjectModuleLabel + Build Results + XCBuildResultsTrigger_Collapse + 1021 + XCBuildResultsTrigger_Open + 1011 + + GeometryConfiguration + + Frame + {{10, 27}, {978, 176}} + + Module + PBXBuildResultsModule + + + + + Proportion + 978pt + + + Name + Project + ServiceClasses + + XCModuleDock + PBXSmartGroupTreeModule + XCModuleDock + PBXNavigatorGroup + XCDockableTabModule + XCDetailModule + PBXProjectFindModule + PBXCVSModule + PBXBuildResultsModule + + TableOfContents + + CEE856CF11A9F9C300784F8D + 1CA23ED40692098700951B8B + CEE856D011A9F9C300784F8D + CEA57C021198478C004DCD60 + CEE856D111A9F9C300784F8D + 1CA23EDF0692099D00951B8B + 1CA23EE00692099D00951B8B + 1CA23EE10692099D00951B8B + XCMainBuildResultsModuleGUID + + ToolbarConfigUserDefaultsMinorVersion + 2 + ToolbarConfiguration + xcode.toolbar.config.defaultV3 + + + ChosenToolbarItems + + XCToolbarPerspectiveControl + NSToolbarSeparatorItem + active-combo-popup + NSToolbarFlexibleSpaceItem + debugger-enable-breakpoints + build-and-go + com.apple.ide.PBXToolbarStopButton + debugger-restart-executable + debugger-pause + debugger-step-over + debugger-step-into + debugger-step-out + NSToolbarFlexibleSpaceItem + servicesModulebreakpoints + debugger-show-console-window + + ControllerClassBaseName + PBXDebugSessionModule + IconName + DebugTabIcon + Identifier + perspective.debug + IsVertical + + Layout + + + ContentConfiguration + + PBXProjectModuleGUID + 1CCC7628064C1048000F2A68 + PBXProjectModuleLabel + Debugger Console + + GeometryConfiguration + + Frame + {{0, 0}, {1280, 344}} + + Module + PBXDebugCLIModule + Proportion + 344pt + + + ContentConfiguration + + Debugger + + HorizontalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {625, 160}} + {{625, 0}, {655, 160}} + + + VerticalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {1280, 160}} + {{0, 160}, {1280, 169}} + + + + LauncherConfigVersion + 8 + PBXProjectModuleGUID + 1CCC7629064C1048000F2A68 + PBXProjectModuleLabel + Debug + + GeometryConfiguration + + DebugConsoleVisible + None + DebugConsoleWindowFrame + {{200, 200}, {500, 300}} + DebugSTDIOWindowFrame + {{200, 200}, {500, 300}} + Frame + {{0, 349}, {1280, 329}} + PBXDebugSessionStackFrameViewKey + + DebugVariablesTableConfiguration + + Name + 120 + Value + 85 + Summary + 425 + + Frame + {{625, 0}, {655, 160}} + + + Module + PBXDebugSessionModule + Proportion + 329pt + + + Name + Debug + ServiceClasses + + XCModuleDock + PBXDebugCLIModule + PBXDebugSessionModule + PBXDebugProcessAndThreadModule + PBXDebugProcessViewModule + PBXDebugThreadViewModule + PBXDebugStackFrameViewModule + PBXNavigatorGroup + + TableOfContents + + CE1819C711A1E86200B7A5B0 + 1CCC7628064C1048000F2A68 + 1CCC7629064C1048000F2A68 + CE1819C811A1E86200B7A5B0 + CE1819C911A1E86200B7A5B0 + CE1819CA11A1E86200B7A5B0 + CE1819CB11A1E86200B7A5B0 + CE1819CC11A1E86200B7A5B0 + + ToolbarConfigUserDefaultsMinorVersion + 2 + ToolbarConfiguration + xcode.toolbar.config.debugV3 + + + PerspectivesBarVisible + + ShelfIsVisible + + SourceDescription + file at '/Developer/Library/PrivateFrameworks/DevToolsInterface.framework/Resources/XCPerspectivesSpecification.xcperspec' + StatusbarIsVisible + + TimeStamp + 0.0 + ToolbarConfigUserDefaultsMinorVersion + 2 + ToolbarDisplayMode + 1 + ToolbarIsVisible + + ToolbarSizeMode + 1 + Type + Perspectives + UpdateMessage + + WindowJustification + 5 + WindowOrderList + + /Users/yusefnapora/Documents/Code/SNES-HD/SNES4iPad.xcodeproj + + WindowString + 0 59 1280 719 0 0 1280 778 + WindowToolsV3 + + + Identifier + windowTool.debugger + Layout + + + Dock + + + ContentConfiguration + + Debugger + + HorizontalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {317, 164}} + {{317, 0}, {377, 164}} + + + VerticalSplitView + + _collapsingFrameDimension + 0.0 + _indexOfCollapsedView + 0 + _percentageOfCollapsedView + 0.0 + isCollapsed + yes + sizes + + {{0, 0}, {694, 164}} + {{0, 164}, {694, 216}} + + + + LauncherConfigVersion + 8 + PBXProjectModuleGUID + 1C162984064C10D400B95A72 + PBXProjectModuleLabel + Debug - GLUTExamples (Underwater) + + GeometryConfiguration + + DebugConsoleDrawerSize + {100, 120} + DebugConsoleVisible + None + DebugConsoleWindowFrame + {{200, 200}, {500, 300}} + DebugSTDIOWindowFrame + {{200, 200}, {500, 300}} + Frame + {{0, 0}, {694, 380}} + RubberWindowFrame + 321 238 694 422 0 0 1440 878 + + Module + PBXDebugSessionModule + Proportion + 100% + + + Proportion + 100% + + + Name + Debugger + ServiceClasses + + PBXDebugSessionModule + + StatusbarIsVisible + 1 + TableOfContents + + 1CD10A99069EF8BA00B06720 + 1C0AD2AB069F1E9B00FABCE6 + 1C162984064C10D400B95A72 + 1C0AD2AC069F1E9B00FABCE6 + + ToolbarConfiguration + xcode.toolbar.config.debugV3 + WindowString + 321 238 694 422 0 0 1440 878 + WindowToolGUID + 1CD10A99069EF8BA00B06720 + WindowToolIsVisible + 0 + + + Identifier + windowTool.build + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CD0528F0623707200166675 + PBXProjectModuleLabel + <No Editor> + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1CD052900623707200166675 + + SplitCount + 1 + + StatusBarVisibility + 1 + + GeometryConfiguration + + Frame + {{0, 0}, {500, 215}} + RubberWindowFrame + 192 257 500 500 0 0 1280 1002 + + Module + PBXNavigatorGroup + Proportion + 218pt + + + BecomeActive + 1 + ContentConfiguration + + PBXProjectModuleGUID + XCMainBuildResultsModuleGUID + PBXProjectModuleLabel + Build Results + + GeometryConfiguration + + Frame + {{0, 222}, {500, 236}} + RubberWindowFrame + 192 257 500 500 0 0 1280 1002 + + Module + PBXBuildResultsModule + Proportion + 236pt + + + Proportion + 458pt + + + Name + Build Results + ServiceClasses + + PBXBuildResultsModule + + StatusbarIsVisible + 1 + TableOfContents + + 1C78EAA5065D492600B07095 + 1C78EAA6065D492600B07095 + 1CD0528F0623707200166675 + XCMainBuildResultsModuleGUID + + ToolbarConfiguration + xcode.toolbar.config.buildV3 + WindowString + 192 257 500 500 0 0 1280 1002 + + + Identifier + windowTool.find + Layout + + + Dock + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1CDD528C0622207200134675 + PBXProjectModuleLabel + <No Editor> + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1CD0528D0623707200166675 + + SplitCount + 1 + + StatusBarVisibility + 1 + + GeometryConfiguration + + Frame + {{0, 0}, {781, 167}} + RubberWindowFrame + 62 385 781 470 0 0 1440 878 + + Module + PBXNavigatorGroup + Proportion + 781pt + + + Proportion + 50% + + + BecomeActive + 1 + ContentConfiguration + + PBXProjectModuleGUID + 1CD0528E0623707200166675 + PBXProjectModuleLabel + Project Find + + GeometryConfiguration + + Frame + {{8, 0}, {773, 254}} + RubberWindowFrame + 62 385 781 470 0 0 1440 878 + + Module + PBXProjectFindModule + Proportion + 50% + + + Proportion + 428pt + + + Name + Project Find + ServiceClasses + + PBXProjectFindModule + + StatusbarIsVisible + 1 + TableOfContents + + 1C530D57069F1CE1000CFCEE + 1C530D58069F1CE1000CFCEE + 1C530D59069F1CE1000CFCEE + 1CDD528C0622207200134675 + 1C530D5A069F1CE1000CFCEE + 1CE0B1FE06471DED0097A5F4 + 1CD0528E0623707200166675 + + WindowString + 62 385 781 470 0 0 1440 878 + WindowToolGUID + 1C530D57069F1CE1000CFCEE + WindowToolIsVisible + 0 + + + Identifier + windowTool.snapshots + Layout + + + Dock + + + Module + XCSnapshotModule + Proportion + 100% + + + Proportion + 100% + + + Name + Snapshots + ServiceClasses + + XCSnapshotModule + + StatusbarIsVisible + Yes + ToolbarConfiguration + xcode.toolbar.config.snapshots + WindowString + 315 824 300 550 0 0 1440 878 + WindowToolIsVisible + Yes + + + Identifier + windowTool.debuggerConsole + Layout + + + Dock + + + BecomeActive + 1 + ContentConfiguration + + PBXProjectModuleGUID + 1C78EAAC065D492600B07095 + PBXProjectModuleLabel + Debugger Console + + GeometryConfiguration + + Frame + {{0, 0}, {700, 358}} + RubberWindowFrame + 149 87 700 400 0 0 1440 878 + + Module + PBXDebugCLIModule + Proportion + 358pt + + + Proportion + 358pt + + + Name + Debugger Console + ServiceClasses + + PBXDebugCLIModule + + StatusbarIsVisible + 1 + TableOfContents + + 1C530D5B069F1CE1000CFCEE + 1C530D5C069F1CE1000CFCEE + 1C78EAAC065D492600B07095 + + ToolbarConfiguration + xcode.toolbar.config.consoleV3 + WindowString + 149 87 440 400 0 0 1440 878 + WindowToolGUID + 1C530D5B069F1CE1000CFCEE + WindowToolIsVisible + 0 + + + Identifier + windowTool.scm + Layout + + + Dock + + + ContentConfiguration + + PBXProjectModuleGUID + 1C78EAB2065D492600B07095 + PBXProjectModuleLabel + <No Editor> + PBXSplitModuleInNavigatorKey + + Split0 + + PBXProjectModuleGUID + 1C78EAB3065D492600B07095 + + SplitCount + 1 + + StatusBarVisibility + 1 + + GeometryConfiguration + + Frame + {{0, 0}, {452, 0}} + RubberWindowFrame + 743 379 452 308 0 0 1280 1002 + + Module + PBXNavigatorGroup + Proportion + 0pt + + + BecomeActive + 1 + ContentConfiguration + + PBXProjectModuleGUID + 1CD052920623707200166675 + PBXProjectModuleLabel + SCM + + GeometryConfiguration + + ConsoleFrame + {{0, 259}, {452, 0}} + Frame + {{0, 7}, {452, 259}} + RubberWindowFrame + 743 379 452 308 0 0 1280 1002 + TableConfiguration + + Status + 30 + FileName + 199 + Path + 197.09500122070312 + + TableFrame + {{0, 0}, {452, 250}} + + Module + PBXCVSModule + Proportion + 262pt + + + Proportion + 266pt + + + Name + SCM + ServiceClasses + + PBXCVSModule + + StatusbarIsVisible + 1 + TableOfContents + + 1C78EAB4065D492600B07095 + 1C78EAB5065D492600B07095 + 1C78EAB2065D492600B07095 + 1CD052920623707200166675 + + ToolbarConfiguration + xcode.toolbar.config.scmV3 + WindowString + 743 379 452 308 0 0 1280 1002 + + + Identifier + windowTool.breakpoints + IsVertical + 0 + Layout + + + Dock + + + BecomeActive + 1 + ContentConfiguration + + PBXBottomSmartGroupGIDs + + 1C77FABC04509CD000000102 + + PBXProjectModuleGUID + 1CE0B1FE06471DED0097A5F4 + PBXProjectModuleLabel + Files + PBXProjectStructureProvided + no + PBXSmartGroupTreeModuleColumnData + + PBXSmartGroupTreeModuleColumnWidthsKey + + 168 + + PBXSmartGroupTreeModuleColumnsKey_v4 + + MainColumn + + + PBXSmartGroupTreeModuleOutlineStateKey_v7 + + PBXSmartGroupTreeModuleOutlineStateExpansionKey + + 1C77FABC04509CD000000102 + + PBXSmartGroupTreeModuleOutlineStateSelectionKey + + + 0 + + + PBXSmartGroupTreeModuleOutlineStateVisibleRectKey + {{0, 0}, {168, 350}} + + PBXTopSmartGroupGIDs + + XCIncludePerspectivesSwitch + 0 + + GeometryConfiguration + + Frame + {{0, 0}, {185, 368}} + GroupTreeTableConfiguration + + MainColumn + 168 + + RubberWindowFrame + 315 424 744 409 0 0 1440 878 + + Module + PBXSmartGroupTreeModule + Proportion + 185pt + + + ContentConfiguration + + PBXProjectModuleGUID + 1CA1AED706398EBD00589147 + PBXProjectModuleLabel + Detail + + GeometryConfiguration + + Frame + {{190, 0}, {554, 368}} + RubberWindowFrame + 315 424 744 409 0 0 1440 878 + + Module + XCDetailModule + Proportion + 554pt + + + Proportion + 368pt + + + MajorVersion + 3 + MinorVersion + 0 + Name + Breakpoints + ServiceClasses + + PBXSmartGroupTreeModule + XCDetailModule + + StatusbarIsVisible + 1 + TableOfContents + + 1CDDB66807F98D9800BB5817 + 1CDDB66907F98D9800BB5817 + 1CE0B1FE06471DED0097A5F4 + 1CA1AED706398EBD00589147 + + ToolbarConfiguration + xcode.toolbar.config.breakpointsV3 + WindowString + 315 424 744 409 0 0 1440 878 + WindowToolGUID + 1CDDB66807F98D9800BB5817 + WindowToolIsVisible + 1 + + + Identifier + windowTool.debugAnimator + Layout + + + Dock + + + Module + PBXNavigatorGroup + Proportion + 100% + + + Proportion + 100% + + + Name + Debug Visualizer + ServiceClasses + + PBXNavigatorGroup + + StatusbarIsVisible + 1 + ToolbarConfiguration + xcode.toolbar.config.debugAnimatorV3 + WindowString + 100 100 700 500 0 0 1280 1002 + + + Identifier + windowTool.bookmarks + Layout + + + Dock + + + Module + PBXBookmarksModule + Proportion + 166pt + + + Proportion + 166pt + + + Name + Bookmarks + ServiceClasses + + PBXBookmarksModule + + StatusbarIsVisible + 0 + WindowString + 538 42 401 187 0 0 1280 1002 + + + Identifier + windowTool.projectFormatConflicts + Layout + + + Dock + + + Module + XCProjectFormatConflictsModule + Proportion + 100% + + + Proportion + 100% + + + Name + Project Format Conflicts + ServiceClasses + + XCProjectFormatConflictsModule + + StatusbarIsVisible + 0 + WindowContentMinSize + 450 300 + WindowString + 50 850 472 307 0 0 1440 877 + + + Identifier + windowTool.classBrowser + Layout + + + Dock + + + BecomeActive + 1 + ContentConfiguration + + OptionsSetName + Hierarchy, all classes + PBXProjectModuleGUID + 1CA6456E063B45B4001379D8 + PBXProjectModuleLabel + Class Browser - NSObject + + GeometryConfiguration + + ClassesFrame + {{0, 0}, {369, 96}} + ClassesTreeTableConfiguration + + PBXClassNameColumnIdentifier + 208 + PBXClassBookColumnIdentifier + 22 + + Frame + {{0, 0}, {616, 353}} + MembersFrame + {{0, 105}, {369, 395}} + MembersTreeTableConfiguration + + PBXMemberTypeIconColumnIdentifier + 22 + PBXMemberNameColumnIdentifier + 216 + PBXMemberTypeColumnIdentifier + 94 + PBXMemberBookColumnIdentifier + 22 + + PBXModuleWindowStatusBarHidden2 + 1 + RubberWindowFrame + 597 125 616 374 0 0 1280 1002 + + Module + PBXClassBrowserModule + Proportion + 354pt + + + Proportion + 354pt + + + Name + Class Browser + ServiceClasses + + PBXClassBrowserModule + + StatusbarIsVisible + 0 + TableOfContents + + 1C78EABA065D492600B07095 + 1C78EABB065D492600B07095 + 1CA6456E063B45B4001379D8 + + ToolbarConfiguration + xcode.toolbar.config.classbrowser + WindowString + 597 125 616 374 0 0 1280 1002 + + + Identifier + windowTool.refactoring + IncludeInToolsMenu + 0 + Layout + + + Dock + + + BecomeActive + 1 + GeometryConfiguration + + Frame + {0, 0}, {500, 335} + RubberWindowFrame + {0, 0}, {500, 335} + + Module + XCRefactoringModule + Proportion + 100% + + + Proportion + 100% + + + Name + Refactoring + ServiceClasses + + XCRefactoringModule + + WindowString + 200 200 500 356 0 0 1920 1200 + + + + diff --git a/SNES4iPad_Prefix.pch b/SNES4iPad_Prefix.pch new file mode 100644 index 0000000..fd19408 --- /dev/null +++ b/SNES4iPad_Prefix.pch @@ -0,0 +1,15 @@ +// +// Prefix header for all source files of the 'SNES4iPad' target in the 'SNES4iPad' project +// +#import + +#ifndef __IPHONE_3_2 +#warning "This project uses features only available in iPhone SDK 3.2 and later." +#endif + + +#ifdef __OBJC__ + #import + #import +#import "SNES4iPadAppDelegate.h" +#endif diff --git a/main.m b/main.m new file mode 100644 index 0000000..bf51642 --- /dev/null +++ b/main.m @@ -0,0 +1,17 @@ +// +// main.m +// SNES4iPad +// +// Created by Yusef Napora on 5/10/10. +// Copyright __MyCompanyName__ 2010. All rights reserved. +// + +#import + +int main(int argc, char *argv[]) { + + NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; + int retVal = UIApplicationMain(argc, argv, nil, nil); + [pool release]; + return retVal; +} diff --git a/package-control.txt b/package-control.txt new file mode 100644 index 0000000..b732d4b --- /dev/null +++ b/package-control.txt @@ -0,0 +1,9 @@ +Package: com.wherethewoozlewasnt.snes-hd +Name: SNES (HD) +Version: 1.0-1 +Architecture: iphoneos-arm +Description: SNES (HD) is a Super Nintendo emulator for the iPad. It is designed to be controlled with an iPhone/iPod Touch app called ControlPad, also available in this repository. +Homepage: http://wherethewoozlewasnt.com/?page_id=12 +Maintainer: WoozleWrangler +Author: Yusef Napora (WoozleWrangler) +Section: Games diff --git a/package-dir/Applications/SNES-HD.app/ControlPadConnectViewController.nib b/package-dir/Applications/SNES-HD.app/ControlPadConnectViewController.nib new file mode 100644 index 0000000..a908045 Binary files /dev/null and b/package-dir/Applications/SNES-HD.app/ControlPadConnectViewController.nib differ diff --git a/package-dir/Applications/SNES-HD.app/Default-Landscape.png b/package-dir/Applications/SNES-HD.app/Default-Landscape.png new file mode 100644 index 0000000..3f6c90c Binary files /dev/null and b/package-dir/Applications/SNES-HD.app/Default-Landscape.png differ diff --git a/package-dir/Applications/SNES-HD.app/Default-Portrait.png b/package-dir/Applications/SNES-HD.app/Default-Portrait.png new file mode 100644 index 0000000..5d8ebcf Binary files /dev/null and b/package-dir/Applications/SNES-HD.app/Default-Portrait.png differ diff --git a/package-dir/Applications/SNES-HD.app/DetailView.nib b/package-dir/Applications/SNES-HD.app/DetailView.nib new file mode 100644 index 0000000..d1963df Binary files /dev/null and b/package-dir/Applications/SNES-HD.app/DetailView.nib differ diff --git a/package-dir/Applications/SNES-HD.app/Icon.png b/package-dir/Applications/SNES-HD.app/Icon.png new file mode 100644 index 0000000..21d42e4 Binary files /dev/null and b/package-dir/Applications/SNES-HD.app/Icon.png differ diff --git a/package-dir/Applications/SNES-HD.app/Info.plist b/package-dir/Applications/SNES-HD.app/Info.plist new file mode 100644 index 0000000..56f1768 --- /dev/null +++ b/package-dir/Applications/SNES-HD.app/Info.plist @@ -0,0 +1,39 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + SNES (HD) + CFBundleExecutable + SNES-HD + CFBundleIconFile + Icon.png + CFBundleIdentifier + com.wherethewoozlewasnt.snes-hd + CFBundleInfoDictionaryVersion + 6.0 + UIDeviceFamily + 2 + CFBundleName + SNES-HD + CFBundlePackageType + APPL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + LSRequiresIPhoneOS + + NSMainNibFile + MainWindow + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/package-dir/Applications/SNES-HD.app/MainWindow.nib b/package-dir/Applications/SNES-HD.app/MainWindow.nib new file mode 100644 index 0000000..9fe14fe Binary files /dev/null and b/package-dir/Applications/SNES-HD.app/MainWindow.nib differ diff --git a/package-dir/Applications/SNES-HD.app/SNES-HD b/package-dir/Applications/SNES-HD.app/SNES-HD new file mode 100755 index 0000000..c201e64 Binary files /dev/null and b/package-dir/Applications/SNES-HD.app/SNES-HD differ diff --git a/package-dir/Applications/SNES-HD.app/SaveStateSelectionViewController.nib b/package-dir/Applications/SNES-HD.app/SaveStateSelectionViewController.nib new file mode 100644 index 0000000..6f38f6e Binary files /dev/null and b/package-dir/Applications/SNES-HD.app/SaveStateSelectionViewController.nib differ diff --git a/package-dir/Applications/SNES-HD.app/SettingsViewController.nib b/package-dir/Applications/SNES-HD.app/SettingsViewController.nib new file mode 100644 index 0000000..3680a5e Binary files /dev/null and b/package-dir/Applications/SNES-HD.app/SettingsViewController.nib differ diff --git a/package-dir/Applications/SNES-HD.app/cartridge.png b/package-dir/Applications/SNES-HD.app/cartridge.png new file mode 100644 index 0000000..2e1b447 Binary files /dev/null and b/package-dir/Applications/SNES-HD.app/cartridge.png differ diff --git a/package-dir/Applications/SNES-HD.app/console.png b/package-dir/Applications/SNES-HD.app/console.png new file mode 100644 index 0000000..9216470 Binary files /dev/null and b/package-dir/Applications/SNES-HD.app/console.png differ diff --git a/package-dir/Applications/SNES-HD.app/controlpad.png b/package-dir/Applications/SNES-HD.app/controlpad.png new file mode 100644 index 0000000..45790a9 Binary files /dev/null and b/package-dir/Applications/SNES-HD.app/controlpad.png differ diff --git a/package-dir/Applications/SNES-HD.app/gear.png b/package-dir/Applications/SNES-HD.app/gear.png new file mode 100644 index 0000000..2790af6 Binary files /dev/null and b/package-dir/Applications/SNES-HD.app/gear.png differ diff --git a/package-dir/Applications/SNES-HD.app/greenButton.png b/package-dir/Applications/SNES-HD.app/greenButton.png new file mode 100644 index 0000000..fb06c06 Binary files /dev/null and b/package-dir/Applications/SNES-HD.app/greenButton.png differ diff --git a/package-dir/Applications/SNES-HD.app/loadbutton.png b/package-dir/Applications/SNES-HD.app/loadbutton.png new file mode 100644 index 0000000..3491fc9 Binary files /dev/null and b/package-dir/Applications/SNES-HD.app/loadbutton.png differ diff --git a/package-dir/Applications/SNES-HD.app/powerbutton.png b/package-dir/Applications/SNES-HD.app/powerbutton.png new file mode 100644 index 0000000..e68f170 Binary files /dev/null and b/package-dir/Applications/SNES-HD.app/powerbutton.png differ diff --git a/package-dir/Applications/SNES-HD.app/redButton.png b/package-dir/Applications/SNES-HD.app/redButton.png new file mode 100644 index 0000000..a1cf553 Binary files /dev/null and b/package-dir/Applications/SNES-HD.app/redButton.png differ diff --git a/package-dir/Applications/SNES-HD.app/snapshot-test.png b/package-dir/Applications/SNES-HD.app/snapshot-test.png new file mode 100644 index 0000000..4c8fc7b Binary files /dev/null and b/package-dir/Applications/SNES-HD.app/snapshot-test.png differ diff --git a/package-dir/Applications/SNES-HD.app/snesadvance.dat b/package-dir/Applications/SNES-HD.app/snesadvance.dat new file mode 100755 index 0000000..e66a250 --- /dev/null +++ b/package-dir/Applications/SNES-HD.app/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/package-dir/DEBIAN/control b/package-dir/DEBIAN/control new file mode 100644 index 0000000..b732d4b --- /dev/null +++ b/package-dir/DEBIAN/control @@ -0,0 +1,9 @@ +Package: com.wherethewoozlewasnt.snes-hd +Name: SNES (HD) +Version: 1.0-1 +Architecture: iphoneos-arm +Description: SNES (HD) is a Super Nintendo emulator for the iPad. It is designed to be controlled with an iPhone/iPod Touch app called ControlPad, also available in this repository. +Homepage: http://wherethewoozlewasnt.com/?page_id=12 +Maintainer: WoozleWrangler +Author: Yusef Napora (WoozleWrangler) +Section: Games 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 100644 index 0000000..9c4827b --- /dev/null +++ b/src/snes4iphone_src/Makefile @@ -0,0 +1,107 @@ +VERSION=3.2 +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/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-darwin10-gcc-4.2.1 +GXX = /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/arm-apple-darwin10-g++-4.2.1 +STRIP = /Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/strip +#-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 ../../Classes/EmulationViewController.o ../../Classes/ControlPadConnectViewController.o ../../Classes/ControlPadManager.o ../../Classes/RomDetailViewController.o ../../Classes/RomSelectionViewController.o ../../Classes/ScreenView.o ../../Classes/ScreenLayer.o ../../Classes/SaveStateSelectionViewController.o ../../Classes/SettingsViewController.o ../../Classes/SNES4iPadAppDelegate.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 = -multiply_defined suppress -lobjc -fobjc-exceptions \ + -lpthread \ + -framework CoreFoundation \ + -framework Foundation \ + -framework UIKit \ + -framework QuartzCore \ + -framework CoreGraphics \ + -framework IOSurface \ + -framework CoreLocation \ + -framework AudioToolbox \ + -framework GraphicsServices \ + -framework OpenGLES \ + -framework AddressBook -lsqlite3 -framework SystemConfiguration \ + -lz \ + -framework WebKit \ + -framework GameKit \ + -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 + $(STRIP) pocketsnesd -o snes4iphone + +tidy: + rm *.o ../../*.o ../../Classes/*.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 100644 index 0000000..62892f7 --- /dev/null +++ b/src/snes4iphone_src/iphone_sdk.c @@ -0,0 +1,393 @@ + +#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; +unsigned long player2_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..1fd7961 --- /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 which1); +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..451254d --- /dev/null +++ b/src/snes4iphone_src/main.cpp @@ -0,0 +1,1338 @@ + +#include +#include +#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 __fps_debug; +extern int iphone_soundon; +extern volatile int __emulation_paused; +extern "C" void app_DemuteSound(int buffersize); +extern "C" void app_MuteSound(void); + +extern "C" void saveScreenshotToFile(char *filepath); +#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/SNES-HD.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/SNES-HD.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 ((i= 4) return val; + unsigned long joy = gp_getButton(which1); + + if (joy & (1<100) 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); + sprintf(snesRomDir, "%s", currentWorkingDir); + + printf("rom dir: %s\n", snesRomDir); + printf("sram dir: %s\n", snesSramDir); + printf("save dir: %s\n", snesSaveStateDir); + + InputInit(); // clear input context + + //ensure dirs exist + //should really check if these worked but hey whatever + mode_t dir_mode = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH; + mkdir(snesOptionsDir,dir_mode); + mkdir(snesSramDir,dir_mode); + mkdir(snesSaveStateDir,dir_mode); +#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(); + + printf("initializing...\n"); fflush(stdout); + // 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; + + printf("creating vrambuffer\n"); fflush(stdout); + + 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; + + printf("init memory and APU\n"); fflush(stdout); + if (!Memory.Init () || !S9xInitAPU()) + erk(); + + //S9xSetRenderPixelFormat (RGB565); + + printf("initing graphics\n"); fflush(stdout); + 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= (__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; + char *temp = (char *)malloc(MAX_PATH + 1); + sprintf(temp, "%s", filename); + pos = strlen(filename)-17; + filename[pos] = '\0'; + __saved = 1; + sprintf(save_filename,"%s%s%s",snesSaveStateDir,DIR_SEPERATOR,temp); + free(temp); + } else { + save_filename[0] = '\0'; + } + #endif + + //Save current rom shortname for save state etc + strcpy(currentRomFilename,filename); + + // get full filename + sprintf(filename,"%s%s%s",snesRomDir,DIR_SEPERATOR,currentRomFilename); + + + + printf("Loading Rom: %s\n", filename) ; fflush(stdout); + + if (!Memory.LoadROM (filename)) + { + printf("Load ROM Failed!\n"); fflush(stdout); + sprintf(text,"Loading Rom...Failed"); + gp_drawString(0,0,strlen(text),text,0xFFFF,(unsigned char*)vrambuffer); + MenuFlip(); + MenuPause(); + return 0; + } + printf("Load ROM OK!\n"); fflush(stdout); + + 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")); + printf("Loading sram...\n"); fflush(stdout); + S9xLoadSRAM(); + printf("loaded sram OK\n"); fflush(stdout); + + 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) + { + printf("Loading save state: %s\n", save_filename); fflush(stdout); + LoadStateFile(save_filename); + printf("Load finished\n"); fflush(stdout); + __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; + + printf("entering main loop\n"); fflush(stdout); + 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); + sprintf(svfilename, "%s%s%s", snesSaveStateDir, DIR_SEPERATOR, svfilename); + 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) + { + printf("saving state "); + if(__saved != 0 && __emulation_saving == 2 && strlen(save_filename) > 0) + { + printf("to current file: %s\n", save_filename);fflush(stdout); + 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%s-%s.sv", snesSaveStateDir, DIR_SEPERATOR, currentRomFilename, buffer); + printf("to new file: %s\n", svfilename);fflush(stdout); + } + SaveStateFile(svfilename); + char *imagefile = (char *)malloc(MAX_PATH + 1); + sprintf(imagefile, "%s.png", svfilename); + saveScreenshotToFile(imagefile); + free(imagefile); + __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..f6951fa --- /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 "sram" +#define SNES_SAVESTATE_DIR "saves" + +#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/pocketsnesd b/src/snes4iphone_src/pocketsnesd new file mode 100755 index 0000000..91d4ac3 Binary files /dev/null and b/src/snes4iphone_src/pocketsnesd differ 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..c472b47 --- /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() +{ +#if 0 + 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/snes4iphone b/src/snes4iphone_src/snes4iphone new file mode 100755 index 0000000..ceae541 Binary files /dev/null and b/src/snes4iphone_src/snes4iphone differ 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..40a95d1 --- /dev/null +++ b/src/snes4iphone_src/srtc.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 _srtc_h_ +#define _srtc_h_ + +#if !defined(_SNESPPC) && !defined(__GIZ__) && !defined(__GP2X__) && !defined(__IPHONE__) +#include +#endif + +#ifdef __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