1
0
mirror of synced 2026-01-12 00:02:46 +00:00
2023-05-05 16:49:25 -07:00

2291 lines
161 KiB
C++

//
//
// File Name : MCL65_Apple1.ino
// Used on :
// Author : Ted Fried, MicroCore Labs
// Creation : 4/18/2023
//
// Description:
// ============
//
// MOS 6502 emulator with bus interface.
//
// Apple I version which also emulate motherboard RAM and ROM
//
//
//------------------------------------------------------------------------
//
// Modification History:
// =====================
//
// Revision 1 4/18/2023
// Initial revision
//
//
//------------------------------------------------------------------------
//
// Copyright (c) 2023 Ted Fried
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
//------------------------------------------------------------------------
#include <stdint.h>
// Teensy 4.1 pin assignments
//
#define PIN_CLK0 24
#define PIN_RESET 40
#define PIN_READY_n 26
#define PIN_IRQ 25
#define PIN_NMI 41
#define PIN_RDWR_n 12
#define PIN_SYNC 39
#define PIN_ADDR0 27
#define PIN_ADDR1 38
#define PIN_ADDR2 28
#define PIN_ADDR3 37
#define PIN_ADDR4 29
#define PIN_ADDR5 36
#define PIN_ADDR6 30
#define PIN_ADDR7 35
#define PIN_ADDR8 31
#define PIN_ADDR9 34
#define PIN_ADDR10 32
#define PIN_ADDR11 33
#define PIN_ADDR12 1
#define PIN_ADDR13 0
#define PIN_ADDR14 2
#define PIN_ADDR15 23
#define PIN_DATAIN0 14
#define PIN_DATAIN1 15
#define PIN_DATAIN2 16
#define PIN_DATAIN3 17
#define PIN_DATAIN4 18
#define PIN_DATAIN5 19
#define PIN_DATAIN6 20
#define PIN_DATAIN7 21
#define PIN_DATAOUT0 11
#define PIN_DATAOUT1 10
#define PIN_DATAOUT2 9
#define PIN_DATAOUT3 8
#define PIN_DATAOUT4 7
#define PIN_DATAOUT5 6
#define PIN_DATAOUT6 5
#define PIN_DATAOUT7 4
#define PIN_DATAOUT_OE_n 3
// 6502 Flags
//
#define flag_n (register_flags & 0x80) >> 7 // register_flags[7]
#define flag_v (register_flags & 0x40) >> 6 // register_flags[6]
#define flag_b (register_flags & 0x10) >> 4 // register_flags[4]
#define flag_d (register_flags & 0x08) >> 3 // register_flags[3]
#define flag_i (register_flags & 0x04) >> 2 // register_flags[2]
#define flag_z (register_flags & 0x02) >> 1 // register_flags[1]
#define flag_c (register_flags & 0x01) >> 0 // register_flags[0]
// 6502 stack always in Page 1
//
#define register_sp_fixed (0x0100 | register_sp)
// CPU register for direct reads of the GPIOs
//
uint8_t register_flags=0x34;
uint8_t next_instruction;
uint8_t internal_memory_range=0;
uint8_t nmi_n_old=1;
uint8_t register_a=0;
uint8_t register_x=0;
uint8_t register_y=0;
uint8_t register_sp=0xFF;
uint8_t direct_datain=0;
uint8_t direct_reset=0;
uint8_t direct_ready_n=0;
uint8_t direct_irq=0;
uint8_t direct_nmi=0;
uint8_t assert_sync=0;
uint8_t global_temp=0;
uint8_t last_access_internal_RAM=0;
uint8_t ignore_count=0;
uint8_t mode=1;
uint16_t register_pc=0;
uint16_t current_address=0;
uint16_t effective_address=0;
uint8_t Apple1_Force_Physical=0;
uint16_t Apple1_Video_Array_Index=0;
uint16_t Apple1_Video_Array[1024];
uint16_t Apple1_Video_Next_Row_Array[1024] = { 40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,40,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,80,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,120,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,200,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,320,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,360,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,440,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,560,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,680,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,720,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,760,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,800,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,840,880,880,880,880,880,880,880,880,880,880,880,880,880,880,880,880,880,880,880,880,880,880,880,880,880,880,880,880,880,880,880,880,880,880,880,880,880,880,880,880,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,920,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960,960 };
// Apple 1 BIOS PROMs - Woz Monitor
//
uint8_t Apple1_PROM[256]={ 0xd8,0x58,0xa0,0x7f,0x8c,0x12,0xd0,0xa9,0xa7,0x8d,0x11,0xd0,0x8d,0x13,0xd0,0xc9,0xdf,0xf0,0x13,0xc9,0x9b,0xf0,0x3,0xc8,0x10,0xf,0xa9,0xdc,0x20,0xef,0xff,0xa9,0x8d,0x20,0xef,0xff,0xa0,0x1,0x88,0x30,0xf6,0xad,0x11,0xd0,0x10,0xfb,0xad,0x10,0xd0,0x99,0x0,0x2,0x20,0xef,0xff,0xc9,0x8d,0xd0,0xd4,0xa0,0xff,0xa9,0x0,0xaa,0xa,0x85,0x2b,0xc8,0xb9,0x0,0x2,0xc9,0x8d,0xf0,0xd4,0xc9,0xae,0x90,0xf4,0xf0,0xf0,0xc9,0xba,0xf0,0xeb,0xc9,0xd2,0xf0,0x3b,0x86,0x28,0x86,0x29,0x84,0x2a,0xb9,0x0,0x2,0x49,0xb0,0xc9,0xa,0x90,0x6,0x69,0x88,0xc9,0xfa,0x90,0x11,0xa,0xa,0xa,0xa,0xa2,0x4,0xa,0x26,0x28,0x26,0x29,0xca,0xd0,0xf8,0xc8,0xd0,0xe0,0xc4,0x2a,0xf0,0x97,0x24,0x2b,0x50,0x10,0xa5,0x28,0x81,0x26,0xe6,0x26,0xd0,0xb5,0xe6,0x27,0x4c,0x44,0xff,0x6c,0x24,0x0,0x30,0x2b,0xa2,0x2,0xb5,0x27,0x95,0x25,0x95,0x23,0xca,0xd0,0xf7,0xd0,0x14,0xa9,0x8d,0x20,0xef,0xff,0xa5,0x25,0x20,0xdc,0xff,0xa5,0x24,0x20,0xdc,0xff,0xa9,0xba,0x20,0xef,0xff,0xa9,0xa0,0x20,0xef,0xff,0xa1,0x24,0x20,0xdc,0xff,0x86,0x2b,0xa5,0x24,0xc5,0x28,0xa5,0x25,0xe5,0x29,0xb0,0xc1,0xe6,0x24,0xd0,0x2,0xe6,0x25,0xa5,0x24,0x29,0x7,0x10,0xc8,0x48,0x4a,0x4a,0x4a,0x4a,0x20,0xe5,0xff,0x68,0x29,0xf,0x9,0xb0,0xc9,0xba,0x90,0x2,0x69,0x6,0x2c,0x12,0xd0,0x30,0xfb,0x8d,0x12,0xd0,0x60,0x0,0x0,0x0,0xf,0x0,0xff,0x0,0x0 };
// Apple 1 programs.
// Press 0 [enter] Then R [enter]
//
//uint8_t internal_RAM[65536] = { 0xA9, 0x0, 0xAA, 0x20, 0xEF, 0xFF, 0xE8, 0x8A, 0x4C, 0x02, 0x00 }; // Print ASCII characters.
//uint8_t internal_RAM[65536] = { 0xA2, 0x0C, 0xBD, 0x8B, 0x02, 0x20, 0xEF, 0xFF, 0xCA, 0xD0, 0xF7, 0x60, 0x8D, 0xC4, 0xCC, 0xD2, 0xCF, 0xD7, 0xA0, 0xCF, 0xCC, 0xCC, 0xC5, 0xC8 }; // Print HELLO WORLD. Press 0 [enter] Then R [enter]
// Woz and Apple picture program loaded into address 0x0280
// BASIC loaded into address 0xE000
//
uint8_t internal_RAM[65536] = { 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 ,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 ,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 ,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 ,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 ,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 ,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 ,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 ,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 ,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 ,0xa9 ,0xff ,0x48 ,0xa9 ,0x0 ,0x48 ,0xa9 ,0x2d ,0x85 ,0x6 ,0xa9 ,0x3 ,0x85 ,0x7 ,0x20 ,0x15 ,0x3 ,0xa0 ,0x0 ,0xb1 ,0x6 ,0xf0 ,0x1b ,0x4a ,0x4a ,0x4a ,0x4a ,0xaa ,0xb1 ,0x6 ,0x29 ,0xf ,0xa8 ,0xb9 ,0x1d ,0x3 ,0x20 ,0xef ,0xff ,0xca ,0xd0 ,0xfa ,0xe6 ,0x6 ,0xd0 ,0xe3 ,0xe6 ,0x7 ,0xd0 ,0xdf ,0xc8 ,0x38 ,0xa9 ,0x28 ,0xf1 ,0x6 ,0x4a ,0xaa ,0xa9 ,0xa0 ,0x20 ,0xef ,0xff ,0xca ,0xd0 ,0xfa ,0xb1 ,0x6 ,0xaa ,0xc8 ,0xb1 ,0x6 ,0x20 ,0xef ,0xff ,0xca ,0xd0 ,0xf7 ,0xc8 ,0x98 ,0x18 ,0x65 ,0x6 ,0x85 ,0x6 ,0xa9 ,0x0 ,0x65 ,0x7 ,0x85 ,0x7 ,0xa9 ,0x10 ,0x20 ,0xeb ,0x2 ,0x20 ,0x15 ,0x3 ,0xa0 ,0x0 ,0xb1 ,0x6 ,0xf0 ,0x9d ,0xd0 ,0xa3 ,0x48 ,0x8a ,0x48 ,0x98 ,0x48 ,0xa0 ,0xff ,0xa2 ,0xff ,0xad ,0x11 ,0xd0 ,0x10 ,0x9 ,0x68 ,0xa8 ,0x68 ,0xaa ,0x68 ,0xad ,0x10 ,0xd0 ,0x60 ,0xca ,0xd0 ,0xef ,0x88 ,0xd0 ,0xea ,0x68 ,0xa8 ,0x68 ,0xaa ,0x68 ,0x38 ,0xe9 ,0x1 ,0xd0 ,0xd9 ,0xa9 ,0x0 ,0x60 ,0x48 ,0xa9 ,0x8d ,0x20 ,0xef ,0xff ,0x68 ,0x60 ,0xa0 ,0xae ,0xba ,0xac ,0xbb ,0xa1 ,0xad ,0xde ,0xab ,0xbd ,0xbf ,0xa6 ,0xaa ,0xa5 ,0xa3 ,0xc0 ,0xff ,0x1f ,0x1b ,0x17 ,0x16 ,0x14 ,0x13 ,0x14 ,0x17 ,0x1b ,0x1e ,0xff ,0xcf ,0x1e ,0x2c ,0x18 ,0x50 ,0x21 ,0x12 ,0x14 ,0x17 ,0x1c ,0xff ,0x8f ,0x1b ,0x16 ,0x12 ,0x21 ,0x70 ,0x31 ,0x10 ,0x11 ,0x18 ,0xff ,0x5f ,0x1d ,0x15 ,0x50 ,0x21 ,0x70 ,0x41 ,0x18 ,0x1d ,0xff ,0x2f ,0x1e ,0x14 ,0xf0 ,0x30 ,0x11 ,0x10 ,0x12 ,0x17 ,0x1e ,0xff ,0x19 ,0xe0 ,0x11 ,0x12 ,0x24 ,0x12 ,0x40 ,0x19 ,0xff ,0x14 ,0x50 ,0x23 ,0x11 ,0x20 ,0x21 ,0x20 ,0x12 ,0x15 ,0x18 ,0x19 ,0x16 ,0x12 ,0x30 ,0x12 ,0x19 ,0xdf ,0x1c ,0x11 ,0x40 ,0x12 ,0x19 ,0x1a ,0x17 ,0x25 ,0x26 ,0x34 ,0x17 ,0x2a ,0x19 ,0x17 ,0x13 ,0x30 ,0x11 ,0x1b ,0xcf ,0x18 ,0x50 ,0x13 ,0x2a ,0x19 ,0x38 ,0x19 ,0x18 ,0x27 ,0x28 ,0x27 ,0x18 ,0x17 ,0x12 ,0x30 ,0x18 ,0xcf ,0x1a ,0x50 ,0x15 ,0x19 ,0x17 ,0x14 ,0x13 ,0x22 ,0x13 ,0x16 ,0x17 ,0x16 ,0x13 ,0x21 ,0x12 ,0x14 ,0x17 ,0x15 ,0x20 ,0x13 ,0x1d ,0xcf ,0x1c ,0x40 ,0x12 ,0x28 ,0x15 ,0x13 ,0x11 ,0x30 ,0x12 ,0x28 ,0x12 ,0x10 ,0x11 ,0x12 ,0x14 ,0x17 ,0x18 ,0x12 ,0x10 ,0x1a ,0xdf ,0x1d ,0x12 ,0x30 ,0x14 ,0x1a ,0x19 ,0x18 ,0x17 ,0x45 ,0x16 ,0x1b ,0x1d ,0x18 ,0x26 ,0x17 ,0x18 ,0x1a ,0x1b ,0x15 ,0x11 ,0x1c ,0xef ,0x18 ,0x10 ,0x13 ,0x12 ,0x13 ,0x59 ,0x18 ,0x27 ,0x19 ,0x1b ,0x2c ,0x1a ,0x27 ,0x19 ,0x2a ,0x17 ,0x12 ,0x18 ,0xef ,0x1e ,0x12 ,0x23 ,0x11 ,0x15 ,0x16 ,0x35 ,0x24 ,0x35 ,0x16 ,0x17 ,0x16 ,0x14 ,0x13 ,0x14 ,0x15 ,0x16 ,0x15 ,0x11 ,0x18 ,0xff ,0x17 ,0x30 ,0x12 ,0x24 ,0x13 ,0x21 ,0x23 ,0x11 ,0x10 ,0x21 ,0x22 ,0x21 ,0x13 ,0x14 ,0x12 ,0x13 ,0x1d ,0xff ,0x1d ,0x16 ,0x11 ,0x10 ,0x21 ,0x22 ,0x11 ,0x22 ,0x13 ,0x24 ,0x25 ,0x14 ,0x23 ,0x41 ,0x1a ,0xff ,0x2f ,0x1d ,0x16 ,0x15 ,0x20 ,0x31 ,0x13 ,0x24 ,0x15 ,0x16 ,0x47 ,0x13 ,0x11 ,0x10 ,0x12 ,0x19 ,0xff ,0x2f ,0x1d ,0x1a ,0x1c ,0x19 ,0x13 ,0x11 ,0x20 ,0x21 ,0x13 ,0x24 ,0x33 ,0x24 ,0x21 ,0x13 ,0x1a ,0xef ,0x2e ,0x1d ,0x1c ,0x1b ,0x1d ,0x1e ,0x1b ,0x16 ,0x13 ,0x51 ,0x12 ,0x41 ,0x12 ,0x21 ,0x12 ,0x18 ,0x1a ,0x1d ,0xaf ,0x1e ,0x1d ,0x3c ,0x2d ,0x4e ,0x1a ,0x14 ,0x22 ,0x11 ,0x20 ,0x71 ,0x13 ,0x15 ,0x17 ,0x2c ,0x1d ,0x1e ,0x7f ,0x4d ,0x2e ,0x2d ,0x2e ,0x1d ,0x2e ,0x19 ,0x23 ,0x32 ,0x31 ,0x22 ,0x13 ,0x15 ,0x16 ,0x14 ,0x17 ,0x2e ,0x3d ,0x2e ,0x4f ,0x2e ,0x7d ,0x2e ,0x1d ,0x2e ,0x1a ,0x14 ,0x43 ,0x14 ,0x13 ,0x14 ,0x15 ,0x16 ,0x17 ,0x15 ,0x14 ,0x18 ,0x1d ,0x4e ,0x2d ,0x4e ,0x9d ,0x4e ,0x1c ,0x1a ,0x18 ,0x15 ,0x14 ,0x43 ,0x15 ,0x26 ,0x15 ,0x13 ,0x16 ,0x1a ,0x3e ,0x8d ,0x0 ,0x4 ,0x57 ,0x4f ,0x5a ,0x20 ,0x8f ,0x1e ,0x1b ,0x18 ,0x15 ,0x34 ,0x15 ,0x17 ,0x18 ,0x19 ,0x1b ,0x1d ,0x1e ,0xff ,0x7f ,0x1e ,0x1a ,0x17 ,0x14 ,0x11 ,0x40 ,0x21 ,0x30 ,0x31 ,0x12 ,0x16 ,0x1c ,0xff ,0x4f ,0x1c ,0x16 ,0x11 ,0x50 ,0x21 ,0x20 ,0x11 ,0x12 ,0x11 ,0x50 ,0x11 ,0x17 ,0x1d ,0xff ,0x1f ,0x1b ,0x14 ,0xa0 ,0x21 ,0x12 ,0x11 ,0x20 ,0x21 ,0x30 ,0x13 ,0x1a ,0xef ,0x19 ,0x11 ,0xa0 ,0x11 ,0x12 ,0x15 ,0x17 ,0x13 ,0x20 ,0x51 ,0x10 ,0x11 ,0x17 ,0x1e ,0xbf ,0x1a ,0xb0 ,0x11 ,0x12 ,0x13 ,0x15 ,0x18 ,0x15 ,0x30 ,0x61 ,0x10 ,0x16 ,0x1e ,0xaf ,0x18 ,0xa0 ,0x11 ,0x12 ,0x14 ,0x25 ,0x1a ,0x19 ,0x13 ,0x40 ,0x41 ,0x20 ,0x18 ,0xaf ,0x16 ,0x90 ,0x11 ,0x12 ,0x14 ,0x27 ,0x16 ,0x18 ,0x1a ,0x16 ,0x11 ,0x90 ,0x15 ,0xaf ,0x16 ,0x70 ,0x11 ,0x12 ,0x23 ,0x24 ,0x13 ,0x32 ,0x23 ,0x11 ,0x80 ,0x13 ,0x1e ,0x9f ,0x18 ,0x50 ,0x31 ,0x12 ,0x13 ,0x14 ,0x13 ,0x11 ,0x40 ,0x12 ,0x14 ,0x15 ,0x14 ,0x13 ,0x11 ,0x50 ,0x11 ,0x1c ,0x9f ,0x1a ,0x40 ,0x31 ,0x20 ,0x12 ,0x18 ,0x17 ,0x13 ,0x12 ,0x21 ,0x12 ,0x16 ,0x19 ,0x1a ,0x1b ,0x1a ,0x18 ,0x13 ,0x50 ,0x16 ,0x1e ,0x8f ,0x1c ,0x11 ,0x20 ,0x11 ,0x14 ,0x23 ,0x22 ,0x14 ,0x1b ,0x1d ,0x1a ,0x18 ,0x27 ,0x18 ,0x19 ,0x4b ,0x1a ,0x18 ,0x13 ,0x40 ,0x11 ,0x18 ,0x9f ,0x17 ,0x20 ,0x11 ,0x17 ,0x19 ,0x37 ,0x16 ,0x1a ,0x2e ,0x1b ,0x28 ,0x49 ,0x48 ,0x17 ,0x15 ,0x14 ,0x11 ,0x20 ,0x17 ,0x9f ,0x1d ,0x15 ,0x20 ,0x16 ,0x48 ,0x26 ,0x29 ,0x18 ,0x47 ,0x18 ,0x27 ,0x38 ,0x19 ,0x17 ,0x13 ,0x11 ,0x20 ,0x1a ,0xaf ,0x1e ,0x15 ,0x10 ,0x12 ,0x26 ,0x17 ,0x18 ,0x17 ,0x14 ,0x23 ,0x14 ,0x27 ,0x15 ,0x14 ,0x16 ,0x27 ,0x48 ,0x15 ,0x40 ,0x15 ,0x1e ,0xaf ,0x1e ,0x15 ,0x10 ,0x14 ,0x27 ,0x16 ,0x15 ,0x14 ,0x13 ,0x12 ,0x13 ,0x25 ,0x14 ,0x13 ,0x15 ,0x16 ,0x37 ,0x18 ,0x17 ,0x15 ,0x11 ,0x20 ,0x12 ,0x15 ,0x1c ,0xbf ,0x1c ,0x12 ,0x11 ,0x26 ,0x15 ,0x23 ,0x24 ,0x13 ,0x14 ,0x15 ,0x26 ,0x25 ,0x36 ,0x15 ,0x14 ,0x17 ,0x14 ,0x20 ,0x12 ,0x16 ,0x1a ,0xcf ,0x1a ,0x22 ,0x25 ,0x14 ,0x25 ,0x14 ,0x13 ,0x15 ,0x16 ,0x27 ,0x26 ,0x15 ,0x14 ,0x13 ,0x12 ,0x15 ,0x18 ,0x17 ,0x11 ,0x10 ,0x11 ,0x14 ,0x17 ,0x1b ,0xcf ,0x1b ,0x16 ,0x24 ,0x25 ,0x26 ,0x25 ,0x46 ,0x14 ,0x13 ,0x22 ,0x13 ,0x16 ,0x28 ,0x13 ,0x10 ,0x11 ,0x13 ,0x15 ,0x17 ,0x1c ,0xcf ,0x1d ,0x14 ,0x22 ,0x14 ,0x15 ,0x24 ,0x53 ,0x32 ,0x13 ,0x15 ,0x16 ,0x17 ,0x18 ,0x14 ,0x21 ,0x13 ,0x25 ,0x19 ,0xcf ,0x1b ,0x23 ,0x21 ,0x12 ,0x93 ,0x24 ,0x15 ,0x16 ,0x27 ,0x13 ,0x11 ,0x12 ,0x14 ,0x15 ,0x16 ,0x19 ,0x1b ,0x1e ,0xaf ,0x19 ,0x13 ,0x14 ,0x13 ,0x32 ,0x33 ,0x14 ,0x23 ,0x34 ,0x35 ,0x16 ,0x15 ,0x13 ,0x12 ,0x13 ,0x25 ,0x17 ,0x28 ,0x1c ,0x1e ,0x1d ,0x1e ,0x4f ,0x2e ,0x1d ,0x19 ,0x15 ,0x34 ,0x33 ,0x94 ,0x35 ,0x14 ,0x13 ,0x14 ,0x16 ,0x25 ,0x17 ,0x19 ,0x1d ,0x2e ,0x1d ,0x1e ,0x0 ,0xb ,0x53 ,0x54 ,0x45 ,0x56 ,0x45 ,0x20 ,0x4a ,0x4f ,0x42 ,0x53 ,0x20 ,0xff ,0xaf ,0x27 ,0xff ,0xff ,0x5f ,0x57 ,0xff ,0xff ,0x4f ,0x57 ,0xff ,0xff ,0x4f ,0x57 ,0xff ,0xff ,0x4f ,0x57 ,0xff ,0xdf ,0x37 ,0x4f ,0x27 ,0x4f ,0x47 ,0xff ,0x4f ,0xf7 ,0xa7 ,0xdf ,0xf7 ,0xd7 ,0xbf ,0xfc ,0xcc ,0xcf ,0xfc ,0xcc ,0xdf ,0xfc ,0xbc ,0xdf ,0xf8 ,0xc8 ,0xdf ,0xf8 ,0xc8 ,0xdf ,0xf8 ,0xd8 ,0xdf ,0xf4 ,0xd4 ,0xcf ,0xf4 ,0xe4 ,0xcf ,0xf4 ,0xf4 ,0xaf ,0xf3 ,0xf3 ,0xbf ,0xf3 ,0xd3 ,0xdf ,0xf3 ,0xb3 ,0xff ,0x1f ,0xf4 ,0x84 ,0xff ,0x3f ,0x84 ,0x4f ,0x84 ,0xff ,0xff ,0xff ,0x5f ,0x0 ,0x1b ,0x48 ,0x41 ,0x50 ,0x50 ,0x59 ,0x20 ,0x33 ,0x30 ,0x54 ,0x48 ,0x20 ,0x42 ,0x49 ,0x52 ,0x54 ,0x48 ,0x44 ,0x41 ,0x59 ,0x20 ,0x41 ,0x50 ,0x50 ,0x4c ,0x45 ,0x21 ,0x20 ,0xff ,0xaf ,0x1e ,0x19 ,0x15 ,0x13 ,0x14 ,0x19 ,0x1d ,0xff ,0xff ,0x2f ,0x1e ,0x18 ,0x13 ,0x31 ,0x13 ,0x17 ,0x1d ,0xef ,0x1e ,0x1d ,0x1c ,0x1d ,0xdf ,0x1c ,0x16 ,0x22 ,0x24 ,0x13 ,0x15 ,0x1a ,0xdf ,0x1c ,0x17 ,0x12 ,0x11 ,0x15 ,0x1a ,0xcf ,0x1d ,0x18 ,0x25 ,0x28 ,0x27 ,0x19 ,0x1e ,0xbf ,0x1c ,0x16 ,0x11 ,0x10 ,0x11 ,0x12 ,0x15 ,0x1a ,0xcf ,0x1c ,0x19 ,0x27 ,0x18 ,0x27 ,0x19 ,0x1d ,0xbf ,0x1a ,0x15 ,0x14 ,0x15 ,0x17 ,0x26 ,0x18 ,0x1c ,0xcf ,0x1b ,0x16 ,0x24 ,0x25 ,0x18 ,0x1c ,0xbf ,0x1b ,0x17 ,0x15 ,0x16 ,0x18 ,0x17 ,0x18 ,0x1a ,0x1e ,0xcf ,0x1c ,0x17 ,0x14 ,0x13 ,0x14 ,0x15 ,0x18 ,0x1b ,0xbf ,0x1d ,0x18 ,0x45 ,0x17 ,0x1b ,0x1e ,0xcf ,0x1e ,0x1c ,0x19 ,0x27 ,0x19 ,0x1b ,0x1e ,0xcf ,0x1b ,0x15 ,0x22 ,0x13 ,0x17 ,0x1c ,0xff ,0x1f ,0x2d ,0x1e ,0xef ,0x1e ,0x19 ,0x13 ,0x11 ,0x14 ,0x19 ,0x1e ,0xaf ,0x2e ,0xaf ,0x3e ,0x5f ,0x4e ,0x1b ,0x17 ,0x14 ,0x16 ,0x1a ,0x1d ,0xaf ,0x1e ,0x1d ,0x1e ,0x8f ,0x1e ,0x3d ,0x1e ,0x3f ,0x1e ,0x4d ,0x1c ,0x2b ,0x1a ,0x1b ,0x1c ,0x2d ,0x2e ,0x5f ,0x1e ,0x2d ,0x1e ,0x7f ,0x1e ,0x1d ,0x2c ,0x1d ,0x2e ,0x1f ,0x1e ,0x3d ,0x6e ,0x5d ,0x1e ,0x6f ,0x1d ,0x1c ,0x1d ,0x1e ,0x3f ,0x2e ,0x1f ,0x1e ,0x1d ,0x2c ,0x1d ,0x3e ,0x5d ,0x9e ,0x1d ,0x6c ,0x1b ,0x1a ,0x39 ,0x2a ,0x19 ,0x1a ,0x1c ,0x2e ,0x1d ,0x2b ,0x1c ,0x1e ,0x2f ,0x1e ,0x7d ,0x3e ,0x2d ,0x1e ,0x1d ,0x1a ,0x17 ,0x25 ,0x16 ,0x55 ,0x14 ,0x25 ,0x16 ,0x18 ,0x1b ,0x1e ,0x1f ,0x1d ,0x2b ,0x1c ,0x1d ,0x3e ,0x2d ,0x1c ,0x1b ,0x2c ,0x1d ,0x1e ,0x1f ,0x1e ,0x2d ,0x1c ,0x1b ,0x18 ,0x16 ,0x15 ,0x84 ,0x25 ,0x16 ,0x18 ,0x1b ,0x1e ,0x1f ,0x1e ,0x3c ,0x1d ,0x1e ,0x1c ,0x3d ,0x3c ,0x1d ,0x1e ,0x3f ,0x1e ,0x1d ,0x1b ,0x19 ,0x18 ,0x17 ,0x16 ,0x15 ,0x24 ,0x25 ,0x44 ,0x23 ,0x16 ,0x1a ,0x1d ,0x3f ,0x1e ,0x2d ,0x1c ,0x1d ,0x2c ,0x2d ,0x4e ,0x2f ,0x1d ,0x1b ,0x19 ,0x18 ,0x27 ,0x15 ,0x14 ,0x13 ,0x14 ,0x26 ,0x14 ,0x33 ,0x12 ,0x13 ,0x14 ,0x17 ,0x1a ,0x1c ,0x1d ,0x3e ,0x4d ,0x1b ,0x19 ,0x1a ,0x1b ,0x1d ,0x3e ,0x1d ,0x1c ,0x19 ,0x17 ,0x16 ,0x17 ,0x38 ,0x17 ,0x16 ,0x17 ,0x18 ,0x29 ,0x17 ,0x26 ,0x15 ,0x16 ,0x27 ,0x38 ,0x19 ,0x1a ,0x1d ,0x4f ,0x1d ,0x1b ,0x39 ,0x1a ,0x49 ,0x38 ,0x19 ,0x1a ,0x1c ,0x1e ,0x1f ,0x2e ,0x1f ,0x1e ,0x1d ,0x1b ,0x3a ,0x19 ,0x18 ,0x27 ,0x18 ,0x19 ,0x1a ,0x1c ,0x1e ,0x5f ,0x1d ,0x1a ,0x18 ,0x27 ,0x18 ,0x29 ,0x3a ,0x19 ,0x18 ,0x1a ,0x1d ,0x6f ,0x1c ,0x19 ,0x18 ,0x69 ,0x1a ,0x1b ,0x1a ,0x1b ,0x1d ,0x5f ,0x1d ,0x19 ,0x16 ,0x15 ,0x56 ,0x15 ,0x14 ,0x12 ,0x13 ,0x16 ,0x1c ,0x6f ,0x1e ,0x19 ,0x15 ,0x23 ,0x44 ,0x35 ,0x16 ,0x1a ,0x1e ,0x4f ,0x1e ,0x18 ,0x13 ,0x10 ,0x21 ,0x12 ,0x23 ,0x12 ,0x11 ,0x10 ,0x11 ,0x15 ,0x1b ,0x7f ,0x1a ,0x15 ,0x42 ,0x23 ,0x14 ,0x15 ,0x16 ,0x18 ,0x1b ,0x1e ,0x2f ,0x0 ,0x1d ,0x57 ,0x4f ,0x5a ,0x20 ,0x41 ,0x4e ,0x44 ,0x20 ,0x4a ,0x4f ,0x42 ,0x53 ,0x20 ,0x48 ,0x4f ,0x4c ,0x44 ,0x49 ,0x4e ,0x47 ,0x20 ,0x41 ,0x50 ,0x50 ,0x4c ,0x45 ,0x20 ,0x49 ,0x20 ,0xff ,0x3f ,0x3e ,0xff ,0xff ,0x5f ,0x1e ,0x7d ,0x1e ,0xff ,0xef ,0x1e ,0x3d ,0x6e ,0x4d ,0x1e ,0xff ,0x8f ,0x1e ,0x2d ,0xee ,0x3d ,0x2e ,0xff ,0x2f ,0x1e ,0x1d ,0xfe ,0x4e ,0x5d ,0x1e ,0xcf ,0x1e ,0x1d ,0xfe ,0x7e ,0x3d ,0x1b ,0x19 ,0x9f ,0x1c ,0x2d ,0x6e ,0x1d ,0x1e ,0x3f ,0x2e ,0x2f ,0x7e ,0x1d ,0x1e ,0x1d ,0x1a ,0x17 ,0x15 ,0x1e ,0x7f ,0x1e ,0x1c ,0x2a ,0x1c ,0x1d ,0x3e ,0x19 ,0x16 ,0x18 ,0x19 ,0x1c ,0x1e ,0x4f ,0x1e ,0x1f ,0x6e ,0x1c ,0x19 ,0x16 ,0x14 ,0x16 ,0x7f ,0x2d ,0x3e ,0x1c ,0x3b ,0x1d ,0x1b ,0x1a ,0x18 ,0x37 ,0x1a ,0x1f ,0x4e ,0x1f ,0x4e ,0x1b ,0x18 ,0x25 ,0x16 ,0x17 ,0x5f ,0x1e ,0x3d ,0x19 ,0x14 ,0x18 ,0x1c ,0x2e ,0x1d ,0x3b ,0x1c ,0x1b ,0x2a ,0x1d ,0x8e ,0x1f ,0x1b ,0x16 ,0x14 ,0x15 ,0x27 ,0x18 ,0x4f ,0x1e ,0x1d ,0x1e ,0x1d ,0x15 ,0x30 ,0x11 ,0x14 ,0x19 ,0x1c ,0x1e ,0x1f ,0x1d ,0x1c ,0x2b ,0x1c ,0x8e ,0x1f ,0x1e ,0x18 ,0x14 ,0x16 ,0x47 ,0x3f ,0x2d ,0x1e ,0x1b ,0x14 ,0x10 ,0x41 ,0x20 ,0x11 ,0x14 ,0x18 ,0x1c ,0x1e ,0x1f ,0x1e ,0x1c ,0x3b ,0x1d ,0x2e ,0x2f ,0x1e ,0x19 ,0x26 ,0x37 ,0x15 ,0x1b ,0x1f ,0x1e ,0x3d ,0x1e ,0x1a ,0x11 ,0x30 ,0x51 ,0x20 ,0x11 ,0x14 ,0x18 ,0x1c ,0x1e ,0x1f ,0x1e ,0x1c ,0x1b ,0x1a ,0x1b ,0x1c ,0x1d ,0x1a ,0x16 ,0x37 ,0x16 ,0x15 ,0x1c ,0x2f ,0x1c ,0x16 ,0x19 ,0x1d ,0x2e ,0x1d ,0x13 ,0x31 ,0x10 ,0x71 ,0x10 ,0x11 ,0x14 ,0x18 ,0x1c ,0x1e ,0x1f ,0x1e ,0x1d ,0x1c ,0x19 ,0x47 ,0x26 ,0x1d ,0x4f ,0x1d ,0x16 ,0x12 ,0x17 ,0x1b ,0x1e ,0x1a ,0x14 ,0x51 ,0x10 ,0x11 ,0x12 ,0x61 ,0x1b ,0x2d ,0x1e ,0x1f ,0x1c ,0x47 ,0x15 ,0x17 ,0x8f ,0x1a ,0x14 ,0x12 ,0x14 ,0x1a ,0x1d ,0x1c ,0x17 ,0x13 ,0x21 ,0x12 ,0x11 ,0x20 ,0x22 ,0x21 ,0x1c ,0x1f ,0x3e ,0x1b ,0x47 ,0x15 ,0x19 ,0xbf ,0x1d ,0x17 ,0x23 ,0x17 ,0x1c ,0x1d ,0x1b ,0x16 ,0x12 ,0x11 ,0x12 ,0x11 ,0x20 ,0x14 ,0x1e ,0x1f ,0x2e ,0x1f ,0x1b ,0x47 ,0x15 ,0x1b ,0xff ,0x1b ,0x15 ,0x12 ,0x14 ,0x19 ,0x2d ,0x1a ,0x2e ,0x1a ,0x17 ,0x1e ,0x1f ,0x2e ,0x1f ,0x1c ,0x37 ,0x16 ,0x15 ,0x1c ,0xff ,0x3f ,0x1e ,0x18 ,0x23 ,0x16 ,0x1b ,0x1d ,0x1e ,0x2f ,0x3e ,0x1f ,0x1c ,0x37 ,0x26 ,0x1e ,0xff ,0x7f ,0x1c ,0x16 ,0x12 ,0x13 ,0x17 ,0x1c ,0x1e ,0x1f ,0x1e ,0x1f ,0x1d ,0x37 ,0x15 ,0x17 ,0xff ,0xbf ,0x1e ,0x19 ,0x14 ,0x12 ,0x14 ,0x19 ,0x2c ,0x18 ,0x27 ,0x15 ,0x19 ,0xff ,0xff ,0x1d ,0x17 ,0x12 ,0x11 ,0x12 ,0x23 ,0x14 ,0x1b ,0xff ,0xff ,0x4f ,0x1b ,0x19 ,0x28 ,0x1c ,0xef ,0x0 ,0x9 ,0x41 ,0x50 ,0x50 ,0x4c ,0x45 ,0x20 ,0x49 ,0x49 ,0x20 ,0xff ,0xff ,0xff ,0xff ,0xcf ,0x1e ,0xff ,0x7f ,0x1e ,0x6d ,0x7c ,0x3b ,0x1a ,0x1d ,0xff ,0x6f ,0x1d ,0x15 ,0x14 ,0x35 ,0xa4 ,0x2a ,0x1d ,0xff ,0x6f ,0x1d ,0x15 ,0x18 ,0x39 ,0x2a ,0x79 ,0x14 ,0x1a ,0x19 ,0x1d ,0xff ,0x6f ,0x1c ,0x14 ,0x18 ,0x19 ,0x1a ,0x1b ,0x19 ,0x1a ,0x1b ,0x39 ,0x3a ,0x14 ,0x29 ,0x1d ,0xff ,0x5f ,0x1e ,0x1b ,0x14 ,0x29 ,0x1a ,0x19 ,0x16 ,0x18 ,0x19 ,0x17 ,0x16 ,0x17 ,0x28 ,0x1a ,0x14 ,0x28 ,0x1d ,0xff ,0x5f ,0x1e ,0x1a ,0x14 ,0x28 ,0x39 ,0x68 ,0x19 ,0x1a ,0x14 ,0x28 ,0x1d ,0xff ,0x5f ,0x1e ,0x1a ,0x14 ,0x28 ,0x39 ,0x7a ,0x19 ,0x14 ,0x18 ,0x17 ,0x1d ,0xff ,0x5f ,0x1d ,0x19 ,0x13 ,0x26 ,0x55 ,0x46 ,0x25 ,0x13 ,0x18 ,0x17 ,0x1c ,0xff ,0x5f ,0x1d ,0x19 ,0x1a ,0x19 ,0x28 ,0x47 ,0x16 ,0x57 ,0x18 ,0x1a ,0x16 ,0x1c ,0xff ,0x5f ,0x1c ,0x19 ,0x3a ,0x79 ,0x58 ,0x17 ,0x16 ,0x1c ,0xff ,0x5f ,0x1b ,0x68 ,0x57 ,0x36 ,0x25 ,0x26 ,0x1c ,0xff ,0x5f ,0x1b ,0xd7 ,0x36 ,0x17 ,0x16 ,0x1c ,0xff ,0x5f ,0x1a ,0x17 ,0x16 ,0x47 ,0x86 ,0x17 ,0x26 ,0x15 ,0x1b ,0xff ,0x5f ,0x19 ,0x65 ,0x74 ,0x55 ,0x1a ,0x1d ,0x1e ,0x8f ,0x1d ,0x7c ,0x2b ,0x17 ,0x44 ,0x13 ,0x14 ,0x53 ,0x15 ,0x16 ,0x13 ,0x22 ,0x13 ,0x14 ,0x1d ,0x1f ,0x1e ,0x1d ,0x1e ,0x5f ,0x1d ,0x27 ,0x36 ,0x65 ,0x34 ,0x23 ,0x14 ,0x43 ,0x14 ,0x1a ,0x1c ,0x14 ,0x10 ,0x11 ,0x12 ,0x13 ,0x1d ,0x3f ,0x1d ,0x1e ,0x4f ,0x1b ,0x16 ,0x17 ,0x15 ,0x17 ,0x15 ,0x16 ,0x17 ,0x36 ,0x15 ,0x54 ,0x53 ,0x14 ,0x1a ,0x1c ,0x16 ,0x11 ,0x13 ,0x14 ,0x17 ,0x1f ,0x1e ,0x3f ,0x1e ,0x4f ,0x1e ,0x1d ,0x1a ,0x19 ,0x1a ,0x99 ,0x58 ,0x27 ,0x18 ,0x3b ,0x18 ,0x17 ,0x1b ,0x5d ,0x1b ,0x19 ,0x1b ,0x1f ,0x1e ,0x19 ,0x48 ,0x19 ,0x88 ,0x77 ,0x56 ,0x25 ,0x1a ,0x1d ,0x1a ,0x19 ,0x1a ,0x1b ,0x1a ,0x17 ,0x14 ,0x1a ,0x2f ,0x1c ,0x4a ,0xb9 ,0xb8 ,0x19 ,0x1c ,0x1d ,0x17 ,0x26 ,0x15 ,0x14 ,0x15 ,0x17 ,0x1d ,0xff ,0xff ,0x3e ,0x1d ,0x1c ,0x2b ,0x1d ,0x3f ,0x0 ,0xa ,0x4d ,0x41 ,0x43 ,0x49 ,0x4e ,0x54 ,0x4f ,0x53 ,0x48 ,0x20 ,0xef ,0x1e ,0x2d ,0xff ,0xff ,0x4f ,0x1d ,0x19 ,0x18 ,0x29 ,0x17 ,0x1c ,0x1e ,0x1d ,0xff ,0xff ,0x19 ,0x15 ,0x19 ,0x1a ,0x29 ,0x17 ,0x18 ,0x1e ,0x1b ,0x1c ,0x1e ,0xff ,0xbf ,0x1c ,0x26 ,0x2b ,0x1a ,0x19 ,0x28 ,0x16 ,0x1e ,0x16 ,0x14 ,0x19 ,0x1c ,0xff ,0x9f ,0x19 ,0x14 ,0x19 ,0x2c ,0x1b ,0x29 ,0x18 ,0x17 ,0x15 ,0x1a ,0x1b ,0x10 ,0x12 ,0x16 ,0x1a ,0xff ,0x6f ,0x1e ,0x16 ,0x17 ,0x3c ,0x1b ,0x1a ,0x19 ,0x18 ,0x17 ,0x16 ,0x15 ,0x16 ,0x1e ,0x14 ,0x11 ,0x14 ,0x18 ,0x1b ,0xff ,0x4f ,0x1c ,0x15 ,0x18 ,0x2c ,0x3b ,0x19 ,0x18 ,0x16 ,0x35 ,0x13 ,0x1d ,0x19 ,0x10 ,0x12 ,0x17 ,0x1a ,0x1e ,0xff ,0x2f ,0x1b ,0x14 ,0x19 ,0x1c ,0x2b ,0x2a ,0x29 ,0x17 ,0x15 ,0x34 ,0x12 ,0x1a ,0x1c ,0x21 ,0x14 ,0x18 ,0x1c ,0xff ,0x1f ,0x1a ,0x14 ,0x19 ,0x1b ,0x2a ,0x29 ,0x38 ,0x16 ,0x24 ,0x13 ,0x14 ,0x12 ,0x15 ,0x1e ,0x13 ,0x10 ,0x12 ,0x16 ,0x1a ,0xff ,0x1b ,0x12 ,0x17 ,0x39 ,0x28 ,0x37 ,0x16 ,0x15 ,0x63 ,0x1e ,0x17 ,0x10 ,0x11 ,0x15 ,0x18 ,0x1e ,0xef ,0x13 ,0x12 ,0x16 ,0x47 ,0x26 ,0x45 ,0x13 ,0x22 ,0x23 ,0x11 ,0x2a ,0x11 ,0x10 ,0x13 ,0x17 ,0x1c ,0xdf ,0x1a ,0x10 ,0x11 ,0x14 ,0x45 ,0x64 ,0x13 ,0x42 ,0x11 ,0x16 ,0x1d ,0x12 ,0x10 ,0x12 ,0x16 ,0x19 ,0xdf ,0x17 ,0x10 ,0x31 ,0x12 ,0x93 ,0x42 ,0x11 ,0x14 ,0x1e ,0x14 ,0x10 ,0x11 ,0x15 ,0x17 ,0x1e ,0xcf ,0x1d ,0x1b ,0x1a ,0x19 ,0x17 ,0x16 ,0x25 ,0x12 ,0x11 ,0x12 ,0x43 ,0x12 ,0x13 ,0x22 ,0x11 ,0x12 ,0x1d ,0x16 ,0x20 ,0x13 ,0x16 ,0x1c ,0xcf ,0x2d ,0x5e ,0x1d ,0x1c ,0x19 ,0x17 ,0x16 ,0x15 ,0x14 ,0x13 ,0x42 ,0x21 ,0x1a ,0x1b ,0x13 ,0x12 ,0x13 ,0x15 ,0x1a ,0xcf ,0x1e ,0x1c ,0x1d ,0x7e ,0x1d ,0x1c ,0x1b ,0x1a ,0x29 ,0x18 ,0x16 ,0x14 ,0x12 ,0x10 ,0x17 ,0x1e ,0x1c ,0x1b ,0x2a ,0x1c ,0xdf ,0x1d ,0x1c ,0x1d ,0x2e ,0x2d ,0x5c ,0x2d ,0x1c ,0x1d ,0x1c ,0x2b ,0x18 ,0x19 ,0x1c ,0x19 ,0x1a ,0x19 ,0x1a ,0x1c ,0xef ,0x1d ,0x4c ,0x7d ,0x3c ,0x2d ,0x1e ,0x2d ,0x19 ,0x10 ,0x15 ,0x18 ,0x17 ,0x18 ,0x1b ,0xef ,0x1e ,0x2d ,0x1b ,0x1c ,0x1d ,0x3e ,0x2d ,0x2c ,0x1d ,0x2e ,0x2d ,0x1c ,0x19 ,0x10 ,0x15 ,0x19 ,0x18 ,0x19 ,0x1a ,0xff ,0x2f ,0x1e ,0x1d ,0x2c ,0x1d ,0x2e ,0x4d ,0x1e ,0x2d ,0x1e ,0x1b ,0x18 ,0x16 ,0x17 ,0x18 ,0x2b ,0x4d ,0x2c ,0x1e ,0xaf ,0x3e ,0x1d ,0x1c ,0x5b ,0x1a ,0x2b ,0x18 ,0x27 ,0x29 ,0x1b ,0x1a ,0x29 ,0x14 ,0x53 ,0x12 ,0x13 ,0x16 ,0x18 ,0x29 ,0x1d ,0x3f ,0x2e ,0x1d ,0x1c ,0x2b ,0x4a ,0x29 ,0x28 ,0x17 ,0x56 ,0x15 ,0x18 ,0x1c ,0x19 ,0x43 ,0x22 ,0x14 ,0x17 ,0x28 ,0x29 ,0x1c ,0xff ,0x6f ,0x1e ,0x1c ,0x2b ,0x1c ,0x2e ,0x1d ,0x3c ,0x2b ,0x1d ,0x1e ,0x4f ,0x0 ,0x5 ,0x49 ,0x4d ,0x41 ,0x43 ,0x20 ,0xa0 ,0x13 ,0x64 ,0xd5 ,0x12 ,0xf0 ,0x30 ,0x19 ,0x1e ,0x1c ,0x5d ,0x6c ,0x5d ,0x1c ,0x1d ,0x1f ,0x16 ,0xf0 ,0x20 ,0x1d ,0x1b ,0x19 ,0x3c ,0x2d ,0x1b ,0x1a ,0x1b ,0x3a ,0x1c ,0x1d ,0x1c ,0x1d ,0x1c ,0x1a ,0x18 ,0x1f ,0x1a ,0xf0 ,0x20 ,0x3c ,0x3b ,0x3e ,0xbf ,0x1a ,0x1f ,0x1a ,0xf0 ,0x20 ,0x3c ,0x17 ,0x14 ,0x19 ,0x17 ,0x14 ,0x1a ,0x1e ,0x6d ,0x4f ,0x1a ,0x1f ,0x1a ,0xf0 ,0x20 ,0x1c ,0x1b ,0x1c ,0x1b ,0x15 ,0x1d ,0x27 ,0x1d ,0x1e ,0x3c ,0x7f ,0x1a ,0x1f ,0x1a ,0xf0 ,0x20 ,0x1c ,0x1b ,0x1c ,0x18 ,0x13 ,0x1b ,0x16 ,0x14 ,0x1b ,0x1e ,0x1c ,0x3d ,0x1c ,0x5f ,0x1a ,0x1f ,0x1a ,0xf0 ,0x20 ,0x1c ,0x1b ,0x1c ,0x19 ,0x18 ,0x29 ,0x18 ,0x1a ,0x4d ,0x1e ,0x6f ,0x1a ,0x1f ,0x1a ,0xf0 ,0x20 ,0x1c ,0x1b ,0x1d ,0x2b ,0x8c ,0x1d ,0x3f ,0x1e ,0x1d ,0x1e ,0x1a ,0x1f ,0x1a ,0xf0 ,0x20 ,0x1c ,0x4b ,0x6c ,0x6d ,0x1c ,0x1b ,0x1c ,0x1a ,0x1f ,0x1a ,0xf0 ,0x20 ,0x1b ,0x1e ,0x6d ,0xce ,0x2f ,0x1a ,0xf0 ,0x20 ,0x1b ,0x5e ,0xff ,0x1f ,0x1a ,0xf0 ,0x20 ,0x1b ,0x6e ,0x2d ,0x1c ,0x2d ,0x2c ,0x1d ,0x1e ,0x6f ,0x1a ,0xf0 ,0x20 ,0x1b ,0x4e ,0x1d ,0x2c ,0x6b ,0x3c ,0x5f ,0x1a ,0xf0 ,0x20 ,0x1b ,0x3e ,0x1d ,0x5b ,0x3d ,0x4b ,0x1c ,0x4f ,0x1a ,0xf0 ,0x20 ,0x1b ,0x1e ,0x2d ,0x1c ,0x2b ,0x1a ,0x1b ,0x4f ,0x1e ,0x1a ,0x3b ,0x1e ,0x3f ,0x1a ,0xf0 ,0x20 ,0x1a ,0x3d ,0x1b ,0x4a ,0x1e ,0x3f ,0x1d ,0x4a ,0x1e ,0x3f ,0x1a ,0xf0 ,0x20 ,0x1a ,0x1d ,0x1c ,0x1d ,0x1c ,0x1a ,0x19 ,0x1a ,0x19 ,0x1a ,0x2b ,0x1a ,0x19 ,0x2a ,0x19 ,0x1b ,0x4f ,0x1a ,0xf0 ,0x20 ,0x1a ,0x3c ,0x1d ,0x1c ,0x1a ,0x89 ,0x1a ,0x1b ,0x1e ,0x4f ,0x1a ,0xf0 ,0x20 ,0x19 ,0x4c ,0x2d ,0x1c ,0x1b ,0x1a ,0x2b ,0x1a ,0x1b ,0x1c ,0x1d ,0x3e ,0x3f ,0x1a ,0xf0 ,0x20 ,0x1a ,0x5c ,0x6d ,0x7e ,0x3f ,0x19 ,0xf0 ,0x20 ,0x15 ,0x3b ,0x5c ,0x8d ,0x4e ,0x1d ,0x13 ,0xf0 ,0x30 ,0x11 ,0xf2 ,0x42 ,0x11 ,0x90 ,0x0 ,0x5 ,0x49 ,0x50 ,0x4f ,0x44 ,0x20 ,0xef ,0x1d ,0x4c ,0x1b ,0x2c ,0x4b ,0x5a ,0x29 ,0x1a ,0x39 ,0x28 ,0x1b ,0xdf ,0x1d ,0x15 ,0x16 ,0x47 ,0x18 ,0x19 ,0x1a ,0x49 ,0x2a ,0x49 ,0x48 ,0x19 ,0x17 ,0x19 ,0xdf ,0x1c ,0x14 ,0x13 ,0x24 ,0x25 ,0x16 ,0x17 ,0x18 ,0x27 ,0x78 ,0x67 ,0x16 ,0x19 ,0xdf ,0x1a ,0x13 ,0x22 ,0x13 ,0x14 ,0x15 ,0x46 ,0x17 ,0x18 ,0xb7 ,0x26 ,0x1a ,0xdf ,0x19 ,0x13 ,0x22 ,0x13 ,0x25 ,0x26 ,0xb7 ,0x46 ,0x17 ,0x16 ,0x1b ,0xdf ,0x17 ,0x13 ,0x32 ,0x14 ,0x26 ,0x27 ,0xc6 ,0x37 ,0x16 ,0x1c ,0xdf ,0x16 ,0x42 ,0x14 ,0x15 ,0x17 ,0x18 ,0x25 ,0x26 ,0x25 ,0x36 ,0x15 ,0x76 ,0x1d ,0xdf ,0x15 ,0x42 ,0x13 ,0x16 ,0x19 ,0x55 ,0x14 ,0x36 ,0x75 ,0x14 ,0x15 ,0x1e ,0xcf ,0x1e ,0x14 ,0x41 ,0x13 ,0x27 ,0x54 ,0x16 ,0x17 ,0x16 ,0x25 ,0x14 ,0x15 ,0x24 ,0x33 ,0x15 ,0x1e ,0xcf ,0x1d ,0x13 ,0x41 ,0x14 ,0x17 ,0x14 ,0x43 ,0x16 ,0x17 ,0x25 ,0x44 ,0x23 ,0x22 ,0x13 ,0x15 ,0xdf ,0x1c ,0x13 ,0x41 ,0x14 ,0x23 ,0x22 ,0x13 ,0x26 ,0x15 ,0x14 ,0x43 ,0x52 ,0x13 ,0x16 ,0xdf ,0x1a ,0x12 ,0x30 ,0x62 ,0x44 ,0x23 ,0x22 ,0x31 ,0x22 ,0x11 ,0x12 ,0x16 ,0xdf ,0x18 ,0x11 ,0x20 ,0x61 ,0x62 ,0x91 ,0x12 ,0x17 ,0xdf ,0x17 ,0x11 ,0x20 ,0xc1 ,0x50 ,0x41 ,0x12 ,0x18 ,0xdf ,0x16 ,0xf0 ,0x60 ,0x31 ,0x12 ,0x18 ,0xdf ,0x15 ,0x30 ,0x14 ,0x11 ,0x13 ,0x12 ,0x13 ,0x22 ,0x51 ,0x30 ,0x11 ,0x50 ,0x12 ,0x19 ,0xbf ,0x1d ,0x19 ,0x14 ,0x33 ,0x26 ,0x17 ,0x28 ,0x19 ,0x1a ,0x25 ,0x17 ,0x16 ,0x27 ,0x15 ,0x13 ,0x1a ,0x14 ,0x12 ,0x30 ,0x12 ,0x1a ,0x7f ,0x1c ,0x19 ,0x16 ,0x14 ,0x13 ,0x15 ,0x17 ,0x46 ,0x17 ,0x26 ,0x37 ,0x15 ,0x16 ,0x58 ,0x27 ,0x16 ,0x14 ,0x12 ,0x21 ,0x13 ,0x1b ,0x2f ,0x1e ,0x1c ,0x1a ,0x28 ,0x49 ,0x3a ,0x28 ,0x17 ,0x18 ,0x47 ,0x16 ,0x15 ,0x16 ,0x25 ,0x14 ,0x45 ,0x14 ,0x13 ,0x31 ,0x13 ,0x16 ,0x1d ,0x1f ,0x29 ,0x1b ,0x3c ,0x3d ,0x5e ,0x1c ,0x1b ,0x1a ,0x29 ,0x17 ,0x16 ,0x17 ,0x28 ,0x16 ,0x25 ,0x24 ,0x13 ,0x14 ,0x12 ,0x21 ,0x13 ,0x25 ,0x1b ,0x2f ,0x1a ,0x46 ,0x17 ,0x18 ,0x19 ,0x3a ,0x1c ,0x1b ,0x1a ,0x19 ,0x18 ,0x1b ,0x1c ,0x1b ,0x4a ,0x29 ,0x18 ,0x17 ,0x16 ,0x25 ,0x14 ,0x13 ,0x14 ,0x19 ,0x16 ,0x1b ,0x9f ,0x1e ,0x1d ,0x1c ,0x1b ,0x1a ,0x19 ,0x18 ,0x17 ,0x16 ,0x15 ,0x14 ,0x25 ,0x14 ,0x23 ,0x84 ,0x23 ,0x14 ,0x16 ,0x1b ,0xff ,0x9f ,0x1e ,0x1d ,0x1c ,0x1b ,0x1a ,0x19 ,0x18 ,0x17 ,0x25 ,0x14 ,0x13 ,0x14 ,0x1a ,0x8f ,0x0 ,0xc ,0x4d ,0x41 ,0x43 ,0x42 ,0x4f ,0x4f ,0x4b ,0x20 ,0x50 ,0x52 ,0x4f ,0x20 ,0xff ,0x9f ,0x40 ,0xff ,0xff ,0x4f ,0x60 ,0xff ,0xff ,0x2f ,0x70 ,0xff ,0xff ,0x3f ,0x60 ,0xff ,0xff ,0x3f ,0x50 ,0xff ,0xbf ,0x40 ,0x5f ,0x20 ,0x5f ,0x60 ,0xef ,0xf0 ,0xf0 ,0x8f ,0xf0 ,0xf0 ,0x30 ,0x5f ,0xf0 ,0xf0 ,0x40 ,0x5f ,0xf0 ,0xf0 ,0x30 ,0x7f ,0xf0 ,0xf0 ,0x20 ,0x8f ,0xf0 ,0xf0 ,0x20 ,0x8f ,0xf0 ,0xf0 ,0x20 ,0x8f ,0xf0 ,0xf0 ,0x20 ,0x8f ,0xf0 ,0xf0 ,0x30 ,0x7f ,0xf0 ,0xf0 ,0x50 ,0x6f ,0xf0 ,0xf0 ,0x60 ,0x5f ,0xf0 ,0xf0 ,0x50 ,0x5f ,0xf0 ,0xf0 ,0x40 ,0x8f ,0xf0 ,0xf0 ,0x10 ,0xaf ,0xf0 ,0xe0 ,0xdf ,0xf0 ,0xb0 ,0xff ,0x80 ,0x7f ,0x80 ,0x8f ,0x0 ,0x13 ,0x54 ,0x48 ,0x45 ,0x20 ,0x4e ,0x45 ,0x58 ,0x54 ,0x20 ,0x54 ,0x48 ,0x49 ,0x52 ,0x54 ,0x59 ,0x2e ,0x2e ,0x2e ,0x20 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 ,0x0 };
uint8_t BASIC_ROM[4096] = { 0x4C,0xB0,0xE2,0xAD,0x11,0xD0,0x10,0xFB,0xAD,0x10,0xD0,0x60,0x8A,0x29,0x20,0xF0,0x23,0xA9,0xA0,0x85,0xE4,0x4C,0xC9,0xE3,0xA9,0x20,0xC5,0x24,0xB0,0xC,0xA9,0x8D,0xA0,0x7,0x20,0xC9,0xE3,0xA9,0xA0,0x88,0xD0,0xF8,0xA0,0x0,0xB1,0xE2,0xE6,0xE2,0xD0,0x2,0xE6,0xE3,0x60,0x20,0x15,0xE7,0x20,0x76,0xE5,0xA5,0xE2,0xC5,0xE6,0xA5,0xE3,0xE5,0xE7,0xB0,0xEF,0x20,0x6D,0xE0,0x4C,0x3B,0xE0,0xA5,0xCA,0x85,0xE2,0xA5,0xCB,0x85,0xE3,0xA5,0x4C,0x85,0xE6,0xA5,0x4D,0x85,0xE7,0xD0,0xDE,0x20,0x15,0xE7,0x20,0x6D,0xE5,0xA5,0xE4,0x85,0xE2,0xA5,0xE5,0x85,0xE3,0xB0,0xC7,0x86,0xD8,0xA9,0xA0,0x85,0xFA,0x20,0x2A,0xE0,0x98,0x85,0xE4,0x20,0x2A,0xE0,0xAA,0x20,0x2A,0xE0,0x20,0x1B,0xE5,0x20,0x18,0xE0,0x84,0xFA,0xAA,0x10,0x18,0xA,0x10,0xE9,0xA5,0xE4,0xD0,0x3,0x20,0x11,0xE0,0x8A,0x20,0xC9,0xE3,0xA9,0x25,0x20,0x1A,0xE0,0xAA,0x30,0xF5,0x85,0xE4,0xC9,0x1,0xD0,0x5,0xA6,0xD8,0x4C,0xCD,0xE3,0x48,0x84,0xCE,0xA2,0xED,0x86,0xCF,0xC9,0x51,0x90,0x4,0xC6,0xCF,0xE9,0x50,0x48,0xB1,0xCE,0xAA,0x88,0xB1,0xCE,0x10,0xFA,0xE0,0xC0,0xB0,0x4,0xE0,0x0,0x30,0xF2,0xAA,0x68,0xE9,0x1,0xD0,0xE9,0x24,0xE4,0x30,0x3,0x20,0xF8,0xEF,0xB1,0xCE,0x10,0x10,0xAA,0x29,0x3F,0x85,0xE4,0x18,0x69,0xA0,0x20,0xC9,0xE3,0x88,0xE0,0xC0,0x90,0xEC,0x20,0xC,0xE0,0x68,0xC9,0x5D,0xF0,0xA4,0xC9,0x28,0xD0,0x8A,0xF0,0x9E,0x20,0x18,0xE1,0x95,0x50,0xD5,0x78,0x90,0x11,0xA0,0x2B,0x4C,0xE0,0xE3,0x20,0x34,0xEE,0xD5,0x50,0x90,0xF4,0x20,0xE4,0xEF,0x95,0x78,0x4C,0x23,0xE8,0x20,0x34,0xEE,0xF0,0xE7,0x38,0xE9,0x1,0x60,0x20,0x18,0xE1,0x95,0x50,0x18,0xF5,0x78,0x4C,0x2,0xE1,0xA0,0x14,0xD0,0xD6,0x20,0x18,0xE1,0xE8,0xB5,0x50,0x85,0xDA,0x65,0xCE,0x48,0xA8,0xB5,0x78,0x85,0xDB,0x65,0xCF,0x48,0xC4,0xCA,0xE5,0xCB,0xB0,0xE3,0xA5,0xDA,0x69,0xFE,0x85,0xDA,0xA9,0xFF,0xA8,0x65,0xDB,0x85,0xDB,0xC8,0xB1,0xDA,0xD9,0xCC,0x0,0xD0,0xF,0x98,0xF0,0xF5,0x68,0x91,0xDA,0x99,0xCC,0x0,0x88,0x10,0xF7,0xE8,0x60,0xEA,0xA0,0x80,0xD0,0x95,0xA9,0x0,0x20,0xA,0xE7,0xA0,0x2,0x94,0x78,0x20,0xA,0xE7,0xA9,0xBF,0x20,0xC9,0xE3,0xA0,0x0,0x20,0x9E,0xE2,0x94,0x78,0xEA,0xEA,0xEA,0xB5,0x51,0x85,0xCE,0xB5,0x79,0x85,0xCF,0xE8,0xE8,0x20,0xBC,0xE1,0xB5,0x4E,0xD5,0x76,0xB0,0x15,0xF6,0x4E,0xA8,0xB1,0xCE,0xB4,0x50,0xC4,0xE4,0x90,0x4,0xA0,0x83,0xD0,0xC1,0x91,0xDA,0xF6,0x50,0x90,0xE5,0xB4,0x50,0x8A,0x91,0xDA,0xE8,0xE8,0x60,0xB5,0x51,0x85,0xDA,0x38,0xE9,0x2,0x85,0xE4,0xB5,0x79,0x85,0xDB,0xE9,0x0,0x85,0xE5,0xA0,0x0,0xB1,0xE4,0x18,0xE5,0xDA,0x85,0xE4,0x60,0xB5,0x53,0x85,0xCE,0xB5,0x7B,0x85,0xCF,0xB5,0x51,0x85,0xDA,0xB5,0x79,0x85,0xDB,0xE8,0xE8,0xE8,0xA0,0x0,0x94,0x78,0x94,0xA0,0xC8,0x94,0x50,0xB5,0x4D,0xD5,0x75,0x8,0x48,0xB5,0x4F,0xD5,0x77,0x90,0x7,0x68,0x28,0xB0,0x2,0x56,0x50,0x60,0xA8,0xB1,0xCE,0x85,0xE4,0x68,0xA8,0x28,0xB0,0xF3,0xB1,0xDA,0xC5,0xE4,0xD0,0xED,0xF6,0x4F,0xF6,0x4D,0xB0,0xD7,0x20,0xD7,0xE1,0x4C,0x36,0xE7,0x20,0x54,0xE2,0x6,0xCE,0x26,0xCF,0x90,0xD,0x18,0xA5,0xE6,0x65,0xDA,0x85,0xE6,0xA5,0xE7,0x65,0xDB,0x85,0xE7,0x88,0xF0,0x9,0x6,0xE6,0x26,0xE7,0x10,0xE4,0x4C,0x7E,0xE7,0xA5,0xE6,0x20,0x8,0xE7,0xA5,0xE7,0x95,0xA0,0x6,0xE5,0x90,0x28,0x4C,0x6F,0xE7,0xA9,0x55,0x85,0xE5,0x20,0x5B,0xE2,0xA5,0xCE,0x85,0xDA,0xA5,0xCF,0x85,0xDB,0x20,0x15,0xE7,0x84,0xE6,0x84,0xE7,0xA5,0xCF,0x10,0x9,0xCA,0x6,0xE5,0x20,0x6F,0xE7,0x20,0x15,0xE7,0xA0,0x10,0x60,0x20,0x6C,0xEE,0xF0,0xC5,0xFF,0xC9,0x84,0xD0,0x2,0x46,0xF8,0xC9,0xDF,0xF0,0x11,0xC9,0x9B,0xF0,0x6,0x99,0x0,0x2,0xC8,0x10,0xA,0xA0,0x8B,0x20,0xC4,0xE3,0xA0,0x1,0x88,0x30,0xF6,0x20,0x3,0xE0,0xEA,0xEA,0x20,0xC9,0xE3,0xC9,0x8D,0xD0,0xD6,0xA9,0xDF,0x99,0x0,0x2,0x60,0x20,0xD3,0xEF,0x20,0xCD,0xE3,0x46,0xD9,0xA9,0xBE,0x20,0xC9,0xE3,0xA0,0x0,0x84,0xFA,0x24,0xF8,0x10,0xC,0xA6,0xF6,0xA5,0xF7,0x20,0x1B,0xE5,0xA9,0xA0,0x20,0xC9,0xE3,0xA2,0xFF,0x9A,0x20,0x9E,0xE2,0x84,0xF1,0x8A,0x85,0xC8,0xA2,0x20,0x20,0x91,0xE4,0xA5,0xC8,0x69,0x0,0x85,0xE0,0xA9,0x0,0xAA,0x69,0x2,0x85,0xE1,0xA1,0xE0,0x29,0xF0,0xC9,0xB0,0xF0,0x3,0x4C,0x83,0xE8,0xA0,0x2,0xB1,0xE0,0x99,0xCD,0x0,0x88,0xD0,0xF8,0x20,0x8A,0xE3,0xA5,0xF1,0xE5,0xC8,0xC9,0x4,0xF0,0xA8,0x91,0xE0,0xA5,0xCA,0xF1,0xE0,0x85,0xE4,0xA5,0xCB,0xE9,0x0,0x85,0xE5,0xA5,0xE4,0xC5,0xCC,0xA5,0xE5,0xE5,0xCD,0x90,0x45,0xA5,0xCA,0xF1,0xE0,0x85,0xE6,0xA5,0xCB,0xE9,0x0,0x85,0xE7,0xB1,0xCA,0x91,0xE6,0xE6,0xCA,0xD0,0x2,0xE6,0xCB,0xA5,0xE2,0xC5,0xCA,0xA5,0xE3,0xE5,0xCB,0xB0,0xE0,0xB5,0xE4,0x95,0xCA,0xCA,0x10,0xF9,0xB1,0xE0,0xA8,0x88,0xB1,0xE0,0x91,0xE6,0x98,0xD0,0xF8,0x24,0xF8,0x10,0x9,0xB5,0xF7,0x75,0xF5,0x95,0xF7,0xE8,0xF0,0xF7,0x10,0x7E,0x0,0x0,0x0,0x0,0xA0,0x14,0xD0,0x71,0x20,0x15,0xE7,0xA5,0xE2,0x85,0xE6,0xA5,0xE3,0x85,0xE7,0x20,0x75,0xE5,0xA5,0xE2,0x85,0xE4,0xA5,0xE3,0x85,0xE5,0xD0,0xE,0x20,0x15,0xE7,0x20,0x6D,0xE5,0xA5,0xE6,0x85,0xE2,0xA5,0xE7,0x85,0xE3,0xA0,0x0,0xA5,0xCA,0xC5,0xE4,0xA5,0xCB,0xE5,0xE5,0xB0,0x16,0xA5,0xE4,0xD0,0x2,0xC6,0xE5,0xC6,0xE4,0xA5,0xE6,0xD0,0x2,0xC6,0xE7,0xC6,0xE6,0xB1,0xE4,0x91,0xE6,0x90,0xE0,0xA5,0xE6,0x85,0xCA,0xA5,0xE7,0x85,0xCB,0x60,0x20,0xC9,0xE3,0xC8,0xB9,0x0,0xEB,0x30,0xF7,0xC9,0x8D,0xD0,0x6,0xA9,0x0,0x85,0x24,0xA9,0x8D,0xE6,0x24,0x2C,0x12,0xD0,0x30,0xFB,0x8D,0x12,0xD0,0x60,0xA0,0x6,0x20,0xD3,0xEE,0x24,0xD9,0x30,0x3,0x4C,0xB6,0xE2,0x4C,0x9A,0xEB,0x2A,0x69,0xA0,0xDD,0x0,0x2,0xD0,0x53,0xB1,0xFE,0xA,0x30,0x6,0x88,0xB1,0xFE,0x30,0x29,0xC8,0x86,0xC8,0x98,0x48,0xA2,0x0,0xA1,0xFE,0xAA,0x4A,0x49,0x48,0x11,0xFE,0xC9,0xC0,0x90,0x1,0xE8,0xC8,0xD0,0xF3,0x68,0xA8,0x8A,0x4C,0xC0,0xE4,0xE6,0xF1,0xA6,0xF1,0xF0,0xBC,0x9D,0x0,0x2,0x60,0xA6,0xC8,0xA9,0xA0,0xE8,0xDD,0x0,0x2,0xB0,0xFA,0xB1,0xFE,0x29,0x3F,0x4A,0xD0,0xB6,0xBD,0x0,0x2,0xB0,0x6,0x69,0x3F,0xC9,0x1A,0x90,0x6F,0x69,0x4F,0xC9,0xA,0x90,0x69,0xA6,0xFD,0xC8,0xB1,0xFE,0x29,0xE0,0xC9,0x20,0xF0,0x7A,0xB5,0xA8,0x85,0xC8,0xB5,0xD1,0x85,0xF1,0x88,0xB1,0xFE,0xA,0x10,0xFA,0x88,0xB0,0x38,0xA,0x30,0x35,0xB4,0x58,0x84,0xFF,0xB4,0x80,0xE8,0x10,0xDA,0xF0,0xB3,0xC9,0x7E,0xB0,0x22,0xCA,0x10,0x4,0xA0,0x6,0x10,0x29,0x94,0x80,0xA4,0xFF,0x94,0x58,0xA4,0xC8,0x94,0xA8,0xA4,0xF1,0x94,0xD1,0x29,0x1F,0xA8,0xB9,0x20,0xEC,0xA,0xA8,0xA9,0x76,0x2A,0x85,0xFF,0xD0,0x1,0xC8,0xC8,0x86,0xFD,0xB1,0xFE,0x30,0x84,0xD0,0x5,0xA0,0xE,0x4C,0xE0,0xE3,0xC9,0x3,0xB0,0xC3,0x4A,0xA6,0xC8,0xE8,0xBD,0x0,0x2,0x90,0x4,0xC9,0xA2,0xF0,0xA,0xC9,0xDF,0xF0,0x6,0x86,0xC8,0x20,0x1C,0xE4,0xC8,0x88,0xA6,0xFD,0xB1,0xFE,0x88,0xA,0x10,0xCF,0xB4,0x58,0x84,0xFF,0xB4,0x80,0xE8,0xB1,0xFE,0x29,0x9F,0xD0,0xED,0x85,0xF2,0x85,0xF3,0x98,0x48,0x86,0xFD,0xB4,0xD0,0x84,0xC9,0x18,0xA9,0xA,0x85,0xF9,0xA2,0x0,0xC8,0xB9,0x0,0x2,0x29,0xF,0x65,0xF2,0x48,0x8A,0x65,0xF3,0x30,0x1C,0xAA,0x68,0xC6,0xF9,0xD0,0xF2,0x85,0xF2,0x86,0xF3,0xC4,0xF1,0xD0,0xDE,0xA4,0xC9,0xC8,0x84,0xF1,0x20,0x1C,0xE4,0x68,0xA8,0xA5,0xF3,0xB0,0xA9,0xA0,0x0,0x10,0x8B,0x85,0xF3,0x86,0xF2,0xA2,0x4,0x86,0xC9,0xA9,0xB0,0x85,0xF9,0xA5,0xF2,0xDD,0x63,0xE5,0xA5,0xF3,0xFD,0x68,0xE5,0x90,0xD,0x85,0xF3,0xA5,0xF2,0xFD,0x63,0xE5,0x85,0xF2,0xE6,0xF9,0xD0,0xE7,0xA5,0xF9,0xE8,0xCA,0xF0,0xE,0xC9,0xB0,0xF0,0x2,0x85,0xC9,0x24,0xC9,0x30,0x4,0xA5,0xFA,0xF0,0xB,0x20,0xC9,0xE3,0x24,0xF8,0x10,0x4,0x99,0x0,0x2,0xC8,0xCA,0x10,0xC1,0x60,0x1,0xA,0x64,0xE8,0x10,0x0,0x0,0x0,0x3,0x27,0xA5,0xCA,0x85,0xE6,0xA5,0xCB,0x85,0xE7,0xE8,0xA5,0xE7,0x85,0xE5,0xA5,0xE6,0x85,0xE4,0xC5,0x4C,0xA5,0xE5,0xE5,0x4D,0xB0,0x26,0xA0,0x1,0xB1,0xE4,0xE5,0xCE,0xC8,0xB1,0xE4,0xE5,0xCF,0xB0,0x19,0xA0,0x0,0xA5,0xE6,0x71,0xE4,0x85,0xE6,0x90,0x3,0xE6,0xE7,0x18,0xC8,0xA5,0xCE,0xF1,0xE4,0xC8,0xA5,0xCF,0xF1,0xE4,0xB0,0xCA,0x60,0x46,0xF8,0xA5,0x4C,0x85,0xCA,0xA5,0x4D,0x85,0xCB,0xA5,0x4A,0x85,0xCC,0xA5,0x4B,0x85,0xCD,0xA9,0x0,0x85,0xFB,0x85,0xFC,0x85,0xFE,0xA9,0x0,0x85,0x1D,0x60,0xA5,0xD0,0x69,0x5,0x85,0xD2,0xA5,0xD1,0x69,0x0,0x85,0xD3,0xA5,0xD2,0xC5,0xCA,0xA5,0xD3,0xE5,0xCB,0x90,0x3,0x4C,0x6B,0xE3,0xA5,0xCE,0x91,0xD0,0xA5,0xCF,0xC8,0x91,0xD0,0xA5,0xD2,0xC8,0x91,0xD0,0xA5,0xD3,0xC8,0x91,0xD0,0xA9,0x0,0xC8,0x91,0xD0,0xC8,0x91,0xD0,0xA5,0xD2,0x85,0xCC,0xA5,0xD3,0x85,0xCD,0xA5,0xD0,0x90,0x43,0x85,0xCE,0x84,0xCF,0x20,0xFF,0xE6,0x30,0xE,0xC9,0x40,0xF0,0xA,0x4C,0x28,0xE6,0x6,0xC9,0x49,0xD0,0x7,0xA9,0x49,0x85,0xCF,0x20,0xFF,0xE6,0xA5,0x4B,0x85,0xD1,0xA5,0x4A,0x85,0xD0,0xC5,0xCC,0xA5,0xD1,0xE5,0xCD,0xB0,0x94,0xB1,0xD0,0xC8,0xC5,0xCE,0xD0,0x6,0xB1,0xD0,0xC5,0xCF,0xF0,0xE,0xC8,0xB1,0xD0,0x48,0xC8,0xB1,0xD0,0x85,0xD1,0x68,0xA0,0x0,0xF0,0xDB,0xA5,0xD0,0x69,0x3,0x20,0xA,0xE7,0xA5,0xD1,0x69,0x0,0x95,0x78,0xA5,0xCF,0xC9,0x40,0xD0,0x1C,0x88,0x98,0x20,0xA,0xE7,0x88,0x94,0x78,0xA0,0x3,0xF6,0x78,0xC8,0xB1,0xD0,0x30,0xF9,0x10,0x9,0xA9,0x0,0x85,0xD4,0x85,0xD5,0xA2,0x20,0x48,0xA0,0x0,0xB1,0xE0,0x10,0x18,0xA,0x30,0x81,0x20,0xFF,0xE6,0x20,0x8,0xE7,0x20,0xFF,0xE6,0x95,0xA0,0x24,0xD4,0x10,0x1,0xCA,0x20,0xFF,0xE6,0xB0,0xE6,0xC9,0x28,0xD0,0x1F,0xA5,0xE0,0x20,0xA,0xE7,0xA5,0xE1,0x95,0x78,0x24,0xD4,0x30,0xB,0xA9,0x1,0x20,0xA,0xE7,0xA9,0x0,0x95,0x78,0xF6,0x78,0x20,0xFF,0xE6,0x30,0xF9,0xB0,0xD3,0x24,0xD4,0x10,0x6,0xC9,0x4,0xB0,0xD0,0x46,0xD4,0xA8,0x85,0xD6,0xB9,0x98,0xE9,0x29,0x55,0xA,0x85,0xD7,0x68,0xA8,0xB9,0x98,0xE9,0x29,0xAA,0xC5,0xD7,0xB0,0x9,0x98,0x48,0x20,0xFF,0xE6,0xA5,0xD6,0x90,0x95,0xB9,0x10,0xEA,0x85,0xCE,0xB9,0x88,0xEA,0x85,0xCF,0x20,0xFC,0xE6,0x4C,0xD8,0xE6,0x6C,0xCE,0x0,0xE6,0xE0,0xD0,0x2,0xE6,0xE1,0xB1,0xE0,0x60,0x94,0x77,0xCA,0x30,0x3,0x95,0x50,0x60,0xA0,0x66,0x4C,0xE0,0xE3,0xA0,0x0,0xB5,0x50,0x85,0xCE,0xB5,0xA0,0x85,0xCF,0xB5,0x78,0xF0,0xE,0x85,0xCF,0xB1,0xCE,0x48,0xC8,0xB1,0xCE,0x85,0xCF,0x68,0x85,0xCE,0x88,0xE8,0x60,0x20,0x4A,0xE7,0x20,0x15,0xE7,0x98,0x20,0x8,0xE7,0x95,0xA0,0xC5,0xCE,0xD0,0x6,0xC5,0xCF,0xD0,0x2,0xF6,0x50,0x60,0x20,0x82,0xE7,0x20,0x59,0xE7,0x20,0x15,0xE7,0x24,0xCF,0x30,0x1B,0xCA,0x60,0x20,0x15,0xE7,0xA5,0xCF,0xD0,0x4,0xA5,0xCE,0xF0,0xF3,0xA9,0xFF,0x20,0x8,0xE7,0x95,0xA0,0x24,0xCF,0x30,0xE9,0x20,0x15,0xE7,0x98,0x38,0xE5,0xCE,0x20,0x8,0xE7,0x98,0xE5,0xCF,0x50,0x23,0xA0,0x0,0x10,0x90,0x20,0x6F,0xE7,0x20,0x15,0xE7,0xA5,0xCE,0x85,0xDA,0xA5,0xCF,0x85,0xDB,0x20,0x15,0xE7,0x18,0xA5,0xCE,0x65,0xDA,0x20,0x8,0xE7,0xA5,0xCF,0x65,0xDB,0x70,0xDD,0x95,0xA0,0x60,0x20,0x15,0xE7,0xA4,0xCE,0xF0,0x5,0x88,0xA5,0xCF,0xF0,0xC,0x60,0xA5,0x24,0x9,0x7,0xA8,0xC8,0xA9,0xA0,0x20,0xC9,0xE3,0xC4,0x24,0xB0,0xF7,0x60,0x20,0xB1,0xE7,0x20,0x15,0xE7,0xA5,0xCF,0x10,0xA,0xA9,0xAD,0x20,0xC9,0xE3,0x20,0x72,0xE7,0x50,0xEF,0x88,0x84,0xD5,0x86,0xCF,0xA6,0xCE,0x20,0x1B,0xE5,0xA6,0xCF,0x60,0x20,0x15,0xE7,0xA5,0xCE,0x85,0xF6,0xA5,0xCF,0x85,0xF7,0x88,0x84,0xF8,0xC8,0xA9,0xA,0x85,0xF4,0x84,0xF5,0x60,0x20,0x15,0xE7,0xA5,0xCE,0xA4,0xCF,0x10,0xF2,0x20,0x15,0xE7,0xB5,0x50,0x85,0xDA,0xB5,0x78,0x85,0xDB,0xA5,0xCE,0x91,0xDA,0xC8,0xA5,0xCF,0x91,0xDA,0xE8,0x60,0x68,0x68,0x24,0xD5,0x10,0x5,0x20,0xCD,0xE3,0x46,0xD5,0x60,0xA0,0xFF,0x84,0xD7,0x60,0x20,0xCD,0xEF,0xF0,0x7,0xA9,0x25,0x85,0xD6,0x88,0x84,0xD4,0xE8,0x60,0xA5,0xCA,0xA4,0xCB,0xD0,0x5A,0xA0,0x41,0xA5,0xFC,0xC9,0x8,0xB0,0x5E,0xA8,0xE6,0xFC,0xA5,0xE0,0x99,0x0,0x1,0xA5,0xE1,0x99,0x8,0x1,0xA5,0xDC,0x99,0x10,0x1,0xA5,0xDD,0x99,0x18,0x1,0x20,0x15,0xE7,0x20,0x6D,0xE5,0x90,0x4,0xA0,0x37,0xD0,0x3B,0xA5,0xE4,0xA4,0xE5,0x85,0xDC,0x84,0xDD,0x2C,0x11,0xD0,0x30,0x4F,0x18,0x69,0x3,0x90,0x1,0xC8,0xA2,0xFF,0x86,0xD9,0x9A,0x85,0xE0,0x84,0xE1,0x20,0x79,0xE6,0x24,0xD9,0x10,0x49,0x18,0xA0,0x0,0xA5,0xDC,0x71,0xDC,0xA4,0xDD,0x90,0x1,0xC8,0xC5,0x4C,0xD0,0xD1,0xC4,0x4D,0xD0,0xCD,0xA0,0x34,0x46,0xD9,0x4C,0xE0,0xE3,0xA0,0x4A,0xA5,0xFC,0xF0,0xF7,0xC6,0xFC,0xA8,0xB9,0xF,0x1,0x85,0xDC,0xB9,0x17,0x1,0x85,0xDD,0xBE,0xFF,0x0,0xB9,0x7,0x1,0xA8,0x8A,0x4C,0x7A,0xE8,0xA0,0x63,0x20,0xC4,0xE3,0xA0,0x1,0xB1,0xDC,0xAA,0xC8,0xB1,0xDC,0x20,0x1B,0xE5,0x4C,0xB3,0xE2,0xC6,0xFB,0xA0,0x5B,0xA5,0xFB,0xF0,0xC4,0xA8,0xB5,0x50,0xD9,0x1F,0x1,0xD0,0xF0,0xB5,0x78,0xD9,0x27,0x1,0xD0,0xE9,0xB9,0x2F,0x1,0x85,0xDA,0xB9,0x37,0x1,0x85,0xDB,0x20,0x15,0xE7,0xCA,0x20,0x93,0xE7,0x20,0x1,0xE8,0xCA,0xA4,0xFB,0xB9,0x67,0x1,0x95,0x9F,0xB9,0x5F,0x1,0xA0,0x0,0x20,0x8,0xE7,0x20,0x82,0xE7,0x20,0x59,0xE7,0x20,0x15,0xE7,0xA4,0xFB,0xA5,0xCE,0xF0,0x5,0x59,0x37,0x1,0x10,0x12,0xB9,0x3F,0x1,0x85,0xDC,0xB9,0x47,0x1,0x85,0xDD,0xBE,0x4F,0x1,0xB9,0x57,0x1,0xD0,0x87,0xC6,0xFB,0x60,0xA0,0x54,0xA5,0xFB,0xC9,0x8,0xF0,0x9A,0xE6,0xFB,0xA8,0xB5,0x50,0x99,0x20,0x1,0xB5,0x78,0x99,0x28,0x1,0x60,0x20,0x15,0xE7,0xA4,0xFB,0xA5,0xCE,0x99,0x5F,0x1,0xA5,0xCF,0x99,0x67,0x1,0xA9,0x1,0x99,0x2F,0x1,0xA9,0x0,0x99,0x37,0x1,0xA5,0xDC,0x99,0x3F,0x1,0xA5,0xDD,0x99,0x47,0x1,0xA5,0xE0,0x99,0x4F,0x1,0xA5,0xE1,0x99,0x57,0x1,0x60,0x20,0x15,0xE7,0xA4,0xFB,0xA5,0xCE,0x99,0x2F,0x1,0xA5,0xCF,0x4C,0x66,0xE9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xAB,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3F,0x3F,0xC0,0xC0,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x3C,0x30,0xF,0xC0,0xCC,0xFF,0x55,0x0,0xAB,0xAB,0x3,0x3,0xFF,0xFF,0x55,0xFF,0xFF,0x55,0xCF,0xCF,0xCF,0xCF,0xCF,0xFF,0x55,0xC3,0xC3,0xC3,0x55,0xF0,0xF0,0xCF,0x56,0x56,0x56,0x55,0xFF,0xFF,0x55,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0xFF,0xFF,0xFF,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x0,0xAB,0x3,0x57,0x3,0x3,0x3,0x3,0x7,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0xAA,0xFF,0xFF,0xFF,0xFF,0xFF,0x17,0xFF,0xFF,0x19,0x5D,0x35,0x4B,0xF2,0xEC,0x87,0x6F,0xAD,0xB7,0xE2,0xF8,0x54,0x80,0x96,0x85,0x82,0x22,0x10,0x33,0x4A,0x13,0x6,0xB,0x4A,0x1,0x40,0x47,0x7A,0x0,0xFF,0x23,0x9,0x5B,0x16,0xB6,0xCB,0xFF,0xFF,0xFB,0xFF,0xFF,0x24,0xF6,0x4E,0x59,0x50,0x0,0xFF,0x23,0xA3,0x6F,0x36,0x23,0xD7,0x1C,0x22,0xC2,0xAE,0xBA,0x23,0xFF,0xFF,0x21,0x30,0x1E,0x3,0xC4,0x20,0x0,0xC1,0xFF,0xFF,0xFF,0xA0,0x30,0x1E,0xA4,0xD3,0xB6,0xBC,0xAA,0x3A,0x1,0x50,0x7E,0xD8,0xD8,0xA5,0x3C,0xFF,0x16,0x5B,0x28,0x3,0xC4,0x1D,0x0,0xC,0x4E,0x0,0x3E,0x0,0xA6,0xB0,0x0,0xBC,0xC6,0x57,0x8C,0x1,0x27,0xFF,0xFF,0xFF,0xFF,0xFF,0xE8,0xFF,0xFF,0xE8,0xE0,0xE0,0xE0,0xEF,0xEF,0xE3,0xE3,0xE5,0xE5,0xE7,0xE7,0xEE,0xEF,0xEF,0xE7,0xE7,0xE2,0xEF,0xE7,0xE7,0xEC,0xEC,0xEC,0xE7,0xEC,0xEC,0xEC,0xE2,0x0,0xFF,0xE8,0xE1,0xE8,0xE8,0xEF,0xEB,0xFF,0xFF,0xE0,0xFF,0xFF,0xEF,0xEE,0xEF,0xE7,0xE7,0x0,0xFF,0xE8,0xE7,0xE7,0xE7,0xE8,0xE1,0xE2,0xEE,0xEE,0xEE,0xEE,0xE8,0xFF,0xFF,0xE1,0xE1,0xEF,0xEE,0xE7,0xE8,0xEE,0xE7,0xFF,0xFF,0xFF,0xEE,0xE1,0xEF,0xE7,0xE8,0xEF,0xEF,0xEB,0xE9,0xE8,0xE9,0xE9,0xE8,0xE8,0xE8,0xE8,0xFF,0xE8,0xE8,0xE8,0xEE,0xE7,0xE8,0xEF,0xEF,0xEE,0xEF,0xEE,0xEF,0xEE,0xEE,0xEF,0xEE,0xEE,0xEE,0xE1,0xE8,0xE8,0xFF,0xFF,0xFF,0xFF,0xFF,0xBE,0xB3,0xB2,0xB7,0xB6,0x37,0xD4,0xCF,0xCF,0xA0,0xCC,0xCF,0xCE,0x47,0xD3,0xD9,0xCE,0xD4,0xC1,0x58,0xCD,0xC5,0xCD,0xA0,0xC6,0xD5,0xCC,0x4C,0xD4,0xCF,0xCF,0xA0,0xCD,0xC1,0xCE,0xD9,0xA0,0xD0,0xC1,0xD2,0xC5,0xCE,0x53,0xD3,0xD4,0xD2,0xC9,0xCE,0x47,0xCE,0xCF,0xA0,0xC5,0xCE,0x44,0xC2,0xC1,0xC4,0xA0,0xC2,0xD2,0xC1,0xCE,0xC3,0x48,0xBE,0xB8,0xA0,0xC7,0xCF,0xD3,0xD5,0xC2,0x53,0xC2,0xC1,0xC4,0xA0,0xD2,0xC5,0xD4,0xD5,0xD2,0x4E,0xBE,0xB8,0xA0,0xC6,0xCF,0xD2,0x53,0xC2,0xC1,0xC4,0xA0,0xCE,0xC5,0xD8,0x54,0xD3,0xD4,0xCF,0xD0,0xD0,0xC5,0xC4,0xA0,0xC1,0xD4,0x20,0xAA,0xAA,0xAA,0x20,0xA0,0xC5,0xD2,0xD2,0xD,0xBE,0xB2,0xB5,0x35,0xD2,0xC1,0xCE,0xC7,0x45,0xC4,0xC9,0x4D,0xD3,0xD4,0xD2,0xA0,0xCF,0xD6,0xC6,0x4C,0xDC,0xD,0xD2,0xC5,0xD4,0xD9,0xD0,0xC5,0xA0,0xCC,0xC9,0xCE,0xC5,0x8D,0x3F,0x46,0xD9,0x90,0x3,0x4C,0xC3,0xE8,0xA6,0xCF,0x9A,0xA6,0xCE,0xA0,0x8D,0xD0,0x2,0xA0,0x99,0x20,0xC4,0xE3,0x86,0xCE,0xBA,0x86,0xCF,0xA0,0xFE,0x84,0xD9,0xC8,0x84,0xC8,0x20,0x99,0xE2,0x84,0xF1,0xA2,0x20,0xA9,0x30,0x20,0x91,0xE4,0xE6,0xD9,0xA6,0xCE,0xA4,0xC8,0xA,0x85,0xCE,0xC8,0xB9,0x0,0x2,0xC9,0x74,0xF0,0xD2,0x49,0xB0,0xC9,0xA,0xB0,0xF0,0xC8,0xC8,0x84,0xC8,0xB9,0x0,0x2,0x48,0xB9,0xFF,0x1,0xA0,0x0,0x20,0x8,0xE7,0x68,0x95,0xA0,0xA5,0xCE,0xC9,0xC7,0xD0,0x3,0x20,0x6F,0xE7,0x4C,0x1,0xE8,0xFF,0xFF,0xFF,0x50,0x20,0x13,0xEC,0xD0,0x15,0x20,0xB,0xEC,0xD0,0x10,0x20,0x82,0xE7,0x20,0x6F,0xE7,0x50,0x3,0x20,0x82,0xE7,0x20,0x59,0xE7,0x56,0x50,0x4C,0x36,0xE7,0xFF,0xFF,0xC1,0xFF,0x7F,0xD1,0xCC,0xC7,0xCF,0xCE,0xC5,0x9A,0x98,0x8B,0x96,0x95,0x93,0xBF,0xB2,0x32,0x2D,0x2B,0xBC,0xB0,0xAC,0xBE,0x35,0x8E,0x61,0xFF,0xFF,0xFF,0xDD,0xFB,0x20,0xC9,0xEF,0x15,0x4F,0x10,0x5,0x20,0xC9,0xEF,0x35,0x4F,0x95,0x50,0x10,0xCB,0x4C,0xC9,0xEF,0x40,0x60,0x8D,0x60,0x8B,0x0,0x7E,0x8C,0x33,0x0,0x0,0x60,0x3,0xBF,0x12,0x0,0x40,0x89,0xC9,0x47,0x9D,0x17,0x68,0x9D,0xA,0x0,0x40,0x60,0x8D,0x60,0x8B,0x0,0x7E,0x8C,0x3C,0x0,0x0,0x60,0x3,0xBF,0x1B,0x4B,0x67,0xB4,0xA1,0x7,0x8C,0x7,0xAE,0xA9,0xAC,0xA8,0x67,0x8C,0x7,0xB4,0xAF,0xAC,0xB0,0x67,0x9D,0xB2,0xAF,0xAC,0xAF,0xA3,0x67,0x8C,0x7,0xA5,0xAB,0xAF,0xB0,0xF4,0xAE,0xA9,0xB2,0xB0,0x7F,0xE,0x27,0xB4,0xAE,0xA9,0xB2,0xB0,0x7F,0xE,0x28,0xB4,0xAE,0xA9,0xB2,0xB0,0x64,0x7,0xA6,0xA9,0x67,0xAF,0xB4,0xAF,0xA7,0x78,0xB4,0xA5,0xAC,0x78,0x7F,0x2,0xAD,0xA5,0xB2,0x67,0xA2,0xB5,0xB3,0xAF,0xA7,0xEE,0xB2,0xB5,0xB4,0xA5,0xB2,0x7E,0x8C,0x39,0xB4,0xB8,0xA5,0xAE,0x67,0xB0,0xA5,0xB4,0xB3,0x27,0xAF,0xB4,0x7,0x9D,0x19,0xB2,0xAF,0xA6,0x7F,0x5,0x37,0xB4,0xB5,0xB0,0xAE,0xA9,0x7F,0x5,0x28,0xB4,0xB5,0xB0,0xAE,0xA9,0x7F,0x5,0x2A,0xB4,0xB5,0xB0,0xAE,0xA9,0xE4,0xAE,0xA5,0x0,0xFF,0xFF,0x47,0xA2,0xA1,0xB4,0x7F,0xD,0x30,0xAD,0xA9,0xA4,0x7F,0xD,0x23,0xAD,0xA9,0xA4,0x67,0xAC,0xAC,0xA1,0xA3,0x0,0x40,0x80,0xC0,0xC1,0x80,0x0,0x47,0x8C,0x68,0x8C,0xDB,0x67,0x9B,0x68,0x9B,0x50,0x8C,0x63,0x8C,0x7F,0x1,0x51,0x7,0x88,0x29,0x84,0x80,0xC4,0x80,0x57,0x71,0x7,0x88,0x14,0xED,0xA5,0xAD,0xAF,0xAC,0xED,0xA5,0xAD,0xA9,0xA8,0xF2,0xAF,0xAC,0xAF,0xA3,0x71,0x8,0x88,0xAE,0xA5,0xAC,0x68,0x83,0x8,0x68,0x9D,0x8,0x71,0x7,0x88,0x60,0x76,0xB4,0xAF,0xAE,0x76,0x8D,0x76,0x8B,0x51,0x7,0x88,0x19,0xB8,0xA4,0xAE,0xB2,0xF2,0xB3,0xB5,0xF3,0xA2,0xA1,0xEE,0xA7,0xB3,0xE4,0xAE,0xB2,0xEB,0xA5,0xA5,0xB0,0x51,0x7,0x88,0x39,0x81,0xC1,0x4F,0x7F,0xF,0x2F,0x0,0x51,0x6,0x88,0x29,0xC2,0xC,0x82,0x57,0x8C,0x6A,0x8C,0x42,0xAE,0xA5,0xA8,0xB4,0x60,0xAE,0xA5,0xA8,0xB4,0x4F,0x7E,0x1E,0x35,0x8C,0x27,0x51,0x7,0x88,0x9,0x8B,0xFE,0xE4,0xAF,0xAD,0xF2,0xAF,0xE4,0xAE,0xA1,0xDC,0xDE,0x9C,0xDD,0x9C,0xDE,0xDD,0x9E,0xC3,0xDD,0xCF,0xCA,0xCD,0xCB,0x0,0x47,0x9D,0xAD,0xA5,0xAD,0xAF,0xAC,0x76,0x9D,0xAD,0xA5,0xAD,0xA9,0xA8,0xE6,0xA6,0xAF,0x60,0x8C,0x20,0xAF,0xB4,0xB5,0xA1,0xF2,0xAC,0xA3,0xF2,0xA3,0xB3,0x60,0x8C,0x20,0xAC,0xA5,0xA4,0xEE,0xB5,0xB2,0x60,0xAE,0xB5,0xB2,0xF4,0xB3,0xA9,0xAC,0x60,0x8C,0x20,0xB4,0xB3,0xA9,0xAC,0x7A,0x7E,0x9A,0x22,0x20,0x0,0x60,0x3,0xBF,0x60,0x3,0xBF,0x1F,0x20,0xB1,0xE7,0xE8,0xE8,0xB5,0x4F,0x85,0xDA,0xB5,0x77,0x85,0xDB,0xB4,0x4E,0x98,0xD5,0x76,0xB0,0x9,0xB1,0xDA,0x20,0xC9,0xE3,0xC8,0x4C,0xF,0xEE,0xA9,0xFF,0x85,0xD5,0x60,0xE8,0xA9,0x0,0x95,0x78,0x95,0xA0,0xB5,0x77,0x38,0xF5,0x4F,0x95,0x50,0x4C,0x23,0xE8,0xFF,0x20,0x15,0xE7,0xA5,0xCF,0xD0,0x28,0xA5,0xCE,0x60,0x20,0x34,0xEE,0xA4,0xC8,0xC9,0x30,0xB0,0x21,0xC0,0x28,0xB0,0x1D,0x60,0xEA,0xEA,0x20,0x34,0xEE,0x60,0xEA,0x8A,0xA2,0x1,0xB4,0xCE,0x94,0x4C,0xB4,0x48,0x94,0xCA,0xCA,0xF0,0xF5,0xAA,0x60,0xA0,0x77,0x4C,0xE0,0xE3,0xA0,0x7B,0xD0,0xF9,0x20,0x54,0xE2,0xA5,0xDA,0xD0,0x7,0xA5,0xDB,0xD0,0x3,0x4C,0x7E,0xE7,0x6,0xCE,0x26,0xCF,0x26,0xE6,0x26,0xE7,0xA5,0xE6,0xC5,0xDA,0xA5,0xE7,0xE5,0xDB,0x90,0xA,0x85,0xE7,0xA5,0xE6,0xE5,0xDA,0x85,0xE6,0xE6,0xCE,0x88,0xD0,0xE1,0x60,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x20,0x15,0xE7,0x6C,0xCE,0x0,0xA5,0x4C,0xD0,0x2,0xC6,0x4D,0xC6,0x4C,0xA5,0x48,0xD0,0x2,0xC6,0x49,0xC6,0x48,0xA0,0x0,0xB1,0x4C,0x91,0x48,0xA5,0xCA,0xC5,0x4C,0xA5,0xCB,0xE5,0x4D,0x90,0xE0,0x4C,0x53,0xEE,0xC9,0x28,0xB0,0x9B,0xA8,0xA5,0xC8,0x60,0xEA,0xEA,0x98,0xAA,0xA0,0x6E,0x20,0xC4,0xE3,0x8A,0xA8,0x20,0xC4,0xE3,0xA0,0x72,0x4C,0xC4,0xE3,0x20,0x15,0xE7,0x6,0xCE,0x26,0xCF,0x30,0xFA,0xB0,0xDC,0xD0,0x4,0xC5,0xCE,0xB0,0xD6,0x60,0x20,0x15,0xE7,0xB1,0xCE,0x94,0x9F,0x4C,0x8,0xE7,0x20,0x34,0xEE,0xA5,0xCE,0x48,0x20,0x15,0xE7,0x68,0x91,0xCE,0x60,0xFF,0xFF,0xFF,0x20,0x6C,0xEE,0xA5,0xCE,0x85,0xE6,0xA5,0xCF,0x85,0xE7,0x4C,0x44,0xE2,0x20,0xE4,0xEE,0x4C,0x34,0xE1,0x20,0xE4,0xEE,0xB4,0x78,0xB5,0x50,0x69,0xFE,0xB0,0x1,0x88,0x85,0xDA,0x84,0xDB,0x18,0x65,0xCE,0x95,0x50,0x98,0x65,0xCF,0x95,0x78,0xA0,0x0,0xB5,0x50,0xD1,0xDA,0xC8,0xB5,0x78,0xF1,0xDA,0xB0,0x80,0x4C,0x23,0xE8,0x20,0x15,0xE7,0xA5,0x4E,0x20,0x8,0xE7,0xA5,0x4F,0xD0,0x4,0xC5,0x4E,0x69,0x0,0x29,0x7F,0x85,0x4F,0x95,0xA0,0xA0,0x11,0xA5,0x4F,0xA,0x18,0x69,0x40,0xA,0x26,0x4E,0x26,0x4F,0x88,0xD0,0xF2,0xA5,0xCE,0x20,0x8,0xE7,0xA5,0xCF,0x95,0xA0,0x4C,0x7A,0xE2,0x20,0x15,0xE7,0xA4,0xCE,0xC4,0x4C,0xA5,0xCF,0xE5,0x4D,0x90,0x1F,0x84,0x48,0xA5,0xCF,0x85,0x49,0x4C,0xB6,0xEE,0x20,0x15,0xE7,0xA4,0xCE,0xC4,0xCA,0xA5,0xCF,0xE5,0xCB,0xB0,0x9,0x84,0x4A,0xA5,0xCF,0x85,0x4B,0x4C,0xB7,0xE5,0x4C,0xCB,0xEE,0xEA,0xEA,0xEA,0xEA,0x20,0xC9,0xEF,0x20,0x71,0xE1,0x4C,0xBF,0xEF,0x20,0x3,0xEE,0xA9,0xFF,0x85,0xC8,0xA9,0x74,0x8D,0x0,0x2,0x60,0x20,0x36,0xE7,0xE8,0x20,0x36,0xE7,0xB5,0x50,0x60,0xA9,0x0,0x85,0x4A,0x85,0x4C,0xA9,0x8,0x85,0x4B,0xA9,0x10,0x85,0x4D,0x4C,0xAD,0xE5,0xD5,0x78,0xD0,0x1,0x18,0x4C,0x2,0xE1,0x20,0xB7,0xE5,0x4C,0x36,0xE8,0x20,0xB7,0xE5,0x4C,0x5B,0xE8,0xE0,0x80,0xD0,0x1,0x88,0x4C,0xC,0xE0 };
// ------------------------------------------------------------------------------
// ------------------------------------------------------------------------------
// Setup Teensy 4.1 IO's
//
void setup() {
pinMode(PIN_CLK0, INPUT);
pinMode(PIN_RESET, INPUT);
pinMode(PIN_READY_n, INPUT);
pinMode(PIN_IRQ, INPUT);
pinMode(PIN_NMI, INPUT);
pinMode(PIN_RDWR_n, OUTPUT);
pinMode(PIN_SYNC, OUTPUT);
pinMode(PIN_ADDR0, OUTPUT);
pinMode(PIN_ADDR1, OUTPUT);
pinMode(PIN_ADDR2, OUTPUT);
pinMode(PIN_ADDR3, OUTPUT);
pinMode(PIN_ADDR4, OUTPUT);
pinMode(PIN_ADDR5, OUTPUT);
pinMode(PIN_ADDR6, OUTPUT);
pinMode(PIN_ADDR7, OUTPUT);
pinMode(PIN_ADDR8, OUTPUT);
pinMode(PIN_ADDR9, OUTPUT);
pinMode(PIN_ADDR10, OUTPUT);
pinMode(PIN_ADDR11, OUTPUT);
pinMode(PIN_ADDR12, OUTPUT);
pinMode(PIN_ADDR13, OUTPUT);
pinMode(PIN_ADDR14, OUTPUT);
pinMode(PIN_ADDR15, OUTPUT);
pinMode(PIN_DATAIN0, INPUT);
pinMode(PIN_DATAIN1, INPUT);
pinMode(PIN_DATAIN2, INPUT);
pinMode(PIN_DATAIN3, INPUT);
pinMode(PIN_DATAIN4, INPUT);
pinMode(PIN_DATAIN5, INPUT);
pinMode(PIN_DATAIN6, INPUT);
pinMode(PIN_DATAIN7, INPUT);
pinMode(PIN_DATAOUT0, OUTPUT);
pinMode(PIN_DATAOUT1, OUTPUT);
pinMode(PIN_DATAOUT2, OUTPUT);
pinMode(PIN_DATAOUT3, OUTPUT);
pinMode(PIN_DATAOUT4, OUTPUT);
pinMode(PIN_DATAOUT5, OUTPUT);
pinMode(PIN_DATAOUT6, OUTPUT);
pinMode(PIN_DATAOUT7, OUTPUT);
pinMode(PIN_DATAOUT_OE_n, OUTPUT);
Serial.begin(9600);
// Copy PROM contents into the Teensy's internal RAM
//
for (uint16_t u=0; u<=0xFF ; u++) { internal_RAM[0xFF00+u] = Apple1_PROM[u]; }
// Copy BASIC into the Teensy's internal RAM
//
for (uint16_t u=0; u<=4096 ; u++) { internal_RAM[0xE000+u] = BASIC_ROM[u]; }
}
// --------------------------------------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------
//
// Begin Apple 1 Keyboard and Video translation
//
// --------------------------------------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------
void Apple1_Redraw_Screen() {
uint16_t i=0;
uint16_t y=0;
Apple1_Force_Physical=1;
for (i=0 ; i<=39 ; i++) { write_byte( 0x0400+i , Apple1_Video_Array[y] ); y++; }
for (i=0 ; i<=39 ; i++) { write_byte( 0x0480+i , Apple1_Video_Array[y] ); y++; }
for (i=0 ; i<=39 ; i++) { write_byte( 0x0500+i , Apple1_Video_Array[y] ); y++; }
for (i=0 ; i<=39 ; i++) { write_byte( 0x0580+i , Apple1_Video_Array[y] ); y++; }
for (i=0 ; i<=39 ; i++) { write_byte( 0x0600+i , Apple1_Video_Array[y] ); y++; }
for (i=0 ; i<=39 ; i++) { write_byte( 0x0680+i , Apple1_Video_Array[y] ); y++; }
for (i=0 ; i<=39 ; i++) { write_byte( 0x0700+i , Apple1_Video_Array[y] ); y++; }
for (i=0 ; i<=39 ; i++) { write_byte( 0x0780+i , Apple1_Video_Array[y] ); y++; }
for (i=0 ; i<=39 ; i++) { write_byte( 0x0428+i , Apple1_Video_Array[y] ); y++; }
for (i=0 ; i<=39 ; i++) { write_byte( 0x04A8+i , Apple1_Video_Array[y] ); y++; }
for (i=0 ; i<=39 ; i++) { write_byte( 0x0528+i , Apple1_Video_Array[y] ); y++; }
for (i=0 ; i<=39 ; i++) { write_byte( 0x05a8+i , Apple1_Video_Array[y] ); y++; }
for (i=0 ; i<=39 ; i++) { write_byte( 0x0628+i , Apple1_Video_Array[y] ); y++; }
for (i=0 ; i<=39 ; i++) { write_byte( 0x06a8+i , Apple1_Video_Array[y] ); y++; }
for (i=0 ; i<=39 ; i++) { write_byte( 0x0728+i , Apple1_Video_Array[y] ); y++; }
for (i=0 ; i<=39 ; i++) { write_byte( 0x07a8+i , Apple1_Video_Array[y] ); y++; }
for (i=0 ; i<=39 ; i++) { write_byte( 0x0450+i , Apple1_Video_Array[y] ); y++; }
for (i=0 ; i<=39 ; i++) { write_byte( 0x04d0+i , Apple1_Video_Array[y] ); y++; }
for (i=0 ; i<=39 ; i++) { write_byte( 0x0550+i , Apple1_Video_Array[y] ); y++; }
for (i=0 ; i<=39 ; i++) { write_byte( 0x05d0+i , Apple1_Video_Array[y] ); y++; }
for (i=0 ; i<=39 ; i++) { write_byte( 0x0650+i , Apple1_Video_Array[y] ); y++; }
for (i=0 ; i<=39 ; i++) { write_byte( 0x06d0+i , Apple1_Video_Array[y] ); y++; }
for (i=0 ; i<=39 ; i++) { write_byte( 0x0750+i , Apple1_Video_Array[y] ); y++; }
for (i=0 ; i<=39 ; i++) { write_byte( 0x07D0+i , Apple1_Video_Array[y] ); y++; }
Apple1_Force_Physical=0;
return;
}
void Apple1_Clear_Screen() {
for (uint16_t x=0; x<=959; x++) { Apple1_Video_Array[x]=0xA0; } // Fill with spaces
Apple1_Video_Array_Index=0;
Apple1_Video_Array[0]=0x40; // Place cursor @
Apple1_Redraw_Screen();
return;
}
void Apple1_Scroll_Screen() {
for (uint16_t x=0; x<=919; x++) { Apple1_Video_Array[x] = Apple1_Video_Array[x+40]; }
for (uint16_t x=920; x<=959; x++) { Apple1_Video_Array[x] = 0xA0; } // Clear to end of row
Apple1_Video_Array_Index=920;
Apple1_Video_Array[920]=0x40; // Place cursor @
Apple1_Redraw_Screen();
return;
}
void Apple1_Putchar(uint8_t local_char) {
//Serial.println(local_char,HEX);
// Carriage Return
//
if (local_char==0x0D) {
Apple1_Video_Array[Apple1_Video_Array_Index]=0xA0; // Remove old cursor @
Apple1_Video_Array_Index = Apple1_Video_Next_Row_Array[Apple1_Video_Array_Index];
if (Apple1_Video_Array_Index==960) Apple1_Scroll_Screen();
Apple1_Video_Array[Apple1_Video_Array_Index]=0x40; // Place new cursor @
Apple1_Redraw_Screen();
}
else {
// Place character in current cursor slot
//
local_char = local_char & 0x3F; local_char = local_char | 0x80; // Force character to Apple II non-inverted and non-blinking
Apple1_Video_Array[Apple1_Video_Array_Index] = local_char;
Apple1_Video_Array_Index++;
// Place cursor in next slot if not at end of screen
//
if (Apple1_Video_Array_Index!=960) {
Apple1_Video_Array[Apple1_Video_Array_Index]=0x40; // Place cursor @
Apple1_Redraw_Screen();
}
// Else scroll the screen
//
else {
Apple1_Scroll_Screen();
}
}
return;
}
// --------------------------------------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------
//
// End Apple 1 Keyboard and Video translation
//
// --------------------------------------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------
//
// Begin 6502 Bus Interface Unit
//
// --------------------------------------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------
// ----------------------------------------------------------
// Address range check
// Return: 0x0 - All exernal memory accesses
// 0x1 - Reads use cycle accurate internal memory and writes pass through to motherboard
// 0x2 - Reads accelerated using internal memory and writes pass through to motherboard
// 0x3 - All read and write accesses use accelerated internal memory
// ----------------------------------------------------------
inline uint8_t internal_address_check(int32_t local_address) {
if ( (local_address>=0x0000) && (local_address <=0x0FFF)) return mode; // Apple I DRAM Bank 0 - 4 KB
if ( (local_address>=0xD000) && (local_address <=0xDFFF)) return mode; // Apple I PIA for Terminal Access
if ( (local_address>=0xE000) && (local_address <=0xEFFF)) return mode; // Apple I DRAM Bank 1 - 4 KB
if ( (local_address>=0xFF00) && (local_address <=0xFFFF)) return mode; // Apple I PROM - 256 Bytes
return 0x0;
}
// -------------------------------------------------
// Wait for the CLK1 rising edge and sample signals
// -------------------------------------------------
inline void wait_for_CLK_rising_edge() {
register uint32_t GPIO6_data=0;
register uint32_t GPIO6_data_d1=0;
uint32_t d10, d2, d3, d4, d5, d76;
while (((GPIO6_DR >> 12) & 0x1)!=0) {} // Teensy 4.1 Pin-24 GPIO6_DR[12] CLK
//while (((GPIO6_DR >> 12) & 0x1)==0) {GPIO6_data=GPIO6_DR;} // This method is ok for VIC-20 and Apple-II+ non-DRAM ranges
do { GPIO6_data_d1=GPIO6_DR; } while (((GPIO6_data_d1 >> 12) & 0x1)==0); // This method needed to support Apple-II+ DRAM read data setup time
GPIO6_data=GPIO6_data_d1;
d10 = (GPIO6_data&0x000C0000) >> 18; // Teensy 4.1 Pin-14 GPIO6_DR[19:18] D1:D0
d2 = (GPIO6_data&0x00800000) >> 21; // Teensy 4.1 Pin-16 GPIO6_DR[23] D2
d3 = (GPIO6_data&0x00400000) >> 19; // Teensy 4.1 Pin-17 GPIO6_DR[22] D3
d4 = (GPIO6_data&0x00020000) >> 13; // Teensy 4.1 Pin-18 GPIO6_DR[17] D4
d5 = (GPIO6_data&0x00010000) >> 11; // Teensy 4.1 Pin-19 GPIO6_DR[16] D5
d76 = (GPIO6_data&0x0C000000) >> 20; // Teensy 4.1 Pin-20 GPIO6_DR[27:26] D7:D6
direct_irq = (GPIO6_data&0x00002000) >> 13; // Teensy 4.1 Pin-25 GPIO6_DR[13] IRQ
direct_ready_n = (GPIO6_data&0x40000000) >> 30; // Teensy 4.1 Pin-26 GPIO6_DR[30] READY
direct_reset = (GPIO6_data&0x00100000) >> 20; // Teensy 4.1 Pin-40 GPIO6_DR[20] RESET
direct_nmi = (GPIO6_data&0x00200000) >> 21; // Teensy 4.1 Pin-41 GPIO6_DR[21] NMI
direct_datain = d76 | d5 | d4 | d3 | d2 | d10;
return;
}
// -------------------------------------------------
// Wait for the CLK1 falling edge
// -------------------------------------------------
inline void wait_for_CLK_falling_edge() {
while (((GPIO6_DR >> 12) & 0x1)==0) {} // Teensy 4.1 Pin-24 GPIO6_DR[12] CLK
while (((GPIO6_DR >> 12) & 0x1)!=0) {}
return;
}
// -------------------------------------------------
// Drive the 6502 Address pins
// -------------------------------------------------
inline void send_address(uint32_t local_address) {
register uint32_t writeback_data=0;
writeback_data = (0x6DFFFFF3 & GPIO6_DR); // Read in current GPIOx register value and clear the bits we intend to update
writeback_data = writeback_data | (local_address & 0x8000)<<10 ; // 6502_Address[15] TEENSY_PIN23 GPIO6_DR[25]
writeback_data = writeback_data | (local_address & 0x2000)>>10 ; // 6502_Address[13] TEENSY_PIN0 GPIO6_DR[3]
writeback_data = writeback_data | (local_address & 0x1000)>>10 ; // 6502_Address[12] TEENSY_PIN1 GPIO6_DR[2]
writeback_data = writeback_data | (local_address & 0x0002)<<27 ; // 6502_Address[1] TEENSY_PIN38 GPIO6_DR[28]
GPIO6_DR = writeback_data | (local_address & 0x0001)<<31 ; // 6502_Address[0] TEENSY_PIN27 GPIO6_DR[31]
writeback_data = (0xCFF3EFFF & GPIO7_DR); // Read in current GPIOx register value and clear the bits we intend to update
writeback_data = writeback_data | (local_address & 0x0400)<<2 ; // 6502_Address[10] TEENSY_PIN32 GPIO7_DR[12]
writeback_data = writeback_data | (local_address & 0x0200)<<20 ; // 6502_Address[9] TEENSY_PIN34 GPIO7_DR[29]
writeback_data = writeback_data | (local_address & 0x0080)<<21 ; // 6502_Address[7] TEENSY_PIN35 GPIO7_DR[28]
writeback_data = writeback_data | (local_address & 0x0020)<<13 ; // 6502_Address[5] TEENSY_PIN36 GPIO7_DR[18]
GPIO7_DR = writeback_data | (local_address & 0x0008)<<16 ; // 6502_Address[3] TEENSY_PIN37 GPIO7_DR[19]
writeback_data = (0xFF3BFFFF & GPIO8_DR); // Read in current GPIOx register value and clear the bits we intend to update
writeback_data = writeback_data | (local_address & 0x0100)<<14 ; // 6502_Address[8] TEENSY_PIN31 GPIO8_DR[22]
writeback_data = writeback_data | (local_address & 0x0040)<<17 ; // 6502_Address[6] TEENSY_PIN30 GPIO8_DR[23]
GPIO8_DR = writeback_data | (local_address & 0x0004)<<16 ; // 6502_Address[2] TEENSY_PIN28 GPIO8_DR[18]
writeback_data = (0x7FFFFF6F & GPIO9_DR); // Read in current GPIOx register value and clear the bits we intend to update
writeback_data = writeback_data | (local_address & 0x4000)>>10 ; // 6502_Address[14] TEENSY_PIN2 GPIO9_DR[4]
writeback_data = writeback_data | (local_address & 0x0800)>>4 ; // 6502_Address[11] TEENSY_PIN33 GPIO9_DR[7]
GPIO9_DR = writeback_data | (local_address & 0x0010)<<27 ; // 6502_Address[4] TEENSY_PIN29 GPIO9_DR[31]
return;
}
// -------------------------------------------------
// Send the address for a read cyle
// -------------------------------------------------
inline void start_read(uint32_t local_address) {
current_address = local_address;
if (internal_address_check(current_address)>0x1) {
//last_access_internal_RAM=1;
}
else
{
if (last_access_internal_RAM==1) wait_for_CLK_rising_edge();
last_access_internal_RAM=0;
digitalWriteFast(PIN_RDWR_n, 0x1);
digitalWriteFast(PIN_SYNC, assert_sync);
send_address(local_address);
}
return;
}
// -------------------------------------------------
// On the rising CLK edge, read in the data
// -------------------------------------------------
inline uint8_t finish_read_byte() {
if (internal_address_check(current_address)>0x1) {
last_access_internal_RAM=1;
return internal_RAM[current_address];
}
else
{
if (last_access_internal_RAM==1) wait_for_CLK_rising_edge();
last_access_internal_RAM=0;
digitalWriteFast(PIN_SYNC, 0x0);
do { wait_for_CLK_rising_edge(); } while (direct_ready_n == 0x1); // Delay a clock cycle until ready is active
if (internal_address_check(current_address)>0x0) { return internal_RAM[current_address]; }
else { return direct_datain; }
}
}
// -------------------------------------------------
// Full read cycle with address and data read in
// -------------------------------------------------
inline uint8_t read_byte(uint16_t local_address) {
uint8_t return_data;
int incomingByte;
// Apple 1 terminal input from Teensy UART
//
if ( (internal_RAM[0xD011]==0x00) && Serial.available() ) {
incomingByte = Serial.read();
internal_RAM[0xD010] = (0x80 | incomingByte ); // Force bit[7] to '1' like Apple 1
internal_RAM[0xD011] = 0x80; // Set bit[7] to '1' to indicate a new keypress available
//Serial.write(incomingByte);
}
// Redirect Apple I accesses to cassette addresses to those on the Apple II motherboard
//
if (local_address==0xC081) local_address = 0xC060;
if (internal_address_check(local_address)>0x1) {
last_access_internal_RAM=1;
return internal_RAM[local_address];
}
else
{
if (last_access_internal_RAM==1) wait_for_CLK_rising_edge();
last_access_internal_RAM=0;
start_read(local_address);
do { wait_for_CLK_rising_edge(); } while (direct_ready_n == 0x1); // Delay a clock cycle until ready is active
if (internal_address_check(current_address)>0x0) { return_data = internal_RAM[current_address]; }
else { return_data = direct_datain; }
}
// Apple 1 terminal input from Teensy UART
//
if (local_address==0xD011) internal_RAM[0xD011] = 0x00; // Debounce bit[7] when KBDCR is read by Monitor
return return_data;
}
// -------------------------------------------------
// Full write cycle with address and data written
// -------------------------------------------------
inline void write_byte(uint16_t local_address , uint8_t local_write_data) {
// Always mirror writes to internal RAM
//
if ( (local_address < 0xF000) && (Apple1_Force_Physical==0) ) internal_RAM[local_address] = local_write_data;
// Apple 1 terminal output to Teensy UART
//
if (local_address == 0xD012) {
Serial.write(0x7F&local_write_data);
internal_RAM[0xD012] = 0x00; // Set bit[7] to 0 to indicate display ready for another charater
if ((local_write_data!=0x7F) && (local_write_data!=0x00)) Apple1_Putchar(0x7F&local_write_data);
}
// Internal RAM
//
if (internal_address_check(local_address)>0x2) {
last_access_internal_RAM=1;
}
else
{
if (last_access_internal_RAM==1) wait_for_CLK_rising_edge();
last_access_internal_RAM=0;
digitalWriteFast(PIN_RDWR_n, 0x0);
digitalWriteFast(PIN_SYNC, 0x0);
send_address(local_address);
// Drive the data bus pins from the Teensy to the bus driver which is inactive
//
digitalWriteFast(PIN_DATAOUT0, (local_write_data & 0x01) );
digitalWriteFast(PIN_DATAOUT1, (local_write_data & 0x02)>>1 );
digitalWriteFast(PIN_DATAOUT2, (local_write_data & 0x04)>>2 );
digitalWriteFast(PIN_DATAOUT3, (local_write_data & 0x08)>>3 );
digitalWriteFast(PIN_DATAOUT4, (local_write_data & 0x10)>>4 );
digitalWriteFast(PIN_DATAOUT5, (local_write_data & 0x20)>>5 );
digitalWriteFast(PIN_DATAOUT6, (local_write_data & 0x40)>>6 );
digitalWriteFast(PIN_DATAOUT7, (local_write_data & 0x80)>>7 );
// During the second CLK phase, enable the data bus output drivers
//
wait_for_CLK_falling_edge();
digitalWriteFast(PIN_DATAOUT_OE_n, 0x0 );
wait_for_CLK_rising_edge();
digitalWriteFast(PIN_DATAOUT_OE_n, 0x1 );
}
return;
}
// --------------------------------------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------
//
// End 6502 Bus Interface Unit
//
// --------------------------------------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------
void push(uint8_t push_data) {
write_byte(register_sp_fixed, push_data);
register_sp = register_sp - 1;
return;
}
uint8_t pop() {
uint8_t temp=0;
register_sp = register_sp + 1;
temp = read_byte(register_sp_fixed);
return temp;
}
void Calc_Flags_NEGATIVE_ZERO(uint8_t local_data) {
if (0x80&local_data) register_flags = register_flags | 0x80; // Set the N flag
else register_flags = register_flags & 0x7F; // Clear the N flag
if (local_data==0) register_flags = register_flags | 0x02; // Set the Z flag
else register_flags = register_flags & 0xFD; // Clear the Z flag
return;
}
uint16_t Sign_Extend16(uint16_t reg_data) {
if ((reg_data&0x0080)== 0x0080) { return (reg_data | 0xFF00); }
else { return (reg_data & 0x00FF); }
}
void Begin_Fetch_Next_Opcode() {
register_pc++;
assert_sync=1;
start_read(register_pc);
return;
}
// -------------------------------------------------
// Addressing Modes
// -------------------------------------------------
uint8_t Fetch_Immediate() {
register_pc++;
return read_byte(register_pc);
}
uint8_t Fetch_ZeroPage() {
effective_address = Fetch_Immediate();
return read_byte(effective_address);
}
uint8_t Fetch_ZeroPage_X() {
uint16_t bal;
bal = Fetch_Immediate();
read_byte(register_pc+1);
effective_address = (0x00FF & (bal + register_x));
return read_byte(effective_address);
}
uint8_t Fetch_ZeroPage_Y() {
uint16_t bal;
bal = Fetch_Immediate();
read_byte(register_pc+1);
effective_address = (0x00FF & (bal + register_y));
return read_byte(effective_address);
}
uint16_t Calculate_Absolute() {
uint16_t adl, adh;
adl = Fetch_Immediate();
adh = Fetch_Immediate()<<8;
effective_address = adl + adh;
return effective_address;
}
uint8_t Fetch_Absolute() {
uint16_t adl, adh;
adl = Fetch_Immediate();
adh = Fetch_Immediate()<<8;
effective_address = adl + adh;
return read_byte(effective_address);
}
uint8_t Fetch_Absolute_X(uint8_t page_cross_check) {
uint16_t bal, bah;
uint8_t local_data;
bal = Fetch_Immediate();
bah = Fetch_Immediate()<<8;
effective_address = bah + bal + register_x;
local_data = read_byte(effective_address );
if ( page_cross_check==1 && ( (0xFF00&effective_address) != (0xFF00&bah) ) ) {
local_data = read_byte(effective_address );
}
return local_data;
}
uint8_t Fetch_Absolute_Y(uint8_t page_cross_check) {
uint16_t bal, bah;
uint8_t local_data;
bal = Fetch_Immediate();
bah = Fetch_Immediate()<<8;
effective_address = bah + bal + register_y;
local_data = read_byte(effective_address );
if ( page_cross_check==1 && ( (0xFF00&effective_address) != (0xFF00&bah) ) ) {
local_data = read_byte(effective_address );
}
return local_data;
}
uint8_t Fetch_Indexed_Indirect_X() {
uint16_t bal;
uint16_t adl, adh;
uint8_t local_data;
bal = Fetch_Immediate() + register_x;
read_byte(bal);
adl = read_byte(0xFF&bal);
adh = read_byte(0xFF&(bal+1)) << 8;
effective_address = adh + adl ;
local_data = read_byte(effective_address);
return local_data;
}
uint8_t Fetch_Indexed_Indirect_Y(uint8_t page_cross_check) {
uint16_t ial, bah, bal;
uint8_t local_data;
ial = Fetch_Immediate();
bal = read_byte(0xFF&ial);
bah = read_byte(0xFF&(ial+1)) << 8;
effective_address = bah + bal + register_y;
local_data = read_byte(effective_address);
if ( page_cross_check==1 && ((0xFF00&effective_address) != (0xFF00&bah)) ) {
local_data = read_byte(effective_address);
}
return local_data;
}
void Write_ZeroPage(uint8_t local_data) {
effective_address = Fetch_Immediate();
write_byte(effective_address , local_data);
return;
}
void Write_Absolute(uint8_t local_data) {
effective_address = Fetch_Immediate();
effective_address = (Fetch_Immediate() << 8) + effective_address;
write_byte(effective_address , local_data );
return;
}
void Write_ZeroPage_X(uint8_t local_data) {
effective_address = Fetch_Immediate();
read_byte(effective_address);
write_byte( (0x00FF&(effective_address + register_x)) , local_data );
return;
}
void Write_ZeroPage_Y(uint8_t local_data) {
effective_address = Fetch_Immediate();
read_byte(effective_address);
write_byte( (0x00FF&(effective_address + register_y)) , local_data );
return;
}
void Write_Absolute_X(uint8_t local_data) {
uint16_t bal,bah;
bal = Fetch_Immediate();
bah = Fetch_Immediate()<<8;
effective_address = bal + bah + register_x;
read_byte(effective_address);
write_byte(effective_address , local_data );
return;
}
void Write_Absolute_Y(uint8_t local_data) {
uint16_t bal,bah;
bal = Fetch_Immediate();
bah = Fetch_Immediate()<<8;
effective_address = bal + bah + register_y;
read_byte(effective_address);
if ( (0xFF00&effective_address) != (0xFF00&bah) ) {
read_byte(effective_address);
}
write_byte(effective_address , local_data );
return;
}
void Write_Indexed_Indirect_X(uint8_t local_data) {
uint16_t bal;
uint16_t adl, adh;
bal = Fetch_Immediate();
read_byte(bal);
adl = read_byte(0xFF&(bal+register_x));
adh = read_byte(0xFF&(bal+register_x+1)) << 8;
effective_address = adh + adl;
write_byte(effective_address , local_data );
return;
}
void Write_Indexed_Indirect_Y(uint8_t local_data) {
uint16_t ial;
uint16_t bal, bah;
ial = Fetch_Immediate();
bal = read_byte(ial);
bah = read_byte(ial+1)<<8;
effective_address = bah + bal + register_y;
read_byte(effective_address);
write_byte(effective_address , local_data );
return;
}
void Double_WriteBack(uint8_t local_data) {
write_byte(effective_address , local_data);
write_byte(effective_address , local_data);
return;
}
// -------------------------------------------------
// Reset sequence for the 6502
// -------------------------------------------------
void reset_sequence() {
uint16_t temp1, temp2;
Apple1_Clear_Screen();
while (digitalReadFast(PIN_RESET)!=0) {} // Stay here until RESET deasserts
digitalWriteFast(PIN_RDWR_n, 0x1);
digitalWriteFast(PIN_DATAOUT_OE_n, 0x1 );
temp1 = read_byte(register_pc); // Address ??
temp1 = read_byte(register_pc+1); // Address ?? + 1
temp1 = read_byte(register_sp_fixed); // Address SP
temp1 = read_byte(register_sp_fixed-1); // Address SP - 1
temp1 = read_byte(register_sp_fixed-2); // Address SP - 2
temp1 = read_byte(0xFFFC); // Fetch Vector PCL
temp2 = read_byte(0xFFFD); // Fetch Vector PCH
register_flags = 0x34; // Set the I and B flags
register_pc = (temp2<<8) | temp1;
assert_sync=1;
start_read(register_pc); // Fetch first opcode at vector PCH,PCL
return;
}
// -------------------------------------------------
// NMI Interrupt Processing
// -------------------------------------------------
void nmi_handler() {
uint16_t temp1, temp2;
wait_for_CLK_rising_edge(); // Begin processing on next CLK edge
register_flags = register_flags | 0x20; // Set the flag[5]
register_flags = register_flags & 0xEF; // Clear the B flag
read_byte(register_pc+1); // Fetch PC+1 (Discard)
push(register_pc>>8); // Push PCH
push(register_pc); // Push PCL
push(register_flags); // Push P
temp1 = read_byte(0xFFFA); // Fetch Vector PCL
temp2 = read_byte(0xFFFB); // Fetch Vector PCH
register_flags = register_flags | 0x34; // Set the I flag and restore the B flag
register_pc = (temp2<<8) | temp1;
assert_sync=1;
start_read(register_pc); // Fetch first opcode at vector PCH,PCL
return;
}
// -------------------------------------------------
// BRK & IRQ Interrupt Processing
// -------------------------------------------------
void irq_handler(uint8_t opcode_is_brk) {
uint16_t temp1, temp2;
wait_for_CLK_rising_edge(); // Begin processing on next CLK edge
register_flags = register_flags | 0x20; // Set the flag[5]
if (opcode_is_brk==1) register_flags = register_flags | 0x10; // Set the B flag
else register_flags = register_flags & 0xEF; // Clear the B flag
read_byte(register_pc+1); // Fetch PC+1 (Discard)
push(register_pc>>8); // Push PCH
push(register_pc); // Push PCL
push(register_flags); // Push P
temp1 = read_byte(0xFFFE); // Fetch Vector PCL
temp2 = read_byte(0xFFFF); // Fetch Vector PCH
register_flags = register_flags | 0x34; // Set the I flag and restore the B flag
register_pc = (temp2<<8) | temp1;
assert_sync=1;
start_read(register_pc); // Fetch first opcode at vector PCH,PCL
return;
}
// -------------------------------------------------
//
// 6502 Opcodes
//
// -------------------------------------------------
// -------------------------------------------------
// 0x0A - ASL A - Arithmetic Shift Left - Accumulator
// -------------------------------------------------
void opcode_0x0A() {
read_byte(register_pc);
Begin_Fetch_Next_Opcode();
if (0x80&register_a) register_flags = register_flags | 0x01; // Set the C flag
else register_flags = register_flags & 0xFE; // Clear the C flag
register_a = register_a << 1;
Calc_Flags_NEGATIVE_ZERO(register_a);
return;
}
// -------------------------------------------------
// 0x4A - LSR A - Logical Shift Right - Accumulator
// -------------------------------------------------
void opcode_0x4A() {
read_byte(register_pc);
Begin_Fetch_Next_Opcode();
if (0x01&register_a) register_flags = register_flags | 0x01; // Set the C flag
else register_flags = register_flags & 0xFE; // Clear the C flag
register_a = register_a >> 1;
Calc_Flags_NEGATIVE_ZERO(register_a);
return;
}
// -------------------------------------------------
// 0x6A - ROR A - Rotate Right - Accumulator
// -------------------------------------------------
void opcode_0x6A() {
uint8_t old_carry_flag=0;
read_byte(register_pc);
Begin_Fetch_Next_Opcode();
old_carry_flag = register_flags << 7; // Shift the old carry flag to bit[8] to be rotated in
if (0x01&register_a) register_flags = register_flags | 0x01; // Set the C flag
else register_flags = register_flags & 0xFE; // Clear the C flag
register_a = ( old_carry_flag | (register_a>>1) );
Calc_Flags_NEGATIVE_ZERO(register_a);
return;
}
// -------------------------------------------------
// 0x2A - ROL A - Rotate Left - Accumulator
// -------------------------------------------------
void opcode_0x2A() {
uint8_t old_carry_flag=0;
read_byte(register_pc);
Begin_Fetch_Next_Opcode();
old_carry_flag = 0x1 & register_flags; // Store the old carry flag to be rotated in
if (0x80&register_a) register_flags = register_flags | 0x01; // Set the C flag
else register_flags = register_flags & 0xFE; // Clear the C flag
register_a = (register_a<<1) | old_carry_flag;
Calc_Flags_NEGATIVE_ZERO(register_a);
return;
}
// -------------------------------------------------
// ADC
// -------------------------------------------------
void Calculate_ADC(uint16_t local_data) {
uint16_t total=0;
uint16_t bcd_low=0;
uint16_t bcd_high=0;
uint16_t bcd_total=0;
uint8_t operand0=0;
uint8_t operand1=0;
uint8_t result=0;
uint8_t low_carry=0;
uint8_t high_carry=0;
Begin_Fetch_Next_Opcode();
if ((flag_d)==1) {
bcd_low = (0x0F&register_a) + (0x0F&local_data) + (flag_c) ;
if (bcd_low>0x9) { low_carry=0x10; bcd_low = bcd_low - 0xA ; }
bcd_high = (0xF0&register_a) + (0xF0&local_data) + low_carry;
if (bcd_high>0x90) { high_carry=1; bcd_high = bcd_high - 0xA0 ; }
register_flags = register_flags & 0xFE; // Clear the C flag
if ((0x00FF&bcd_total) > 0x09) { bcd_total=bcd_total+0x010; bcd_total=bcd_total-0x0A; }
if (high_carry==1) { bcd_total=bcd_total-0xA0; register_flags = register_flags | 0x01; } // Set the C flag
else register_flags = register_flags & 0xFE; // Clear the C flag
total = (0xFF & (bcd_low + bcd_high));
}
else {
total = register_a + local_data + (flag_c);
if (total>255) register_flags = register_flags | 0x01; // Set the C flag
else register_flags = register_flags & 0xFE; // Clear the C flag
}
operand0 = (register_a & 0x80);
operand1 = (local_data & 0x80);
result = (total & 0x80);
if (operand0==0 && operand1==0 && result!=0) register_flags = register_flags | 0x40; // Set the V flag
else if (operand0!=0 && operand1!=0 && result==0) register_flags = register_flags | 0x40;
else register_flags = register_flags & 0xBF; // Clear the V flag
register_a = (0xFF & total);
Calc_Flags_NEGATIVE_ZERO(register_a);
return;
}
void opcode_0x69() { Calculate_ADC(Fetch_Immediate()); return; } // 0x69 - ADC - Immediate - Binary
void opcode_0x65() { Calculate_ADC(Fetch_ZeroPage()); return; } // 0x65 - ADC - ZeroPage
void opcode_0x75() { Calculate_ADC(Fetch_ZeroPage_X()); return; } // 0x75 - ADC - ZeroPage , X
void opcode_0x6D() { Calculate_ADC(Fetch_Absolute()); return; } // 0x6D - ADC - Absolute
void opcode_0x7D() { Calculate_ADC(Fetch_Absolute_X(1)); return; } // 0x7D - ADC - Absolute , X
void opcode_0x79() { Calculate_ADC(Fetch_Absolute_Y(1)); return; } // 0x79 - ADC - Absolute , Y
void opcode_0x61() { Calculate_ADC(Fetch_Indexed_Indirect_X()); return; } // 0x61 - ADC - Indexed Indirect X
void opcode_0x71() { Calculate_ADC(Fetch_Indexed_Indirect_Y(1)); return; } // 0x71 - ADC - Indirect Indexed Y
// -------------------------------------------------
// SBC
// -------------------------------------------------
void Calculate_SBC(uint16_t local_data) {
uint16_t total=0;
uint16_t bcd_low=0;
uint16_t bcd_high=0;
uint16_t bcd_total=0;
int16_t signed_total=0;
uint8_t operand0=0;
uint8_t operand1=0;
uint8_t result=0;
uint8_t flag_c_invert=0;
uint8_t low_carry=0;
uint8_t high_carry=0;
Begin_Fetch_Next_Opcode();
if (flag_c!=0) flag_c_invert=0; else flag_c_invert=1;
if ((flag_d)==1) {
bcd_low = (0x0F&register_a) - (0x0F&local_data) - flag_c_invert ;
if (bcd_low>0x9) { low_carry=0x10; bcd_low = bcd_low + 0xA ; }
bcd_high = (0xF0&register_a) - (0xF0&local_data) - low_carry;
if (bcd_high>0x90) { high_carry=1; bcd_high = bcd_high + 0xA0 ; }
register_flags = register_flags & 0xFE; // Clear the C flag
if ((0x00FF&bcd_total) > 0x09) { bcd_total=bcd_total+0x010; bcd_total=bcd_total-0x0A; }
if (high_carry==0) { bcd_total=bcd_total-0xA0; register_flags = register_flags | 0x01; } // Set the C flag
else register_flags = register_flags & 0xFE; // Clear the C flag
total = (0xFF & (bcd_low + bcd_high));
}
else {
total = register_a - local_data - flag_c_invert;
signed_total = (int16_t)register_a - (int16_t)(local_data ) - flag_c_invert;
if (signed_total>=0) register_flags = register_flags | 0x01; // Set the C flag
else register_flags = register_flags & 0xFE; // Clear the C flag
}
operand0 = (register_a & 0x80);
operand1 = (local_data & 0x80);
result = (total & 0x80);
if (operand0==0 && operand1!=0 && result!=0) register_flags = register_flags | 0x40; // Set the V flag
else if (operand0!=0 && operand1==0 && result==0) register_flags = register_flags | 0x40;
else register_flags = register_flags & 0xBF; // Clear the V flag
register_a = (0xFF & total);
Calc_Flags_NEGATIVE_ZERO(register_a);
return;
}
void opcode_0xE9() { Calculate_SBC(Fetch_Immediate()); return; } // 0xE9 - SBC - Immediate
void opcode_0xE5() { Calculate_SBC(Fetch_ZeroPage()); return; } // 0xE5 - SBC - ZeroPage
void opcode_0xF5() { Calculate_SBC(Fetch_ZeroPage_X()); return; } // 0xF5 - SBC - ZeroPage , X
void opcode_0xED() { Calculate_SBC(Fetch_Absolute()); return; } // 0xED - SBC - Absolute
void opcode_0xFD() { Calculate_SBC(Fetch_Absolute_X(1)); return; } // 0xFD - SBC - Absolute , X
void opcode_0xF9() { Calculate_SBC(Fetch_Absolute_Y(1)); return; } // 0xF9 - SBC - Absolute , Y
void opcode_0xE1() { Calculate_SBC(Fetch_Indexed_Indirect_X()); return; } // 0xE1 - SBC - Indexed Indirect X
void opcode_0xF1() { Calculate_SBC(Fetch_Indexed_Indirect_Y(1)); return; } // 0xF1 - SBC - Indirect Indexed Y
// -------------------------------------------------
// Flag set/resets and NOP
// -------------------------------------------------
void opcode_0xEA() { read_byte(register_pc+1); Begin_Fetch_Next_Opcode(); return; } // 0xEA - NOP
void opcode_0x18() { read_byte(register_pc+1); Begin_Fetch_Next_Opcode(); register_flags=register_flags&0xFE; return; } // 0x18 - CLC - Clear Carry Flag
void opcode_0xD8() { read_byte(register_pc+1); Begin_Fetch_Next_Opcode(); register_flags=register_flags&0xF7; return; } // 0xD8 - CLD - Clear Decimal Mode
void opcode_0x58() { read_byte(register_pc+1); Begin_Fetch_Next_Opcode(); register_flags=register_flags&0xFB; return; } // 0x58 - CLI - Clear Interrupt Flag
void opcode_0xB8() { read_byte(register_pc+1); Begin_Fetch_Next_Opcode(); register_flags=register_flags&0xBF; return; } // 0xB8 - CLV - Clear Overflow Flag
void opcode_0x38() { read_byte(register_pc+1); Begin_Fetch_Next_Opcode(); register_flags=register_flags|0x01; return; } // 0x38 - SEC - Set Carry Flag
void opcode_0x78() { read_byte(register_pc+1); Begin_Fetch_Next_Opcode(); register_flags=register_flags|0x04; return; } // 0x78 - SEI - Set Interrupt Flag
void opcode_0xF8() { read_byte(register_pc+1); Begin_Fetch_Next_Opcode(); register_flags=register_flags|0x08; return; } // 0xF8 - SED - Set Decimal Mode
// -------------------------------------------------
// Increment/Decrements
// -------------------------------------------------
void opcode_0xCA() { read_byte(register_pc+1); Begin_Fetch_Next_Opcode(); register_x=register_x-1; Calc_Flags_NEGATIVE_ZERO(register_x); return; } // 0xCA - DEX - Decrement X
void opcode_0x88() { read_byte(register_pc+1); Begin_Fetch_Next_Opcode(); register_y=register_y-1; Calc_Flags_NEGATIVE_ZERO(register_y); return; } // 0x88 - DEY - Decrement Y
void opcode_0xE8() { read_byte(register_pc+1); Begin_Fetch_Next_Opcode(); register_x=register_x+1; Calc_Flags_NEGATIVE_ZERO(register_x); return; } // 0xE8 - INX - Increment X
void opcode_0xC8() { read_byte(register_pc+1); Begin_Fetch_Next_Opcode(); register_y=register_y+1; Calc_Flags_NEGATIVE_ZERO(register_y); return; } // 0xC8 - INY - Increment Y
// -------------------------------------------------
// Transfers
// -------------------------------------------------
void opcode_0xAA() { read_byte(register_pc+1); Begin_Fetch_Next_Opcode(); register_x=register_a; Calc_Flags_NEGATIVE_ZERO(register_x); return; } // 0xAA - TAX - Transfer Accumulator to X
void opcode_0xA8() { read_byte(register_pc+1); Begin_Fetch_Next_Opcode(); register_y=register_a; Calc_Flags_NEGATIVE_ZERO(register_y); return; } // 0xA8 - TAY - Transfer Accumulator to Y
void opcode_0xBA() { read_byte(register_pc+1); Begin_Fetch_Next_Opcode(); register_x=register_sp; Calc_Flags_NEGATIVE_ZERO(register_x); return; } // 0xBA - TSX - Transfer Stack Pointer to X
void opcode_0x8A() { read_byte(register_pc+1); Begin_Fetch_Next_Opcode(); register_a=register_x; Calc_Flags_NEGATIVE_ZERO(register_a); return; } // 0x8A - TXA - Transfer X to Accumulator
void opcode_0x9A() { read_byte(register_pc+1); Begin_Fetch_Next_Opcode(); register_sp=register_x; return; } // 0x9A - TXS - Transfer X to Stack Pointer
void opcode_0x98() { read_byte(register_pc+1); Begin_Fetch_Next_Opcode(); register_a=register_y; Calc_Flags_NEGATIVE_ZERO(register_a); return; } // 0x98 - TYA - Transfer Y to Accumulator
// -------------------------------------------------
// PUSH/POP Flags and Accumulator
// -------------------------------------------------
void opcode_0x08() { read_byte(register_pc+1); push(register_flags|0x30); Begin_Fetch_Next_Opcode(); return; } // 0x08 - PHP - Push Flags to Stack
void opcode_0x48() { read_byte(register_pc+1); push(register_a); Begin_Fetch_Next_Opcode(); return; } // 0x48 - PHA - Push Accumulator to the stack
void opcode_0x28() { read_byte(register_pc+1); read_byte(register_sp_fixed); register_flags=(pop()|0x30); Begin_Fetch_Next_Opcode(); return; } // 0x28 - PLP - Pop Flags from Stack
void opcode_0x68() { read_byte(register_pc+1); read_byte(register_sp_fixed); register_a=pop(); Calc_Flags_NEGATIVE_ZERO(register_a); Begin_Fetch_Next_Opcode(); return; } // 0x68 - PLA - Pop Accumulator from Stack
// -------------------------------------------------
// AND
// -------------------------------------------------
void opcode_0x29() { register_a=register_a&(Fetch_Immediate()); Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_a); return; } // 0x29 - AND - Immediate
void opcode_0x25() { register_a=register_a&(Fetch_ZeroPage()); Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_a); return; } // 0x25 - AND - ZeroPage
void opcode_0x35() { register_a=register_a&(Fetch_ZeroPage_X()); Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_a); return; } // 0x35 - AND - ZeroPage , X
void opcode_0x2D() { register_a=register_a&(Fetch_Absolute()); Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_a); return; } // 0x2D - AND - Absolute
void opcode_0x3D() { register_a=register_a&(Fetch_Absolute_X(1)); Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_a); return; } // 0x3D - AND - Absolute , X
void opcode_0x39() { register_a=register_a&(Fetch_Absolute_Y(1)); Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_a); return; } // 0x19 - OR - Absolute , Y
void opcode_0x21() { register_a=register_a&(Fetch_Indexed_Indirect_X()); Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_a); return; } // 0x21 - AND - Indexed Indirect X
void opcode_0x31() { register_a=register_a&(Fetch_Indexed_Indirect_Y(1)); Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_a); return; } // 0x31 - AND - Indirect Indexed Y
// -------------------------------------------------
// ORA
// -------------------------------------------------
void opcode_0x09() { register_a=register_a|(Fetch_Immediate()); Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_a); return; } // 0x09 - OR - Immediate
void opcode_0x05() { register_a=register_a|(Fetch_ZeroPage()); Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_a); return; } // 0x05 - OR - ZeroPage
void opcode_0x15() { register_a=register_a|(Fetch_ZeroPage_X()); Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_a); return; } // 0x15 - OR - ZeroPage , X
void opcode_0x0D() { register_a=register_a|(Fetch_Absolute()); Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_a); return; } // 0x0D - OR - Absolute
void opcode_0x1D() { register_a=register_a|(Fetch_Absolute_X(1)); Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_a); return; } // 0x1D - OR - Absolute , X
void opcode_0x19() { register_a=register_a|(Fetch_Absolute_Y(1)); Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_a); return; } // 0x19 - OR - Absolute , Y
void opcode_0x01() { register_a=register_a|(Fetch_Indexed_Indirect_X()); Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_a); return; } // 0x01 - OR - Indexed Indirect X
void opcode_0x11() { register_a=register_a|(Fetch_Indexed_Indirect_Y(1)); Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_a); return; } // 0x11 - OR - Indirect Indexed Y
// -------------------------------------------------
// EOR
// -------------------------------------------------
void opcode_0x49() { register_a=register_a^(Fetch_Immediate()); Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_a); return; } // 0x49 - EOR - Immediate
void opcode_0x45() { register_a=register_a^(Fetch_ZeroPage()); Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_a); return; } // 0x45 - EOR - ZeroPage
void opcode_0x55() { register_a=register_a^(Fetch_ZeroPage_X()); Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_a); return; } // 0x55 - EOR - ZeroPage , X
void opcode_0x4D() { register_a=register_a^(Fetch_Absolute()); Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_a); return; } // 0x4D - EOR - Absolute
void opcode_0x5D() { register_a=register_a^(Fetch_Absolute_X(1)); Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_a); return; } // 0x5D - EOR - Absolute , X
void opcode_0x59() { register_a=register_a^(Fetch_Absolute_Y(1)); Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_a); return; } // 0x59 - EOR - Absolute , Y
void opcode_0x41() { register_a=register_a^(Fetch_Indexed_Indirect_X()); Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_a); return; } // 0x41 - EOR - Indexed Indirect X
void opcode_0x51() { register_a=register_a^(Fetch_Indexed_Indirect_Y(1)); Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_a); return; } // 0x51 - EOR - Indirect Indexed Y
// -------------------------------------------------
// LDA
// -------------------------------------------------
void opcode_0xA9() { register_a=Fetch_Immediate(); Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_a); return; } // 0xA9 - LDA - Immediate
void opcode_0xA5() { register_a=Fetch_ZeroPage(); Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_a); return; } // 0xA5 - LDA - ZeroPage
void opcode_0xB5() { register_a=Fetch_ZeroPage_X(); Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_a); return; } // 0xB5 - LDA - ZeroPage , X
void opcode_0xAD() { register_a=Fetch_Absolute(); Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_a); return; } // 0xAD - LDA - Absolute
void opcode_0xBD() { register_a=Fetch_Absolute_X(1); Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_a); return; } // 0xBD - LDA - Absolute , X
void opcode_0xB9() { register_a=Fetch_Absolute_Y(1); Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_a); return; } // 0xB9 - LDA - Absolute , Y
void opcode_0xA1() { register_a=Fetch_Indexed_Indirect_X(); Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_a); return; } // 0xA1 - LDA - Indexed Indirect X
void opcode_0xB1() { register_a=Fetch_Indexed_Indirect_Y(1); Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_a); return; } // 0xB1 - LDA - Indirect Indexed Y
// -------------------------------------------------
// LDX
// -------------------------------------------------
void opcode_0xA2() { register_x=Fetch_Immediate(); Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_x); return; } // 0xA2 - LDX - Immediate
void opcode_0xA6() { register_x=Fetch_ZeroPage(); Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_x); return; } // 0xA6 - LDX - ZeroPage
void opcode_0xB6() { register_x=Fetch_ZeroPage_Y(); Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_x); return; } // 0xB6 - LDX - ZeroPage , Y
void opcode_0xAE() { register_x=Fetch_Absolute(); Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_x); return; } // 0xAE - LDX - Absolute
void opcode_0xBE() { register_x=Fetch_Absolute_Y(1); Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_x); return; } // 0xBE - LDX - Absolute , Y
// -------------------------------------------------
// LDY
// -------------------------------------------------
void opcode_0xA0() { register_y=Fetch_Immediate(); Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_y);return; } // 0xA0 - LDY - Immediate
void opcode_0xA4() { register_y=Fetch_ZeroPage(); Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_y);return; } // 0xA4 - LDY - ZeroPage
void opcode_0xB4() { register_y=Fetch_ZeroPage_X(); Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_y);return; } // 0xB4 - LDY - ZeroPage , X
void opcode_0xAC() { register_y=Fetch_Absolute(); Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_y);return; } // 0xAC - LDY - Absolute
void opcode_0xBC() { register_y=Fetch_Absolute_X(1); Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_y);return; } // 0xBC - LDY - Absolute , X
// -------------------------------------------------
// BIT
// -------------------------------------------------
void Calculate_BIT(uint8_t local_data) {
uint8_t temp=0;
Begin_Fetch_Next_Opcode();
register_flags = (register_flags & 0x3F) | (local_data & 0xC0); // Copy fetched memory[7:6] to C,V flags
temp = local_data & register_a;
if (temp==0) register_flags = register_flags | 0x02; // Set the Z flag
else register_flags = register_flags & 0xFD; // Clear the Z flag
return;
}
void opcode_0x24() { Calculate_BIT(Fetch_ZeroPage()); return; } // 0x24 - BIT - ZeroPage
void opcode_0x2C() { Calculate_BIT(Fetch_Absolute()); return; } // 0x2C - BIT - Absolute
// -------------------------------------------------
// CMP
// -------------------------------------------------
void Calculate_CMP(uint8_t local_data) {
int16_t temp=0;
Begin_Fetch_Next_Opcode();
temp = register_a - local_data;
if (register_a >= local_data) register_flags = register_flags | 0x01; // Set the C flag
else register_flags = register_flags & 0xFE; // Clear the C flag
Calc_Flags_NEGATIVE_ZERO(temp);
return;
}
void opcode_0xC9() { Calculate_CMP(Fetch_Immediate()); return; } // 0xC9 - CMP - Immediate
void opcode_0xC5() { Calculate_CMP(Fetch_ZeroPage()); return; } // 0xC5 - CMP - ZeroPage
void opcode_0xD5() { Calculate_CMP(Fetch_ZeroPage_X()); return; } // 0xD5 - CMP - ZeroPage , X
void opcode_0xCD() { Calculate_CMP(Fetch_Absolute()); return; } // 0xCD - CMP - Absolute
void opcode_0xDD() { Calculate_CMP(Fetch_Absolute_X(1)); return; } // 0xDD - CMP - Absolute , X
void opcode_0xD9() { Calculate_CMP(Fetch_Absolute_Y(1)); return; } // 0xD9 - CMP - Absolute , Y
void opcode_0xC1() { Calculate_CMP(Fetch_Indexed_Indirect_X()); return; } // 0xC1 - CMP - Indexed Indirect X
void opcode_0xD1() { Calculate_CMP(Fetch_Indexed_Indirect_Y(1)); return; } // 0xD1 - CMP - Indirect Indexed Y
// -------------------------------------------------
// CPX
// -------------------------------------------------
void Calculate_CPX(uint8_t local_data) {
uint16_t temp=0;
Begin_Fetch_Next_Opcode();
temp = register_x - local_data;
if (register_x >= local_data) register_flags = register_flags | 0x01; // Set the C flag
else register_flags = register_flags & 0xFE; // Clear the C flag
Calc_Flags_NEGATIVE_ZERO(temp);
return;
}
void opcode_0xE0() { Calculate_CPX(Fetch_Immediate()); return; } // 0xE0 - CPX - Immediate
void opcode_0xE4() { Calculate_CPX(Fetch_ZeroPage()); return; } // 0xE4 - CPX - ZeroPage
void opcode_0xEC() { Calculate_CPX(Fetch_Absolute()); return; } // 0xEC - CPX - Absolute
// -------------------------------------------------
// CPY
// -------------------------------------------------
void Calculate_CPY(uint8_t local_data) {
uint16_t temp=0;
Begin_Fetch_Next_Opcode();
temp = register_y - local_data;
if (register_y >= local_data) register_flags = register_flags | 0x01; // Set the C flag
else register_flags = register_flags & 0xFE; // Clear the C flag
Calc_Flags_NEGATIVE_ZERO(temp);
return;
}
void opcode_0xC0() { Calculate_CPY(Fetch_Immediate()); return; } // 0xC0 - CPY - Immediate
void opcode_0xC4() { Calculate_CPY(Fetch_ZeroPage()); return; } // 0xC4 - CPY - ZeroPage
void opcode_0xCC() { Calculate_CPY(Fetch_Absolute()); return; } // 0xCC - CPY - Absolute
// -------------------------------------------------
// Store Operations
// -------------------------------------------------
void opcode_0x85() { Write_ZeroPage(register_a); Begin_Fetch_Next_Opcode(); return; } // 0x85 - STA - ZeroPage
void opcode_0x8D() { Write_Absolute(register_a); Begin_Fetch_Next_Opcode(); return; } // 0x8D - STA - Absolute
void opcode_0x95() { Write_ZeroPage_X(register_a); Begin_Fetch_Next_Opcode(); return; } // 0x95 - STA - ZeroPage , X
void opcode_0x9D() { Write_Absolute_X(register_a); Begin_Fetch_Next_Opcode(); return; } // 0x9D - STA - Absolute , X
void opcode_0x99() { Write_Absolute_Y(register_a); Begin_Fetch_Next_Opcode(); return; } // 0x99 - STA - Absolute , Y
void opcode_0x81() { Write_Indexed_Indirect_X(register_a); Begin_Fetch_Next_Opcode(); return; } // 0x81 - STA - Indexed Indirect X
void opcode_0x91() { Write_Indexed_Indirect_Y(register_a); Begin_Fetch_Next_Opcode(); return; } // 0x91 - STA - Indirect Indexed Y
void opcode_0x86() { Write_ZeroPage(register_x); Begin_Fetch_Next_Opcode(); return; } // 0x86 - STX - ZeroPage
void opcode_0x96() { Write_ZeroPage_Y(register_x); Begin_Fetch_Next_Opcode(); return; } // 0x96 - STX - ZeroPage , Y
void opcode_0x8E() { Write_Absolute(register_x); Begin_Fetch_Next_Opcode(); return; } // 0x8E - STX - Absolute
void opcode_0x84() { Write_ZeroPage(register_y); Begin_Fetch_Next_Opcode(); return; } // 0x84 - STY - ZeroPage
void opcode_0x94() { Write_ZeroPage_X(register_y); Begin_Fetch_Next_Opcode(); return; } // 0x94 - STY - ZeroPage , X
void opcode_0x8C() { Write_Absolute(register_y); Begin_Fetch_Next_Opcode(); return; } // 0x8C - STY - Absolute
// -------------------------------------------------
// ASL - Arithmetic Shift Left - Memory
// -------------------------------------------------
uint8_t Calculate_ASL(uint8_t local_data) {
if ((0x80&local_data)==0x80) register_flags = register_flags | 0x01; // Set the C flag
else register_flags = register_flags & 0xFE; // Clear the C flag
local_data = ((local_data << 1) & 0xFE);
Calc_Flags_NEGATIVE_ZERO(local_data);
return local_data;
}
// -------------------------------------------------
// ASL - Read-modify-write Operations
// -------------------------------------------------
void opcode_0x06() { Double_WriteBack(Calculate_ASL(Fetch_ZeroPage())); Begin_Fetch_Next_Opcode(); return; } // 0x06 - ASL - Arithmetic Shift Left - ZeroPage
void opcode_0x16() { Double_WriteBack(Calculate_ASL(Fetch_ZeroPage_X())); Begin_Fetch_Next_Opcode(); return; } // 0x16 - ASL - Arithmetic Shift Left - ZeroPage , X
void opcode_0x0E() { Double_WriteBack(Calculate_ASL(Fetch_Absolute())); Begin_Fetch_Next_Opcode(); return; } // 0x0E - ASL - Arithmetic Shift Left - Absolute
void opcode_0x1E() { Double_WriteBack(Calculate_ASL(Fetch_Absolute_X(0))); Begin_Fetch_Next_Opcode(); return; } // 0x1E - ASL - Arithmetic Shift Left - Absolute , X
// -------------------------------------------------
// INC - Memory
// -------------------------------------------------
uint8_t Calculate_INC(uint8_t local_data) {
local_data = local_data + 1;
global_temp = local_data;
Calc_Flags_NEGATIVE_ZERO(local_data);
return local_data;
}
void opcode_0xE6() { Double_WriteBack(Calculate_INC(Fetch_ZeroPage())); Begin_Fetch_Next_Opcode(); return; } // 0xE6 - INC - ZeroPage
void opcode_0xF6() { Double_WriteBack(Calculate_INC(Fetch_ZeroPage_X())); Begin_Fetch_Next_Opcode(); return; } // 0xF6 - INC - ZeroPage , X
void opcode_0xEE() { Double_WriteBack(Calculate_INC(Fetch_Absolute())); Begin_Fetch_Next_Opcode(); return; } // 0xEE - INC - Absolute
void opcode_0xFE() { Double_WriteBack(Calculate_INC(Fetch_Absolute_X(0))); Begin_Fetch_Next_Opcode(); return; } // 0xFE - INC - Absolute , X
// -------------------------------------------------
// DEC - Memory
// -------------------------------------------------
uint8_t Calculate_DEC(uint8_t local_data) {
local_data = local_data - 1;
global_temp = local_data;
Calc_Flags_NEGATIVE_ZERO(local_data);
return local_data;
}
void opcode_0xC6() { Double_WriteBack(Calculate_DEC(Fetch_ZeroPage())); Begin_Fetch_Next_Opcode(); return; } // 0xC6 - DEC - ZeroPage
void opcode_0xD6() { Double_WriteBack(Calculate_DEC(Fetch_ZeroPage_X())); Begin_Fetch_Next_Opcode(); return; } // 0xD6 - DEC - ZeroPage , X
void opcode_0xCE() { Double_WriteBack(Calculate_DEC(Fetch_Absolute())); Begin_Fetch_Next_Opcode(); return; } // 0xCE - DEC - Absolute
void opcode_0xDE() { Double_WriteBack(Calculate_DEC(Fetch_Absolute_X(0))); Begin_Fetch_Next_Opcode(); return; } // 0xDE - DEC - Absolute , X
// -------------------------------------------------
// LSR - Memory
// -------------------------------------------------
uint8_t Calculate_LSR(uint8_t local_data) {
if ((0x01&local_data)==0x01) register_flags = register_flags | 0x01; // Set the C flag
else register_flags = register_flags & 0xFE; // Clear the C flag
local_data = (0x7F& (local_data >> 1));
Calc_Flags_NEGATIVE_ZERO(local_data);
return local_data;
}
void opcode_0x46() { Double_WriteBack(Calculate_LSR(Fetch_ZeroPage())); Begin_Fetch_Next_Opcode(); return; } // 0x46 - LSR - Logical Shift Right - ZeroPage
void opcode_0x56() { Double_WriteBack(Calculate_LSR(Fetch_ZeroPage_X())); Begin_Fetch_Next_Opcode(); return; } // 0x56 - LSR - Logical Shift Right - ZeroPage , X
void opcode_0x4E() { Double_WriteBack(Calculate_LSR(Fetch_Absolute())); Begin_Fetch_Next_Opcode(); return; } // 0x4E - LSR - Logical Shift Right - Absolute
void opcode_0x5E() { Double_WriteBack(Calculate_LSR(Fetch_Absolute_X(0))); Begin_Fetch_Next_Opcode(); return; } // 0x5E - LSR - Logical Shift Right - Absolute , X
// -------------------------------------------------
// ROR - Memory
// -------------------------------------------------
uint8_t Calculate_ROR(uint8_t local_data) {
uint8_t old_carry_flag=0;
old_carry_flag = register_flags << 7; // Shift the old carry flag to bit[8] to be rotated in
if ((0x01&local_data)==0x01) register_flags = register_flags | 0x01; // Set the C flag
else register_flags = register_flags & 0xFE; // Clear the C flag
local_data = ( old_carry_flag | (local_data>>1) );
Calc_Flags_NEGATIVE_ZERO(local_data);
return local_data;
}
void opcode_0x66() { Double_WriteBack(Calculate_ROR(Fetch_ZeroPage())); Begin_Fetch_Next_Opcode(); return; } // 0x66 - ROR - Rotate Right - ZeroPage
void opcode_0x76() { Double_WriteBack(Calculate_ROR(Fetch_ZeroPage_X())); Begin_Fetch_Next_Opcode(); return; } // 0x76 - ROR - Rotate Right - ZeroPage , X
void opcode_0x6E() { Double_WriteBack(Calculate_ROR(Fetch_Absolute())); Begin_Fetch_Next_Opcode(); return; } // 0x6E - ROR - Rotate Right - Absolute
void opcode_0x7E() { Double_WriteBack(Calculate_ROR(Fetch_Absolute_X(0))); Begin_Fetch_Next_Opcode(); return; } // 0x7E - ROR - Rotate Right - Absolute , X
// -------------------------------------------------
// ROL - Memory
// -------------------------------------------------
uint8_t Calculate_ROL(uint8_t local_data) {
uint8_t old_carry_flag=0;
old_carry_flag = 0x1 & register_flags; // Store the old carry flag to be rotated in
if (0x80&local_data) register_flags = register_flags | 0x01; // Set the C flag
else register_flags = register_flags & 0xFE; // Clear the C flag
local_data = (local_data<<1) | old_carry_flag;
Calc_Flags_NEGATIVE_ZERO(local_data);
return local_data;
}
void opcode_0x26() { Double_WriteBack(Calculate_ROL(Fetch_ZeroPage())); Begin_Fetch_Next_Opcode(); return; } // 0x26 - ROL - Rotate Left - ZeroPage
void opcode_0x36() { Double_WriteBack(Calculate_ROL(Fetch_ZeroPage_X())); Begin_Fetch_Next_Opcode(); return; } // 0x36 - ROL - Rotate Left - ZeroPage , X
void opcode_0x2E() { Double_WriteBack(Calculate_ROL(Fetch_Absolute())); Begin_Fetch_Next_Opcode(); return; } // 0x2E - ROL - Rotate Left - Absolute
void opcode_0x3E() { Double_WriteBack(Calculate_ROL(Fetch_Absolute_X(0))); Begin_Fetch_Next_Opcode(); return; } // 0x3E - ROL - Rotate Left - Absolute , X
// -------------------------------------------------
// Branches
// -------------------------------------------------
void Branch_Taken() {
effective_address = Sign_Extend16(Fetch_Immediate());
effective_address = (register_pc+1) + effective_address;
if ( (0xFF00&register_pc) == (0xFF00&effective_address) ) { Fetch_Immediate(); } // Page boundary not crossed
else { Fetch_Immediate(); Fetch_Immediate(); } // Page boundary crossed
register_pc = effective_address;
assert_sync=1;
start_read(register_pc);
return;
}
void opcode_0xB0() { if ((flag_c)==1) Branch_Taken(); else { Fetch_Immediate(); Begin_Fetch_Next_Opcode();} return; } // 0xB0 - BCS - Branch on Carry Set
void opcode_0x90() { if ((flag_c)==0) Branch_Taken(); else { Fetch_Immediate(); Begin_Fetch_Next_Opcode();} return; } // 0x90 - BCC - Branch on Carry Clear
void opcode_0xF0() { if ((flag_z)==1) Branch_Taken(); else { Fetch_Immediate(); Begin_Fetch_Next_Opcode();} return; } // 0xF0 - BEQ - Branch on Zero Set
void opcode_0xD0() { if ((flag_z)==0) Branch_Taken(); else { Fetch_Immediate(); Begin_Fetch_Next_Opcode();} return; } // 0xD0 - BNE - Branch on Zero Clear
void opcode_0x70() { if ((flag_v)==1) Branch_Taken(); else { Fetch_Immediate(); Begin_Fetch_Next_Opcode();} return; } // 0x70 - BVS - Branch on Overflow Set
void opcode_0x50() { if ((flag_v)==0) Branch_Taken(); else { Fetch_Immediate(); Begin_Fetch_Next_Opcode();} return; } // 0x50 - BVC - Branch on Overflow Clear
void opcode_0x30() { if ((flag_n)==1) Branch_Taken(); else { Fetch_Immediate(); Begin_Fetch_Next_Opcode();} return; } // 0x30 - BMI - Branch on Minus (N Flag Set)
void opcode_0x10() { if ((flag_n)==0) Branch_Taken(); else { Fetch_Immediate(); Begin_Fetch_Next_Opcode();} return; } // 0x10 - BPL - Branch on Plus (N Flag Clear)
// -------------------------------------------------
// Jumps and Returns
// -------------------------------------------------
void opcode_0x4C() { register_pc=Calculate_Absolute(); assert_sync=1; start_read(register_pc); return; } // 0x4C - JMP - Jump Absolute
// -------------------------------------------------
// 0x6C - JMP - Jump Indirect
// -------------------------------------------------
void opcode_0x6C() {
uint16_t lal, lah;
uint16_t adl, adh;
lal = Fetch_Immediate();
lah = Fetch_Immediate()<<8;
adl = read_byte(lah + lal);
adh = read_byte(lah + lal + 1)<<8;
effective_address = adh+adl;
register_pc = (0xFF00&adh) + (0x00FF&effective_address) ; // 6502 page wrapping bug
assert_sync=1;
start_read(register_pc);
return ;
}
// -------------------------------------------------
// 0x20 - JSR - Jump to Subroutine
// -------------------------------------------------
void opcode_0x20() {
uint16_t adl, adh;
adl = Fetch_Immediate();
adh = Fetch_Immediate()<<8;
read_byte(register_sp_fixed);
push((0xFF00&register_pc)>>8);
push(0x00FF&register_pc);
register_pc = adh+adl;
assert_sync=1;
start_read(register_pc);
return ;
}
// -------------------------------------------------
// 0x40 - RTI - Return from Interrupt
// -------------------------------------------------
void opcode_0x40() {
uint16_t pcl, pch;
Fetch_Immediate();
read_byte(register_sp_fixed);
register_flags = pop();
pcl = pop();
pch = pop()<<8;
register_pc = pch+pcl;
assert_sync=1;
start_read(register_pc);
return ;
}
// -------------------------------------------------
// 0x60 - RTS - Return from Subroutine
// -------------------------------------------------
void opcode_0x60() {
uint16_t pcl, pch;
Fetch_Immediate();
read_byte(register_sp_fixed);
pcl = pop();
pch = pop()<<8;
register_pc = pch+pcl+1;
read_byte(register_pc);
assert_sync=1;
start_read(register_pc);
return ;
}
// -------------------------------------------------
//
// *** Undocumented 6502 Opcodes ***
//
// -------------------------------------------------
// --------------------------------------------------------------------------------------------------
// SLO - Shift left one bit in memory, then OR accumulator with memory.
// --------------------------------------------------------------------------------------------------
uint8_t Calculate_SLO(uint8_t local_data) {
if ((0x80&local_data)==0x80) register_flags = register_flags | 0x01; // Set the C flag
else register_flags = register_flags & 0xFE; // Clear the C flag
local_data = ((local_data << 1) & 0xFE);
register_a = register_a | local_data;
Calc_Flags_NEGATIVE_ZERO(register_a);
return local_data;
}
void opcode_0x07() { Double_WriteBack(Calculate_SLO(Fetch_ZeroPage())); Begin_Fetch_Next_Opcode(); return; } // 0x07 - SLO - ZeroPage
void opcode_0x17() { Double_WriteBack(Calculate_SLO(Fetch_ZeroPage_X())); Begin_Fetch_Next_Opcode(); return; } // 0x17 - SLO - ZeroPage , X
void opcode_0x03() { Double_WriteBack(Calculate_SLO(Fetch_Indexed_Indirect_X())); Begin_Fetch_Next_Opcode(); return; } // 0x03 - SLO - Indexed Indirect X
void opcode_0x13() { Double_WriteBack(Calculate_SLO(Fetch_Indexed_Indirect_Y(1))); Begin_Fetch_Next_Opcode(); return; } // 0x13 - SLO - Indirect Indexed Y
void opcode_0x0F() { Double_WriteBack(Calculate_SLO(Fetch_Absolute())); Begin_Fetch_Next_Opcode(); return; } // 0x0F - SLO - Absolute
void opcode_0x1F() { Double_WriteBack(Calculate_SLO(Fetch_Absolute_X(1))); Begin_Fetch_Next_Opcode(); return; } // 0x1F - SLO - Absolute , X
void opcode_0x1B() { Double_WriteBack(Calculate_SLO(Fetch_Absolute_Y(1))); Begin_Fetch_Next_Opcode(); return; } // 0x1B - SLO - Absolute , Y
// --------------------------------------------------------------------------------------------------
// RLA - Rotate one bit left in memory, then AND accumulator with memory.
// --------------------------------------------------------------------------------------------------
uint8_t Calculate_RLA(uint8_t local_data) {
uint8_t old_carry_flag=0;
old_carry_flag = 0x1 & register_flags; // Store the old carry flag to be rotated in
if (0x80&local_data) register_flags = register_flags | 0x01; // Set the C flag
else register_flags = register_flags & 0xFE; // Clear the C flag
local_data = (local_data<<1) | old_carry_flag;
register_a = register_a & local_data;
Calc_Flags_NEGATIVE_ZERO(register_a);
return local_data;
}
void opcode_0x27() { Double_WriteBack(Calculate_RLA(Fetch_ZeroPage())); Begin_Fetch_Next_Opcode(); return; } // 0x27 - RLA - ZeroPage
void opcode_0x37() { Double_WriteBack(Calculate_RLA(Fetch_ZeroPage_X())); Begin_Fetch_Next_Opcode(); return; } // 0x37 - RLA - ZeroPage , X
void opcode_0x23() { Double_WriteBack(Calculate_RLA(Fetch_Indexed_Indirect_X())); Begin_Fetch_Next_Opcode(); return; } // 0x23 - RLA - Indexed Indirect X
void opcode_0x33() { Double_WriteBack(Calculate_RLA(Fetch_Indexed_Indirect_Y(1))); Begin_Fetch_Next_Opcode(); return; } // 0x33 - RLA - Indirect Indexed Y
void opcode_0x2F() { Double_WriteBack(Calculate_RLA(Fetch_Absolute())); Begin_Fetch_Next_Opcode(); return; } // 0x2F - RLA - Absolute
void opcode_0x3F() { Double_WriteBack(Calculate_RLA(Fetch_Absolute_X(1))); Begin_Fetch_Next_Opcode(); return; } // 0x3F - RLA - Absolute , X
void opcode_0x3B() { Double_WriteBack(Calculate_RLA(Fetch_Absolute_Y(1))); Begin_Fetch_Next_Opcode(); return; } // 0x3B - RLA - Absolute , Y
// --------------------------------------------------------------------------------------------------
// SRE - Shift right one bit in memory, then EOR accumulator with memory.
// --------------------------------------------------------------------------------------------------
uint8_t Calculate_SRE(uint8_t local_data) {
if ((0x01&local_data)==0x01) register_flags = register_flags | 0x01; // Set the C flag
else register_flags = register_flags & 0xFE; // Clear the C flag
local_data = (0x7F& (local_data >> 1));
register_a = register_a ^ local_data;
Calc_Flags_NEGATIVE_ZERO(register_a);
return local_data;
}
void opcode_0x47() { Double_WriteBack(Calculate_SRE(Fetch_ZeroPage())); Begin_Fetch_Next_Opcode(); return; } // 0x47 - SRE - ZeroPage
void opcode_0x57() { Double_WriteBack(Calculate_SRE(Fetch_ZeroPage_X())); Begin_Fetch_Next_Opcode(); return; } // 0x57 - SRE - ZeroPage , X
void opcode_0x43() { Double_WriteBack(Calculate_SRE(Fetch_Indexed_Indirect_X())); Begin_Fetch_Next_Opcode(); return; } // 0x43 - SRE - Indexed Indirect X
void opcode_0x53() { Double_WriteBack(Calculate_SRE(Fetch_Indexed_Indirect_Y(1))); Begin_Fetch_Next_Opcode(); return; } // 0x53 - SRE - Indirect Indexed Y
void opcode_0x4F() { Double_WriteBack(Calculate_SRE(Fetch_Absolute())); Begin_Fetch_Next_Opcode(); return; } // 0x4F - SRE - Absolute
void opcode_0x5F() { Double_WriteBack(Calculate_SRE(Fetch_Absolute_X(1))); Begin_Fetch_Next_Opcode(); return; } // 0x5F - SRE - Absolute , X
void opcode_0x5B() { Double_WriteBack(Calculate_SRE(Fetch_Absolute_Y(1))); Begin_Fetch_Next_Opcode(); return; } // 0x5B - SRE - Absolute , Y
// --------------------------------------------------------------------------------------------------
// RRA - Rotate one bit right in memory, then add memory to accumulator (with carry).
// --------------------------------------------------------------------------------------------------
uint8_t Calculate_RRA(uint8_t local_data) {
if ((0x01&local_data)==0x01) register_flags = register_flags | 0x01; // Set the C flag
else register_flags = register_flags & 0xFE; // Clear the C flag
local_data = (0x7F& (local_data >> 1));
global_temp = local_data;
return local_data;
}
void opcode_0x67() { Double_WriteBack(Calculate_RRA(Fetch_ZeroPage())); Calculate_ADC(global_temp); return; } // 0x67 - RRA - ZeroPage
void opcode_0x77() { Double_WriteBack(Calculate_RRA(Fetch_ZeroPage_X())); Calculate_ADC(global_temp); return; } // 0x77 - RRA - ZeroPage , X
void opcode_0x63() { Double_WriteBack(Calculate_RRA(Fetch_Indexed_Indirect_X())); Calculate_ADC(global_temp); return; } // 0x63 - RRA - Indexed Indirect X
void opcode_0x73() { Double_WriteBack(Calculate_RRA(Fetch_Indexed_Indirect_Y(1))); Calculate_ADC(global_temp); return; } // 0x73 - RRA - Indirect Indexed Y
void opcode_0x6F() { Double_WriteBack(Calculate_RRA(Fetch_Absolute())); Calculate_ADC(global_temp); return; } // 0x6F - RRA - Absolute
void opcode_0x7F() { Double_WriteBack(Calculate_RRA(Fetch_Absolute_X(1))); Calculate_ADC(global_temp); return; } // 0x7F - RRA - Absolute , X
void opcode_0x7B() { Double_WriteBack(Calculate_RRA(Fetch_Absolute_Y(1))); Calculate_ADC(global_temp); return; } // 0x7B - RRA - Absolute , Y
// --------------------------------------------------------------------------------------------------
// AND the contents of the A and X registers (without changing the contents of either register) and
// stores the result in memory.
// --------------------------------------------------------------------------------------------------
void opcode_0x87() { Write_ZeroPage(register_a&register_x); Begin_Fetch_Next_Opcode(); return; } // 0x87 - SAX - ZeroPage
void opcode_0x97() { Write_ZeroPage_Y(register_a&register_x); Begin_Fetch_Next_Opcode(); return; } // 0x97 - SAX - ZeroPage , Y
void opcode_0x83() { Write_Indexed_Indirect_X(register_a&register_x); Begin_Fetch_Next_Opcode(); return; } // 0x83 - SAX - Indexed Indirect X
void opcode_0x8F() { Write_Absolute(register_a&register_x); Begin_Fetch_Next_Opcode(); return; } // 0x8F - SAX - Absolute
// --------------------------------------------------------------------------------------------------
// Load both the accumulator and the X register with the contents of a memory location.
// --------------------------------------------------------------------------------------------------
void opcode_0xA7() { register_a=Fetch_ZeroPage(); register_x=register_a; Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_a); return; } // 0xA7 - LAX - ZeroPage
void opcode_0xB7() { register_a=Fetch_ZeroPage_Y(); register_x=register_a; Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_a); return; } // 0xB7 - LAX - ZeroPage , Y
void opcode_0xA3() { register_a=Fetch_Indexed_Indirect_X(); register_x=register_a; Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_a); return; } // 0xA3 - LAX - Indexed Indirect X
void opcode_0xB3() { register_a=Fetch_Indexed_Indirect_Y(1); register_x=register_a; Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_a); return; } // 0xB3 - LAX - Indirect Indexed Y
void opcode_0xAF() { register_a=Fetch_Absolute(); register_x=register_a; Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_a); return; } // 0xAF - LAX - Absolute
void opcode_0xBF() { register_a=Fetch_Absolute_Y(1); register_x=register_a; Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_a); return; } // 0xBF - LAX - Absolute , Y
// --------------------------------------------------------------------------------------------------
// Decrement the contents of a memory location and then compare the result with the A register.
// --------------------------------------------------------------------------------------------------
void opcode_0xC7() { Double_WriteBack(Calculate_DEC(Fetch_ZeroPage())); Calculate_CMP(global_temp); return; } // 0xC7 - DCP - ZeroPage
void opcode_0xD7() { Double_WriteBack(Calculate_DEC(Fetch_ZeroPage_X())); Calculate_CMP(global_temp); return; } // 0xD7 - DCP - ZeroPage , X
void opcode_0xC3() { Double_WriteBack(Calculate_DEC(Fetch_Indexed_Indirect_X())); Calculate_CMP(global_temp); return; } // 0xC3 - DCP - Indexed Indirect X
void opcode_0xD3() { Double_WriteBack(Calculate_DEC(Fetch_Indexed_Indirect_Y(0))); Calculate_CMP(global_temp); return; } // 0xD3 - DCP - Indirect Indexed Y
void opcode_0xCF() { Double_WriteBack(Calculate_DEC(Fetch_Absolute())); Calculate_CMP(global_temp); return; } // 0xCF - DCP - Absolute
void opcode_0xDF() { Double_WriteBack(Calculate_DEC(Fetch_Absolute_X(0))); Calculate_CMP(global_temp); return; } // 0xDF - DCP - Absolute , X
void opcode_0xDB() { Double_WriteBack(Calculate_DEC(Fetch_Absolute_Y(0))); Calculate_CMP(global_temp); return; } // 0xDB - DCP - Absolute , Y
// --------------------------------------------------------------------------------------------------
// ISC - Increase memory by one, then subtract memory from accumulator (with borrow).
// --------------------------------------------------------------------------------------------------
void opcode_0xE7() { Double_WriteBack(Calculate_INC(Fetch_ZeroPage())); Calculate_SBC(global_temp); return; } // 0xE7 - ISC - ZeroPage
void opcode_0xF7() { Double_WriteBack(Calculate_INC(Fetch_ZeroPage_X())); Calculate_SBC(global_temp); return; } // 0xF7 - ISC - ZeroPage , X
void opcode_0xE3() { Double_WriteBack(Calculate_INC(Fetch_Indexed_Indirect_X())); Calculate_SBC(global_temp); return; } // 0xE3 - ISC - Indexed Indirect X
void opcode_0xF3() { Double_WriteBack(Calculate_INC(Fetch_Indexed_Indirect_Y(0))); Calculate_SBC(global_temp); return; } // 0xF3 - ISC - Indirect Indexed Y
void opcode_0xEF() { Double_WriteBack(Calculate_INC(Fetch_Absolute())); Calculate_SBC(global_temp); return; } // 0xEF - ISC - Absolute
void opcode_0xFF() { Double_WriteBack(Calculate_INC(Fetch_Absolute_X(0))); Calculate_SBC(global_temp); return; } // 0xFF - ISC - Absolute , X
void opcode_0xFB() { Double_WriteBack(Calculate_INC(Fetch_Absolute_Y(0))); Calculate_SBC(global_temp); return; } // 0xFB - ISC - Absolute , Y
// --------------------------------------------------------------------------------------------------
// ANC - ANDs the contents of the A register with an immediate value and then moves bit 7 of A
// into the Carry flag.
// --------------------------------------------------------------------------------------------------
void Calculate_ANC(uint8_t local_data) {
Begin_Fetch_Next_Opcode();
register_a = register_a & local_data;
if ((0x80&register_a)==0x80) register_flags = register_flags | 0x01; // Set the C flag
else register_flags = register_flags & 0xFE; // Clear the C flag
Calc_Flags_NEGATIVE_ZERO(register_a);
return;
}
void opcode_0x0B() { Calculate_ANC(Fetch_Immediate()); return; } // 0x0B - ANC - Immediate
void opcode_0x2B() { Calculate_ANC(Fetch_Immediate()); return; } // 0x2B - ANC - Immediate
// --------------------------------------------------------------------------------------------------
// ALR - AND the contents of the A register with an immediate value and then LSRs the result.
// --------------------------------------------------------------------------------------------------
void Calculate_ALR(uint8_t local_data) {
Begin_Fetch_Next_Opcode();
register_a = register_a & local_data;
if ((0x01&register_a)==0x01) register_flags = register_flags | 0x01; // Set the C flag
else register_flags = register_flags & 0xFE; // Clear the C flag
register_a = (0x7F& (register_a >> 1));
Calc_Flags_NEGATIVE_ZERO(register_a);
return;
}
void opcode_0x4B() { Calculate_ALR(Fetch_Immediate()); return; } // 0x4B - ALR - Immediate
// --------------------------------------------------------------------------------------------------
// ARR - ANDs the accumulator with an immediate value and then rotates the content right.
// --------------------------------------------------------------------------------------------------
void Calculate_ARR(uint8_t local_data) {
Begin_Fetch_Next_Opcode();
register_a = register_a & local_data;
register_a = (0x7F& (register_a >> 1));
register_flags = register_flags & 0xBE; // Pre-clear the C and V flags
if ( (0xC0 & register_a) == 0x40) { register_flags = register_flags | 0x40; } // Set the V flag
if ( (0xC0 & register_a) == 0x80) { register_flags = register_flags | 0x41; } // Set the C and V flags
if ( (0xC0 & register_a) == 0xC0) { register_flags = register_flags | 0x01; } // Set the C flag
Calc_Flags_NEGATIVE_ZERO(register_a);
return;
}
void opcode_0x6B() { Calculate_ARR(Fetch_Immediate()); return; } // 0x6B - ARR - Immediate
// --------------------------------------------------------------------------------------------------
// SBX - ANDs the contents of the A and X registers (leaving the contents of A intact),
// subtracts an immediate value, and then stores the result in X.
// --------------------------------------------------------------------------------------------------
void Calculate_SBX(uint16_t local_data) {
int16_t signed_total=0;
Begin_Fetch_Next_Opcode();
register_x = register_a & register_x;
register_x = register_x - local_data;
signed_total = (int16_t)register_x - (int16_t)(local_data );
if (signed_total>=0) register_flags = register_flags | 0x01; // Set the C flag
else register_flags = register_flags & 0xFE; // Clear the C flag
register_x = (0xFF & register_x);
Calc_Flags_NEGATIVE_ZERO(register_x);
return;
}
void opcode_0xCB() { Calculate_SBX(Fetch_Immediate()); return; } // 0xCB - SBX - Immediate
// --------------------------------------------------------------------------------------------------
// LAS - AND memory with stack pointer, transfer result to accumulator, X register and stack pointer.
// --------------------------------------------------------------------------------------------------
void opcode_0xBB() { register_sp=(register_sp&Fetch_Absolute_Y(1)); register_a=register_sp; register_x=register_sp; Begin_Fetch_Next_Opcode(); Calc_Flags_NEGATIVE_ZERO(register_a); return; } // 0xBB - LAS - Absolute , Y
// --------------------------------------------------------------------------------------------------
// NOP - Fetch Immediate
// --------------------------------------------------------------------------------------------------
void opcode_0x80() { Fetch_Immediate(); Begin_Fetch_Next_Opcode(); return; } // 0x80 - NOP - Immediate
void opcode_0x82() { Fetch_Immediate(); Begin_Fetch_Next_Opcode(); return; } // 0x82 - NOP - Immediate
void opcode_0xC2() { Fetch_Immediate(); Begin_Fetch_Next_Opcode(); return; } // 0xC2 - NOP - Immediate
void opcode_0xE2() { Fetch_Immediate(); Begin_Fetch_Next_Opcode(); return; } // 0xE2 - NOP - Immediate
void opcode_0x89() { Fetch_Immediate(); Begin_Fetch_Next_Opcode(); return; } // 0x89 - NOP - Immediate
// --------------------------------------------------------------------------------------------------
// NOP - Fetch ZeroPage
// --------------------------------------------------------------------------------------------------
void opcode_0x04() { Fetch_ZeroPage(); Begin_Fetch_Next_Opcode(); return; } // 0x04 - NOP - ZeroPage
void opcode_0x44() { Fetch_ZeroPage(); Begin_Fetch_Next_Opcode(); return; } // 0x44 - NOP - ZeroPage
void opcode_0x64() { Fetch_ZeroPage(); Begin_Fetch_Next_Opcode(); return; } // 0x64 - NOP - ZeroPage
// --------------------------------------------------------------------------------------------------
// NOP - Fetch ZeroPage , X
// --------------------------------------------------------------------------------------------------
void opcode_0x14() { Fetch_ZeroPage_X(); Begin_Fetch_Next_Opcode(); return; } // 0x14 - NOP - ZeroPage , X
void opcode_0x34() { Fetch_ZeroPage_X(); Begin_Fetch_Next_Opcode(); return; } // 0x34 - NOP - ZeroPage , X
void opcode_0x54() { Fetch_ZeroPage_X(); Begin_Fetch_Next_Opcode(); return; } // 0x54 - NOP - ZeroPage , X
void opcode_0x74() { Fetch_ZeroPage_X(); Begin_Fetch_Next_Opcode(); return; } // 0x74 - NOP - ZeroPage , X
void opcode_0xD4() { Fetch_ZeroPage_X(); Begin_Fetch_Next_Opcode(); return; } // 0xD4 - NOP - ZeroPage , X
void opcode_0xF4() { Fetch_ZeroPage_X(); Begin_Fetch_Next_Opcode(); return; } // 0xF4 - NOP - ZeroPage , X
// --------------------------------------------------------------------------------------------------
// NOP - Fetch Absolute
// --------------------------------------------------------------------------------------------------
void opcode_0x0C() { Fetch_Absolute(); Begin_Fetch_Next_Opcode(); return; } // 0x0C - NOP - Absolute
// --------------------------------------------------------------------------------------------------
// NOP - Fetch Absolute , X
// --------------------------------------------------------------------------------------------------
void opcode_0x1C() { Fetch_Absolute_X(1); Begin_Fetch_Next_Opcode(); return; } // 0x1C - NOP - Absolute , X
void opcode_0x3C() { Fetch_Absolute_X(1); Begin_Fetch_Next_Opcode(); return; } // 0x3C - NOP - Absolute , X
void opcode_0x5C() { Fetch_Absolute_X(1); Begin_Fetch_Next_Opcode(); return; } // 0x5C - NOP - Absolute , X
void opcode_0x7C() { Fetch_Absolute_X(1); Begin_Fetch_Next_Opcode(); return; } // 0x7C - NOP - Absolute , X
void opcode_0xDC() { Fetch_Absolute_X(1); Begin_Fetch_Next_Opcode(); return; } // 0xDC - NOP - Absolute , X
void opcode_0xFC() { Fetch_Absolute_X(1); Begin_Fetch_Next_Opcode(); return; } // 0xFC - NOP - Absolute , X
// --------------------------------------------------------------------------------------------------
// JAM - Lock up the processor
// --------------------------------------------------------------------------------------------------
void opcode_0x02() { Fetch_Immediate(); while (1) {} return; } // 0x02 - JAM
void opcode_0x12() { Fetch_Immediate(); while (1) {} return; } // 0x12 - JAM
void opcode_0x22() { Fetch_Immediate(); while (1) {} return; } // 0x22 - JAM
void opcode_0x32() { Fetch_Immediate(); while (1) {} return; } // 0x32 - JAM
void opcode_0x42() { Fetch_Immediate(); while (1) {} return; } // 0x42 - JAM
void opcode_0x52() { Fetch_Immediate(); while (1) {} return; } // 0x52 - JAM
void opcode_0x62() { Fetch_Immediate(); while (1) {} return; } // 0x62 - JAM
void opcode_0x72() { Fetch_Immediate(); while (1) {} return; } // 0x72 - JAM
void opcode_0x92() { Fetch_Immediate(); while (1) {} return; } // 0x92 - JAM
void opcode_0xB2() { Fetch_Immediate(); while (1) {} return; } // 0xB2 - JAM
void opcode_0xD2() { Fetch_Immediate(); while (1) {} return; } // 0xD2 - JAM
void opcode_0xF2() { Fetch_Immediate(); while (1) {} return; } // 0xF2 - JAM
// --------------------------------------------------------------------------------------------------
// Unstable 6502 opcodes
// --------------------------------------------------------------------------------------------------
void opcode_0x93() { Fetch_ZeroPage_Y(); Begin_Fetch_Next_Opcode(); return; } // 0x93 - SHA - ZeroPage , Y - Implelented here as a size 2 NOP
void opcode_0x9F() { Fetch_Absolute_Y(0); Begin_Fetch_Next_Opcode(); return; } // 0x9F - SHA - Absolute , Y - Implelented here as a size 3 NOP
void opcode_0x9E() { Fetch_Absolute_Y(0); Begin_Fetch_Next_Opcode(); return; } // 0x9E - SHX - Absolute , Y - Implelented here as a size 3 NOP
void opcode_0x9C() { Fetch_Absolute_X(0); Begin_Fetch_Next_Opcode(); return; } // 0x9C - SHY - Absolute , X - Implelented here as a size 3 NOP
void opcode_0x9B() { Fetch_Absolute_Y(0); Begin_Fetch_Next_Opcode(); return; } // 0x9B - TAS - Absolute , Y - Implelented here as a size 3 NOP
void opcode_0x8B() { Fetch_Immediate(); Begin_Fetch_Next_Opcode(); return; } // 0x8B - ANE - Immediate - Implelented here as a size 2 NOP
void opcode_0xAB() { Fetch_Immediate(); Begin_Fetch_Next_Opcode(); return; } // 0xAB - LAX - Immediate - Implelented here as a size 2 NOP
// --------------------------------------------------------------------------------------------------
// --------------------------------------------------------------------------------------------------
// -------------------------------------------------
//
// Main loop
//
// -------------------------------------------------
void loop() {
uint8_t Keyboard_Byte=0;
uint8_t Keyboard_Poll_Delay=0;
// Give Teensy 4.1 a moment
delay (3000);
reset_sequence();
wait_for_CLK_rising_edge();
wait_for_CLK_rising_edge();
wait_for_CLK_rising_edge();
reset_sequence();
// Set Apple II Soft-Switches to the correct video mode and page
//
write_byte(0xC051 , 0x0 ); // Set Apple II Text Mode
write_byte(0xC054 , 0x0 ); // Set Apple II Text Page 1
// Clear out any existing keystrokes
//
read_byte(0xC010); delay (1);
read_byte(0xC010); delay (1);
read_byte(0xC010); delay (1);
read_byte(0xC010); delay (1);
while (1) {
if (direct_reset==1) reset_sequence();
// Poll for NMI and IRQ
//
if (nmi_n_old==0 && direct_nmi==1) nmi_handler();
nmi_n_old = direct_nmi;
if (direct_irq==0x1 && (flag_i)==0x0) irq_handler(0x0);
next_instruction = finish_read_byte();
assert_sync=0;
// Apple 1 terminal input from Apple II Keyboard
//
Keyboard_Poll_Delay++;
if (Keyboard_Poll_Delay==0xFF) { // Poll keyboard once every 256 instructions
Keyboard_Byte = read_byte(0xC000);delay (1); // Read character from keyboard
if ( (internal_RAM[0xD011]==0x00) && Keyboard_Byte>=0x80 ) {
internal_RAM[0xD010] = (0x80 | Keyboard_Byte ); // Force bit[7] to '1' like Apple 1
internal_RAM[0xD011] = 0x80; // Set bit[7] to '1' to indicate a new keypress available
Keyboard_Byte = read_byte(0xC010);delay (1);
while(Keyboard_Byte >= 0x80) { Keyboard_Byte = read_byte(0xC010); }
}
}
switch (next_instruction){
case 0x00: irq_handler(0x1); break; // BRK - Break
case 0x01: opcode_0x01(); break; // OR - Indexed Indirect X
case 0x02: opcode_0x02(); break; // JAM
case 0x03: opcode_0x03(); break; // SLO - Indexed Indirect X
case 0x04: opcode_0x04(); break; // NOP - ZeroPage
case 0x05: opcode_0x05(); break; // OR ZeroPage
case 0x06: opcode_0x06(); break; // ASL A - Arithmetic Shift Left - ZeroPage
case 0x07: opcode_0x07(); break; // SLO - ZeroPage
case 0x08: opcode_0x08(); break; // PHP - Push processor status to the stack
case 0x09: opcode_0x09(); break; // OR - Immediate
case 0x0A: opcode_0x0A(); break; // ASL A
case 0x0B: opcode_0x0B(); break; // ANC - Immediate
case 0x0C: opcode_0x0C(); break; // NOP - Absolute
case 0x0D: opcode_0x0D(); break; // OR - Absolute
case 0x0E: opcode_0x0E(); break; // ASL A - Arithmetic Shift Left - Absolute
case 0x0F: opcode_0x0F(); break; // SLO - Absolute
case 0x10: opcode_0x10(); break; // BNE - Branch on Zero Clear
case 0x11: opcode_0x11(); break; // OR Indirect Indexed Y
case 0x12: opcode_0x12(); break; // JAM
case 0x13: opcode_0x13(); break; // Indirect Indexed Y
case 0x14: opcode_0x14(); break; // NOP - ZeroPage , X
case 0x15: opcode_0x15(); break; // OR - ZeroPage,X
case 0x16: opcode_0x16(); break; // ASL A - Arithmetic Shift Left - ZeroPage , X
case 0x17: opcode_0x17(); break; // SLO - ZeroPage , X
case 0x18: opcode_0x18(); break; // CLC
case 0x19: opcode_0x19(); break; // OR - Absolute,Y
case 0x1A: opcode_0xEA(); break; // NOP
case 0x1B: opcode_0x1B(); break; // SLO - Absolute , Y
case 0x1C: opcode_0x1C(); break; // NOP - Absolute , X
case 0x1D: opcode_0x1D(); break; // OR - Absolute,X
case 0x1E: opcode_0x1E(); break; // ASL A - Arithmetic Shift Left - Absolute , X
case 0x1F: opcode_0x1F(); break; // SLO - Absolute , X
case 0x20: opcode_0x20(); break; // JSR - Jump to Subroutine
case 0x21: opcode_0x21(); break; // AND - Indexed Indirect
case 0x22: opcode_0x22(); break; // JAM
case 0x23: opcode_0x23(); break; // RLA - Indexed Indirect X
case 0x24: opcode_0x24(); break; // BIT - ZeroPage
case 0x25: opcode_0x25(); break; // AND - ZeroPage
case 0x26: opcode_0x26(); break; // ROL - Rotate Left - ZeroPage
case 0x27: opcode_0x27(); break; // RLA - ZeroPage
case 0x28: opcode_0x28(); break; // PLP - Pop processor status from the stack
case 0x29: opcode_0x29(); break; // AND - Immediate
case 0x2A: opcode_0x2A(); break; // ROL A
case 0x2B: opcode_0x2B(); break; // ANC - Immediate
case 0x2C: opcode_0x2C(); break; // BIT - Absolute
case 0x2D: opcode_0x2D(); break; // AND - Absolute
case 0x2E: opcode_0x2E(); break; // ROL - Rotate Left - Absolute
case 0x2F: opcode_0x2F(); break; // RLA - Absolute
case 0x30: opcode_0x30(); break; // BMI - Branch on Minus (N Flag Set)
case 0x31: opcode_0x31(); break; // AND - Indirect Indexed
case 0x32: opcode_0x32(); break; // JAM
case 0x33: opcode_0x33(); break; // RLA - Indirect Indexed Y
case 0x34: opcode_0x34(); break; // NOP - ZeroPage , X
case 0x35: opcode_0x35(); break; // AND - ZeroPage,X
case 0x36: opcode_0x36(); break; // ROL - Rotate Left - ZeroPage , X
case 0x37: opcode_0x37(); break; // RLA - ZeroPage , X
case 0x38: opcode_0x38(); break; // SEC
case 0x39: opcode_0x39(); break; // AND - Absolute,Y
case 0x3A: opcode_0xEA(); break; // NOP
case 0x3B: opcode_0x3B(); break; // RLA - Absolute , Y
case 0x3C: opcode_0x3C(); break; // NOP - Absolute , X
case 0x3D: opcode_0x3D(); break; // AND - Absolute,X
case 0x3E: opcode_0x3E(); break; // ROL - Rotate Left - Absolute , X
case 0x3F: opcode_0x3F(); break; // RLA - Absolute , X
case 0x40: opcode_0x40(); break; // RTI - Return from Interrupt
case 0x41: opcode_0x41(); break; // EOR - Indexed Indirect X
case 0x42: opcode_0x42(); break; // JAM
case 0x43: opcode_0x43(); break; // SRE - Indexed Indirect X
case 0x44: opcode_0x44(); break; // NOP - ZeroPage
case 0x45: opcode_0x45(); break; // EOR - ZeroPage
case 0x46: opcode_0x46(); break; // LSR - Logical Shift Right - ZeroPage
case 0x47: opcode_0x47(); break; // SRE - ZeroPage
case 0x48: opcode_0x48(); break; // PHA - Push Accumulator to the stack
case 0x49: opcode_0x49(); break; // EOR - Immediate
case 0x4A: opcode_0x4A(); break; // LSR A
case 0x4B: opcode_0x4B(); break; // ALR - Immediate
case 0x4C: opcode_0x4C(); break; // JMP - Jump Absolute
case 0x4D: opcode_0x4D(); break; // EOR - Absolute
case 0x4E: opcode_0x4E(); break; // LSR - Logical Shift Right - Absolute
case 0x4F: opcode_0x4F(); break; // SRE - Absolute
case 0x50: opcode_0x50(); break; // BVC - Branch on Overflow Clear
case 0x51: opcode_0x51(); break; // EOR - Indirect Indexed Y
case 0x52: opcode_0x52(); break; // JAM
case 0x53: opcode_0x53(); break; // SRE - Indirect Indexed Y
case 0x54: opcode_0x54(); break; // NOP - ZeroPage , X
case 0x55: opcode_0x55(); break; // EOR - ZeroPage,X
case 0x56: opcode_0x56(); break; // LSR - Logical Shift Right - ZeroPage , X
case 0x57: opcode_0x57(); break; // SRE - ZeroPage , X
case 0x58: opcode_0x58(); break; // CLI
case 0x59: opcode_0x59(); break; // EOR - Absolute,Y
case 0x5A: opcode_0xEA(); break; // NOP
case 0x5B: opcode_0x5B(); break; // RE - Absolute , Y
case 0x5C: opcode_0x5C(); break; // NOP - Absolute , X
case 0x5D: opcode_0x5D(); break; // EOR - Absolute,X
case 0x5E: opcode_0x5E(); break; // LSR - Logical Shift Right - Absolute , X
case 0x5F: opcode_0x5F(); break; // SRE - Absolute , X
case 0x60: opcode_0x60(); break; // RTS - Return from Subroutine
case 0x61: opcode_0x61(); break; // ADC - Indexed Indirect X
case 0x62: opcode_0x62(); break; // JAM
case 0x63: opcode_0x63(); break; // RRA - Indexed Indirect X
case 0x64: opcode_0x64(); break; // NOP - ZeroPage
case 0x65: opcode_0x65(); break; // ADC - ZeroPage
case 0x66: opcode_0x66(); break; // ROR - Rotate Right - ZeroPage
case 0x67: opcode_0x67(); break; // RRA - ZeroPage
case 0x68: opcode_0x68(); break; // PLA - Pop Accumulator from the stack
case 0x69: opcode_0x69(); break; // ADC - Immediate
case 0x6A: opcode_0x6A(); break; // ROR A
case 0x6B: opcode_0x6B(); break; // ARR - Immediate
case 0x6C: opcode_0x6C(); break; // JMP - Jump Indirect
case 0x6D: opcode_0x6D(); break; // ADC - Absolute
case 0x6E: opcode_0x6E(); break; // ROR - Rotate Right - Absolute
case 0x6F: opcode_0x6F(); break; // RRA - Absolute
case 0x70: opcode_0x70(); break; // BVS - Branch on Overflow Set
case 0x71: opcode_0x71(); break; // ADC - Indirect Indexed Y
case 0x72: opcode_0x72(); break; // JAM
case 0x73: opcode_0x73(); break; // RRA - Indirect Indexed Y
case 0x74: opcode_0x74(); break; // NOP - ZeroPage , X
case 0x75: opcode_0x75(); break; // ADC - ZeroPage , X
case 0x76: opcode_0x76(); break; // ROR - Rotate Right - ZeroPage , X
case 0x77: opcode_0x77(); break; // RRA - ZeroPage , X
case 0x78: opcode_0x78(); break; // SEI
case 0x79: opcode_0x79(); break; // ADC - Absolute , Y
case 0x7A: opcode_0xEA(); break; // NOP
case 0x7B: opcode_0x7B(); break; // RRA - Absolute , Y
case 0x7C: opcode_0x7C(); break; // NOP - Absolute , X
case 0x7D: opcode_0x7D(); break; // ADC - Absolute , X
case 0x7E: opcode_0x7E(); break; // ROR - Rotate Right - Absolute , X
case 0x7F: opcode_0x7F(); break; // RRA - Absolute , X
case 0x80: opcode_0x80(); break; // NOP - Immediate
case 0x81: opcode_0x81(); break; // STA - Indexed Indirect X
case 0x82: opcode_0x82(); break; // NOP - Immediate
case 0x83: opcode_0x83(); break; // SAX - Indexed Indirect X
case 0x84: opcode_0x84(); break; // STY - ZeroPage
case 0x85: opcode_0x85(); break; // STA - ZeroPage
case 0x86: opcode_0x86(); break; // STX - ZeroPage
case 0x87: opcode_0x87(); break; // SAX - ZeroPage
case 0x88: opcode_0x88(); break; // DEY
case 0x89: opcode_0x89(); break; // NOP - Immediate
case 0x8A: opcode_0x8A(); break; // TXA
case 0x8B: opcode_0x8B(); break; // ANE - Immediate
case 0x8C: opcode_0x8C(); break; // STY - Absolute
case 0x8D: opcode_0x8D(); break; // STA - Absolute
case 0x8E: opcode_0x8E(); break; // STX - Absolute
case 0x8F: opcode_0x8F(); break; // SAX - Absolute
case 0x90: opcode_0x90(); break; // BCC - Branch on Carry Clear
case 0x91: opcode_0x91(); break; // STA - Indirect Indexed Y
case 0x92: opcode_0x92(); break; // JAM
case 0x93: opcode_0x93(); break; // SHA - ZeroPage , Y
case 0x94: opcode_0x94(); break; // STY - ZeroPage , X
case 0x95: opcode_0x95(); break; // STA - ZeroPage , X
case 0x96: opcode_0x96(); break; // STX - ZeroPage , Y
case 0x97: opcode_0x97(); break; // SAX - ZeroPage , Y
case 0x98: opcode_0x98(); break; // TYA
case 0x99: opcode_0x99(); break; // STA - Absolute , Y
case 0x9A: opcode_0x9A(); break; // TXS
case 0x9B: opcode_0x9B(); break; // TAS - Absolute , Y
case 0x9C: opcode_0x9C(); break; // SHY - Absolute , X
case 0x9D: opcode_0x9D(); break; // STA - Absolute , X
case 0x9E: opcode_0x9E(); break; // SHX - Absolute , Y
case 0x9F: opcode_0x9F(); break; // SHA - Absolute , Y
case 0xA0: opcode_0xA0(); break; // LDY - Immediate
case 0xA1: opcode_0xA1(); break; // LDA - Indexed Indirect X
case 0xA2: opcode_0xA2(); break; // LDX - Immediate
case 0xA3: opcode_0xA3(); break; // LAX - Indexed Indirect X
case 0xA4: opcode_0xA4(); break; // LDY - ZeroPage
case 0xA5: opcode_0xA5(); break; // LDA - ZeroPage
case 0xA6: opcode_0xA6(); break; // LDX - ZeroPage
case 0xA7: opcode_0xA7(); break; // LAX - ZeroPage
case 0xA8: opcode_0xA8(); break; // TAY
case 0xA9: opcode_0xA9(); break; // LDA - Immediate
case 0xAA: opcode_0xAA(); break; // TAX
case 0xAB: opcode_0xAB(); break; // LAX - Immediate
case 0xAC: opcode_0xAC(); break; // LDY - Absolute
case 0xAD: opcode_0xAD(); break; // LDA - Absolute
case 0xAE: opcode_0xAE(); break; // LDX - Absolute
case 0xAF: opcode_0xAF(); break; // LAX - Absolute
case 0xB0: opcode_0xB0(); break; // BCS - Branch on Carry Set
case 0xB1: opcode_0xB1(); break; // LDA - Indirect Indexed Y
case 0xB2: opcode_0xB2(); break; // JAM
case 0xB3: opcode_0xB3(); break; // LAX - Indirect Indexed Y
case 0xB4: opcode_0xB4(); break; // LDY - ZeroPage , X
case 0xB5: opcode_0xB5(); break; // LDA - ZeroPage , X
case 0xB6: opcode_0xB6(); break; // LDX - ZeroPage , Y
case 0xB7: opcode_0xB7(); break; // LAX - ZeroPage , Y
case 0xB8: opcode_0xB8(); break; // CLV
case 0xB9: opcode_0xB9(); break; // LDA - Absolute , Y
case 0xBA: opcode_0xBA(); break; // TSX
case 0xBB: opcode_0xBB(); break; // LAS - Absolute , Y
case 0xBC: opcode_0xBC(); break; // LDY - Absolute , X
case 0xBD: opcode_0xBD(); break; // LDA - Absolute , X
case 0xBE: opcode_0xBE(); break; // LDX - Absolute , Y
case 0xBF: opcode_0xBF(); break; // LAX - Absolute , Y
case 0xC0: opcode_0xC0(); break; // CPY - Immediate
case 0xC1: opcode_0xC1(); break; // CMP - Indexed Indirect X
case 0xC2: opcode_0xC2(); break; // NOP - Immediate
case 0xC3: opcode_0xC3(); break; // DCP - Indexed Indirect X
case 0xC4: opcode_0xC4(); break; // CPY - ZeroPage
case 0xC5: opcode_0xC5(); break; // CMP - ZeroPage
case 0xC6: opcode_0xC6(); break; // DEC - ZeroPage
case 0xC7: opcode_0xC7(); break; // DCP - ZeroPage
case 0xC8: opcode_0xC8(); break; // INY
case 0xC9: opcode_0xC9(); break; // CMP - Immediate
case 0xCA: opcode_0xCA(); break; // DEX
case 0xCB: opcode_0xCB(); break; // SBX - Immediate
case 0xCC: opcode_0xCC(); break; // CPY - Absolute
case 0xCD: opcode_0xCD(); break; // CMP - Absolute
case 0xCE: opcode_0xCE(); break; // DEC - Absolute
case 0xCF: opcode_0xCF(); break; // DCP - Absolute
case 0xD0: opcode_0xD0(); break; // BNE - Branch on Zero Clear
case 0xD1: opcode_0xD1(); break; // CMP - Indirect Indexed Y
case 0xD2: opcode_0xD2(); break; // JAM
case 0xD3: opcode_0xD3(); break; // DCP - Indirect Indexed Y
case 0xD4: opcode_0xD4(); break; // NOP - ZeroPage , X
case 0xD5: opcode_0xD5(); break; // CMP - ZeroPage , X
case 0xD6: opcode_0xD6(); break; // DEC - ZeroPage , X
case 0xD7: opcode_0xD7(); break; // DCP - ZeroPage , X
case 0xD8: opcode_0xD8(); break; // CLD
case 0xD9: opcode_0xD9(); break; // CMP - Absolute , Y
case 0xDA: opcode_0xEA(); break; // NOP
case 0xDB: opcode_0xDB(); break; // DCP - Absolute , Y
case 0xDC: opcode_0xDC(); break; // NOP - Absolute , X
case 0xDD: opcode_0xDD(); break; // CMP - Absolute , X
case 0xDE: opcode_0xDE(); break; // DEC - Absolute , X
case 0xDF: opcode_0xDF(); break; // DCP - Absolute , X
case 0xE0: opcode_0xE0(); break; // CPX - Immediate
case 0xE1: opcode_0xE1(); break; // SBC - Indexed Indirect X
case 0xE2: opcode_0xE2(); break; // NOP - Immediate
case 0xE3: opcode_0xE3(); break; // ISC - Indexed Indirect X
case 0xE4: opcode_0xE4(); break; // CPX - ZeroPage
case 0xE5: opcode_0xE5(); break; // SBC - ZeroPage
case 0xE6: opcode_0xE6(); break; // INC - ZeroPage
case 0xE7: opcode_0xE7(); break; // ISC - ZeroPage
case 0xE8: opcode_0xE8(); break; // INX
case 0xE9: opcode_0xE9(); break; // SBC - Immediate
case 0xEA: opcode_0xEA(); break; // NOP
case 0xEB: opcode_0xE9(); break; // SBC - Immediate
case 0xEC: opcode_0xEC(); break; // CPX - Absolute
case 0xED: opcode_0xED(); break; // SBC - Absolute
case 0xEE: opcode_0xEE(); break; // INC - Absolute
case 0xEF: opcode_0xEF(); break; // ISC - Absolute
case 0xF0: opcode_0xF0(); break; // BEQ - Branch on Zero Set
case 0xF1: opcode_0xF1(); break; // SBC - Indirect Indexed Y
case 0xF2: opcode_0xF2(); break; // JAM
case 0xF3: opcode_0xF3(); break; // ISC - Indirect Indexed Y
case 0xF4: opcode_0xF4(); break; // NOP - ZeroPage , X
case 0xF5: opcode_0xF5(); break; // SBC - ZeroPage , X
case 0xF6: opcode_0xF6(); break; // INC - ZeroPage , X
case 0xF7: opcode_0xF7(); break; // ISC - ZeroPage , X
case 0xF8: opcode_0xF8(); break; // SED
case 0xF9: opcode_0xF9(); break; // SBC - Absolute , Y
case 0xFA: opcode_0xEA(); break; // NOP
case 0xFB: opcode_0xFB(); break; // ISC - Absolute , Y
case 0xFC: opcode_0xFC(); break; // NOP - Absolute , X
case 0xFD: opcode_0xFD(); break; // SBC - Absolute , X
case 0xFE: opcode_0xFE(); break; // INC - Absolute , X
case 0xFF: opcode_0xFF(); break; // ISC - Absolute , X
}
}
}