Compare commits

...

8 Commits

Author SHA1 Message Date
Stefan Wessels
4d05b76198 Update 2024-09-11 23:00:12 -07:00
Stefan Wessels
2612a3e7f7 Audio Fixed 2024-09-11 22:52:26 -07:00
Stefan Wessels
9a8454ab9e Audio Fixed 2024-09-11 22:40:45 -07:00
Stefan Wessels
1496ca5762 Comment fix 2024-09-10 19:27:24 -07:00
Stefan Wessels
8a40be6ff0 Time ops not cycles 2024-09-10 19:25:27 -07:00
Stefan Wessels
ff91a8be65 Speaker adjust 2024-09-10 12:47:01 -07:00
Stefan Wessels
6c23dcc1b1 Small Updates 2024-09-10 12:02:47 -07:00
Stefan Wessels
93368af8f5 Spelling, bugs, cleanup 2024-09-10 01:24:48 -07:00
4 changed files with 107 additions and 641 deletions

View File

@ -1,16 +1,16 @@
# The Manic Miner Machine
The Manic Minder Machine is a very, very small Apple II emulator that I built specifically to run the version of Manic Miner that I made, for the Apple II, on my Windows PC. Yesterday, after I finished my harte_6502 6502 cycle-accurate CPU emulator, I thought about doing a Commodore 64 emulator, but then realized that Manic Miner loads into RAM all in one go (well, the loader loads it), and I don't use any ROM routines.
The Manic Minder Machine is a very, very small Apple II emulator that I built specifically to run, on a modern computer, the unmodified 6502 version of Manic Miner that I made for the Apple II.
Manic Miner uses only the 2 hires banks (at $2000 and $4000), the Keyboard ($C000), Keyboard Strobe ($c010) and the speaker ($C030). So building an emulator should be very easy. Well, it was.
Manic Miner uses only the Keyboard ($C000), Keyboard Strobe ($C010), the speaker ($C030) and 2 hires banks (with toggles at $C054 and $C055). So building an emulator should be very easy. Well, it was.
My speaker code is beyond terrible, but I'll maybe figure that out later. Turn audio off with M or S (Music & Sound). ESC will quit. O & P for left and right and SPACE to jump.
Turn audio off with M or S (Music & Sound). ESC will quit. O & P for left and right and SPACE to jump. The original ZX Spectum cheat will also work.
# The Files
| File | Description
| --- | ---
| 6502.c | The 6502 Machine
| mminer.c | The 6502 Manic Miner compiled code
| mmm.c | The Apple II emulator (all 403 lines of it ;)
| mmm.c | The Apple II emulator (around 400 lines :)
# Building the code
The CMakeLists.txt file works for my installation. This is my note at the top which sums up my feelings and frustrations.
@ -24,10 +24,10 @@ The CMakeLists.txt file works for my installation. This is my note at the top w
```
# The Speed
On my M3 Mac Mini, the harte_6502 test run in 11s and on my windows PC in 35s. But the emulator runs great on Windows, and can run a little faster than the 1.023 MHz that the Apple II runs at. But the emulator runs pretty slow on my M3 Mac Mini. I did not look to see if the issue is related to SDL_GetPerformanceFrequency or something else.
The game runs equally well on my M3 Mac Mini as well as on my Windows PC. I did not build for Linux.
# The Future
I will probably not do too much with this. I'll see about fixing the audio.
I will probably not do too much with this.
Feel free to contact me at swessels@email.com if you have thoughts or suggestions.

View File

@ -11,7 +11,7 @@ struct MEMORY_REGION {
uint8_t *memory;
};
/* RAM_BANK is */
/* RAM contains an array of MEMORY_REGIONS which may (or not) be mapped into the 6502's 64K*/
typedef struct MEMORY_REGION RAM_BANK;
struct RAM {
RAM_BANK *ram_banks;
@ -119,10 +119,6 @@ void rom_add(ROMS *roms, uint8_t rom_num, uint32_t address, uint32_t length,
uint8_t pages_init(PAGES *pages, uint16_t num_pages);
void pages_map(PAGES *pages, uint32_t start_page, uint32_t num_pages, uint8_t *memory);
// Exposed so that HARTE tests can be loaded and checked
uint8_t read_from_memory(MACHINE *m, uint16_t address);
void write_to_memory(MACHINE *m, uint16_t address, uint8_t value);
// 1 time init
void cpu_init(CPU *cpu);

View File

@ -513,518 +513,6 @@ uint8_t manic_miner[] = {
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,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x25,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x35,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,
0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0xD5,0xAA,0xD5,0xAA,
0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x29,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x35,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,
0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x7A,0x8F,0x80,0x80,0xF8,
0x5F,0x2A,0x55,0x2A,0x15,0x55,0x2A,0x2B,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x15,0x55,0x2A,0x15,0x00,0x55,0x2A,0x2B,0x55,0x2A,0xA9,0x2D,0x55,0x2A,0x55,0x7A,
0x77,0x2F,0x5F,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x7A,0x8F,0x80,0x80,0xF8,
0x5F,0x2A,0x55,0x2A,0x65,0x52,0x55,0x2C,0xAA,0xD5,0xAB,0xD5,0xAB,0xFF,0xAF,0xDD,
0xFA,0xD5,0xEB,0xD5,0xAA,0xD5,0xEA,0xDD,0xAB,0xD7,0xAE,0xFD,0xEA,0xD5,0xBA,0xDD,
0xAA,0xD5,0xBA,0xF5,0xFE,0xDD,0xEE,0xDF,0xAF,0xF5,0xEA,0xFD,0xBB,0xF5,0xEA,0xDD,
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,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x55,0x54,0x1A,0x15,0x00,0x4D,0x55,0xD2,0xDA,0x2A,0xAA,0xB5,0x55,0xD4,0x56,0x2A,
0x55,0x2A,0x55,0x2A,0x55,0x32,0x69,0x32,0x69,0x32,0x69,0x7A,0xFF,0xFF,0xFF,0xFF,
0x5F,0x7B,0x5D,0x6F,0x55,0x52,0x5A,0x2A,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xDF,0xAA,0xD5,
0xC0,0x81,0xC3,0xE1,0xB0,0x98,0x8C,0xE0,0x80,0x86,0x83,0xE0,0xB0,0xF8,0x83,0x86,
0xC3,0xE1,0xB0,0x98,0x8C,0x86,0xC3,0xE1,0x80,0x98,0x8C,0x86,0x83,0xE0,0xC0,0xE1,
0xB0,0xE0,0xC0,0xE1,0xB0,0x98,0x8C,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x55,0x2A,0x55,0x0A,0x40,0x2A,0x25,0xD5,0xAA,0x2D,0xA9,0x2D,0x25,0xD5,0xAA,0x2B,
0x55,0x2A,0x55,0x2A,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0xAA,0xD5,0xAA,0xD5,0xAA,0xF5,0xAF,0xF7,
0xAA,0xDF,0xAF,0xDD,0xAE,0xD7,0xBB,0xF7,0xEE,0xDD,0xAA,0xDF,0xEE,0xDD,0xEB,0xF5,
0xAE,0xD5,0xAE,0xFF,0xFE,0xD7,0xAE,0xD5,0xAA,0xD5,0xAA,0xD5,0xFE,0xDF,0xAA,0xD5,
0x80,0x80,0x80,0x98,0x80,0xFE,0xF0,0x9F,0xC3,0xE1,0xB0,0xE0,0xB0,0x80,0xC0,0xE1,
0xFF,0x87,0xFC,0xFF,0xC0,0xE1,0xBF,0xF8,0x8F,0xFE,0x83,0xE0,0xBF,0xF8,0x8F,0xFE,
0xC3,0xE1,0xBF,0x80,0x8C,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x55,0x2A,0x55,0x0A,0x40,0x2A,0x55,0x2A,0x55,0xD2,0xAA,0xD5,0x56,0x2A,0x55,0x2A,
0x2F,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
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,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x95,0x55,0x2A,0x05,0x20,0x50,0x2A,0xAD,0xD5,0xAA,0xAA,0xAD,0xD5,0xAA,0x95,0x55,
0xFF,0x5F,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x8F,0xF8,0xC0,0x87,0xBC,0x9E,0xB0,0xE0,
0xF3,0x81,0x8F,0xF8,0xC0,0xE7,0x83,0x86,0xBC,0xFE,0xC0,0x81,0xCF,0x87,0xBC,0xE0,
0x83,0x9E,0x8F,0x98,0xF0,0xF9,0xC0,0x87,0xBC,0xE0,0xF3,0x81,0x83,0x9E,0x8F,0x98,
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,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0xBF,0xFE,0xF3,0x9F,0xBF,0xFE,0xFC,0xF9,
0xF3,0xE7,0xBF,0xFE,0xF3,0xE7,0xCF,0x9F,0xBF,0xFE,0xF3,0xE7,0xCF,0x9F,0xFF,0xF9,
0xCF,0x9F,0xBF,0xFE,0xFC,0xF9,0xF3,0x9F,0xFF,0xF9,0xF3,0xE7,0xCF,0x9F,0xBF,0xFE,
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,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x25,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,
0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0xD5,0xAA,0xD5,0xAA,
0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x29,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,
0x7F,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x7A,0x8F,0x80,0x80,0xF8,
0x5F,0x2A,0x55,0x2A,0x15,0x2B,0x15,0x2B,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x25,0x55,0x2A,0x15,0x00,0x55,0x2A,0x2B,0x55,0x4A,0xAA,0xD5,0x55,0x2A,0x55,0xFF,
0x57,0x6F,0x57,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x7A,0xCF,0x9F,0xFC,0xF9,
0x5F,0x7B,0x5D,0x6F,0x65,0x2C,0x56,0x2C,0xAA,0xD5,0xAB,0xD5,0xAB,0xD7,0xAE,0xDD,
0xFA,0xD5,0xEB,0xD5,0xAB,0xD5,0xEA,0xD5,0xAB,0xD7,0xAE,0xFD,0xEA,0xD5,0xBB,0xDD,
0xBE,0xD5,0xFA,0xFD,0xBA,0xFD,0xEE,0xD5,0xBB,0xF5,0xEA,0xF5,0xBA,0xF5,0xEA,0xDD,
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,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x55,0x52,0x56,0x14,0x00,0x2D,0x55,0xD2,0xEA,0x2A,0xAA,0xB5,0x15,0xD5,0xDA,0x2A,
0x55,0x2A,0x55,0x2A,0x55,0x32,0x69,0x32,0x69,0x32,0x69,0x7A,0xFF,0xFF,0xFF,0xFF,
0x5F,0x7B,0x5D,0x6F,0x45,0x52,0x5A,0x28,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xFA,0xDF,0xAA,0xD5,
0x80,0xFE,0xC0,0xFF,0xF0,0x9F,0x8C,0xE0,0xBF,0xFE,0x83,0xE0,0xBF,0xE0,0x80,0xFE,
0xC3,0xE1,0xF3,0x9F,0xFC,0x87,0xCF,0xFF,0x80,0xF8,0x8F,0x86,0x83,0x80,0xBF,0xE0,
0xF0,0xE1,0xC0,0xE1,0xBF,0xF8,0x8F,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x55,0x2A,0x55,0x0A,0x40,0x2A,0x55,0xD4,0xAA,0x2D,0xA9,0x2D,0xA9,0xD5,0xEA,0x2A,
0x55,0x2A,0x55,0x52,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0xAA,0xD5,0xAA,0xD5,0xAA,0xF5,0xBA,0xF7,
0xAA,0xF7,0xEE,0xDF,0xAE,0xD7,0xBB,0xFF,0xEE,0xDD,0xAA,0xF5,0xEE,0xDD,0xEB,0xF5,
0xAE,0xD5,0xAE,0xF5,0xAE,0xD7,0xBA,0xD5,0xAA,0xD5,0xAA,0xD5,0xFE,0xDF,0xAA,0xD5,
0x80,0x80,0x80,0xE0,0x83,0x98,0xB0,0x98,0xC3,0xE1,0xF0,0x9F,0xB0,0x80,0xC0,0xE1,
0xB0,0x98,0x8C,0x86,0xC3,0xE1,0xB0,0x98,0x8C,0x86,0x80,0x80,0xB0,0x98,0x8C,0x86,
0xC3,0xE1,0xB0,0x80,0x8C,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x55,0x2A,0x55,0x0A,0x40,0x2A,0x59,0x2A,0x55,0xD2,0xAA,0xD5,0xDA,0x2A,0x55,0xF4,
0x3F,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
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,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xA5,0x55,0x2A,0x45,0x28,0x51,0x2A,0x35,0xD5,0xAA,0xA9,0xD5,0xD5,0xAA,0xA5,0x55,
0xFF,0xFF,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x8F,0xF8,0xC0,0x87,0xBC,0x9E,0xB0,0xE0,
0xF3,0x81,0x8F,0xF8,0xC0,0xE7,0x83,0x86,0xBC,0xFE,0xC0,0x81,0xCF,0x87,0xBC,0xE0,
0x83,0x9E,0x8F,0x98,0xF0,0xF9,0xC0,0x87,0xBC,0xE0,0xF3,0x81,0x83,0x9E,0x8F,0x98,
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,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0xBF,0xFE,0xF3,0x9F,0xBF,0xFE,0xFC,0xF9,
0xF3,0xE7,0xBF,0xFE,0xF3,0xE7,0xCF,0x9F,0xBF,0xFE,0xF3,0xE7,0xCF,0x9F,0xFF,0xF9,
0xCF,0x9F,0xBF,0xFE,0xFC,0xF9,0xF3,0x9F,0xFF,0xF9,0xF3,0xE7,0xCF,0x9F,0xBF,0xFE,
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,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x15,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x2D,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,
0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0xD5,0xAA,0xD5,0xAA,
0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x29,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x35,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x6A,
0xFF,0x3F,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x7A,0xCF,0x9F,0xFC,0xF9,
0x5F,0x2A,0x55,0x2A,0x15,0x4B,0x16,0x2B,0xAA,0xF5,0xFF,0xF7,0xAF,0xF5,0xAA,0xDF,
0xFA,0xF7,0xAF,0xFD,0xAA,0xD5,0xFF,0xD5,0xEF,0xDF,0xAF,0xFD,0xFB,0xFF,0xFE,0xDF,
0xAA,0xD5,0xAA,0xD5,0x80,0xC0,0x82,0x85,0x8A,0x94,0xA0,0xD4,0xA8,0x80,0x80,0xC0,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x25,0x55,0x2A,0x15,0x00,0x55,0x5A,0x2A,0x55,0x4A,0xAA,0xD5,0x55,0x2A,0x55,0xFF,
0xFF,0x2F,0x7D,0x2A,0x55,0x54,0xAA,0x55,0xAA,0x55,0xAA,0xFD,0xCF,0x9F,0xFC,0xF9,
0x5F,0x7B,0x5D,0x6F,0x65,0x2C,0x56,0x2C,0xEA,0xF5,0xAA,0xD5,0xAB,0xD7,0xAE,0xDD,
0xEA,0xD5,0xAB,0xF7,0xAB,0xD5,0xEA,0xD5,0xAB,0xD7,0xAE,0xF5,0xEA,0xF5,0xBA,0xF5,
0xEA,0xD5,0xBA,0xF7,0xBA,0xDD,0xEF,0xD7,0xAF,0xF5,0xEE,0xF5,0xBA,0xF5,0xAA,0xD7,
0x80,0xFE,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
0xC0,0xE1,0x80,0x80,0x8C,0x80,0x83,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xBF,0xE0,
0x80,0xE0,0xC0,0x81,0x80,0x98,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x55,0x52,0x56,0x14,0x00,0x2B,0x55,0xD4,0xEA,0x2A,0xAA,0xB5,0x15,0xD5,0xDA,0x2A,
0x55,0x2A,0x55,0x2A,0x55,0x32,0x69,0x32,0x69,0x32,0x69,0x7A,0xFF,0xFF,0xFF,0xFF,
0x5F,0x7B,0x5D,0x6F,0x45,0x52,0x5A,0x28,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xFE,0xD7,0xAA,0xD5,
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,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x55,0x2A,0x55,0x0A,0x40,0x2A,0x55,0xD2,0xAA,0x2D,0x55,0x2A,0xA9,0xD5,0xDA,0x2A,
0x55,0x2A,0x25,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0xAA,0xD5,0xAA,0xD5,0xAA,0xF5,0xBA,0xF7,
0xAA,0xF7,0xEE,0xDD,0xAE,0xD7,0xBB,0xD7,0xBE,0xDF,0xAA,0xF5,0xEE,0xDD,0xEB,0xF5,
0xAE,0xD5,0xAE,0xDD,0xAE,0xD7,0xBA,0xD5,0xAA,0xD5,0xAA,0xD5,0xBF,0xFF,0xAA,0xD5,
0x80,0x80,0x80,0x80,0x8C,0x98,0xF0,0x9F,0xF3,0xE7,0xB0,0xE0,0xB0,0x80,0xC0,0xE1,
0xB0,0x98,0x8C,0x86,0xC3,0xE1,0xB0,0xF8,0x8F,0x86,0x80,0xE0,0xBF,0x98,0x8C,0x86,
0xC3,0xE1,0xBF,0x80,0x83,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x55,0x2A,0x55,0x0C,0x40,0x2C,0xA9,0x2B,0x55,0xD2,0xAA,0xD5,0xDA,0x2A,0x25,0xF5,
0x3F,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
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,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xA5,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x35,0xD5,0xAA,0xAA,0xB5,0xD5,0xAA,0x29,0x55,
0x7A,0xFF,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x8F,0xF8,0xC0,0x87,0xBC,0x9E,0xB0,0xE0,
0xF3,0x81,0x8F,0xF8,0xC0,0xE7,0x83,0x86,0xBC,0xFE,0xC0,0x81,0xCF,0x87,0xBC,0xE0,
0x83,0x9E,0x8F,0x98,0xF0,0xF9,0xC0,0x87,0xBC,0xE0,0xF3,0x81,0x83,0x9E,0x8F,0x98,
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,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0xBF,0xFE,0xF3,0x9F,0xBF,0xFE,0xFC,0xF9,
0xF3,0xE7,0xBF,0xFE,0xF3,0xE7,0xCF,0x9F,0xBF,0xFE,0xF3,0xE7,0xCF,0x9F,0xFF,0xF9,
0xCF,0x9F,0xBF,0xFE,0xFC,0xF9,0xF3,0x9F,0xFF,0xF9,0xF3,0xE7,0xCF,0x9F,0xBF,0xFE,
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,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x15,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x35,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,
0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0xD5,0xAA,0xD5,0xAA,
0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x29,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x35,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x7A,
0xFF,0x2B,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x7A,0xCF,0x9F,0xFC,0xF9,
0x5F,0x2A,0x55,0x2A,0x15,0x2B,0x15,0x2B,0xAA,0xF5,0xEA,0xF7,0xAB,0xDD,0xAB,0xFD,
0xEA,0xD5,0xAB,0xF7,0xAB,0xF5,0xEA,0xD5,0xAB,0xD7,0xBE,0xF5,0xEA,0xF5,0xBA,0xFD,
0xAA,0xD5,0xAA,0x95,0xAA,0xD1,0xA8,0xC4,0x88,0xD1,0xA8,0xD0,0x88,0xD5,0xAA,0xD5,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x29,0x55,0x2A,0x15,0x00,0x55,0x5A,0x2A,0x55,0x4A,0xAA,0xD5,0x55,0x2A,0x55,0xFF,
0xFF,0xFF,0x5D,0x2E,0x5F,0x54,0xAA,0x55,0xAA,0x55,0xAA,0xFD,0xCF,0x9F,0xFC,0xF9,
0xFF,0xFF,0xFF,0xFF,0x29,0x55,0x2A,0x35,0xEA,0xDD,0xAA,0xF5,0xEF,0xDF,0xBF,0xFF,
0xEA,0xF7,0xAF,0xFD,0xAA,0xD5,0xFA,0xD5,0xEF,0xDF,0xBF,0xF5,0xFB,0xFF,0xFE,0xD5,
0xBB,0xD5,0xBA,0xF5,0xBA,0xDD,0xEE,0xD5,0xBB,0xF5,0xFB,0xF5,0xBA,0xF5,0xAA,0xD7,
0xC0,0x81,0x83,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
0x80,0xE0,0x80,0x80,0x8C,0x80,0x83,0x80,0x80,0x80,0x80,0x80,0x80,0xE0,0xC0,0x81,
0xB0,0xE0,0xC0,0x81,0x80,0x98,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x55,0x2A,0x55,0x0A,0x00,0x2B,0x55,0xD4,0xAA,0x2B,0xAA,0xB5,0x15,0xD5,0xEA,0x2A,
0x55,0x2A,0x55,0x2A,0x55,0x32,0x69,0x32,0x69,0x32,0x69,0x7A,0xFF,0xFF,0xFF,0xFF,
0x5F,0x7B,0x5D,0x6F,0x45,0x52,0x5A,0x28,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xBA,0xD7,0xAA,0xD5,
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,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x55,0x2A,0x55,0x0A,0x40,0x2A,0x55,0x4A,0xAA,0xB5,0x55,0x2A,0xAA,0xD5,0x55,0x2A,
0x55,0x2A,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0xAA,0xD5,0xAA,0xD5,0xAA,0xF5,0xBA,0xDD,
0xAA,0xF7,0xEE,0xDD,0xAE,0xD7,0xBB,0xF7,0xBA,0xD7,0xEA,0xF5,0xEE,0xDD,0xEB,0xF5,
0xAE,0xD5,0xAE,0xDD,0xAE,0xF7,0xBA,0xD5,0xAA,0xD5,0xAA,0xD5,0xFF,0xFD,0xAA,0xD5,
0x80,0x80,0x80,0x80,0xB0,0x98,0xB0,0x80,0xB3,0xE6,0xB0,0xE0,0xB0,0x80,0xB0,0xE0,
0xB0,0x98,0x8C,0x86,0xC3,0xE1,0xB0,0x98,0x80,0x86,0xFC,0xE1,0xB0,0x98,0x8C,0x86,
0xC3,0xE1,0x80,0xE0,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x55,0x2A,0x55,0x14,0x00,0x35,0xA9,0xB5,0x55,0xD4,0xAA,0xD5,0xDA,0x2A,0xAA,0xF5,
0x3F,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
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,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xA5,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0xE5,0xAA,0xA9,0xD5,0xD5,0xAA,0x2A,0x55,
0x2A,0x7F,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x8F,0xF8,0xC0,0x87,0xBC,0x9E,0xB0,0xE0,
0xF3,0x81,0x8F,0xF8,0xC0,0xE7,0x83,0x86,0xBC,0xFE,0xC0,0x81,0xCF,0x87,0xBC,0xE0,
0x83,0x9E,0x8F,0x98,0xF0,0xF9,0xC0,0x87,0xBC,0xE0,0xF3,0x81,0x83,0x9E,0x8F,0x98,
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,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0xBF,0xFE,0xF3,0x9F,0xBF,0xFE,0xFC,0xF9,
0xF3,0xE7,0xBF,0xFE,0xF3,0xE7,0xCF,0x9F,0xBF,0xFE,0xF3,0xE7,0xCF,0x9F,0xFF,0xF9,
0xCF,0x9F,0xBF,0xFE,0xFC,0xF9,0xF3,0x9F,0xFF,0xF9,0xF3,0xE7,0xCF,0x9F,0xBF,0xFE,
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,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x25,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x35,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,
0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0xD5,0xAA,0xD5,0xAA,
0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x25,0x55,0x2A,0x01,0x2A,0x50,0x2A,0x55,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x3E,
0x75,0x7A,0x57,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x7A,0xCF,0x9F,0xFC,0xF9,
0x5F,0x2A,0x55,0x2A,0x15,0x2B,0x15,0x2B,0xAA,0xDD,0xBB,0xFF,0xAB,0xDD,0xAB,0xFD,
0xEA,0xD5,0xEB,0xD5,0xAB,0xF5,0xEA,0xD7,0xAB,0xD7,0xBE,0xF5,0xEA,0xD5,0xBB,0xF5,
0xAA,0xD5,0xAA,0xD5,0xA0,0xD1,0xA8,0x84,0x8A,0xD4,0xA8,0xC4,0x88,0xC1,0xAA,0xD5,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x29,0x55,0x2A,0x15,0x00,0x55,0x56,0x2A,0x55,0x2A,0xAA,0xB5,0x55,0x2A,0x55,0x3E,
0x7D,0x3F,0x5F,0x6F,0x7F,0x54,0xAA,0x55,0xAA,0x55,0xAA,0xFD,0xCF,0x9F,0xFC,0xF9,
0xFF,0xFF,0xFF,0xFF,0x29,0x55,0x2A,0x35,0xAA,0xD7,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAF,0xD5,0xBA,0xF5,0xFE,0xDD,0xEE,0xDF,0xBB,0xF5,0xEA,0xFD,0xFB,0xF7,0xAF,0xD7,
0xC0,0x81,0xC0,0xFF,0xB0,0x98,0xFC,0xE7,0xBF,0xFE,0x83,0xE0,0xBF,0x86,0x8C,0xFE,
0xC3,0xE1,0xF0,0x9F,0xFC,0x87,0xC3,0xFF,0x80,0xF8,0x8F,0xFE,0x83,0xE0,0x80,0xE0,
0xFC,0xE1,0xC0,0xE1,0xB0,0xF8,0x8F,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x55,0x2A,0x55,0x0A,0x00,0x2B,0x55,0xD4,0xAA,0x2B,0xA9,0x2D,0x15,0xD5,0xEA,0x2A,
0x55,0x2A,0x55,0x2A,0x55,0x32,0x69,0x32,0x69,0x32,0x69,0x7A,0xFF,0xFF,0xFF,0xFF,
0x5F,0x7B,0x5D,0x6F,0x05,0x50,0x0A,0x28,0xAA,0xD5,0xAA,0xD5,0xAA,0xF5,0xAF,0xD5,
0xAA,0xD7,0xAE,0xD5,0xAA,0xD5,0xAB,0xD5,0xAA,0xD5,0xAA,0xDF,0xAA,0xD5,0xAA,0xF5,
0xAA,0xD5,0xAF,0xFF,0xFE,0xD7,0xBF,0xD5,0xAA,0xD5,0xAA,0xD5,0xFA,0xDF,0xAA,0xD5,
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,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x55,0x2A,0x55,0x0A,0x40,0x2A,0x55,0x2A,0xAA,0xB5,0x25,0x2B,0xAA,0xB5,0x55,0x2A,
0x55,0x4A,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0xAA,0xD5,0xAA,0xD5,0xAA,0xF5,0xAF,0xDD,
0xAA,0xD7,0xEE,0xDF,0xBE,0xDF,0xBB,0xFF,0xBA,0xD7,0xAA,0xDF,0xEE,0xDD,0xEB,0xF7,
0xAE,0xD5,0xAE,0xD7,0xFE,0xD7,0xBF,0xD5,0xAA,0xD5,0xAA,0xD5,0xFA,0xD7,0xAA,0xD5,
0x80,0x80,0x80,0x98,0xB0,0x98,0xB0,0x98,0x8C,0x98,0xB0,0xE0,0xB0,0xE0,0xB0,0xE0,
0xB0,0x98,0x8C,0x86,0xC3,0xE1,0xB0,0x98,0x8C,0x86,0x80,0xE0,0xB0,0x98,0x8C,0x86,
0xC3,0xE1,0xB0,0x98,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x55,0x2A,0x25,0x15,0x00,0x35,0xAA,0xD5,0x56,0xD4,0xAA,0xD5,0xDA,0xD2,0xAA,0xF5,
0xFF,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
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,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x29,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0xAB,0xA9,0xAD,0xD5,0x52,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x8F,0xF8,0xC0,0x87,0xBC,0x9E,0xB0,0xE0,
0xF3,0x81,0x8F,0xF8,0xC0,0xE7,0x83,0x86,0xBC,0xFE,0xC0,0x81,0xCF,0x87,0xBC,0xE0,
0x83,0x9E,0x8F,0x98,0xF0,0xF9,0xC0,0x87,0xBC,0xE0,0xF3,0x81,0x83,0x9E,0x8F,0x98,
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,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0xBF,0xFE,0xF3,0x9F,0xBF,0xFE,0xFC,0xF9,
0xF3,0xE7,0xBF,0xFE,0xF3,0xE7,0xCF,0x9F,0xBF,0xFE,0xF3,0xE7,0xCF,0x9F,0xFF,0xF9,
0xCF,0x9F,0xBF,0xFE,0xFC,0xF9,0xF3,0x9F,0xFF,0xF9,0xF3,0xE7,0xCF,0x9F,0xBF,0xFE,
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,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x25,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x2D,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,
0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0xD5,0xAA,0xD5,0xAA,
0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x15,0x55,0x2A,0x15,0x0A,0x50,0x2A,0x35,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x3F,
0x57,0x2E,0x57,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x7A,0xCF,0x9F,0xFC,0xF9,
0x5F,0x2A,0x55,0x2A,0x15,0x2B,0x15,0x2B,0xAA,0xDD,0xBB,0xDF,0xAB,0xD7,0xAE,0xDD,
0xEB,0xD5,0xEB,0xD5,0xAA,0xF5,0xEA,0xF7,0xAB,0xD7,0xEE,0xF5,0xEA,0xD5,0xBA,0xF5,
0xAA,0xD5,0xAA,0xD5,0x8A,0xD1,0x80,0xC4,0x88,0xD1,0xA8,0x94,0x88,0xC5,0xAA,0xD5,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x29,0x55,0x2A,0x15,0x00,0x55,0x55,0x2A,0x59,0x2A,0xAA,0xB5,0x55,0x2C,0x55,0x7A,
0x75,0x3F,0x5F,0x6F,0x7F,0x54,0xAA,0x55,0xAA,0x55,0xAA,0xFD,0xCF,0x9F,0xFC,0xF9,
0x5F,0x7B,0x5D,0x6F,0x2A,0x55,0x2A,0x55,0xBF,0xF5,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xDF,
0xEA,0xFF,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0x80,0x9E,0xC0,0xE1,0xB0,0x98,0x8C,0xE0,0x80,0x86,0x83,0x80,0xB0,0x86,0x8C,0x80,
0xC3,0xE1,0x80,0x98,0x8C,0x86,0xC3,0xE1,0x80,0x98,0x8C,0x86,0x83,0xE0,0x80,0xE0,
0xB0,0xE0,0xFF,0xE1,0xB0,0x98,0x8C,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x55,0x2A,0x55,0x0A,0x40,0x2A,0x15,0xD5,0xAA,0x2B,0xA9,0x2D,0x25,0xD5,0xEA,0x2A,
0x55,0x2A,0x55,0x2A,0x55,0x32,0x69,0x32,0x69,0x32,0x69,0x7A,0xFF,0xFF,0xFF,0xFF,
0x5F,0x7B,0x5D,0x6F,0x45,0x52,0x5A,0x28,0xAA,0xD5,0xAA,0xD5,0xAA,0xF5,0xBA,0xD5,
0xAA,0xD7,0xAE,0xD5,0xAE,0xD7,0xAB,0xD5,0xAA,0xD5,0xEA,0xF5,0xAA,0xD5,0xEB,0xF5,
0xAA,0xF5,0xEE,0xF5,0xAE,0xF7,0xBA,0xD5,0xAA,0xD5,0xAA,0xD5,0xFA,0xD7,0xAA,0xD5,
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x98,
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x55,0x2A,0x55,0x0A,0x40,0x2A,0x55,0x2A,0xA9,0x2D,0xAA,0xB5,0xA9,0x2D,0x55,0x2A,
0x55,0x52,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xDD,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xBE,0xDF,0xAA,0xD5,
0x80,0x80,0x80,0xE0,0x8F,0xF8,0xF0,0x9F,0x8C,0x98,0xF0,0x9F,0xC0,0x9F,0x8C,0xE0,
0xB0,0x98,0x8C,0x86,0xC3,0xE1,0xB0,0xF8,0x8F,0x86,0x80,0xE0,0xBF,0xF8,0x8F,0xFE,
0xC3,0xE7,0xBF,0xF8,0x8F,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x55,0x2A,0x29,0x15,0x00,0x35,0xAA,0xD5,0xDA,0xD4,0xAA,0xD5,0xDA,0xD4,0xAA,0xD5,
0xFF,0x57,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
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,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0xAD,0xAA,0xAD,0x95,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x8F,0xF8,0xC0,0x87,0xBC,0x9E,0xB0,0xE0,
0xF3,0x81,0x8F,0xF8,0xC0,0xE7,0x83,0x86,0xBC,0xFE,0xC0,0x81,0xCF,0x87,0xBC,0xE0,
0x83,0x9E,0x8F,0x98,0xF0,0xF9,0xC0,0x87,0xBC,0xE0,0xF3,0x81,0x83,0x9E,0x8F,0x98,
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,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0xBF,0xFE,0xF3,0x9F,0xBF,0xFE,0xFC,0xF9,
0xF3,0xE7,0xBF,0xFE,0xF3,0xE7,0xCF,0x9F,0xBF,0xFE,0xF3,0xE7,0xCF,0x9F,0xFF,0xF9,
0xCF,0x9F,0xBF,0xFE,0xFC,0xF9,0xF3,0x9F,0xFF,0xF9,0xF3,0xE7,0xCF,0x9F,0xBF,0xFE,
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,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x25,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x35,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,
0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0xAA,0xD5,0xAA,0xD5,0xAA,
0xD5,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x25,0x55,0x2A,0x05,0x08,0x50,0x2A,0x55,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2F,
0x5F,0x3F,0x5F,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x7A,0xCF,0x9F,0xFC,0xF9,
0x5F,0x2A,0x55,0x2A,0x15,0x2B,0x15,0x2B,0xAA,0xF5,0xBA,0xDF,0xAB,0xD7,0xAE,0xDD,
0xEE,0xD5,0xEB,0xD5,0xAA,0xF5,0xEE,0xFD,0xAB,0xD7,0xAE,0xF7,0xEA,0xDF,0xFA,0xDF,
0xAA,0xD5,0x8A,0x80,0xA0,0xD1,0xA8,0xC4,0x88,0x91,0xA0,0xD4,0xA8,0xD0,0xAA,0xD5,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x25,0x55,0x2A,0x15,0x00,0x55,0x55,0x2A,0xDA,0x2A,0xAA,0xB5,0x55,0xB4,0x55,0x6A,
0x77,0x3F,0x7D,0x3F,0x7D,0x54,0xAA,0x55,0xAA,0x55,0xAA,0xFD,0x8F,0x80,0x80,0xF8,
0x5F,0x7B,0x5D,0x6F,0x2A,0x55,0x2A,0x55,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0x80,0xE0,0xC0,0xE1,0xB0,0x98,0x8C,0xE0,0x80,0xFE,0x83,0xE0,0xBF,0x98,0x83,0xFE,
0xC3,0xE1,0xF0,0x9F,0x8C,0x86,0xC3,0xFF,0x80,0x98,0x8C,0x86,0x83,0xE0,0xF0,0xE1,
0xB0,0xE0,0xC0,0xE1,0xB0,0x98,0x8C,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x55,0x2A,0x55,0x0A,0x40,0x2A,0x15,0xD5,0xAA,0x2B,0xA9,0x2D,0x25,0xD5,0xEA,0x2A,
0x55,0x2A,0x55,0x2A,0x55,0x32,0x69,0x32,0x69,0x32,0x69,0x7A,0xFF,0xFF,0xFF,0xFF,
0x5F,0x7B,0x5D,0x6F,0x45,0x4A,0x56,0x28,0xAA,0xD5,0xAA,0xD5,0xAA,0xF5,0xBA,0xD5,
0xAA,0xD7,0xAE,0xD5,0xAE,0xD7,0xAB,0xD5,0xAA,0xD5,0xEA,0xD5,0xAA,0xD5,0xEA,0xF5,
0xAA,0xD5,0xEE,0xF5,0xAE,0xD7,0xBA,0xD5,0xAA,0xD5,0xAA,0xD5,0xEA,0xD5,0xAA,0xD5,
0x80,0x80,0x80,0xE0,0x8F,0x80,0x80,0x80,0x80,0x80,0xF0,0x9F,0xC0,0x9F,0x80,0x86,
0x80,0x80,0x80,0x80,0xC0,0x81,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
0xC0,0x81,0x80,0xF8,0x83,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x55,0x2A,0x55,0x0A,0x40,0x2A,0x55,0x2A,0x25,0xCD,0xAA,0xD5,0xA9,0x2B,0x55,0x2A,
0x15,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD7,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xFE,0xDF,0xAA,0xD5,
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x8C,0x80,
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x98,0x80,0x86,
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x55,0x4A,0x2A,0x15,0x00,0x35,0xAA,0xD5,0x9A,0xD5,0xAA,0xD5,0xEA,0xD4,0xAA,0xD5,
0xFF,0x57,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
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,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0xAD,0xA9,0xD5,0x95,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x8F,0xF8,0xC0,0x87,0xBC,0x9E,0xB0,0xE0,
0xF3,0x81,0x8F,0xF8,0xC0,0xE7,0x83,0x86,0xBC,0xFE,0xC0,0x81,0xCF,0x87,0xBC,0xE0,
0x83,0x9E,0x8F,0x98,0xF0,0xF9,0xC0,0x87,0xBC,0xE0,0xF3,0x81,0x83,0x9E,0x8F,0x98,
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,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x2A,0xD5,0x2A,0xD5,0x2A,0xD5,0x2A,0xD5,0x2A,0xD5,0x2A,0xD5,0x2A,0xD5,0x2A,0xD5,
0x2A,0xD5,0x2A,0xD5,0x2A,0xD5,0x2A,0xD5,0x2A,0xD5,0x2A,0xD5,0x2A,0xD5,0x2A,0xD5,
0x2A,0xD5,0x2A,0xD5,0x2A,0xD5,0x2A,0xD5,0xBF,0xFE,0xF3,0x9F,0xBF,0xFE,0xFC,0xF9,
0xF3,0xE7,0xBF,0xFE,0xF3,0xE7,0xCF,0x9F,0xBF,0xFE,0xF3,0xE7,0xCF,0x9F,0xFF,0xF9,
0xCF,0x9F,0xBF,0xFE,0xFC,0xF9,0xF3,0x9F,0xFF,0xF9,0xF3,0xE7,0xCF,0x9F,0xBF,0xFE,
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,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x25,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,
0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0xAA,0xD5,0xAA,0xD5,0xAA,
0xD5,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x15,0x55,0x2A,0x15,0x08,0x55,0x2A,0x35,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x6B,
0x57,0x3F,0x5F,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x7A,0x8F,0x80,0x80,0xF8,
0x5F,0x2A,0x55,0x2A,0x15,0x2B,0x15,0x2B,0xAA,0xD5,0xAE,0xD7,0xAB,0xD7,0xAE,0xDD,
0xEE,0xD5,0xEB,0xD5,0xAA,0xD5,0xEB,0xDD,0xAB,0xD7,0xAE,0xF7,0xEA,0xD5,0xBA,0xD7,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x25,0x55,0x2A,0x15,0x00,0x55,0x55,0x4A,0xDA,0x2A,0xAA,0xB5,0x55,0xD4,0x55,0x2A,
0x57,0x2F,0x7D,0xFF,0x5F,0x54,0xAA,0x55,0xAA,0x55,0xAA,0xFD,0x8F,0x80,0x80,0xF8,
0x5F,0x7B,0x5D,0x6F,0x2A,0x55,0x2A,0x55,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0x80,0x80,0xC3,0xE1,0xB0,0x98,0x8C,0xE0,0x80,0x86,0x80,0xE0,0xB0,0x98,0x83,0x86,
0xC3,0xE1,0xB0,0x98,0x8C,0x86,0xC3,0x81,0x80,0x98,0x8C,0x86,0x83,0xE0,0xC0,0xE1,
0xB0,0xE0,0xC0,0xE1,0xB0,0x98,0x8C,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x55,0x2A,0x55,0x0A,0x40,0x2A,0x25,0xD5,0xAA,0x2D,0xA9,0x2D,0x25,0xD5,0xAA,0x2B,
0x55,0x2A,0x55,0x2A,0x2A,0x35,0x69,0x32,0x69,0x32,0x69,0x7A,0xFF,0xFF,0xFF,0xFF,
0x5F,0x7B,0x5D,0x6F,0x45,0x2A,0x55,0x28,0xAA,0xD5,0xAA,0xD5,0xAA,0xF5,0xBA,0xF7,
0xAA,0xDF,0xEF,0xDF,0xFF,0xDF,0xBF,0xFF,0xEE,0xDD,0xEA,0xD5,0xFE,0xDF,0xFB,0xF7,
0xAF,0xD5,0xEE,0xF5,0xAE,0xD7,0xBA,0xD5,0xAA,0xD5,0xAA,0xD5,0xFA,0xD7,0xAA,0xD5,
0x80,0x80,0x80,0x98,0xB0,0x98,0x80,0x80,0x80,0x80,0xB0,0xE0,0xB0,0xE0,0x80,0x86,
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
0xC0,0x81,0x80,0x98,0x8C,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x55,0x2A,0x55,0x0A,0x40,0x2A,0x55,0x2A,0x15,0x4B,0xAA,0xD5,0x65,0x2A,0x55,0x2A,
0x29,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xBE,0xFF,0xAA,0xD5,
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,0x98,0x80,0x86,
0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x55,0x52,0x2A,0x15,0x00,0x55,0xAA,0xD5,0x9A,0xD5,0xAA,0xD5,0xEA,0xD4,0xAA,0xD5,
0xFF,0x5F,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,0xAA,0xD5,
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,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x35,0xA9,0xAD,0xA5,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,
0x2A,0x55,0x2A,0x55,0x2A,0x55,0x2A,0x55,0x8F,0xF8,0xC0,0x87,0xBC,0x9E,0xB0,0xE0,
0xF3,0x81,0x8F,0xF8,0xC0,0xE7,0x83,0x86,0xBC,0xFE,0xC0,0x81,0xCF,0x87,0xBC,0xE0,
0x83,0x9E,0x8F,0x98,0xF0,0xF9,0xC0,0x87,0xBC,0xE0,0xF3,0x81,0x83,0x9E,0x8F,0x98,
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,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,
0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,
0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xBF,0xFE,0xF3,0x9F,0xBF,0xFE,0xFC,0xF9,
0xF3,0xE7,0xBF,0xFE,0xF3,0xE7,0xCF,0x9F,0xBF,0xFE,0xF3,0xE7,0xCF,0x9F,0xFF,0xF9,
0xCF,0x9F,0xBF,0xFE,0xFC,0xF9,0xF3,0x9F,0xFF,0xF9,0xF3,0xE7,0xCF,0x9F,0xBF,0xFE,
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,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x20,0x92,0x89,0x20,0xE6,0x80,0x20,0xC0,0x7E,0x29,0x08,0xD0,0x06,0x20,0xA1,0x84,
0x4C,0x06,0x60,0x20,0x00,0xBF,0x65,0x19,0x60,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
0xA5,0x51,0xF0,0x06,0x2C,0x55,0xC0,0x4C,0x2D,0x60,0x2C,0x54,0xC0,0xA5,0x51,0x49,

View File

@ -22,7 +22,8 @@ uint8_t RAM_IO[RAM_SIZE]; // 64K of IO port "mask" (0 =
#define LOWSCR 0xC054 // Port that draw Hires from $2000
#define HISCR 0xC055 // Port that draws Hires from $4000
// The start of a line of pixels (192 rows). (Add to active Hires page ie $2000 or $4000)
// The start of a line of pixels (192 rows) in HGR memory.
// (Add to active Hires page ie $2000 or $4000)
uint16_t row_start[] = {
0x0000,0x0400,0x0800,0x0C00,0x1000,0x1400,0x1800,0x1C00,
0x0080,0x0480,0x0880,0x0C80,0x1080,0x1480,0x1880,0x1C80,
@ -68,76 +69,30 @@ mRGB palette[8] = {
{0XFF, 0XFF, 0XFF}, // White
};
// Global variables to emulate speaker clicks
#define SAMPLE_RATE 44100
enum {
SAMPLE_PREVIOUS,
OUTPUT_PREVIOUS,
SAMPLE_CURRENT,
NUM_SAMPLES,
};
struct A2SPEAKER {
float speaker_state;
float sample_rate;
float samples[NUM_SAMPLES];
};
typedef struct A2SPEAKER A2SPEAKER;
// Speaker should be part of MACHINE but I don't want to modify 6502.?
A2SPEAKER speaker;
// Global handles for SDL rendering
SDL_Window *window;
SDL_Renderer *renderer;
SDL_Surface *surface;
SDL_Texture *texture;
int screen_updated = TARGET_FPS; // Counter - at TARGET_FPS forces screen update
int active_page = 0x2000; // 0x2000 or 0x4000 - active hires memory page
// Global variables to emulate speaker clicks
#define AMPLITUDE 28000
#define SAMPLE_RATE 44100
int audio_paused = 0; // Audio is paused (0) or playing (1)
int speaker_state = 0; // Tracks whether the speaker is in the "on" or "off" state
double frequency = 440.0; // Frequency in Hz (dynamically calculated )
Uint64 last_toggle_time = 0; // Last time the speaker was toggled (in performance counter ticks)
Uint64 frequency_ticks = 0; // Frequency of the performance counter
// Function that gets called when the Apple II code toggles the speaker
void speaker_toggle() {
// Get the current time in performance counter ticks
Uint64 current_time = SDL_GetPerformanceCounter();
// If this isn't the first toggle, calculate the time difference (period)
if (last_toggle_time != 0) {
Uint64 period_ticks = current_time - last_toggle_time; // Time between toggles in ticks
double period_us = (double)period_ticks * 1000000.0 / (double)frequency_ticks; // Convert ticks to microseconds
if (period_us > 0) {
// Calculate frequency in Hz (1000000 microseconds = 1 second,
// so frequency = 1000000 / period_us)
frequency = 1000000.0 / period_us;
}
}
// Update the last toggle time
last_toggle_time = current_time;
// Toggle the speaker state between 1 (high) and 0 (low)
speaker_state = !speaker_state;
// (re)start the SDL audio
if(audio_paused) {
audio_paused = 0;
SDL_PauseAudio(0);
}
}
// SDL audio callback to generate the square wave
void audio_callback(void* userdata, Uint8* stream, int len) {
float* buffer = (float*)stream; // Output buffer (32-bit float samples)
int length = len / sizeof(float); // Number of float samples to generate
static int sample_index = 0;
// Calculate the number of samples per toggle based on the frequency
int samples_per_toggle = (int)(SAMPLE_RATE / (2 * frequency)); // Half-cycle for square wave
for (int i = 0; i < length; i += 2) { // Increment by 2 because of stereo (2 channels)
float sample_value = (speaker_state ? 1.0f : -1.0f); // Square wave: +1.0 or -1.0
// Stereo output: Set both left (i) and right (i + 1) channels
buffer[i] = sample_value; // Left channel
buffer[i + 1] = sample_value; // Right channel
// Toggle speaker state after `samples_per_toggle` samples
if (++sample_index >= samples_per_toggle) {
sample_index = 0; // Reset the sample index
speaker_state = !speaker_state; // Toggle speaker state (square wave generation)
}
}
}
int active_page = 0x4000; // 0x2000 or 0x4000 - active hires memory page
// Present the selected HiRes screen (page)
void show_screen(uint16_t page) {
@ -146,44 +101,39 @@ void show_screen(uint16_t page) {
// Loop through each row
for (y = 0; y < 192; y++) {
uint32_t *p = &pixels[y * surface->w]; // Get the pointer to the start of the row in the SDL surface
int address = page + row_start[y];
// Get the pointer to the start of the row in the SDL surface
uint32_t *p = &pixels[y * surface->w];
// An index to "walk" the pixels in the surface
int px = 0;
// Get the address where this row starts in HGR memory
int address = page + row_start[y];
// Loop through every 2 bytes (40 iterations for each 192-pixel row)
// Loop through every 2 bytes (40 iterations for each 280-pixel row - 140 color pixels)
for (int x = 0; x < 40; x += 2) {
uint16_t col = (RAM_MAIN[address + x + 1] << 8) | RAM_MAIN[address + x]; // Combine two bytes into a 16-bit value
// Combine two bytes into a 16-bit value for ease of extracting pixels
uint16_t col = (RAM_MAIN[address + x + 1] << 8) | RAM_MAIN[address + x];
// Extract pixels and high bits
int p1 = (col & 0b0000000000000001) << 1 | (col & 0b0000000000000010) >> 1;
int p2 = (col & 0b0000000000000100) >> 1 | (col & 0b0000000000001000) >> 3;
int p3 = (col & 0b0000000000010000) >> 3 | (col & 0b0000000000100000) >> 5;
int p4 = (col & 0b0000000001000000) >> 5 | (col & 0b0000000100000000) >> 8;
int p5 = (col & 0b0000001000000000) >> 8 | (col & 0b0000010000000000) >> 10;
int p6 = (col & 0b0000100000000000) >> 10 | (col & 0b0001000000000000) >> 12;
int p7 = (col & 0b0010000000000000) >> 12 | (col & 0b0100000000000000) >> 14;
// High bits for color adjustment
// Extract the phase bits
int ph1 = (col & 0b0000000010000000) >> 5;
int ph2 = (col & 0b1000000000000000) >> 13;
// Precompute color indices for each pixel
int idx1 = p1 + ph1;
int idx2 = p2 + ph1;
int idx3 = p3 + ph1;
int idx4 = p4 + ph1;
int idx5 = p5 + ph2;
int idx6 = p6 + ph2;
int idx7 = p7 + ph2;
// Extract pixels and offset for phase bits
int p1 = ph1 + ((col & 0b0000000000000001) << 1 | (col & 0b0000000000000010) >> 1 );
int p2 = ph1 + ((col & 0b0000000000000100) >> 1 | (col & 0b0000000000001000) >> 3 );
int p3 = ph1 + ((col & 0b0000000000010000) >> 3 | (col & 0b0000000000100000) >> 5 );
int p4 = ph1 + ((col & 0b0000000001000000) >> 5 | (col & 0b0000000100000000) >> 8 );
int p5 = ph2 + ((col & 0b0000001000000000) >> 8 | (col & 0b0000010000000000) >> 10);
int p6 = ph2 + ((col & 0b0000100000000000) >> 10 | (col & 0b0001000000000000) >> 12);
int p7 = ph2 + ((col & 0b0010000000000000) >> 12 | (col & 0b0100000000000000) >> 14);
// Access the surface's pixels and set the pixel value from the palette
p[px++] = SDL_MapRGB(surface->format, palette[idx1].c[0], palette[idx1].c[1], palette[idx1].c[2]);
p[px++] = SDL_MapRGB(surface->format, palette[idx2].c[0], palette[idx2].c[1], palette[idx2].c[2]);
p[px++] = SDL_MapRGB(surface->format, palette[idx3].c[0], palette[idx3].c[1], palette[idx3].c[2]);
p[px++] = SDL_MapRGB(surface->format, palette[idx4].c[0], palette[idx4].c[1], palette[idx4].c[2]);
p[px++] = SDL_MapRGB(surface->format, palette[idx5].c[0], palette[idx5].c[1], palette[idx5].c[2]);
p[px++] = SDL_MapRGB(surface->format, palette[idx6].c[0], palette[idx6].c[1], palette[idx6].c[2]);
p[px++] = SDL_MapRGB(surface->format, palette[idx7].c[0], palette[idx7].c[1], palette[idx7].c[2]);
// Set the pixel value from the palette
p[px++] = SDL_MapRGB(surface->format, palette[p1].c[0], palette[p1].c[1], palette[p1].c[2]);
p[px++] = SDL_MapRGB(surface->format, palette[p2].c[0], palette[p2].c[1], palette[p2].c[2]);
p[px++] = SDL_MapRGB(surface->format, palette[p3].c[0], palette[p3].c[1], palette[p3].c[2]);
p[px++] = SDL_MapRGB(surface->format, palette[p4].c[0], palette[p4].c[1], palette[p4].c[2]);
p[px++] = SDL_MapRGB(surface->format, palette[p5].c[0], palette[p5].c[1], palette[p5].c[2]);
p[px++] = SDL_MapRGB(surface->format, palette[p6].c[0], palette[p6].c[1], palette[p6].c[2]);
p[px++] = SDL_MapRGB(surface->format, palette[p7].c[0], palette[p7].c[1], palette[p7].c[2]);
}
}
@ -196,14 +146,14 @@ void show_screen(uint16_t page) {
screen_updated = 0;
}
// Note the actual program counter and value read from RAM on a read
// Handle the Apple II ports used by Manic Miner
uint8_t io_read_callback(MACHINE *m, uint16_t address) {
switch(address) {
case KBDSTRB:
RAM_MAIN[KBD] &= 0x7F;
break;
case SPEAKER:
speaker_toggle();
speaker.speaker_state = 1.0f - speaker.speaker_state;
break;
case LOWSCR:
active_page = 0x2000;
@ -217,7 +167,7 @@ uint8_t io_read_callback(MACHINE *m, uint16_t address) {
return m->read_pages.pages[address / PAGE_SIZE].memory[address % PAGE_SIZE];
}
// Note the actual program counter and value written to RAM on a write
// Writing to these ports is the same as reading from them
void io_write_callback(MACHINE *m, uint16_t address, uint8_t value) {
io_read_callback(m, address);
}
@ -226,7 +176,7 @@ void io_write_callback(MACHINE *m, uint16_t address, uint8_t value) {
int AppleII_configure(MACHINE *m) {
// Load the Manic Miner logo HGR and the game itself
memcpy(&RAM_MAIN[0x2000], manic_miner, manic_miner_size);
memcpy(&RAM_MAIN[0x4000], manic_miner, manic_miner_size);
// RAM
if(!ram_init(&m->ram, 1)) {
@ -275,7 +225,7 @@ int AppleII_configure(MACHINE *m) {
}
// Set up SDL graphics and Audio
int initSDL() {
int init_sdl() {
// Initialize SDL with video and audio
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER) < 0) {
printf("SDL could not initialize! SDL_Error: %s\n", SDL_GetError());
@ -296,19 +246,21 @@ int initSDL() {
return 0;
}
// Create RGB surface
surface = SDL_CreateRGBSurface(0, 140, 192, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);
if(surface == NULL) {
printf("Surface could not be created! SDL_Error: %s\n", SDL_GetError());
return 0;
}
// Create texture for pixel rendering
texture = SDL_CreateTextureFromSurface(renderer, surface);
if(texture == NULL) {
printf("Texture could not be created! SDL_Error: %s\n", SDL_GetError());
return 0;
}
// Now the Audio
// Now init the Audio
SDL_AudioSpec wanted_spec;
SDL_AudioSpec obtained_spec;
@ -317,20 +269,19 @@ int initSDL() {
wanted_spec.format = AUDIO_F32SYS;
wanted_spec.channels = 2; // Stereo sound
wanted_spec.samples = 4096; // Buffer size
wanted_spec.callback = audio_callback;
wanted_spec.callback = NULL; // No callback
// Open the audio device
if (SDL_OpenAudio(&wanted_spec, &obtained_spec) < 0) {
printf("Couldn't open audio! SDL_Error: %s\n", SDL_GetError());
SDL_Quit();
return 0;
}
// Start with Audio paused
SDL_PauseAudio(1);
// Init the global
frequency_ticks = SDL_GetPerformanceFrequency(); // Ticks per second
// Set up the speaker now that the obtained freq is known
memset(&speaker, 0, sizeof(speaker));
// Should be obtained_spec.freq instead of SAMPLE_RATE, I think, but that doesn't work on macOS
// The 1.5 is a fudge number to make sure the audio doesn't lag
speaker.sample_rate = ((float)CPU_FREQUENCY / SAMPLE_RATE) + 1.5f;
return 1;
}
@ -338,16 +289,26 @@ int initSDL() {
int main(int argc, char* argv[]) {
int quit = 0;
SDL_Event e;
float sample_cycles;
Uint64 start_time, end_time;
Uint64 ticks_per_clock_cycl = frequency_ticks / CPU_FREQUENCY; // Ticks per microsecond
Uint64 ticks_per_clock_cycle = SDL_GetPerformanceFrequency() / CPU_FREQUENCY; // Ticks per microsecond
if(!initSDL()) {
if(!init_sdl()) {
SDL_Quit();
return 1;
}
// Make this machine an Apple II and load Manic Miner into RAM
AppleII_configure(&m);
// Start the audio
SDL_PauseAudio(0);
// After init_sdl that sets up speaker.sample_rate
sample_cycles = speaker.sample_rate;
const float alpha = 0.98f; // High pass filter coefficient
const float beta = 0.98f; // Low pass filter coefficient
// Start running the sim loop
while (!quit) {
// Take note of the time to help sync to Apple II speed
@ -366,8 +327,34 @@ int main(int argc, char* argv[]) {
}
}
// Step the Apple II sim one cycle
machine_step(&m);
// Step the sim one instruction
int cycles = 0;
do {
// Step the sim one cycle
machine_step(&m);
cycles++;
speaker.samples[SAMPLE_CURRENT] += speaker.speaker_state;
if(--sample_cycles <= 0.0f) {
float output_previous = speaker.samples[OUTPUT_PREVIOUS];
float sample_previous = speaker.samples[SAMPLE_PREVIOUS];
float sample_current = speaker.samples[SAMPLE_CURRENT];
// Calculate a high pass and low pass filtered sample
float high_pass_result = alpha * (output_previous + sample_current - sample_previous);
float filter_result = beta * high_pass_result + (1 - beta) * output_previous;
// Save the current sample of next time
speaker.samples[SAMPLE_PREVIOUS] = sample_current;
// And make the filtered sample prev and also use as left and right for SDL
speaker.samples[OUTPUT_PREVIOUS] = filter_result;
speaker.samples[SAMPLE_CURRENT] = filter_result;
// Queue the stero samples
SDL_QueueAudio(1, &speaker.samples[OUTPUT_PREVIOUS], 2 * sizeof(float));
// Start a new sample
speaker.samples[SAMPLE_CURRENT] = 0.0f;
// Reset when the next samples will be queued
sample_cycles += speaker.sample_rate;
}
} while(m.cpu.instruction_cycle != -1);
// If a call was made to the MLI, it's to QUIT
if(m.cpu.pc == MLI) {
@ -381,14 +368,9 @@ int main(int argc, char* argv[]) {
// When the speaker is not being toggled, it needs to turn off
end_time = SDL_GetPerformanceCounter();
if(audio_paused && end_time - last_toggle_time > (frequency_ticks / 8)) {
audio_paused = 1;
SDL_PauseAudio(1);
end_time = SDL_GetPerformanceCounter();
}
// Try to lock the SIM to the Apple II 1.023 MHz
while ((end_time - start_time) < ticks_per_clock_cycl) {
while ((end_time - start_time) < (ticks_per_clock_cycle * cycles)) {
end_time = SDL_GetPerformanceCounter();
}
}