├── 6502tests ├── test │ ├── testRts.c │ ├── testPha.c │ ├── testBrk.c │ ├── testPlp.c │ ├── testRti.c │ ├── test.iml │ ├── testPla.c │ ├── testPhp.c │ ├── testBmi.c │ ├── testBpl.c │ ├── testBeq.c │ ├── testBne.c │ ├── testBvc.c │ ├── testBvs.c │ ├── testBcc.c │ ├── testBcs.c │ ├── testSet.c │ ├── testClear.c │ ├── testJmp.c │ ├── testBit.c │ ├── testSt.c │ ├── testSta.c │ ├── testTransfer.c │ ├── testEor.c │ ├── testDec.c │ ├── testInc.c │ ├── testCpx.c │ ├── testCpy.c │ ├── testLsr.c │ ├── testRor.c │ ├── testRol.c │ ├── testAsl.c │ ├── testOra.c │ ├── testAnd.c │ ├── testCmp.c │ ├── testSbc.c │ ├── testLd.c │ └── testAdc.c └── test.c ├── APPLEII ├── speaker.ino ├── ghettovga.ino ├── monitor.ino ├── screen.ino ├── APPLEII.ino ├── keyboard.ino ├── cassette.ino ├── cpu.ino └── memory.ino ├── README.md └── LICENSE /6502tests/test/testRts.c: -------------------------------------------------------------------------------- 1 | int testRtsImplied() { 2 | push8(0x00); //high byte pc 3 | push8(0x02); // low byte pc 4 | ram[0] = 0x60; 5 | instructions = 1; run(); 6 | if(!(PC == 0x03)) return -1; 7 | return 0; 8 | } -------------------------------------------------------------------------------- /6502tests/test/testPha.c: -------------------------------------------------------------------------------- 1 | int testPhaImplied() { 2 | unsigned short beginSp = SP; 3 | A = 0x23; 4 | ram[0] = 0x48; 5 | instructions = 1; run(); 6 | if(!((beginSp-SP) == 1 && pull8() == 0x23)) return -1; 7 | return 0; 8 | } -------------------------------------------------------------------------------- /6502tests/test/testBrk.c: -------------------------------------------------------------------------------- 1 | int testBrkImplied() { 2 | SR &= (~SR_INT); 3 | SP = 0xFF; 4 | ram[0] = 0x00; 5 | instructions = 4; run(); 6 | if(!(SR&SR_INT) || PC != (read8(0xFFFE)|((unsigned short)read8(0xFFFF)<<8)) || SP != 0xFC) return -1; 7 | return 0; 8 | } -------------------------------------------------------------------------------- /6502tests/test/testPlp.c: -------------------------------------------------------------------------------- 1 | int testPlpImplied() { 2 | SR = 0x20; 3 | push8(0xBA); 4 | ram[0] = 0x28; 5 | instructions = 1; run(); 6 | if(!(SR&SR_NEG && !(SR&SR_OVER) && SR&SR_DEC && !(SR&SR_INT) && SR&SR_ZERO && !(SR&SR_CARRY))) return -1; 7 | return 0; 8 | } -------------------------------------------------------------------------------- /APPLEII/speaker.ino: -------------------------------------------------------------------------------- 1 | #define SPEAKER_PIN 5 2 | 3 | void speaker_begin() { 4 | pinMode(SPEAKER_PIN, OUTPUT); 5 | digitalWrite(SPEAKER_PIN, LOW); 6 | } 7 | 8 | void speaker_toggle() { 9 | static boolean state = false; 10 | state = (state)?false:true; 11 | digitalWrite(SPEAKER_PIN, state); 12 | } 13 | -------------------------------------------------------------------------------- /6502tests/test/testRti.c: -------------------------------------------------------------------------------- 1 | int testRtiImplied() { 2 | push8(0x00); //high byte pc 3 | push8(0x02); // low byte pc 4 | push8(0xBA); //SR 5 | ram[0] = 0x40; 6 | instructions = 1; run(); 7 | if(!(SR&SR_NEG && !(SR&SR_OVER) && SR&SR_DEC && !(SR&SR_INT) && SR&SR_ZERO && !(SR&SR_CARRY) && PC == 0x02)) return -1; 8 | return 0; 9 | } -------------------------------------------------------------------------------- /6502tests/test/test.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /6502tests/test/testPla.c: -------------------------------------------------------------------------------- 1 | int testPlaImplied() { 2 | //no flags 3 | A = 0x00; 4 | push8(0x23); 5 | ram[0] = 0x68; 6 | instructions = 1; run(); 7 | if(!(A == 0x23 && !(SR&SR_ZERO) && !(SR&SR_NEG))) return -1; 8 | 9 | //zero flag 10 | A = 0x23; 11 | push8(0x00); 12 | ram[0] = 0x68; 13 | instructions = 1; run(); 14 | if(!(A == 0x00 && SR&SR_ZERO && !(SR&SR_NEG))) return -1; 15 | 16 | return 0; 17 | } -------------------------------------------------------------------------------- /6502tests/test/testPhp.c: -------------------------------------------------------------------------------- 1 | int testPhpImplied() { 2 | //random pattern 3 | SR |= SR_NEG; SR &= (~SR_OVER); SR |= SR_DEC; SR &= (~SR_INT); SR |= SR_ZERO; SR &= (~SR_CARRY); 4 | ram[0] = 0x08; 5 | instructions = 1; run(); 6 | if(!(pull8() == 0xBA)) return -1; 7 | 8 | //all set 9 | SR = 0xFF; 10 | ram[0] = 0x08; 11 | instructions = 1; run(); 12 | if(!(pull8() == 0xFF)) return -2; 13 | 14 | return 0; 15 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # arduino-appleii 2 | 3 | Emulate the Apple II Microcomputer / 6502 on an Arduino Uno. 4 | To be used in conjuction with video generation code in my arduino-vga repository. 5 | 6 | Currently somewhere between 5 and 8 times slower than real hardware, however the 7 | arduino is maybe 16-32x the speed of the original mos6502 CPU. Should be possible 8 | to tighten things up and reach realtime. 9 | 10 | Feel free to play arround! -------------------------------------------------------------------------------- /6502tests/test/testBmi.c: -------------------------------------------------------------------------------- 1 | int testBmiImplied() { 2 | SR |= SR_NEG; 3 | SR &= (~SR_DEC); 4 | ram[0] = 0x30; 5 | ram[1] = 0x01; 6 | ram[2] = 0x00; 7 | ram[3] = 0xF8; //SED 8 | instructions = 4; run(); 9 | if(!(SR&SR_DEC)) return -1; 10 | 11 | SR &= (~SR_NEG); 12 | SR &= (~SR_DEC); 13 | ram[0] = 0x30; 14 | ram[1] = 0x01; 15 | ram[2] = 0x00; 16 | ram[3] = 0xF8; 17 | instructions = 4; run(); 18 | if(SR&SR_DEC) return -2; 19 | 20 | return 0; 21 | } -------------------------------------------------------------------------------- /6502tests/test/testBpl.c: -------------------------------------------------------------------------------- 1 | int testBplImplied() { 2 | SR |= SR_NEG; 3 | SR &= (~SR_DEC); 4 | ram[0] = 0x10; 5 | ram[1] = 0x01; 6 | ram[2] = 0x00; 7 | ram[3] = 0xF8; //SED 8 | instructions = 4; run(); 9 | if(SR&SR_DEC) return -1; 10 | 11 | SR &= (~SR_NEG); 12 | SR &= (~SR_DEC); 13 | ram[0] = 0x10; 14 | ram[1] = 0x01; 15 | ram[2] = 0x00; 16 | ram[3] = 0xF8; 17 | instructions = 4; run(); 18 | if(!(SR&SR_DEC)) return -2; 19 | 20 | return 0; 21 | } -------------------------------------------------------------------------------- /6502tests/test/testBeq.c: -------------------------------------------------------------------------------- 1 | int testBeqImplied() { 2 | SR|=SR_ZERO; 3 | SR&=(~SR_DEC); 4 | ram[0] = 0xF0; 5 | ram[1] = 0x01; 6 | ram[2] = 0x00; 7 | ram[3] = 0xF8; //SED 8 | instructions = 4; 9 | run(); 10 | if((SR&SR_DEC) == 0) return -1; 11 | 12 | SR&=(~SR_ZERO); 13 | SR&=(~SR_DEC); 14 | ram[0] = 0xF0; 15 | ram[1] = 0x01; 16 | ram[2] = 0x00; 17 | ram[3] = 0xF8; 18 | instructions = 4; run(); 19 | if(SR&SR_DEC) return -2; 20 | 21 | return 0; 22 | } -------------------------------------------------------------------------------- /6502tests/test/testBne.c: -------------------------------------------------------------------------------- 1 | int testBneImplied() { 2 | SR &= (~SR_ZERO); 3 | SR &= (~SR_DEC); 4 | ram[0] = 0xD0; 5 | ram[1] = 0x01; 6 | ram[2] = 0x00; 7 | ram[3] = 0xF8; //SED 8 | instructions = 4; run(); 9 | if(!(SR&SR_DEC)) return -1; 10 | 11 | SR |= SR_ZERO; 12 | SR &= (~SR_DEC); 13 | ram[0] = 0xD0; 14 | ram[1] = 0x01; 15 | ram[2] = 0x00; 16 | ram[3] = 0xF8; 17 | instructions = 4; run(); 18 | if(SR&SR_DEC) return -2; 19 | 20 | return 0; 21 | } -------------------------------------------------------------------------------- /6502tests/test/testBvc.c: -------------------------------------------------------------------------------- 1 | int testBvcImplied() { 2 | SR |= SR_OVER; 3 | SR &= (~SR_DEC); 4 | ram[0] = 0x50; 5 | ram[1] = 0x01; 6 | ram[2] = 0x00; 7 | ram[3] = 0xF8; //SED 8 | instructions = 4; run(); 9 | if(SR&SR_DEC) return -1; 10 | 11 | SR &= (~SR_OVER); 12 | SR &= (~SR_DEC); 13 | ram[0] = 0x50; 14 | ram[1] = 0x01; 15 | ram[2] = 0x00; 16 | ram[3] = 0xF8; 17 | instructions = 4; run(); 18 | if(!(SR&SR_DEC)) return -2; 19 | 20 | return 0; 21 | } -------------------------------------------------------------------------------- /6502tests/test/testBvs.c: -------------------------------------------------------------------------------- 1 | int testBvsImplied() { 2 | SR |= SR_OVER; 3 | SR &= (~SR_DEC); 4 | ram[0] = 0x70; 5 | ram[1] = 0x01; 6 | ram[2] = 0x00; 7 | ram[3] = 0xF8; //SED 8 | instructions = 4; run(); 9 | if(!(SR&SR_DEC)) return -1; 10 | 11 | SR &= (~SR_OVER); 12 | SR &= (~SR_DEC); 13 | ram[0] = 0x70; 14 | ram[1] = 0x01; 15 | ram[2] = 0x00; 16 | ram[3] = 0xF8; 17 | instructions = 4; run(); 18 | if(SR&SR_DEC) return -2; 19 | 20 | return 0; 21 | } -------------------------------------------------------------------------------- /6502tests/test/testBcc.c: -------------------------------------------------------------------------------- 1 | int testBccImplied() { 2 | SR|=SR_CARRY; 3 | SR&=(~SR_DEC); 4 | ram[0] = 0x90; 5 | ram[1] = 0x01; 6 | ram[2] = 0x00; 7 | ram[3] = 0xF8; //SED 8 | instructions = 4; 9 | run(); 10 | if((SR&SR_DEC) > 0) return -1; 11 | 12 | SR&=(~SR_CARRY); 13 | SR&=(~SR_DEC); 14 | ram[0] = 0x90; 15 | ram[1] = 0x01; 16 | ram[2] = 0x00; 17 | ram[3] = 0xF8; 18 | instructions = 4; 19 | run(); 20 | if((SR&SR_DEC) == 0) return -2; 21 | 22 | return 0; 23 | } -------------------------------------------------------------------------------- /6502tests/test/testBcs.c: -------------------------------------------------------------------------------- 1 | int testBcsImplied() { 2 | SR|=SR_CARRY; 3 | SR&=(~SR_DEC); 4 | ram[0] = 0xB0; 5 | ram[1] = 0x01; 6 | ram[2] = 0x00; 7 | ram[3] = 0xF8; //SED 8 | instructions = 4; 9 | run(); 10 | if((SR&SR_DEC) == 0) return -1; 11 | 12 | SR&=(~SR_CARRY); 13 | SR&=(~SR_DEC); 14 | ram[0] = 0xB0; 15 | ram[1] = 0x01; 16 | ram[2] = 0x00; 17 | ram[3] = 0xF8; 18 | instructions = 4; 19 | run(); 20 | if((SR&SR_DEC) > 0) return -2; 21 | 22 | return 0; 23 | } -------------------------------------------------------------------------------- /6502tests/test/testSet.c: -------------------------------------------------------------------------------- 1 | int testSecImplied() { 2 | SR &= (~SR_CARRY); 3 | ram[0] = 0x38; 4 | instructions = 1; run(); 5 | if(!(SR&SR_CARRY)) return -1; 6 | return 0; 7 | } 8 | 9 | int testSedImplied() { 10 | SR &= (~SR_DEC); 11 | ram[0] = 0xF8; 12 | instructions = 1; run(); 13 | if(!(SR&SR_DEC)) return -1; 14 | return 0; 15 | } 16 | 17 | int testSeiImplied() { 18 | SR &= (~SR_INT); 19 | ram[0] = 0x78; 20 | instructions = 1; run(); 21 | if(!(SR&SR_INT)) return -1; 22 | return 0; 23 | } -------------------------------------------------------------------------------- /6502tests/test/testClear.c: -------------------------------------------------------------------------------- 1 | int testClcImplied() { 2 | SR |= SR_CARRY; 3 | ram[0] = 0x18; 4 | instructions = 1; run(); 5 | if(SR&SR_CARRY) return -1; 6 | return 0; 7 | } 8 | 9 | int testCldImplied() { 10 | SR |= SR_DEC; 11 | ram[0] = 0xD8; 12 | instructions = 1; run(); 13 | if(SR&SR_DEC) return -1; 14 | return 0; 15 | } 16 | 17 | int testCliImplied() { 18 | SR |= SR_INT; 19 | ram[0] = 0x58; 20 | instructions = 1; run(); 21 | if(SR&SR_INT) return -1; 22 | return 0; 23 | } 24 | 25 | int testClvImplied() { 26 | SR |= SR_OVER; 27 | ram[0] = 0xB8; 28 | instructions = 1; run(); 29 | if(SR&SR_OVER) return -1; 30 | return 0; 31 | } -------------------------------------------------------------------------------- /6502tests/test/testJmp.c: -------------------------------------------------------------------------------- 1 | int testJmpAbsolute() { 2 | SR &= (~SR_DEC); 3 | ram[0] = 0x4C; 4 | ram[1] = 0x04; 5 | ram[2] = 0x00; 6 | ram[3] = 0x00; 7 | ram[4] = 0xF8; 8 | instructions = 5; run(); 9 | if(!(SR&SR_DEC)) return -1; 10 | return 0; 11 | } 12 | 13 | int testJmpIndirect() { 14 | SR &= (~SR_DEC); 15 | ram[0] = 0x4C; 16 | ram[1] = 0x04; 17 | ram[2] = 0x00; 18 | ram[3] = 0x00; 19 | ram[4] = 0x06; 20 | ram[5] = 0x00; 21 | ram[6] = 0xF8; 22 | instructions = 7; run(); 23 | if(!(SR&SR_DEC)) return -1; 24 | return 0; 25 | } 26 | 27 | int testJsrAbsolute() { 28 | SR &= (~SR_DEC); 29 | ram[0] = 0x20; 30 | ram[1] = 0x04; 31 | ram[2] = 0x00; 32 | ram[3] = 0x00; 33 | ram[4] = 0xF8; 34 | instructions = 5; run(); 35 | if(!(SR&SR_DEC && pull16() == 0x0002)) return -1; 36 | return 0; 37 | } -------------------------------------------------------------------------------- /APPLEII/ghettovga.ino: -------------------------------------------------------------------------------- 1 | void writeCharacter(unsigned char row, unsigned char col, unsigned char val) { 2 | unsigned char buf[4] = {0xFD, 0, 0, 0}; 3 | buf[1] = col; 4 | buf[2] = row; 5 | buf[3] = val; 6 | Serial.write(buf, 4); 7 | } 8 | 9 | unsigned char readCharacter(unsigned char row, unsigned char col) { 10 | unsigned long transaction_begin; 11 | unsigned char buf[4] = {0xFA, 0, 0}; 12 | buf[1] = col; 13 | buf[2] = row; 14 | Serial.write(buf, 3); 15 | for(transaction_begin = millis(); !Serial.available(); millis() < (transaction_begin+50)); 16 | return Serial.read(); 17 | } 18 | 19 | void clearScreen() { 20 | unsigned char cmd = 0xFC; 21 | Serial.write(&cmd, 1); 22 | delay(20); 23 | } 24 | 25 | void screenScroll() { 26 | unsigned char cmd = 0xFB; 27 | Serial.write(&cmd, 1); 28 | delay(20); 29 | } 30 | -------------------------------------------------------------------------------- /6502tests/test/testBit.c: -------------------------------------------------------------------------------- 1 | int testBitZeropage() { 2 | //bits set 3 | A = 0x00; 4 | ram[0] = 0x24; 5 | ram[1] = 0x02; 6 | ram[2] = 0xFF; 7 | instructions = 2; 8 | run(); 9 | if(!(SR&SR_NEG && SR&SR_ZERO && SR&SR_OVER)) return -1; 10 | 11 | //bits unset 12 | A = 0x01; 13 | ram[0] = 0x24; 14 | ram[1] = 0x02; 15 | ram[2] = 0x01; 16 | instructions = 2; 17 | run(); 18 | if(!(!(SR&SR_NEG) && !(SR&SR_ZERO) && !(SR&SR_OVER))) return -2; 19 | 20 | return 0; 21 | } 22 | 23 | int testBitAbsolute() { 24 | //bits set 25 | A = 0x00; 26 | ram[0] = 0x24; 27 | ram[1] = 0x03; 28 | ram[2] = 0x00; 29 | ram[3] = 0xFF; 30 | instructions = 2; 31 | run(); 32 | if(!(SR&SR_NEG && SR&SR_ZERO && !(SR&SR_CARRY) && SR&SR_OVER)) return -1; 33 | 34 | //bits unset 35 | A = 0x01; 36 | ram[0] = 0x24; 37 | ram[1] = 0x03; 38 | ram[2] = 0x00; 39 | ram[3] = 0x01; 40 | instructions = 2; 41 | run(); 42 | if(!(!(SR&SR_NEG) && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -2; 43 | 44 | return 0; 45 | } -------------------------------------------------------------------------------- /APPLEII/monitor.ino: -------------------------------------------------------------------------------- 1 | // Hook routines for the apple II monitor program 2 | // Used to trick the apple code into working on this hardware 3 | // Ideally should patch the ROM itself, will do in future. 4 | void program_hooks(unsigned short addr) { 5 | // hook screen scroll, monitor command 6 | if(addr == 0xFC70) { 7 | screenScroll(); 8 | PC = 0xFC95; 9 | } 10 | // hook cassette write commnand 11 | else if (addr == 0xFECD || addr == 0xFECF) { 12 | // Header length 13 | cassette_header((addr==0xFECD)?64:A); 14 | // Write Data Block 15 | cassette_write_block(read16(0x3C), read16(0x3E)); 16 | // Emulate counter behaviour 17 | write16(0x003C, read16(0x3E)); 18 | PC = 0xFEF5; 19 | } 20 | // hook cassette read command 21 | else if (addr == 0xFEFD) { 22 | // Read Data Block 23 | boolean success = cassette_read_block(read16(0x3C), read16(0x3E)); 24 | // Emulate counter behaviour 25 | write16(0x003C, read16(0x3E)); 26 | if(success) PC = 0xFF3A; 27 | else PC = 0xFF2D; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /6502tests/test/testSt.c: -------------------------------------------------------------------------------- 1 | int testStxZeropage() { 2 | X = 0x23; 3 | ram[0] = 0x86; 4 | ram[1] = 0x02; 5 | ram[2] = 0x00; 6 | instructions = 1; run(); 7 | if(ram[2] != 0x23) return -1; 8 | return 0; 9 | } 10 | 11 | int testStxZeropageY() { 12 | Y = 0x01; 13 | X = 0x23; 14 | ram[0] = 0x96; 15 | ram[1] = 0x01; 16 | ram[2] = 0x00; 17 | instructions = 1; run(); 18 | if(ram[2] != 0x23) return -1; 19 | return 0; 20 | } 21 | 22 | int testStxAbsolute() { 23 | X = 0x23; 24 | ram[0] = 0x8E; 25 | ram[1] = 0x03; 26 | ram[2] = 0x00; 27 | ram[3] = 0x00; 28 | instructions = 1; run(); 29 | if(ram[3] != 0x23) return -1; 30 | return 0; 31 | } 32 | 33 | int testStyZeropage() { 34 | Y = 0x23; 35 | ram[0] = 0x84; 36 | ram[1] = 0x02; 37 | ram[2] = 0x00; 38 | instructions = 1; run(); 39 | if(ram[2] != 0x23) return -1; 40 | return 0; 41 | } 42 | 43 | int testStyZeropageX() { 44 | X = 0x01; 45 | Y = 0x23; 46 | ram[0] = 0x94; 47 | ram[1] = 0x01; 48 | ram[2] = 0x00; 49 | instructions = 1; run(); 50 | if(ram[2] != 0x23) return -1; 51 | return 0; 52 | } 53 | 54 | int testStyAbsolute() { 55 | Y = 0x23; 56 | ram[0] = 0x8C; 57 | ram[1] = 0x03; 58 | ram[2] = 0x00; 59 | ram[3] = 0x00; 60 | instructions = 1; run(); 61 | if(ram[3] != 0x23) return -1; 62 | return 0; 63 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, Damian Peckett 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 18 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 20 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 21 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 22 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | 25 | -------------------------------------------------------------------------------- /APPLEII/screen.ino: -------------------------------------------------------------------------------- 1 | // squash all the modes for this demo 2 | unsigned char appleToGhettoVGA(unsigned char apple) { 3 | if(apple >= 0xC0) return apple-0x40; 4 | else return apple&0x7F; 5 | } 6 | 7 | // Squash into normal mode 8 | unsigned char ghettoVGAToApple(unsigned char ghettoVga) { 9 | if(ghettoVga >= 0x40 && ghettoVga <= 0x7f) return ghettoVga; 10 | else return ghettoVga|0x80; 11 | } 12 | 13 | // Extract row, column addressing from woz's interlacing mode 14 | static unsigned char g_row = 0, g_col = 0; 15 | void decodeScreenAddress(unsigned short address) { 16 | unsigned char block_of_lines = (address>>7) - 0x08; 17 | unsigned char block_offset = (address&0x00FF) - ((block_of_lines&0x01) ? 0x80 : 0x00); 18 | if(block_offset < 0x28) { 19 | g_row = block_of_lines; 20 | g_col = block_offset; 21 | } else if(block_offset < 0x50) { 22 | g_row = block_of_lines + 8; 23 | g_col = block_offset-0x28; 24 | } else { 25 | g_row = block_of_lines + 16; 26 | g_col = block_offset-0x50; 27 | } 28 | } 29 | 30 | unsigned char screenRead(unsigned short address) { 31 | //Find our row/column 32 | decodeScreenAddress(address); 33 | return ghettoVGAToApple(readCharacter(g_row, g_col)); 34 | } 35 | 36 | void screenWrite(unsigned short address, unsigned char value) { 37 | //Find our row/column 38 | decodeScreenAddress(address); 39 | // If not bell character 40 | if(value != 0x87) writeCharacter(g_row, g_col, appleToGhettoVGA(value)); 41 | } 42 | -------------------------------------------------------------------------------- /6502tests/test/testSta.c: -------------------------------------------------------------------------------- 1 | int testStaZeropage() { 2 | A = 0x23; 3 | ram[0] = 0x85; 4 | ram[1] = 0x02; 5 | ram[2] = 0x00; 6 | instructions = 1; run(); 7 | if(ram[2] != 0x23) return -1; 8 | return 0; 9 | } 10 | 11 | int testStaZeropageX() { 12 | X = 0x01; Y = 0x00; 13 | A = 0x23; 14 | ram[0] = 0x95; 15 | ram[1] = 0x01; 16 | ram[2] = 0x00; 17 | instructions = 1; run(); 18 | if(ram[2] != 0x23) return -1; 19 | return 0; 20 | } 21 | 22 | int testStaAbsolute() { 23 | A = 0x23; 24 | ram[0] = 0x8D; 25 | ram[1] = 0x03; 26 | ram[2] = 0x00; 27 | ram[3] = 0x00; 28 | instructions = 1; run(); 29 | if(ram[3] != 0x23) return -1; 30 | return 0; 31 | } 32 | 33 | int testStaAbsoluteX() { 34 | X = 0x01; Y = 0x00; 35 | A = 0x23; 36 | ram[0] = 0x9D; 37 | ram[1] = 0x02; 38 | ram[2] = 0x00; 39 | ram[3] = 0x00; 40 | instructions = 1; run(); 41 | if(ram[3] != 0x23) return -1; 42 | return 0; 43 | } 44 | 45 | int testStaAbsoluteY() { 46 | Y = 0x01; X = 0x00; 47 | A = 0x23; 48 | ram[0] = 0x99; 49 | ram[1] = 0x02; 50 | ram[2] = 0x00; 51 | ram[3] = 0x00; 52 | instructions = 1; run(); 53 | if(ram[3] != 0x23) return -1; 54 | return 0; 55 | } 56 | 57 | int testStaIndirectX() { 58 | X = 0x01; Y = 0x00; 59 | A = 0x23; 60 | ram[0] = 0x81; 61 | ram[1] = 0x02; 62 | ram[2] = 0x02; 63 | ram[3] = 0x00; 64 | instructions = 1; run(); 65 | if(ram[3] != 0x23) return -1; 66 | return 0; 67 | } 68 | 69 | int testStaIndirectY() { 70 | Y = 0x01; X = 0x00; 71 | A = 0x23; 72 | ram[0] = 0x91; 73 | ram[1] = 0x02; 74 | ram[2] = 0x03; 75 | ram[3] = 0x00; 76 | ram[4] = 0x00; 77 | instructions = 1; run(); 78 | if(ram[4] != 0x23) return -1; 79 | return 0; 80 | } 81 | -------------------------------------------------------------------------------- /APPLEII/APPLEII.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2015, Damian Peckett 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 18 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 21 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | 25 | All firmware is property of Apple Computer and is recreated here for 26 | historical purposes only. 27 | */ 28 | 29 | #include 30 | 31 | void setup() { 32 | Serial.begin(115200); 33 | clearScreen(); 34 | speaker_begin(); 35 | cassette_begin(); 36 | keyboard_begin(); 37 | sei(); 38 | } 39 | 40 | void loop() { 41 | run(); 42 | } 43 | -------------------------------------------------------------------------------- /6502tests/test/testTransfer.c: -------------------------------------------------------------------------------- 1 | int testTaxImplied() { 2 | //normal 3 | X = 0; A = 0x23; 4 | ram[0] = 0xAA; 5 | instructions = 1; run(); 6 | if(!(X == 0x23 && !(SR&SR_NEG) && !(SR&SR_ZERO)))return -1; 7 | //negative 8 | X = 0; A = 0xFE; 9 | ram[0] = 0xAA; 10 | instructions = 1; run(); 11 | if(!(X == 0xFE && SR&SR_NEG && !(SR&SR_ZERO)))return -2; 12 | return 0; 13 | } 14 | 15 | int testTayImplied() { 16 | //normal 17 | Y = 0; A = 0x23; 18 | ram[0] = 0xA8; 19 | instructions = 1; run(); 20 | if(!(Y == 0x23 && !(SR&SR_NEG) && !(SR&SR_ZERO)))return -1; 21 | //negative 22 | Y = 0; A = 0xFE; 23 | ram[0] = 0xA8; 24 | instructions = 1; run(); 25 | if(!(Y == 0xFE && SR&SR_NEG && !(SR&SR_ZERO)))return -2; 26 | return 0; 27 | } 28 | 29 | int testTsxImplied() { 30 | //normal 31 | X = 0; SP = 0x23; 32 | ram[0] = 0xBA; 33 | instructions = 1; run(); 34 | if(!(X == 0x23 && !(SR&SR_NEG) && !(SR&SR_ZERO)))return -1; 35 | //negative 36 | X = 0; SP = 0xFE; 37 | ram[0] = 0xBA; 38 | instructions = 1; run(); 39 | if(!(X == 0xFE && SR&SR_NEG && !(SR&SR_ZERO)))return -2; 40 | return 0; 41 | } 42 | 43 | int testTxaImplied() { 44 | //normal 45 | A = 0; X = 0x23; 46 | ram[0] = 0x8A; 47 | instructions = 1; run(); 48 | if(!(A == 0x23 && !(SR&SR_NEG) && !(SR&SR_ZERO)))return -1; 49 | //negative 50 | A = 0; X = 0xFE; 51 | ram[0] = 0x8A; 52 | instructions = 1; run(); 53 | if(!(A == 0xFE && SR&SR_NEG && !(SR&SR_ZERO)))return -2; 54 | return 0; 55 | } 56 | 57 | int testTxsImplied() { 58 | //normal 59 | SR = SR_FIXED_BITS; 60 | X = 0x00; SP = 0x00; 61 | ram[0] = 0x9A; 62 | instructions = 1; run(); 63 | if(!(SP == 0x23 && !(SR&SR_ZERO)))return -1; 64 | return 0; 65 | } 66 | 67 | int testTyaImplied() { 68 | //normal 69 | A = 0; Y = 0x23; 70 | ram[0] = 0x98; 71 | instructions = 1; run(); 72 | if(!(A == 0x23 && !(SR&SR_NEG) && !(SR&SR_ZERO)))return -1; 73 | //negative 74 | A = 0; Y = 0xFE; 75 | ram[0] = 0x98; 76 | instructions = 1; run(); 77 | if(!(A == 0xFE && SR&SR_NEG && !(SR&SR_ZERO)))return -2; 78 | return 0; 79 | } -------------------------------------------------------------------------------- /6502tests/test/testEor.c: -------------------------------------------------------------------------------- 1 | int testEorImmediate() { 2 | A = 0xCE; 3 | ram[0] = 0x49; 4 | ram[1] = 0x20; 5 | instructions = 1; run(); 6 | if(!(A == (0xCE^0x20) && !(SR&SR_ZERO) && SR&SR_NEG)) return -1; 7 | return 0; 8 | } 9 | 10 | int testEorZeropage() { 11 | A = 0xCE; 12 | ram[0] = 0x45; 13 | ram[1] = 0x02; 14 | ram[2] = 0x20; 15 | instructions = 1; run(); 16 | if(!(A == (0xCE^0x20) && !(SR&SR_ZERO) && SR&SR_NEG)) return -1; 17 | return 0; 18 | } 19 | 20 | int testEorZeropageX() { 21 | X = 0x01; Y = 0x00; 22 | A = 0xCE; 23 | ram[0] = 0x55; 24 | ram[1] = 0x01; 25 | ram[2] = 0x20; 26 | instructions = 1; run(); 27 | if(!(A == (0xCE^0x20) && !(SR&SR_ZERO) && SR&SR_NEG)) return -1; 28 | return 0; 29 | } 30 | 31 | int testEorAbsolute() { 32 | A = 0xCE; 33 | ram[0] = 0x4D; 34 | ram[1] = 0x03; 35 | ram[2] = 0x00; 36 | ram[3] = 0x20; 37 | instructions = 1; run(); 38 | if(!(A == (0xCE^0x20) && !(SR&SR_ZERO) && SR&SR_NEG)) return -1; 39 | return 0; 40 | } 41 | 42 | int testEorAbsoluteX() { 43 | X = 0x01; Y = 0x00; 44 | A = 0xCE; 45 | ram[0] = 0x5D; 46 | ram[1] = 0x02; 47 | ram[2] = 0x00; 48 | ram[3] = 0x20; 49 | instructions = 1; run(); 50 | if(!(A == (0xCE^0x20) && !(SR&SR_ZERO) && SR&SR_NEG)) return -1; 51 | return 0; 52 | } 53 | 54 | int testEorAbsoluteY() { 55 | Y = 0x01; X = 0x00; 56 | A = 0xCE; 57 | ram[0] = 0x59; 58 | ram[1] = 0x02; 59 | ram[2] = 0x00; 60 | ram[3] = 0x20; 61 | instructions = 1; run(); 62 | if(!(A == (0xCE^0x20) && !(SR&SR_ZERO) && SR&SR_NEG)) return -1; 63 | return 0; 64 | } 65 | 66 | int testEorIndirectX() { 67 | X = 0x01; Y = 0x00; 68 | A = 0xCE; 69 | ram[0] = 0x41; 70 | ram[1] = 0x02; 71 | ram[2] = 0x02; 72 | ram[3] = 0x20; 73 | instructions = 1; run(); 74 | if(!(A == (0xCE^0x20) && !(SR&SR_ZERO) && SR&SR_NEG)) return -1; 75 | return 0; 76 | } 77 | 78 | int testEorIndirectY() { 79 | Y = 0x01; X = 0x00; 80 | A = 0xCE; 81 | ram[0] = 0x51; 82 | ram[1] = 0x02; 83 | ram[2] = 0x03; 84 | ram[3] = 0x00; 85 | ram[4] = 0x20; 86 | instructions = 1; run(); 87 | if(!(A == (0xCE^0x20) && !(SR&SR_ZERO) && SR&SR_NEG)) return -1; 88 | return 0; 89 | } -------------------------------------------------------------------------------- /6502tests/test/testDec.c: -------------------------------------------------------------------------------- 1 | int testDecZeropage() { 2 | ram[0] = 0xC6; 3 | ram[1] = 0x02; 4 | ram[2] = 0x01; 5 | instructions = 1; run(); 6 | if(!(ram[2] == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO)) return -1; 7 | 8 | //wrap 9 | ram[0] = 0xC6; 10 | ram[1] = 0x02; 11 | ram[2] = 0x00; 12 | instructions = 1; run(); 13 | if(!(ram[2] == 0xFF && SR&SR_NEG && !(SR&SR_ZERO))) return -2; 14 | 15 | return 0; 16 | } 17 | 18 | int testDecZeropageX() { 19 | X = 0x01; Y = 0x00; 20 | 21 | ram[0] = 0xD6; 22 | ram[1] = 0x01; 23 | ram[2] = 0x01; 24 | instructions = 1; run(); 25 | if(!(ram[2] == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO)) return -1; 26 | 27 | //wrap 28 | ram[0] = 0xD6; 29 | ram[1] = 0x01; 30 | ram[2] = 0x00; 31 | instructions = 1; run(); 32 | if(!(ram[2] == 0xFF && SR&SR_NEG && !(SR&SR_ZERO))) return -2; 33 | 34 | return 0; 35 | } 36 | 37 | int testDecAbsolute() { 38 | ram[0] = 0xCE; 39 | ram[1] = 0x03; 40 | ram[2] = 0x00; 41 | ram[3] = 0x01; 42 | instructions = 1; run(); 43 | if(!(ram[3] == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO)) return -1; 44 | 45 | //wrap 46 | ram[0] = 0xCE; 47 | ram[1] = 0x03; 48 | ram[2] = 0x00; 49 | ram[3] = 0x00; 50 | instructions = 1; run(); 51 | if(!(ram[3] == 0xFF && SR&SR_NEG && !(SR&SR_ZERO))) return -2; 52 | 53 | return 0; 54 | } 55 | 56 | int testDecAbsoluteX() { 57 | X = 0x01; Y = 0x00; 58 | 59 | ram[0] = 0xDE; 60 | ram[1] = 0x02; 61 | ram[2] = 0x00; 62 | ram[3] = 0x01; 63 | instructions = 1; run(); 64 | if(!(ram[3] == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO)) return -1; 65 | 66 | //wrap 67 | ram[0] = 0xDE; 68 | ram[1] = 0x02; 69 | ram[2] = 0x00; 70 | ram[3] = 0x00; 71 | instructions = 1; run(); 72 | if(!(ram[3] == 0xFF && SR&SR_NEG && !(SR&SR_ZERO))) return -2; 73 | 74 | return 0; 75 | } 76 | 77 | int testDexImplied() { 78 | X = 0x01; 79 | ram[0] = 0xCA; 80 | instructions = 1; run(); 81 | if(!(X == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO)) return -1; 82 | 83 | //wrap 84 | X = 0x00; 85 | ram[0] = 0xCA; 86 | instructions = 1; run(); 87 | if(!(X == 0xFF && SR&SR_NEG && !(SR&SR_ZERO))) return -2; 88 | 89 | return 0; 90 | } 91 | 92 | int testDeyImplied() { 93 | Y = 0x01; 94 | ram[0] = 0x88; 95 | instructions = 1; run(); 96 | if(!(Y == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO)) return -1; 97 | 98 | //wrap 99 | X = 0x00; 100 | ram[0] = 0x88; 101 | instructions = 1; run(); 102 | if(!(Y == 0xFF && SR&SR_NEG && !(SR&SR_ZERO))) return -2; 103 | 104 | return 0; 105 | } -------------------------------------------------------------------------------- /6502tests/test/testInc.c: -------------------------------------------------------------------------------- 1 | int testIncZeropage() { 2 | ram[0] = 0xE6; 3 | ram[1] = 0x02; 4 | ram[2] = 0xFE; 5 | instructions = 1; run(); 6 | if(!(ram[2] == 0xFF && SR&SR_NEG && !(SR&SR_ZERO))) return -1; 7 | 8 | //wrap 9 | ram[0] = 0xE6; 10 | ram[1] = 0x02; 11 | ram[2] = 0xFF; 12 | instructions = 1; run(); 13 | if(!(ram[2] == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO)) return -2; 14 | 15 | return 0; 16 | } 17 | 18 | int testIncZeropageX() { 19 | X = 0x01; Y = 0x00; 20 | 21 | ram[0] = 0xF6; 22 | ram[1] = 0x01; 23 | ram[2] = 0xFE; 24 | instructions = 1; run(); 25 | if(!(ram[2] == 0xFF && SR&SR_NEG && !(SR&SR_ZERO))) return -1; 26 | 27 | //wrap 28 | ram[0] = 0xF6; 29 | ram[1] = 0x01; 30 | ram[2] = 0xFF; 31 | instructions = 1; run(); 32 | if(!(ram[2] == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO)) return -2; 33 | 34 | return 0; 35 | } 36 | 37 | int testIncAbsolute() { 38 | ram[0] = 0xEE; 39 | ram[1] = 0x03; 40 | ram[2] = 0x00; 41 | ram[3] = 0xFE; 42 | instructions = 1; run(); 43 | if(!(ram[3] == 0xFF && SR&SR_NEG && !(SR&SR_ZERO))) return -1; 44 | 45 | //wrap 46 | ram[0] = 0xEE; 47 | ram[1] = 0x03; 48 | ram[2] = 0x00; 49 | ram[3] = 0xFF; 50 | instructions = 1; run(); 51 | if(!(ram[3] == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO)) return -2; 52 | 53 | return 0; 54 | } 55 | 56 | int testIncAbsoluteX() { 57 | X = 0x01; Y = 0x00; 58 | 59 | ram[0] = 0xFE; 60 | ram[1] = 0x02; 61 | ram[2] = 0x00; 62 | ram[3] = 0xFE; 63 | instructions = 1; run(); 64 | if(!(ram[3] == 0x02 && SR&SR_NEG && !(SR&SR_ZERO))) return -1; 65 | 66 | //wrap 67 | ram[0] = 0xFE; 68 | ram[1] = 0x02; 69 | ram[2] = 0x00; 70 | ram[3] = 0xFF; 71 | instructions = 1; run(); 72 | if(!(ram[3] == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO)) return -2; 73 | 74 | return 0; 75 | } 76 | 77 | int testInxImplied() { 78 | X = 0xFE; 79 | ram[0] = 0xE8; 80 | instructions = 1; run(); 81 | if(!(X == 0xFF && SR&SR_NEG && !(SR&SR_ZERO))) return -1; 82 | 83 | //wrap 84 | X = 0xFF; 85 | ram[0] = 0xE8; 86 | instructions = 1; run(); 87 | if(!(X == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO)) return -2; 88 | 89 | return 0; 90 | } 91 | 92 | int testInyImplied() { 93 | Y = 0xFE; 94 | ram[0] = 0xC8; 95 | instructions = 1; run(); 96 | if(!(Y == 0xFF && SR&SR_NEG && !(SR&SR_ZERO))) return -1; 97 | 98 | //wrap 99 | Y = 0xFF; 100 | ram[0] = 0xC8; 101 | instructions = 1; run(); 102 | if(!(Y == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO)) return -2; 103 | 104 | return 0; 105 | } -------------------------------------------------------------------------------- /6502tests/test/testCpx.c: -------------------------------------------------------------------------------- 1 | int testCpxImmediate() { 2 | //no difference 3 | SR |= SR_ZERO; 4 | SR |= SR_CARRY; 5 | SR |= SR_NEG; 6 | X = 0x10; 7 | ram[0] = 0xE0; 8 | ram[1] = 0x10; 9 | instructions = 2; run(); 10 | if(!(!(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY)) return -1; 11 | 12 | //less 13 | SR |= SR_ZERO; 14 | SR |= SR_CARRY; 15 | SR |= SR_NEG; 16 | X = 0x10; 17 | ram[0] = 0xE0; 18 | ram[1] = 0x04; 19 | instructions = 2; run(); 20 | if(!(!(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY)) return -2; 21 | 22 | //more 23 | SR |= SR_ZERO; 24 | SR |= SR_CARRY; 25 | SR |= SR_NEG; 26 | X = 0x04; 27 | ram[0] = 0xE0; 28 | ram[1] = 0x10; 29 | instructions = 2; run(); 30 | if(!(SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY))) return -2; 31 | 32 | return 0; 33 | } 34 | 35 | int testCpxZeropage() { 36 | //no difference 37 | SR |= SR_ZERO; 38 | SR |= SR_CARRY; 39 | SR |= SR_NEG; 40 | X = 0x10; 41 | ram[0] = 0xE4; 42 | ram[1] = 0x02; 43 | ram[2] = 0x10; 44 | instructions = 2; run(); 45 | if(!(!(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY)) return -1; 46 | 47 | //less 48 | SR |= SR_ZERO; 49 | SR |= SR_CARRY; 50 | SR |= SR_NEG; 51 | X = 0x10; 52 | ram[0] = 0xE4; 53 | ram[1] = 0x02; 54 | ram[2] = 0x04; 55 | instructions = 2; run(); 56 | if(!(!(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY)) return -2; 57 | 58 | //more 59 | SR |= SR_ZERO; 60 | SR |= SR_CARRY; 61 | SR |= SR_NEG; 62 | X = 0x04; 63 | ram[0] = 0xE4; 64 | ram[1] = 0x02; 65 | ram[2] = 0x10; 66 | instructions = 2; run(); 67 | if(!(SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY))) return -2; 68 | 69 | return 0; 70 | } 71 | 72 | int testCpxAbsolute() { 73 | //no difference 74 | SR |= SR_ZERO; 75 | SR |= SR_CARRY; 76 | SR |= SR_NEG; 77 | X = 0x10; 78 | ram[0] = 0xEC; 79 | ram[1] = 0x03; 80 | ram[2] = 0x00; 81 | ram[3] = 0x10; 82 | instructions = 2; run(); 83 | if(!(!(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY)) return -1; 84 | 85 | //less 86 | SR |= SR_ZERO; 87 | SR |= SR_CARRY; 88 | SR |= SR_NEG; 89 | X = 0x10; 90 | ram[0] = 0xEC; 91 | ram[1] = 0x03; 92 | ram[2] = 0x00; 93 | ram[3] = 0x04; 94 | instructions = 2; run(); 95 | if(!(!(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY)) return -2; 96 | 97 | //more 98 | SR |= SR_ZERO; 99 | SR |= SR_CARRY; 100 | SR |= SR_NEG; 101 | X = 0x04; 102 | ram[0] = 0xEC; 103 | ram[1] = 0x03; 104 | ram[2] = 0x00; 105 | ram[3] = 0x10; 106 | instructions = 2; run(); 107 | if(!(SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY))) return -2; 108 | 109 | return 0; 110 | } -------------------------------------------------------------------------------- /6502tests/test/testCpy.c: -------------------------------------------------------------------------------- 1 | int testCpyImmediate() { 2 | //no difference 3 | SR |= SR_ZERO; 4 | SR |= SR_CARRY; 5 | SR |= SR_NEG; 6 | Y = 0x10; 7 | ram[0] = 0xC0; 8 | ram[1] = 0x10; 9 | instructions = 2; run(); 10 | if(!(!(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY)) return -1; 11 | 12 | //less 13 | SR |= SR_ZERO; 14 | SR |= SR_CARRY; 15 | SR |= SR_NEG; 16 | Y = 0x10; 17 | ram[0] = 0xC0; 18 | ram[1] = 0x04; 19 | instructions = 2; run(); 20 | if(!(!(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY)) return -2; 21 | 22 | //more 23 | SR |= SR_ZERO; 24 | SR |= SR_CARRY; 25 | SR |= SR_NEG; 26 | Y = 0x04; 27 | ram[0] = 0xC0; 28 | ram[1] = 0x10; 29 | instructions = 2; run(); 30 | if(!(SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY))) return -3; 31 | 32 | return 0; 33 | } 34 | 35 | int testCpyZeropage() { 36 | //no difference 37 | SR |= SR_ZERO; 38 | SR |= SR_CARRY; 39 | SR |= SR_NEG; 40 | Y = 0x10; 41 | ram[0] = 0xC4; 42 | ram[1] = 0x02; 43 | ram[2] = 0x10; 44 | instructions = 2; run(); 45 | if(!(!(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY)) return -1; 46 | 47 | //less 48 | SR |= SR_ZERO; 49 | SR |= SR_CARRY; 50 | SR |= SR_NEG; 51 | Y = 0x10; 52 | ram[0] = 0xC4; 53 | ram[1] = 0x02; 54 | ram[2] = 0x04; 55 | instructions = 2; run(); 56 | if(!(!(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY)) return -2; 57 | 58 | //more 59 | SR |= SR_ZERO; 60 | SR |= SR_CARRY; 61 | SR |= SR_NEG; 62 | Y = 0x04; 63 | ram[0] = 0xC4; 64 | ram[1] = 0x02; 65 | ram[2] = 0x10; 66 | instructions = 2; run(); 67 | if(!(SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY))) return -3; 68 | 69 | return 0; 70 | } 71 | 72 | int testCpyAbsolute() { 73 | //no difference 74 | SR |= SR_ZERO; 75 | SR |= SR_CARRY; 76 | SR |= SR_NEG; 77 | Y = 0x10; 78 | ram[0] = 0xCC; 79 | ram[1] = 0x03; 80 | ram[2] = 0x00; 81 | ram[3] = 0x10; 82 | instructions = 2; run(); 83 | if(!(!(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY)) return -1; 84 | 85 | //less 86 | SR |= SR_ZERO; 87 | SR |= SR_CARRY; 88 | SR |= SR_NEG; 89 | Y = 0x10; 90 | ram[0] = 0xCC; 91 | ram[1] = 0x03; 92 | ram[2] = 0x00; 93 | ram[3] = 0x04; 94 | instructions = 2; run(); 95 | if(!(!(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY)) return -2; 96 | 97 | //more 98 | SR |= SR_ZERO; 99 | SR |= SR_CARRY; 100 | SR |= SR_NEG; 101 | Y = 0x04; 102 | ram[0] = 0xCC; 103 | ram[1] = 0x03; 104 | ram[2] = 0x00; 105 | ram[3] = 0x10; 106 | instructions = 2; run(); 107 | if(!(SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY))) return -3; 108 | 109 | return 0; 110 | } -------------------------------------------------------------------------------- /6502tests/test/testLsr.c: -------------------------------------------------------------------------------- 1 | int testLsrImplied() { 2 | SR &= (~SR_DEC); 3 | SR &= (~SR_NEG); 4 | 5 | //zero 6 | SR |= SR_CARRY; 7 | A = 0x01; 8 | ram[0] = 0x4A; 9 | instructions = 1; run(); 10 | if(!(A == 0x00 && SR&SR_ZERO && SR&SR_CARRY && !(SR&SR_NEG))) return -1; 11 | 12 | //carry out 13 | A = 0x80; 14 | ram[0] = 0x4A; 15 | instructions = 1; run(); 16 | if(!(A == 0x40 && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_NEG))) return -2; 17 | 18 | return 0; 19 | } 20 | 21 | int testLsrZeropage() { 22 | //zero 23 | SR |= SR_CARRY; 24 | ram[0] = 0x46; 25 | ram[1] = 0x02; 26 | ram[2] = 0x01; 27 | instructions = 1; run(); 28 | if(!(ram[2] == 0x00 && SR&SR_ZERO && SR&SR_CARRY && !(SR&SR_NEG))) return -1; 29 | 30 | //carry out 31 | ram[0] = 0x46; 32 | ram[1] = 0x02; 33 | ram[2] = 0x80; 34 | instructions = 1; run(); 35 | if(!(ram[2] == 0x40 && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_NEG))) return -2; 36 | 37 | return 0; 38 | } 39 | 40 | int testLsrZeropageX() { 41 | X = 0x01; Y = 0x00; 42 | 43 | //zero 44 | SR |= SR_CARRY; 45 | ram[0] = 0x56; 46 | ram[1] = 0x01; 47 | ram[2] = 0x01; 48 | instructions = 1; run(); 49 | if(!(ram[2] == 0x00 && SR&SR_ZERO && SR&SR_CARRY && !(SR&SR_NEG))) return -1; 50 | 51 | //carry out 52 | ram[0] = 0x56; 53 | ram[1] = 0x01; 54 | ram[2] = 0x80; 55 | instructions = 1; run(); 56 | if(!(ram[2] == 0x40 && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_NEG))) return -2; 57 | 58 | return 0; 59 | } 60 | 61 | int testLsrAbsolute() { 62 | //zero 63 | SR |= SR_CARRY; 64 | ram[0] = 0x4E; 65 | ram[1] = 0x03; 66 | ram[2] = 0x00; 67 | ram[3] = 0x01; 68 | instructions = 1; run(); 69 | if(!(ram[3] == 0x00 && SR&SR_ZERO && SR&SR_CARRY && !(SR&SR_NEG))) return -1; 70 | 71 | //carry out 72 | ram[0] = 0x4E; 73 | ram[1] = 0x03; 74 | ram[2] = 0x00; 75 | ram[3] = 0x80; 76 | instructions = 1; run(); 77 | if(!(ram[3] == 0x40 && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_NEG))) return -2; 78 | 79 | return 0; 80 | } 81 | 82 | int testLsrAbsoluteX() { 83 | X = 0x01; Y = 0x00; 84 | 85 | //zero 86 | SR |= SR_CARRY; 87 | ram[0] = 0x5E; 88 | ram[1] = 0x02; 89 | ram[2] = 0x00; 90 | ram[3] = 0x01; 91 | instructions = 1; run(); 92 | if(!(ram[3] == 0x00 && SR&SR_ZERO && SR&SR_CARRY && !(SR&SR_NEG))) return -1; 93 | 94 | //carry out 95 | ram[0] = 0x5E; 96 | ram[1] = 0x02; 97 | ram[2] = 0x00; 98 | ram[3] = 0x80; 99 | instructions = 1; run(); 100 | if(!(ram[3] == 0x40 && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_NEG))) return -2; 101 | 102 | return 0; 103 | } -------------------------------------------------------------------------------- /6502tests/test/testRor.c: -------------------------------------------------------------------------------- 1 | int testRorImplied() { 2 | //rotate in 3 | A = 0x81; 4 | SR |= SR_CARRY; 5 | ram[0] = 0x6A; 6 | instructions = 1; run(); 7 | if(!(A == 0xC0 && !(SR&SR_ZERO) && SR&SR_NEG && SR&SR_CARRY)) return -1; 8 | 9 | //rotate out 10 | A = 0x01; 11 | SR &= (~SR_CARRY); 12 | ram[0] = 0x6A; 13 | instructions = 1; run(); 14 | if(!(A == 0x00 && SR&SR_ZERO && !(SR&SR_NEG) && SR&SR_CARRY)) return -2; 15 | 16 | return 0; 17 | } 18 | 19 | int testRorZeropage() { 20 | //rotate in 21 | SR |= SR_CARRY; 22 | ram[0] = 0x66; 23 | ram[1] = 0x02; 24 | ram[2] = 0x81; 25 | instructions = 1; run(); 26 | if(!(ram[2] == 0xC0 && !(SR&SR_ZERO) && SR&SR_NEG && SR&SR_CARRY)) return -1; 27 | 28 | //rotate out 29 | SR &= (~SR_CARRY); 30 | ram[0] = 0x66; 31 | ram[1] = 0x02; 32 | ram[2] = 0x01; 33 | instructions = 1; run(); 34 | if(!(ram[2] == 0x00 && SR&SR_ZERO && !(SR&SR_NEG) && SR&SR_CARRY)) return -2; 35 | 36 | return 0; 37 | } 38 | 39 | int testRorZeropageX() { 40 | X = 0x01; Y = 0x00; 41 | 42 | //rotate in 43 | SR |= SR_CARRY; 44 | ram[0] = 0x76; 45 | ram[1] = 0x01; 46 | ram[2] = 0x81; 47 | instructions = 1; run(); 48 | if(!(ram[2] == 0xC0 && !(SR&SR_ZERO) && SR&SR_NEG && SR&SR_CARRY)) return -1; 49 | 50 | //rotate out 51 | SR &= (~SR_CARRY); 52 | ram[0] = 0x76; 53 | ram[1] = 0x01; 54 | ram[2] = 0x01; 55 | instructions = 1; run(); 56 | if(!(ram[2] == 0x00 && SR&SR_ZERO && !(SR&SR_NEG) && SR&SR_CARRY)) return -2; 57 | 58 | return 0; 59 | } 60 | 61 | int testRorAbsolute() { 62 | //rotate in 63 | SR |= SR_CARRY; 64 | ram[0] = 0x6E; 65 | ram[1] = 0x03; 66 | ram[2] = 0x00; 67 | ram[3] = 0x81; 68 | instructions = 1; run(); 69 | if(!(ram[3] == 0xC0 && !(SR&SR_ZERO) && SR&SR_NEG && SR&SR_CARRY)) return -1; 70 | 71 | //rotate out 72 | SR &= (~SR_CARRY); 73 | ram[0] = 0x6E; 74 | ram[1] = 0x03; 75 | ram[2] = 0x00; 76 | ram[3] = 0x01; 77 | instructions = 1; run(); 78 | if(!(ram[3] == 0x00 && SR&SR_ZERO && !(SR&SR_NEG) && SR&SR_CARRY)) return -2; 79 | 80 | return 0; 81 | } 82 | 83 | int testRorAbsoluteX() { 84 | X = 0x01; Y = 0x00; 85 | 86 | //rotate in 87 | SR |= SR_CARRY; 88 | ram[0] = 0x7E; 89 | ram[1] = 0x02; 90 | ram[2] = 0x00; 91 | ram[3] = 0x81; 92 | instructions = 1; run(); 93 | if(!(ram[3] == 0xC0 && !(SR&SR_ZERO) && SR&SR_NEG && SR&SR_CARRY)) return -1; 94 | 95 | //rotate out 96 | SR &= (~SR_CARRY); 97 | ram[0] = 0x7E; 98 | ram[1] = 0x02; 99 | ram[2] = 0x00; 100 | ram[3] = 0x01; 101 | instructions = 1; run(); 102 | if(!(ram[3] == 0x00 && SR&SR_ZERO && !(SR&SR_NEG) && SR&SR_CARRY)) return -2; 103 | 104 | return 0; 105 | } -------------------------------------------------------------------------------- /6502tests/test/testRol.c: -------------------------------------------------------------------------------- 1 | int testRolImplied() { 2 | //rotate in 3 | A = 0x81; 4 | SR |= SR_CARRY; 5 | ram[0] = 0x2A; 6 | instructions = 1; run(); 7 | if(!(A == 0x03 && !(SR&SR_ZERO) && !(SR&SR_NEG) && SR&SR_CARRY)) return -1; 8 | 9 | //rotate out 10 | A = 0x80; 11 | SR &= (~SR_CARRY); 12 | ram[0] = 0x2A; 13 | instructions = 1; run(); 14 | if(!(A == 0x00 && SR&SR_ZERO && !(SR&SR_NEG) && SR&SR_CARRY)) return -2; 15 | 16 | return 0; 17 | } 18 | 19 | int testRolZeropage() { 20 | //rotate in 21 | SR |= SR_CARRY; 22 | ram[0] = 0x26; 23 | ram[1] = 0x02; 24 | ram[2] = 0x81; 25 | instructions = 1; run(); 26 | if(!(ram[2] == 0x03 && !(SR&SR_ZERO) && !(SR&SR_NEG) && SR&SR_CARRY)) return -1; 27 | 28 | //rotate out 29 | SR &= (~SR_CARRY); 30 | ram[0] = 0x26; 31 | ram[1] = 0x02; 32 | ram[2] = 0x80; 33 | instructions = 1; run(); 34 | if(!(ram[2] == 0x00 && SR&SR_ZERO && !(SR&SR_NEG) && SR&SR_CARRY)) return -2; 35 | 36 | return 0; 37 | } 38 | 39 | int testRolZeropageX() { 40 | X = 0x01; Y = 0x00; 41 | 42 | //rotate in 43 | SR |= SR_CARRY; 44 | ram[0] = 0x36; 45 | ram[1] = 0x01; 46 | ram[2] = 0x81; 47 | instructions = 1; run(); 48 | if(!(ram[2] == 0x03 && !(SR&SR_ZERO) && !(SR&SR_NEG) && SR&SR_CARRY)) return -1; 49 | 50 | //rotate out 51 | SR &= (~SR_CARRY); 52 | ram[0] = 0x36; 53 | ram[1] = 0x01; 54 | ram[2] = 0x80; 55 | instructions = 1; run(); 56 | if(!(ram[2] == 0x00 && SR&SR_ZERO && !(SR&SR_NEG) && SR&SR_CARRY)) return -2; 57 | 58 | return 0; 59 | } 60 | 61 | int testRolAbsolute() { 62 | //rotate in 63 | SR |= SR_CARRY; 64 | ram[0] = 0x2E; 65 | ram[1] = 0x03; 66 | ram[2] = 0x00; 67 | ram[3] = 0x81; 68 | instructions = 1; run(); 69 | if(!(ram[3] == 0x03 && !(SR&SR_ZERO) && !(SR&SR_NEG) && SR&SR_CARRY)) return -1; 70 | 71 | //rotate out 72 | SR &= (~SR_CARRY); 73 | ram[0] = 0x2E; 74 | ram[1] = 0x03; 75 | ram[2] = 0x00; 76 | ram[3] = 0x80; 77 | instructions = 1; run(); 78 | if(!(ram[3] == 0x00 && SR&SR_ZERO && !(SR&SR_NEG) && SR&SR_CARRY)) return -2; 79 | 80 | return 0; 81 | } 82 | 83 | int testRolAbsoluteX() { 84 | X = 0x01; Y = 0x00; 85 | 86 | //rotate in 87 | SR |= SR_CARRY; 88 | ram[0] = 0x3E; 89 | ram[1] = 0x02; 90 | ram[2] = 0x00; 91 | ram[3] = 0x81; 92 | instructions = 1; run(); 93 | if(!(ram[3] == 0x03 && !(SR&SR_ZERO) && !(SR&SR_NEG) && SR&SR_CARRY)) return -1; 94 | 95 | //rotate out 96 | SR &= (~SR_CARRY); 97 | ram[0] = 0x3E; 98 | ram[1] = 0x02; 99 | ram[2] = 0x00; 100 | ram[3] = 0x80; 101 | instructions = 1; run(); 102 | if(!(ram[3] == 0x00 && SR&SR_ZERO && !(SR&SR_NEG) && SR&SR_CARRY)) return -2; 103 | 104 | return 0; 105 | } -------------------------------------------------------------------------------- /6502tests/test/testAsl.c: -------------------------------------------------------------------------------- 1 | int testAslImplied() { 2 | //normal 3 | A = 0x01; 4 | ram[0] = 0x0A; 5 | instructions = 1; run(); 6 | if(!(A == 0x02 && !(SR&SR_NEG) && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1; 7 | 8 | //carry and zero 9 | A = 0x80; 10 | ram[0] = 0x0A; 11 | instructions = 1; run(); 12 | if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY && !(SR&SR_OVER))) return -2; 13 | 14 | //carry and negative 15 | A = 0xC0; 16 | ram[0] = 0x0A; 17 | instructions = 1; run(); 18 | if(!(A == 0x80 && SR&SR_NEG && !(SR&SR_ZERO) && SR&SR_CARRY && !(SR&SR_OVER))) return -3; 19 | 20 | return 0; 21 | } 22 | 23 | int testAslZeropage() { 24 | //normal 25 | ram[0] = 0x06; 26 | ram[1] = 0x02; 27 | ram[2] = 0x01; 28 | instructions = 1; run(); 29 | if(!(ram[2] == 0x02 && !(SR&SR_NEG) && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1; 30 | 31 | //carry and zero 32 | ram[0] = 0x06; 33 | ram[1] = 0x02; 34 | ram[2] = 0x80; 35 | instructions = 1; run(); 36 | if(!(ram[2] == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY && !(SR&SR_OVER))) return -2; 37 | 38 | //carry and negative 39 | ram[0] = 0x06; 40 | ram[1] = 0x02; 41 | ram[2] = 0xC0; 42 | instructions = 1; run(); 43 | if(!(ram[2] == 0x80 && SR&SR_NEG && !(SR&SR_ZERO) && SR&SR_CARRY && !(SR&SR_OVER))) return -3; 44 | 45 | return 0; 46 | } 47 | 48 | int testAslZeropageX() { 49 | X = 0x01; Y = 0x00; 50 | 51 | //normal 52 | ram[0] = 0x16; 53 | ram[1] = 0x01; 54 | ram[2] = 0x01; 55 | instructions = 1; run(); 56 | if(!(ram[2] == 0x02 && !(SR&SR_NEG) && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1; 57 | 58 | //carry and zero 59 | ram[0] = 0x16; 60 | ram[1] = 0x01; 61 | ram[2] = 0x80; 62 | instructions = 1; run(); 63 | if(!(ram[2] == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY && !(SR&SR_OVER))) return -2; 64 | 65 | //carry and negative 66 | ram[0] = 0x16; 67 | ram[1] = 0x01; 68 | ram[2] = 0xC0; 69 | instructions = 1; run(); 70 | if(!(ram[2] == 0x80 && SR&SR_NEG && !(SR&SR_ZERO) && SR&SR_CARRY && !(SR&SR_OVER))) return -3; 71 | 72 | return 0; 73 | } 74 | 75 | int testAslAbsolute() { 76 | //normal 77 | ram[0] = 0x0E; 78 | ram[1] = 0x03; 79 | ram[2] = 0x00; 80 | ram[3] = 0x01; 81 | instructions = 1; run(); 82 | if(!(ram[3] == 0x02 && !(SR&SR_NEG) && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1; 83 | 84 | //carry and zero 85 | ram[0] = 0x0E; 86 | ram[1] = 0x03; 87 | ram[2] = 0x00; 88 | ram[3] = 0x80; 89 | instructions = 1; run(); 90 | if(!(ram[3] == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY && !(SR&SR_OVER))) return -2; 91 | 92 | //carry and negative 93 | ram[0] = 0x0E; 94 | ram[1] = 0x03; 95 | ram[2] = 0x00; 96 | ram[3] = 0xC0; 97 | instructions = 1; run(); 98 | if(!(ram[3] == 0x80 && SR&SR_NEG && !(SR&SR_ZERO) && SR&SR_CARRY && !(SR&SR_OVER))) return -3; 99 | 100 | return 0; 101 | } 102 | 103 | int testAslAbsoluteX() { 104 | X = 0x01; Y = 0x00; 105 | 106 | //normal 107 | ram[0] = 0x1E; 108 | ram[1] = 0x02; 109 | ram[2] = 0x00; 110 | ram[3] = 0x01; 111 | instructions = 1; run(); 112 | if(!(ram[3] == 0x02 && !(SR&SR_NEG) && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1; 113 | 114 | //carry and zero 115 | ram[0] = 0x1E; 116 | ram[1] = 0x02; 117 | ram[2] = 0x00; 118 | ram[3] = 0x80; 119 | instructions = 1; run(); 120 | if(!(ram[3] == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY && !(SR&SR_OVER))) return -2; 121 | 122 | //carry and negative 123 | ram[0] = 0x1E; 124 | ram[1] = 0x02; 125 | ram[2] = 0x00; 126 | ram[3] = 0xC0; 127 | instructions = 1; run(); 128 | if(!(ram[3] == 0x80 && SR&SR_NEG && !(SR&SR_ZERO) && SR&SR_CARRY && !(SR&SR_OVER))) return -3; 129 | 130 | return 0; 131 | } -------------------------------------------------------------------------------- /6502tests/test/testOra.c: -------------------------------------------------------------------------------- 1 | int testOraImmediate() { 2 | //all set 3 | A = 0xFF; 4 | ram[0] = 0x09; 5 | ram[1] = 0x0F; 6 | instructions = 1; run(); 7 | if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO))) return -1; 8 | 9 | //zero 10 | A = 0x00; 11 | ram[0] = 0x09; 12 | ram[1] = 0x00; 13 | instructions = 1; run(); 14 | if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO)) return -2; 15 | 16 | return 0; 17 | } 18 | 19 | int testOraZeropage() { 20 | //all set 21 | A = 0xFF; 22 | ram[0] = 0x05; 23 | ram[1] = 0x02; 24 | ram[2] = 0x0F; 25 | instructions = 1; run(); 26 | if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO))) return -1; 27 | 28 | //zero 29 | A = 0x00; 30 | ram[0] = 0x05; 31 | ram[1] = 0x02; 32 | ram[2] = 0x00; 33 | instructions = 1; run(); 34 | if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO)) return -2; 35 | 36 | return 0; 37 | } 38 | 39 | int testOraZeropageX() { 40 | X = 0x01; Y = 0x00; 41 | 42 | //all set 43 | A = 0xFF; 44 | ram[0] = 0x15; 45 | ram[1] = 0x01; 46 | ram[2] = 0x0F; 47 | instructions = 1; run(); 48 | if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO))) return -1; 49 | 50 | //zero 51 | A = 0x00; 52 | ram[0] = 0x15; 53 | ram[1] = 0x01; 54 | ram[2] = 0x00; 55 | instructions = 1; run(); 56 | if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO)) return -2; 57 | 58 | return 0; 59 | } 60 | 61 | int testOraAbsolute() { 62 | //all set 63 | A = 0xFF; 64 | ram[0] = 0x0D; 65 | ram[1] = 0x03; 66 | ram[2] = 0x00; 67 | ram[3] = 0x0F; 68 | instructions = 1; run(); 69 | if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO))) return -1; 70 | 71 | //zero 72 | A = 0x00; 73 | ram[0] = 0x0D; 74 | ram[1] = 0x03; 75 | ram[2] = 0x00; 76 | ram[3] = 0x00; 77 | instructions = 1; run(); 78 | if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO)) return -2; 79 | 80 | return 0; 81 | } 82 | 83 | int testOraAbsoluteX() { 84 | X = 0x01; Y = 0x00; 85 | 86 | //all set 87 | A = 0xFF; 88 | ram[0] = 0x1D; 89 | ram[1] = 0x02; 90 | ram[2] = 0x00; 91 | ram[3] = 0x0F; 92 | instructions = 1; run(); 93 | if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO))) return -1; 94 | 95 | //zero 96 | A = 0x00; 97 | ram[0] = 0x1D; 98 | ram[1] = 0x02; 99 | ram[2] = 0x00; 100 | ram[3] = 0x00; 101 | instructions = 1; run(); 102 | if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO)) return -2; 103 | 104 | return 0; 105 | } 106 | 107 | int testOraAbsoluteY() { 108 | X = 0x00; Y = 0x01; 109 | 110 | //all set 111 | A = 0xFF; 112 | ram[0] = 0x19; 113 | ram[1] = 0x02; 114 | ram[2] = 0x00; 115 | ram[3] = 0x0F; 116 | instructions = 1; run(); 117 | if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO))) return -1; 118 | 119 | //zero 120 | A = 0x00; 121 | ram[0] = 0x19; 122 | ram[1] = 0x02; 123 | ram[2] = 0x00; 124 | ram[3] = 0x00; 125 | instructions = 1; run(); 126 | if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO)) return -2; 127 | 128 | return 0; 129 | } 130 | 131 | int testOraIndirectX() { 132 | X = 0x01; Y = 0x00; 133 | 134 | //all set 135 | A = 0xFF; 136 | ram[0] = 0x01; 137 | ram[1] = 0x02; 138 | ram[2] = 0x02; 139 | ram[3] = 0x0F; 140 | instructions = 1; run(); 141 | if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO))) return -1; 142 | 143 | //zero 144 | A = 0x00; 145 | ram[0] = 0x01; 146 | ram[1] = 0x02; 147 | ram[2] = 0x02; 148 | ram[3] = 0x00; 149 | instructions = 1; run(); 150 | if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO)) return -2; 151 | 152 | return 0; 153 | } 154 | 155 | int testOraIndirectY() { 156 | Y = 0x01; X = 0x00; 157 | 158 | //all set 159 | A = 0xFF; 160 | ram[0] = 0x11; 161 | ram[1] = 0x02; 162 | ram[2] = 0x03; 163 | ram[3] = 0x00; 164 | ram[4] = 0x0F; 165 | instructions = 1; run(); 166 | if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO))) return -1; 167 | 168 | //zero 169 | A = 0x00; 170 | ram[0] = 0x11; 171 | ram[1] = 0x02; 172 | ram[2] = 0x02; 173 | ram[3] = 0x00; 174 | instructions = 1; run(); 175 | if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO)) return -2; 176 | 177 | return 0; 178 | } -------------------------------------------------------------------------------- /APPLEII/keyboard.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define KEYBD_DATA_PIN 4 4 | 5 | const unsigned char scancode_to_apple[] PROGMEM = { 6 | //$0 $1 $2 $3 $4 $5 $6 $7 $8 $9 $A $B $C $D $E $F 7 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //$00 8 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xD1, 0xB1, 0x00, 0x00, 0x00, 0xDA, 0xD3, 0xC1, 0xD7, 0xB2, 0x00, //$10 9 | 0x00, 0xC3, 0xD8, 0xC4, 0xC5, 0xB4, 0xB3, 0x00, 0x00, 0xA0, 0xD6, 0xC6, 0xD4, 0xD2, 0xB5, 0x00, //$20 10 | 0x00, 0xCE, 0xC2, 0xC8, 0xC7, 0xD9, 0xB6, 0x00, 0x00, 0x00, 0xCD, 0xCA, 0xD5, 0xB7, 0xB8, 0x00, //$30 11 | 0x00, 0xAC, 0xCB, 0xC9, 0xCF, 0xB0, 0xB9, 0x00, 0x00, 0xAE, 0xAF, 0xCC, 0xBB, 0xD0, 0xAD, 0x00, //$40 12 | 0x00, 0x00, 0xA7, 0x00, 0x00, 0xBD, 0x00, 0x00, 0x00, 0x00, 0x8D, 0x00, 0x00, 0x00, 0x00, 0x00, //$50 13 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0xB1, 0x00, 0xB4, 0xB7, 0x00, 0x00, 0x00, //$60 14 | 0xB0, 0xAE, 0xB2, 0xB5, 0xB6, 0xB8, 0x9B, 0x00, 0x00, 0xAB, 0xB3, 0xAD, 0xAA, 0xB9, 0x00, 0x00, //$70 15 | // High mirror, shift modified keys 16 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //$80 0 17 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xD1, 0xA1, 0x00, 0x00, 0x00, 0xDA, 0xD3, 0xC1, 0xD7, 0xC0, 0x00, //$90 1 18 | 0x00, 0xC3, 0xD8, 0xC4, 0xC5, 0xA4, 0xA3, 0x00, 0x00, 0xA0, 0xD6, 0xC6, 0xD4, 0xD2, 0xA5, 0x00, //$A0 2 19 | 0x00, 0xCE, 0xC2, 0xC8, 0xC7, 0xD9, 0xDE, 0x00, 0x00, 0x00, 0xCD, 0xCA, 0xD5, 0xA6, 0xAA, 0x00, //$B0 3 20 | 0x00, 0xBC, 0xCB, 0xC9, 0xCF, 0xA9, 0xA8, 0x00, 0x00, 0xBE, 0xBF, 0xCC, 0xBA, 0xD0, 0xAD, 0x00, //$C0 4 21 | 0x00, 0x00, 0xA2, 0x00, 0x00, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x8D, 0x00, 0x00, 0x00, 0x00, 0x00, //$D0 5 22 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0xB1, 0x00, 0xB4, 0xB7, 0x00, 0x00, 0x00, //$E0 6 23 | 0xB0, 0xAE, 0xB2, 0xB5, 0xB6, 0xB8, 0x9B, 0x00, 0x00, 0xAB, 0xB3, 0xAD, 0xAA, 0xB9, 0x00, 0x00 //$F0 7 24 | }; 25 | 26 | // keyboard scan buffer 27 | unsigned short keyboard_data[3] = {0, 0, 0}; 28 | unsigned char keyboard_buf_indx = 0, keyboard_mbyte = 0; 29 | boolean shift_enabled = false; 30 | 31 | // In apple II scancode format 32 | volatile unsigned char keymem = 0; 33 | 34 | unsigned char keyboard_read() { 35 | return keymem; 36 | } 37 | 38 | void keyboard_strobe() { 39 | keymem&=0x7F; 40 | } 41 | 42 | // clock must be on digital 3 43 | void keyboard_begin() { 44 | pinMode(3, INPUT_PULLUP); 45 | pinMode(KEYBD_DATA_PIN, INPUT_PULLUP); 46 | attachInterrupt(1, keyboard_bit, FALLING); 47 | } 48 | 49 | void keyboard_bit() { 50 | if(digitalRead(KEYBD_DATA_PIN))keyboard_data[2] |= _BV(keyboard_buf_indx); 51 | else keyboard_data[2] &= ~(_BV(keyboard_buf_indx)); 52 | if(++keyboard_buf_indx == 11) { 53 | // Ignore parity checks for now 54 | keyboard_data[2] = (keyboard_data[2]>>1)&0xFF; 55 | 56 | // extended keys 57 | if(keyboard_data[2] == 0xF0 || keyboard_data[2] == 0xE0) keyboard_mbyte = 1; 58 | else { 59 | //decrement counter for multibyte commands 60 | if(keyboard_mbyte) keyboard_mbyte--; 61 | // multibyte command is finished / normal command, process it 62 | if(!keyboard_mbyte) { 63 | if(keyboard_data[1] != 0xF0 && keyboard_data[1] != 0xE0) { 64 | //Standard keys 65 | if(keyboard_data[2] == 0x12 || keyboard_data[2] == 0x59) shift_enabled = true; //shift modifiers 66 | else keymem = pgm_read_byte_near(scancode_to_apple+keyboard_data[2]+((shift_enabled)?0x80:0x00)); 67 | } else if(keyboard_data[0] != 0xF0 && keyboard_data[1] == 0xE0) { 68 | //Extended keys 69 | if(keyboard_data[2] == 0x6B) keymem = 0x95; //back key 70 | if(keyboard_data[2] == 0x74) keymem = 0x88; //forward key 71 | // Power management keys, hardware reset 72 | if(keyboard_data[2] == 0x37) { 73 | // enable watchdog with min timeout 74 | // wait until reset 75 | wdt_enable(WDTO_15MS); 76 | for(;;); 77 | } 78 | } else if(keyboard_data[1] == 0xF0 && (keyboard_data[2] == 0x12 || keyboard_data[2] == 0x59)) shift_enabled = false; 79 | } 80 | } 81 | 82 | //shuffle buffer 83 | keyboard_data[0] = keyboard_data[1]; 84 | keyboard_data[1] = keyboard_data[2]; 85 | keyboard_buf_indx = 0; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /6502tests/test/testAnd.c: -------------------------------------------------------------------------------- 1 | int testAndImmediate() { 2 | A = 0xFF; 3 | 4 | //all high 5 | ram[0] = 0x29; 6 | ram[1] = 0xFF; 7 | instructions = 1; run(); 8 | if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1; 9 | 10 | //all low 11 | ram[0] = 0x29; 12 | ram[1] = 0x00; 13 | instructions = 1; run(); 14 | if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -2; 15 | 16 | return 0; 17 | } 18 | 19 | int testAndZeropage() { 20 | A = 0xFF; 21 | 22 | //all high 23 | ram[0] = 0x25; 24 | ram[1] = 0x02; 25 | ram[2] = 0xFF; 26 | instructions = 1; run(); 27 | if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1; 28 | 29 | //all low 30 | ram[0] = 0x25; 31 | ram[1] = 0x02; 32 | ram[2] = 0x00; 33 | instructions = 1; run(); 34 | if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -2; 35 | 36 | return 0; 37 | } 38 | 39 | int testAndZeropageX() { 40 | X = 0x01; Y = 0x00; 41 | A = 0xFF; 42 | 43 | //all high 44 | ram[0] = 0x35; 45 | ram[1] = 0x01; 46 | ram[2] = 0xFF; 47 | instructions = 1; run(); 48 | if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1; 49 | 50 | //all low 51 | ram[0] = 0x35; 52 | ram[1] = 0x01; 53 | ram[2] = 0x00; 54 | instructions = 1; run(); 55 | if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -2; 56 | 57 | return 0; 58 | } 59 | 60 | int testAndAbsolute() { 61 | A = 0xFF; 62 | 63 | //all high 64 | ram[0] = 0x2D; 65 | ram[1] = 0x03; 66 | ram[2] = 0x00; 67 | ram[3] = 0xFF; 68 | instructions = 1; run(); 69 | if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1; 70 | 71 | //all low 72 | ram[0] = 0x2D; 73 | ram[1] = 0x03; 74 | ram[2] = 0x00; 75 | ram[3] = 0x00; 76 | instructions = 1; run(); 77 | if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -2; 78 | 79 | return 0; 80 | } 81 | 82 | int testAndAbsoluteX() { 83 | A = 0xFF; 84 | X = 0x01; Y = 0x00; 85 | 86 | //all high 87 | ram[0] = 0x3D; 88 | ram[1] = 0x02; 89 | ram[2] = 0x00; 90 | ram[3] = 0xFF; 91 | instructions = 1; run(); 92 | if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1; 93 | 94 | //all low 95 | ram[0] = 0x3D; 96 | ram[1] = 0x02; 97 | ram[2] = 0x00; 98 | ram[3] = 0x00; 99 | instructions = 1; run(); 100 | if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -2; 101 | 102 | return 0; 103 | } 104 | 105 | int testAndAbsoluteY() { 106 | A = 0xFF; 107 | Y = 0x01; X = 0x00; 108 | 109 | //all high 110 | ram[0] = 0x39; 111 | ram[1] = 0x02; 112 | ram[2] = 0x00; 113 | ram[3] = 0xFF; 114 | instructions = 1; run(); 115 | if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1; 116 | 117 | //all low 118 | ram[0] = 0x39; 119 | ram[1] = 0x02; 120 | ram[2] = 0x00; 121 | ram[3] = 0x00; 122 | instructions = 1; run(); 123 | if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -2; 124 | 125 | return 0; 126 | } 127 | 128 | int testAndIndirectX() { 129 | A = 0xFF; 130 | X = 0x01; Y = 0x00; 131 | 132 | //all high 133 | ram[0] = 0x21; 134 | ram[1] = 0x02; 135 | ram[2] = 0x02; 136 | ram[3] = 0xFF; 137 | instructions = 1; run(); 138 | if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1; 139 | 140 | //all low 141 | ram[0] = 0x21; 142 | ram[1] = 0x02; 143 | ram[2] = 0x02; 144 | ram[3] = 0x00; 145 | instructions = 1; run(); 146 | if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -2; 147 | 148 | return 0; 149 | } 150 | 151 | int testAndIndirectY() { 152 | A = 0xFF; 153 | Y = 0x01; X = 0x00; 154 | 155 | //all high 156 | ram[0] = 0x31; 157 | ram[1] = 0x02; 158 | ram[2] = 0x03; 159 | ram[3] = 0x00; 160 | ram[4] = 0xFF; 161 | instructions = 1; run(); 162 | if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1; 163 | 164 | //all low 165 | ram[0] = 0x31; 166 | ram[1] = 0x02; 167 | ram[2] = 0x03; 168 | ram[3] = 0x00; 169 | ram[4] = 0x00; 170 | instructions = 1; run(); 171 | if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -2; 172 | 173 | return 0; 174 | } -------------------------------------------------------------------------------- /APPLEII/cassette.ino: -------------------------------------------------------------------------------- 1 | // Share speaker pin for output 2 | #define CASSETTE_READ_PIN A5 3 | #define SPEAKER_PIN 5 4 | 5 | #ifndef cbi 6 | #define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) 7 | #endif 8 | #ifndef sbi 9 | #define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit)) 10 | #endif 11 | 12 | void cassette_header(unsigned short periods) { 13 | // Header Tone 14 | for(int i = 0; i < periods*128; ++i) { 15 | digitalWrite(SPEAKER_PIN, HIGH); 16 | delayMicroseconds(650); 17 | digitalWrite(SPEAKER_PIN, LOW); 18 | delayMicroseconds(650); 19 | } 20 | // Sync pulse, one half cycle at 2500hz and then 2000hz 21 | // 2500 hz 22 | digitalWrite(SPEAKER_PIN, HIGH); 23 | delayMicroseconds(200); 24 | // 2000 hz 25 | digitalWrite(SPEAKER_PIN, LOW); 26 | delayMicroseconds(250); 27 | } 28 | 29 | void cassette_write_byte(unsigned char val) { 30 | // Shift it out, MSB first 31 | digitalWrite(SPEAKER_PIN, HIGH); 32 | delayMicroseconds((val&0x80) ? 500 : 250); 33 | digitalWrite(SPEAKER_PIN, LOW); 34 | delayMicroseconds((val&0x80) ? 500 : 250); 35 | //bit 6 36 | digitalWrite(SPEAKER_PIN, HIGH); 37 | delayMicroseconds((val&0x40) ? 500 : 250); 38 | digitalWrite(SPEAKER_PIN, LOW); 39 | delayMicroseconds((val&0x40) ? 500 : 250); 40 | //bit 5 41 | digitalWrite(SPEAKER_PIN, HIGH); 42 | delayMicroseconds((val&0x20) ? 500 : 250); 43 | digitalWrite(SPEAKER_PIN, LOW); 44 | delayMicroseconds((val&0x20) ? 500 : 250); 45 | //bit 4 46 | digitalWrite(SPEAKER_PIN, HIGH); 47 | delayMicroseconds((val&0x10) ? 500 : 250); 48 | digitalWrite(SPEAKER_PIN, LOW); 49 | delayMicroseconds((val&0x10) ? 500 : 250); 50 | //bit 3 51 | digitalWrite(SPEAKER_PIN, HIGH); 52 | delayMicroseconds((val&0x08) ? 500 : 250); 53 | digitalWrite(SPEAKER_PIN, LOW); 54 | delayMicroseconds((val&0x08) ? 500 : 250); 55 | //bit 2 56 | digitalWrite(SPEAKER_PIN, HIGH); 57 | delayMicroseconds((val&0x04) ? 500 : 250); 58 | digitalWrite(SPEAKER_PIN, LOW); 59 | delayMicroseconds((val&0x04) ? 500 : 250); 60 | //bit 1 61 | digitalWrite(SPEAKER_PIN, HIGH); 62 | delayMicroseconds((val&0x02) ? 500 : 250); 63 | digitalWrite(SPEAKER_PIN, LOW); 64 | delayMicroseconds((val&0x02) ? 500 : 250); 65 | //bit 0 66 | digitalWrite(SPEAKER_PIN, HIGH); 67 | delayMicroseconds((val&0x01) ? 500 : 250); 68 | digitalWrite(SPEAKER_PIN, LOW); 69 | delayMicroseconds((val&0x01) ? 500 : 250); 70 | } 71 | 72 | void cassette_write_block(unsigned short A1, unsigned short A2) { 73 | unsigned char checksum = 0xFF, val = 0; 74 | for(unsigned short addr = A1; addr <= A2; ++addr) { 75 | val = read8(addr); 76 | cassette_write_byte(val); 77 | checksum ^= val; 78 | } 79 | cassette_write_byte(checksum); 80 | // High idle for a little while, make sure all bits cleared 81 | digitalWrite(SPEAKER_PIN, HIGH); 82 | delay(10); 83 | digitalWrite(SPEAKER_PIN, LOW); 84 | } 85 | 86 | // Used to track center voltage 87 | float cassette_center_voltage = 512; 88 | // implement zero crossing detector 89 | boolean cassette_read_state() { 90 | static boolean zerocross_state = false; 91 | // get value 92 | short adc = (analogRead(CASSETTE_READ_PIN) - (short)cassette_center_voltage); 93 | // bias drift correction 94 | cassette_center_voltage += adc*0.05f; 95 | // ~7mv hysteresis 96 | if(zerocross_state && adc < -7) zerocross_state = false; 97 | else if(!zerocross_state && adc > 7) zerocross_state = true; 98 | return zerocross_state; 99 | } 100 | 101 | // figure out the duration of zero crossing 102 | short cassette_read_transition() { 103 | unsigned long start_time; 104 | static boolean last = false; 105 | boolean cur = last; 106 | // loop until state transition 107 | for(start_time = micros();cur == last;) cur = cassette_read_state(); 108 | // update transition tracking 109 | last = cur; 110 | //return duration of transition us 111 | return micros() - start_time; 112 | } 113 | 114 | // Based loosely on steve wozniaks original algorithm 115 | boolean cassette_read_block(unsigned short A1, unsigned short A2) { 116 | short bitperiod; 117 | unsigned char val, checksum = 0xFF, datachecksum = 0x00; 118 | 119 | // Calibrate the zero crossing detector 120 | for(short i = 0; i < 10000; ++i) cassette_read_state(); 121 | 122 | // find tape in edge 123 | cassette_read_transition(); 124 | cassette_read_transition(); 125 | 126 | // Small delay to allow things to settle 127 | delay(500); 128 | 129 | //wait for sync bit, short zero 130 | while(cassette_read_transition() > 300); 131 | 132 | // skip second cycle of sync bit 133 | cassette_read_transition(); 134 | 135 | // start reading data 136 | for(unsigned short addr = A1; addr <= A2; ++addr) { 137 | // zero our byte of memory 138 | val = 0; 139 | for(unsigned char i = 8; i != 0; --i) { 140 | bitperiod = (cassette_read_transition() + cassette_read_transition()) / 2; 141 | if(bitperiod > 300) val |= _BV(i-1); 142 | } 143 | // write byte to memory 144 | write8(addr, val); 145 | // update checksum 146 | checksum ^= val; 147 | } 148 | 149 | // Read checksum 150 | for(unsigned char i = 8; i != 0; --i) { 151 | bitperiod = (cassette_read_transition() + cassette_read_transition()) / 2; 152 | if(bitperiod > 300) datachecksum |= _BV(i-1); 153 | } 154 | 155 | //return whether the data passes error checking 156 | return (datachecksum == checksum); 157 | } 158 | 159 | void cassette_begin() { 160 | // ADC prescale, 77khz 161 | sbi(ADCSRA,ADPS2); 162 | cbi(ADCSRA,ADPS1); 163 | cbi(ADCSRA,ADPS0); 164 | // internal pullup on analog pin 165 | digitalWrite(CASSETTE_READ_PIN, HIGH); 166 | // use 1.1v internal analog reference 167 | analogReference(INTERNAL); 168 | } 169 | -------------------------------------------------------------------------------- /6502tests/test/testCmp.c: -------------------------------------------------------------------------------- 1 | int testCmpImmediate() { 2 | //no difference 3 | SR |= SR_ZERO; 4 | SR |= SR_CARRY; 5 | SR |= SR_NEG; 6 | A = 0x10; 7 | ram[0] = 0xC9; 8 | ram[1] = 0x10; 9 | instructions = 2; run(); 10 | if(!(!(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY)) return -1; 11 | 12 | //less 13 | SR |= SR_ZERO; 14 | SR |= SR_CARRY; 15 | SR |= SR_NEG; 16 | A = 0x10; 17 | ram[0] = 0xC9; 18 | ram[1] = 0x04; 19 | instructions = 2; run(); 20 | if(!(!(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY)) return -2; 21 | 22 | //more 23 | SR |= SR_ZERO; 24 | SR |= SR_CARRY; 25 | SR |= SR_NEG; 26 | A = 0x04; 27 | ram[0] = 0xC9; 28 | ram[1] = 0x10; 29 | instructions = 2; run(); 30 | if(!(SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY))) return -2; 31 | 32 | return 0; 33 | } 34 | 35 | int testCmpZeropage() { 36 | //no difference 37 | SR |= SR_ZERO; 38 | SR |= SR_CARRY; 39 | SR |= SR_NEG; 40 | A = 0x10; 41 | ram[0] = 0xC5; 42 | ram[1] = 0x02; 43 | ram[2] = 0x10; 44 | instructions = 2; run(); 45 | if(!(!(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY)) return -1; 46 | 47 | //less 48 | SR |= SR_ZERO; 49 | SR |= SR_CARRY; 50 | SR |= SR_NEG; 51 | A = 0x10; 52 | ram[0] = 0xC5; 53 | ram[1] = 0x02; 54 | ram[2] = 0x04; 55 | instructions = 2; run(); 56 | if(!(!(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY)) return -2; 57 | 58 | //more 59 | SR |= SR_ZERO; 60 | SR |= SR_CARRY; 61 | SR |= SR_NEG; 62 | A = 0x04; 63 | ram[0] = 0xC5; 64 | ram[1] = 0x02; 65 | ram[2] = 0x10; 66 | instructions = 2; run(); 67 | if(!(SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY))) return -2; 68 | 69 | return 0; 70 | } 71 | 72 | int testCmpZeropageX() { 73 | X = 0x01; Y = 0x00; 74 | 75 | //no difference 76 | SR |= SR_ZERO; 77 | SR |= SR_CARRY; 78 | SR |= SR_NEG; 79 | A = 0x10; 80 | ram[0] = 0xD5; 81 | ram[1] = 0x01; 82 | ram[2] = 0x10; 83 | instructions = 2; run(); 84 | if(!(!(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY)) return -1; 85 | 86 | //less 87 | SR |= SR_ZERO; 88 | SR |= SR_CARRY; 89 | SR |= SR_NEG; 90 | A = 0x10; 91 | ram[0] = 0xD5; 92 | ram[1] = 0x01; 93 | ram[2] = 0x04; 94 | instructions = 2; run(); 95 | if(!(!(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY)) return -2; 96 | 97 | //more 98 | SR |= SR_ZERO; 99 | SR |= SR_CARRY; 100 | SR |= SR_NEG; 101 | A = 0x04; 102 | ram[0] = 0xD5; 103 | ram[1] = 0x01; 104 | ram[2] = 0x10; 105 | instructions = 2; run(); 106 | if(!(SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY))) return -2; 107 | 108 | return 0; 109 | } 110 | 111 | int testCmpAbsolute() { 112 | //no difference 113 | SR |= SR_ZERO; 114 | SR |= SR_CARRY; 115 | SR |= SR_NEG; 116 | A = 0x10; 117 | ram[0] = 0xCD; 118 | ram[1] = 0x03; 119 | ram[2] = 0x00; 120 | ram[3] = 0x10; 121 | instructions = 2; run(); 122 | if(!(!(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY)) return -1; 123 | 124 | //less 125 | SR |= SR_ZERO; 126 | SR |= SR_CARRY; 127 | SR |= SR_NEG; 128 | A = 0x10; 129 | ram[0] = 0xCD; 130 | ram[1] = 0x03; 131 | ram[2] = 0x00; 132 | ram[3] = 0x04; 133 | instructions = 2; run(); 134 | if(!(!(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY)) return -2; 135 | 136 | //more 137 | SR |= SR_ZERO; 138 | SR |= SR_CARRY; 139 | SR |= SR_NEG; 140 | A = 0x04; 141 | ram[0] = 0xCD; 142 | ram[1] = 0x03; 143 | ram[2] = 0x00; 144 | ram[3] = 0x10; 145 | instructions = 2; run(); 146 | if(!(SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY))) return -2; 147 | 148 | return 0; 149 | } 150 | 151 | int testCmpAbsoluteX() { 152 | X = 0x01; Y = 0x00; 153 | 154 | //no difference 155 | SR |= SR_ZERO; 156 | SR |= SR_CARRY; 157 | SR |= SR_NEG; 158 | A = 0x10; 159 | ram[0] = 0xDD; 160 | ram[1] = 0x02; 161 | ram[2] = 0x00; 162 | ram[3] = 0x10; 163 | instructions = 2; run(); 164 | if(!(!(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY)) return -1; 165 | 166 | //less 167 | SR |= SR_ZERO; 168 | SR |= SR_CARRY; 169 | SR |= SR_NEG; 170 | A = 0x10; 171 | ram[0] = 0xDD; 172 | ram[1] = 0x02; 173 | ram[2] = 0x00; 174 | ram[3] = 0x04; 175 | instructions = 2; run(); 176 | if(!(!(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY)) return -2; 177 | 178 | //more 179 | SR |= SR_ZERO; 180 | SR |= SR_CARRY; 181 | SR |= SR_NEG; 182 | A = 0x04; 183 | ram[0] = 0xDD; 184 | ram[1] = 0x02; 185 | ram[2] = 0x00; 186 | ram[3] = 0x10; 187 | instructions = 2; run(); 188 | if(!(SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY))) return -2; 189 | 190 | return 0; 191 | } 192 | 193 | int testCmpAbsoluteY() { 194 | Y = 0x01; X = 0x00; 195 | 196 | //no difference 197 | SR |= SR_ZERO; 198 | SR |= SR_CARRY; 199 | SR |= SR_NEG; 200 | A = 0x10; 201 | ram[0] = 0xD9; 202 | ram[1] = 0x02; 203 | ram[2] = 0x00; 204 | ram[3] = 0x10; 205 | instructions = 2; run(); 206 | if(!(!(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY)) return -1; 207 | 208 | //less 209 | SR |= SR_ZERO; 210 | SR |= SR_CARRY; 211 | SR |= SR_NEG; 212 | A = 0x10; 213 | ram[0] = 0xD9; 214 | ram[1] = 0x02; 215 | ram[2] = 0x00; 216 | ram[3] = 0x04; 217 | instructions = 2; run(); 218 | if(!(!(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY)) return -2; 219 | 220 | //more 221 | SR |= SR_ZERO; 222 | SR |= SR_CARRY; 223 | SR |= SR_NEG; 224 | A = 0x04; 225 | ram[0] = 0xD9; 226 | ram[1] = 0x02; 227 | ram[2] = 0x00; 228 | ram[3] = 0x10; 229 | instructions = 2; run(); 230 | if(!(SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY))) return -2; 231 | 232 | return 0; 233 | } 234 | 235 | int testCmpIndirectX() { 236 | X = 0x01; Y = 0x00; 237 | 238 | //no difference 239 | SR |= SR_ZERO; 240 | SR |= SR_CARRY; 241 | SR |= SR_NEG; 242 | A = 0x10; 243 | ram[0] = 0xC1; 244 | ram[1] = 0x02; 245 | ram[2] = 0x02; 246 | ram[3] = 0x10; 247 | instructions = 2; run(); 248 | if(!(!(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY)) return -1; 249 | 250 | //less 251 | SR |= SR_ZERO; 252 | SR |= SR_CARRY; 253 | SR |= SR_NEG; 254 | A = 0x10; 255 | ram[0] = 0xC1; 256 | ram[1] = 0x02; 257 | ram[2] = 0x02; 258 | ram[3] = 0x04; 259 | instructions = 2; run(); 260 | if(!(!(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY)) return -2; 261 | 262 | //more 263 | SR |= SR_ZERO; 264 | SR |= SR_CARRY; 265 | SR |= SR_NEG; 266 | A = 0x04; 267 | ram[0] = 0xC1; 268 | ram[1] = 0x02; 269 | ram[2] = 0x02; 270 | ram[3] = 0x10; 271 | instructions = 2; run(); 272 | if(!(SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY))) return -2; 273 | 274 | return 0; 275 | } 276 | 277 | int testCmpIndirectY() { 278 | Y = 0x01; X = 0x00; 279 | 280 | //no difference 281 | SR |= SR_ZERO; 282 | SR |= SR_CARRY; 283 | SR |= SR_NEG; 284 | A = 0x10; 285 | ram[0] = 0xD1; 286 | ram[1] = 0x02; 287 | ram[2] = 0x03; 288 | ram[3] = 0x00; 289 | ram[4] = 0x10; 290 | instructions = 2; run(); 291 | if(!(!(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY)) return -1; 292 | 293 | //less 294 | SR |= SR_ZERO; 295 | SR |= SR_CARRY; 296 | SR |= SR_NEG; 297 | A = 0x10; 298 | ram[0] = 0xD1; 299 | ram[1] = 0x02; 300 | ram[2] = 0x03; 301 | ram[3] = 0x00; 302 | ram[4] = 0x04; 303 | instructions = 2; run(); 304 | if(!(!(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY)) return -2; 305 | 306 | //more 307 | SR |= SR_ZERO; 308 | SR |= SR_CARRY; 309 | SR |= SR_NEG; 310 | A = 0x04; 311 | ram[0] = 0xD1; 312 | ram[1] = 0x02; 313 | ram[2] = 0x03; 314 | ram[3] = 0x00; 315 | ram[4] = 0x10; 316 | instructions = 2; run(); 317 | if(!(SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY))) return -2; 318 | 319 | return 0; 320 | } -------------------------------------------------------------------------------- /6502tests/test/testSbc.c: -------------------------------------------------------------------------------- 1 | int testSbcImmediate() { 2 | SR &= (~SR_DEC); 3 | 4 | //no overflow 5 | SR |= SR_CARRY; 6 | A = 0x00; 7 | ram[0] = 0xE9; 8 | ram[1] = 0x01; 9 | instructions = 1; run(); 10 | if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1; 11 | 12 | //overflow 13 | SR |= SR_CARRY; 14 | A = 0x7F; 15 | ram[0] = 0xE9; 16 | ram[1] = 0xFF; 17 | instructions = 1; run(); 18 | if(!(A == 0x80 && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && SR&SR_OVER)) return -2; 19 | 20 | //no borrow 21 | SR &= (~SR_CARRY); 22 | A = 0xC0; 23 | ram[0] = 0xE9; 24 | ram[1] = 0x40; 25 | instructions = 1; run(); 26 | //overflow differs from 2nd sim ... 27 | if(!(A == 0x7F && !(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY && SR&SR_OVER)) return -3; 28 | 29 | return 0; 30 | } 31 | 32 | int testSbcZeropage() { 33 | //no overflow 34 | SR |= SR_CARRY; 35 | A = 0x00; 36 | ram[0] = 0xE5; 37 | ram[1] = 0x02; 38 | ram[2] = 0x01; 39 | instructions = 1; run(); 40 | if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1; 41 | 42 | //overflow 43 | SR |= SR_CARRY; 44 | A = 0x7F; 45 | ram[0] = 0xE5; 46 | ram[1] = 0x02; 47 | ram[2] = 0xFF; 48 | instructions = 1; run(); 49 | if(!(A == 0x80 && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && SR&SR_OVER)) return -2; 50 | 51 | //no borrow 52 | SR &= (~SR_CARRY); 53 | A = 0xC0; 54 | ram[0] = 0xE5; 55 | ram[1] = 0x02; 56 | ram[2] = 0x40; 57 | instructions = 1; run(); 58 | //overflow differs from 2nd sim ... 59 | if(!(A == 0x7F && !(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY && SR&SR_OVER)) return -3; 60 | 61 | return 0; 62 | } 63 | 64 | int testSbcZeropageX() { 65 | X = 0x01; Y = 0x00; 66 | 67 | //no overflow 68 | SR |= SR_CARRY; 69 | A = 0x00; 70 | ram[0] = 0xF5; 71 | ram[1] = 0x01; 72 | ram[2] = 0x01; 73 | instructions = 1; run(); 74 | if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1; 75 | 76 | //overflow 77 | SR |= SR_CARRY; 78 | A = 0x7F; 79 | ram[0] = 0xF5; 80 | ram[1] = 0x01; 81 | ram[2] = 0xFF; 82 | instructions = 1; run(); 83 | if(!(A == 0x80 && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && SR&SR_OVER)) return -2; 84 | 85 | //no borrow 86 | SR &= (~SR_CARRY); 87 | A = 0xC0; 88 | ram[0] = 0xF5; 89 | ram[1] = 0x01; 90 | ram[2] = 0x40; 91 | instructions = 1; run(); 92 | //overflow differs from 2nd sim ... 93 | if(!(A == 0x7F && !(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY && SR&SR_OVER)) return -3; 94 | 95 | return 0; 96 | } 97 | 98 | int testSbcAbsolute() { 99 | //no overflow 100 | SR |= SR_CARRY; 101 | A = 0x00; 102 | ram[0] = 0xED; 103 | ram[1] = 0x03; 104 | ram[2] = 0x00; 105 | ram[3] = 0x01; 106 | instructions = 1; run(); 107 | if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1; 108 | 109 | //overflow 110 | SR |= SR_CARRY; 111 | A = 0x7F; 112 | ram[0] = 0xED; 113 | ram[1] = 0x03; 114 | ram[2] = 0x00; 115 | ram[3] = 0xFF; 116 | instructions = 1; run(); 117 | if(!(A == 0x80 && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && SR&SR_OVER)) return -2; 118 | 119 | //no borrow 120 | SR &= (~SR_CARRY); 121 | A = 0xC0; 122 | ram[0] = 0xED; 123 | ram[1] = 0x03; 124 | ram[2] = 0x00; 125 | ram[3] = 0x40; 126 | instructions = 1; run(); 127 | //overflow differs from 2nd sim ... 128 | if(!(A == 0x7F && !(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY && SR&SR_OVER)) return -3; 129 | 130 | return 0; 131 | } 132 | 133 | int testSbcAbsoluteX() { 134 | X = 0x01; Y = 0x00; 135 | 136 | //no overflow 137 | SR |= SR_CARRY; 138 | A = 0x00; 139 | ram[0] = 0xFD; 140 | ram[1] = 0x02; 141 | ram[2] = 0x00; 142 | ram[3] = 0x01; 143 | instructions = 1; run(); 144 | if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1; 145 | 146 | //overflow 147 | SR |= SR_CARRY; 148 | A = 0x7F; 149 | ram[0] = 0xFD; 150 | ram[1] = 0x02; 151 | ram[2] = 0x00; 152 | ram[3] = 0xFF; 153 | instructions = 1; run(); 154 | if(!(A == 0x80 && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && SR&SR_OVER)) return -2; 155 | 156 | //no borrow 157 | SR &= (~SR_CARRY); 158 | A = 0xC0; 159 | ram[0] = 0xFD; 160 | ram[1] = 0x02; 161 | ram[2] = 0x00; 162 | ram[3] = 0x40; 163 | instructions = 1; run(); 164 | //overflow differs from 2nd sim ... 165 | if(!(A == 0x7F && !(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY && SR&SR_OVER)) return -3; 166 | 167 | return 0; 168 | } 169 | 170 | int testSbcAbsoluteY() { 171 | Y = 0x01; X = 0x00; 172 | 173 | //no overflow 174 | SR |= SR_CARRY; 175 | A = 0x00; 176 | ram[0] = 0xF9; 177 | ram[1] = 0x02; 178 | ram[2] = 0x00; 179 | ram[3] = 0x01; 180 | instructions = 1; run(); 181 | if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1; 182 | 183 | //overflow 184 | SR |= SR_CARRY; 185 | A = 0x7F; 186 | ram[0] = 0xF9; 187 | ram[1] = 0x02; 188 | ram[2] = 0x00; 189 | ram[3] = 0xFF; 190 | instructions = 1; run(); 191 | if(!(A == 0x80 && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && SR&SR_OVER)) return -2; 192 | 193 | //no borrow 194 | SR &= (~SR_CARRY); 195 | A = 0xC0; 196 | ram[0] = 0xF9; 197 | ram[1] = 0x02; 198 | ram[2] = 0x00; 199 | ram[3] = 0x40; 200 | instructions = 1; run(); 201 | //overflow differs from 2nd sim ... 202 | if(!(A == 0x7F && !(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY && SR&SR_OVER)) return -3; 203 | 204 | return 0; 205 | } 206 | 207 | int testSbcIndirectX() { 208 | X = 0x01; Y = 0x00; 209 | 210 | //no overflow 211 | SR |= SR_CARRY; 212 | A = 0x00; 213 | ram[0] = 0xE1; 214 | ram[1] = 0x02; 215 | ram[2] = 0x02; 216 | ram[3] = 0x01; 217 | instructions = 1; run(); 218 | if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1; 219 | 220 | //overflow 221 | SR |= SR_CARRY; 222 | A = 0x7F; 223 | ram[0] = 0xE1; 224 | ram[1] = 0x02; 225 | ram[2] = 0x02; 226 | ram[3] = 0xFF; 227 | instructions = 1; run(); 228 | if(!(A == 0x80 && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && SR&SR_OVER)) return -2; 229 | 230 | //no borrow 231 | SR &= (~SR_CARRY); 232 | A = 0xC0; 233 | ram[0] = 0xE1; 234 | ram[1] = 0x02; 235 | ram[2] = 0x02; 236 | ram[3] = 0x40; 237 | instructions = 1; run(); 238 | //overflow differs from 2nd sim ... 239 | if(!(A == 0x7F && !(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY && SR&SR_OVER)) return -3; 240 | 241 | return 0; 242 | } 243 | 244 | int testSbcIndirectY() { 245 | Y = 0x01; X = 0x00; 246 | 247 | //no overflow 248 | SR |= SR_CARRY; 249 | A = 0x00; 250 | ram[0] = 0xF1; 251 | ram[1] = 0x02; 252 | ram[2] = 0x03; 253 | ram[3] = 0x00; 254 | ram[4] = 0x01; 255 | instructions = 1; run(); 256 | if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1; 257 | 258 | //overflow 259 | SR |= SR_CARRY; 260 | A = 0x7F; 261 | ram[0] = 0xF1; 262 | ram[1] = 0x02; 263 | ram[2] = 0x03; 264 | ram[3] = 0x00; 265 | ram[4] = 0xFF; 266 | instructions = 1; run(); 267 | if(!(A == 0x80 && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && SR&SR_OVER)) return -2; 268 | 269 | //no borrow 270 | SR &= (~SR_CARRY); 271 | A = 0xC0; 272 | ram[0] = 0xF1; 273 | ram[1] = 0x02; 274 | ram[2] = 0x03; 275 | ram[3] = 0x00; 276 | ram[4] = 0x40; 277 | instructions = 1; run(); 278 | //overflow differs from 2nd sim ... 279 | if(!(A == 0x7F && !(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY && SR&SR_OVER)) return -3; 280 | 281 | 282 | return 0; 283 | } -------------------------------------------------------------------------------- /6502tests/test.c: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Bunch of unit tests I wrote during the development of the emulator. 4 | These are very nasty and not really release worthy but someone might 5 | find them useful! 6 | 7 | Copyright (c) 2015, Damian Peckett 8 | All rights reserved. 9 | 10 | Redistribution and use in source and binary forms, with or without 11 | modification, are permitted provided that the following conditions are met: 12 | 13 | 1. Redistributions of source code must retain the above copyright notice, this 14 | list of conditions and the following disclaimer. 15 | 2. Redistributions in binary form must reproduce the above copyright notice, 16 | this list of conditions and the following disclaimer in the documentation 17 | and/or other materials provided with the distribution. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 23 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | //TEST Functions 32 | 33 | #include "test/testAdc.c" 34 | #include "test/testAnd.c" 35 | #include "test/testAsl.c" 36 | #include "test/testBcc.c" 37 | #include "test/testBcs.c" 38 | #include "test/testBeq.c" 39 | #include "test/testBit.c" 40 | #include "test/testBmi.c" 41 | #include "test/testBne.c" 42 | #include "test/testBpl.c" 43 | #include "test/testBrk.c" 44 | #include "test/testBvc.c" 45 | #include "test/testBvs.c" 46 | #include "test/testClear.c" 47 | #include "test/testCmp.c" 48 | #include "test/testCpx.c" 49 | #include "test/testCpy.c" 50 | #include "test/testDec.c" 51 | #include "test/testEor.c" 52 | #include "test/testInc.c" 53 | #include "test/testJmp.c" 54 | #include "test/testLd.c" 55 | #include "test/testLsr.c" 56 | #include "test/testOra.c" 57 | #include "test/testPha.c" 58 | #include "test/testPhp.c" 59 | #include "test/testPla.c" 60 | #include "test/testPlp.c" 61 | #include "test/testRol.c" 62 | #include "test/testRor.c" 63 | #include "test/testRti.c" 64 | #include "test/testRts.c" 65 | #include "test/testSbc.c" 66 | #include "test/testSet.c" 67 | #include "test/testSta.c" 68 | #include "test/testSt.c" 69 | #include "test/testTransfer.c" 70 | 71 | void testAdc() { 72 | printf("testAdcImmediate: %d\r\n", testAdcImmediate()); 73 | printf("testAdcZeropage: %d\r\n", testAdcZeropage()); 74 | printf("testAdcZeropageX: %d\r\n", testAdcZeropageX()); 75 | printf("testAdcAbsolute: %d\r\n", testAdcAbsolute()); 76 | printf("testAdcAbsoluteX: %d\r\n", testAdcAbsoluteX()); 77 | printf("testAdcAbsoluteY: %d\r\n", testAdcAbsoluteY()); 78 | printf("testAdcIndirectX: %d\r\n", testAdcIndirectX()); 79 | printf("testAdcIndirectY: %d\r\n", testAdcIndirectY()); 80 | } 81 | 82 | void testAnd() { 83 | printf("testAndImmediate: %d\r\n", testAndImmediate()); 84 | printf("testAndZeropage: %d\r\n", testAndZeropage()); 85 | printf("testAndZeropageX: %d\r\n", testAndZeropageX()); 86 | printf("testAndAbsolute: %d\r\n", testAndAbsolute()); 87 | printf("testAndAbsoluteX: %d\r\n", testAndAbsoluteX()); 88 | printf("testAndAbsoluteY: %d\r\n", testAndAbsoluteY()); 89 | printf("testAndIndirectX: %d\r\n", testAndIndirectX()); 90 | printf("testAndIndirectY: %d\r\n", testAndIndirectY()); 91 | } 92 | 93 | void testAsl() { 94 | printf("testAslImplied: %d\r\n", testAslImplied()); 95 | printf("testAslZeropage: %d\r\n", testAslZeropage()); 96 | printf("testAslZeropageX: %d\r\n", testAslZeropageX()); 97 | printf("testAslAbsolute: %d\r\n", testAslAbsolute()); 98 | printf("testAslAbsoluteX: %d\r\n", testAslAbsoluteX()); 99 | } 100 | 101 | void testBranches() { 102 | printf("testBccImplied: %d\r\n", testBccImplied()); 103 | printf("testBcsImplied: %d\r\n", testBcsImplied()); 104 | printf("testBeqImplied: %d\r\n", testBeqImplied()); 105 | printf("testBmiImplied: %d\r\n", testBmiImplied()); 106 | printf("testBneImplied: %d\r\n", testBneImplied()); 107 | printf("testBplImplied: %d\r\n", testBplImplied()); 108 | printf("testBvcImplied: %d\r\n", testBvcImplied()); 109 | printf("testBvsImplied: %d\r\n", testBvsImplied()); 110 | } 111 | 112 | void testBit() { 113 | printf("testBitZeropage: %d\r\n", testBitZeropage()); 114 | printf("testBitAbsolute: %d\r\n", testBitAbsolute()); 115 | } 116 | 117 | void testBrk() { 118 | printf("testBrkImplied: %d\r\n", testBrkImplied()); 119 | } 120 | 121 | void testClear() { 122 | printf("testClcImplied: %d\r\n", testClcImplied()); 123 | printf("testCldImplied: %d\r\n", testCldImplied()); 124 | printf("testCliImplied: %d\r\n", testCliImplied()); 125 | printf("testClvImplied: %d\r\n", testClvImplied()); 126 | } 127 | 128 | void testCompare() { 129 | printf("testCmpImmediate: %d\r\n", testCmpImmediate()); 130 | printf("testCmpZeropage: %d\r\n", testCmpZeropage()); 131 | printf("testCmpZeropageX: %d\r\n", testCmpZeropageX()); 132 | printf("testCmpAbsolute: %d\r\n", testCmpAbsolute()); 133 | printf("testCmpAbsoluteX: %d\r\n", testCmpAbsoluteX()); 134 | printf("testCmpAbsoluteY: %d\r\n", testCmpAbsoluteY()); 135 | printf("testCmpIndirectX: %d\r\n", testCmpIndirectX()); 136 | printf("testCmpIndirectY: %d\r\n", testCmpIndirectY()); 137 | printf("testCpxImmediate: %d\r\n", testCpxImmediate()); 138 | printf("testCpxZeropage: %d\r\n", testCpxZeropage()); 139 | printf("testCpxAbsolute: %d\r\n", testCpxAbsolute()); 140 | printf("testCpyImmediate: %d\r\n", testCpyImmediate()); 141 | printf("testCpyZeropage: %d\r\n", testCpyZeropage()); 142 | printf("testCpyAbsolute: %d\r\n", testCpyAbsolute()); 143 | } 144 | 145 | void testDec() { 146 | printf("testDecZeropage: %d\r\n", testDecZeropage()); 147 | printf("testDecZeropageX: %d\r\n", testDecZeropageX()); 148 | printf("testDecAbsolute: %d\r\n", testDecAbsolute()); 149 | printf("testDexImplied: %d\r\n", testDexImplied()); 150 | printf("testDeyImplied: %d\r\n", testDeyImplied()); 151 | } 152 | 153 | void testEor() { 154 | printf("testEorImmediate: %d\r\n", testEorImmediate()); 155 | printf("testEorZeropage: %d\r\n", testEorZeropage()); 156 | printf("testEorZeropageX: %d\r\n", testEorZeropageX()); 157 | printf("testEorAbsolute: %d\r\n", testEorAbsolute()); 158 | printf("testEorAbsoluteX: %d\r\n", testEorAbsoluteX()); 159 | printf("testEorAbsoluteY: %d\r\n", testEorAbsoluteY()); 160 | printf("testEorIndirectX: %d\r\n", testEorIndirectX()); 161 | printf("testEorIndirectY: %d\r\n", testEorIndirectY()); 162 | } 163 | 164 | void testInc() { 165 | printf("testIncZeropage: %d\r\n", testIncZeropage()); 166 | printf("testIncZeropageX: %d\r\n", testIncZeropageX()); 167 | printf("testIncAbsolute: %d\r\n", testIncAbsolute()); 168 | printf("testInxImplied: %d\r\n", testInxImplied()); 169 | printf("testInyImplied: %d\r\n", testInyImplied()); 170 | } 171 | 172 | void testJmp() { 173 | printf("testJmpAbsolute: %d\r\n", testJmpAbsolute()); 174 | printf("testJmpIndirect: %d\r\n", testJmpIndirect()); 175 | printf("testJsrAbsolute: %d\r\n", testJsrAbsolute()); 176 | } 177 | 178 | void testLoads() { 179 | printf("testLdaImmediate: %d\r\n", testLdaImmediate()); 180 | printf("testLdaZeropage: %d\r\n", testLdaZeropage()); 181 | printf("testLdaZeropageX: %d\r\n", testLdaZeropageX()); 182 | printf("testLdaAbsolute: %d\r\n", testLdaAbsolute()); 183 | printf("testLdaAbsoluteX: %d\r\n", testLdaAbsoluteX()); 184 | printf("testLdaAbsoluteY: %d\r\n", testLdaAbsoluteY()); 185 | printf("testLdaIndirectX: %d\r\n", testJmpAbsolute()); 186 | printf("testLdaIndirectY: %d\r\n", testLdaIndirectY()); 187 | printf("testLdxImmediate: %d\r\n", testLdxImmediate()); 188 | printf("testLdxZeropage: %d\r\n", testLdxZeropage()); 189 | printf("testLdxZeropageY: %d\r\n", testLdxZeropageY()); 190 | printf("testLdxAbsolute: %d\r\n", testLdxAbsolute()); 191 | printf("testLdxAbsoluteY: %d\r\n", testLdxAbsoluteY()); 192 | printf("testLdyImmediate: %d\r\n", testLdyImmediate()); 193 | printf("testLdyZeropage: %d\r\n", testLdyZeropage()); 194 | printf("testLdyZeropageX: %d\r\n", testLdyZeropageX()); 195 | printf("testLdyAbsolute: %d\r\n", testLdyAbsolute()); 196 | printf("testLdyAbsoluteX: %d\r\n", testLdyAbsoluteX()); 197 | } 198 | 199 | void testLsr() { 200 | printf("testLsrImplied: %d\r\n", testLsrImplied()); 201 | printf("testLsrZeropage: %d\r\n", testLsrZeropage()); 202 | printf("testLdyZeropageX: %d\r\n", testLsrZeropageX()); 203 | printf("testLsrAbsolute: %d\r\n", testLsrAbsolute()); 204 | printf("testLsrAbsoluteX: %d\r\n", testLsrAbsoluteX()); 205 | } 206 | 207 | void testOra() { 208 | printf("testOraImmediate: %d\r\n", testOraImmediate()); 209 | printf("testOraZeropage: %d\r\n", testOraZeropage()); 210 | printf("testOraZeropageX: %d\r\n", testOraZeropageX()); 211 | printf("testOraAbsolute: %d\r\n", testOraAbsolute()); 212 | printf("testOraAbsoluteX: %d\r\n", testOraAbsoluteX()); 213 | printf("testOraAbsoluteY: %d\r\n", testOraAbsoluteY()); 214 | printf("testOraIndirectX: %d\r\n", testOraIndirectX()); 215 | printf("testOraIndirectY: %d\r\n", testOraIndirectY()); 216 | } 217 | 218 | void testStack() { 219 | printf("testPhaImplied: %d\r\n", testPhaImplied()); 220 | printf("testPhpImplied: %d\r\n", testPhpImplied()); 221 | printf("testPlaImplied: %d\r\n", testPlaImplied()); 222 | printf("testPlpImplied: %d\r\n", testPlpImplied()); 223 | } 224 | 225 | void testRotate() { 226 | printf("testRolImplied: %d\r\n", testRolImplied()); 227 | printf("testRolZeropage: %d\r\n", testRolZeropage()); 228 | printf("testRolZeropageX: %d\r\n", testRolZeropageX()); 229 | printf("testRolAbsolute: %d\r\n", testRolAbsolute()); 230 | printf("testRolAbsoluteX: %d\r\n", testRolAbsoluteX()); 231 | printf("testRorImplied: %d\r\n", testRorImplied()); 232 | printf("testRorZeropage: %d\r\n", testRorZeropage()); 233 | printf("testRorZeropageX: %d\r\n", testRorZeropageX()); 234 | printf("testRorAbsolute: %d\r\n", testRorAbsolute()); 235 | printf("testRorAbsoluteX: %d\r\n", testRorAbsoluteX()); 236 | } 237 | 238 | void testReturn() { 239 | printf("testRtiImplied: %d\r\n", testRtiImplied()); 240 | printf("testRtsImplied: %d\r\n", testRtsImplied()); 241 | } 242 | 243 | void testSbc() { 244 | printf("testSbcImmediate: %d\r\n", testSbcImmediate()); 245 | printf("testSbcZeropage: %d\r\n", testSbcZeropage()); 246 | printf("testSbcZeropageX: %d\r\n", testSbcZeropageX()); 247 | printf("testSbcAbsolute: %d\r\n", testSbcAbsolute()); 248 | printf("testSbcAbsoluteX: %d\r\n", testSbcAbsoluteX()); 249 | printf("testSbcAbsoluteY: %d\r\n", testSbcAbsoluteY()); 250 | printf("testSbcIndirectX: %d\r\n", testSbcIndirectX()); 251 | printf("testSbcIndirectY: %d\r\n", testSbcIndirectY()); 252 | } 253 | 254 | void testSet() { 255 | printf("testSecImplied: %d\r\n", testSecImplied()); 256 | printf("testSedImplied: %d\r\n", testSedImplied()); 257 | printf("testSeiImplied: %d\r\n", testSeiImplied()); 258 | } 259 | 260 | void testSta() { 261 | printf("testStaZeropage: %d\r\n", testStaZeropage()); 262 | printf("testStaZeropageX: %d\r\n", testStaZeropageX()); 263 | printf("testStaAbsolute: %d\r\n", testStaAbsolute()); 264 | printf("testStaAbsoluteX: %d\r\n", testStaAbsoluteX()); 265 | printf("testStaAbsoluteY: %d\r\n", testStaAbsoluteY()); 266 | printf("testStaIndirectX: %d\r\n", testStaIndirectX()); 267 | printf("testStaIndirectY: %d\r\n", testStaIndirectY()); 268 | } 269 | 270 | void testStores() { 271 | printf("testStxZeropage: %d\r\n", testStxZeropage()); 272 | printf("testStxZeropageY: %d\r\n", testStxZeropageY()); 273 | printf("testStxAbsolute: %d\r\n", testStxAbsolute()); 274 | printf("testStyZeropage: %d\r\n", testStyZeropage()); 275 | printf("testStyZeropageX: %d\r\n", testStyZeropageX()); 276 | printf("testStyAbsolute: %d\r\n", testStyAbsolute()); 277 | } 278 | 279 | void testTransfer() { 280 | printf("testTaxImplied: %d\r\n", testTaxImplied()); 281 | printf("testTayImplied: %d\r\n", testTayImplied()); 282 | printf("testTsxImplied: %d\r\n", testTsxImplied()); 283 | printf("testTxaImplied: %d\r\n", testTxaImplied()); 284 | printf("testTxsImplied: %d\r\n", testTxsImplied()); 285 | printf("testTyaImplied: %d\r\n", testTyaImplied()); 286 | } 287 | 288 | int main() { 289 | testAnd(); 290 | testAdc(); 291 | testAsl(); 292 | testBranches(); 293 | testBit(); 294 | testBrk(); 295 | testClear(); 296 | testCompare(); 297 | testDec(); 298 | testEor(); 299 | testInc(); 300 | testJmp(); 301 | testLoads(); 302 | testLsr(); 303 | testOra(); 304 | testStack(); 305 | testRotate(); 306 | testReturn(); 307 | testSbc(); 308 | testSet(); 309 | testSta(); 310 | testStores(); 311 | testTransfer(); 312 | return 0; 313 | } -------------------------------------------------------------------------------- /6502tests/test/testLd.c: -------------------------------------------------------------------------------- 1 | int testLdaImmediate() { 2 | //zero 3 | SR &= ~(SR_NEG|SR_ZERO); 4 | ram[0] = 0xA9; 5 | ram[1] = 0x00; 6 | instructions = 1; run(); 7 | if(!(A == 0x00 && SR&SR_ZERO && !(SR&SR_NEG))) return -1; 8 | 9 | //normal 10 | SR &= ~(SR_NEG|SR_ZERO); 11 | ram[0] = 0xA9; 12 | ram[1] = 0x20; 13 | instructions = 1; run(); 14 | if(!(A == 0x20 && !(SR&SR_ZERO) && !(SR&SR_NEG))) return -2; 15 | 16 | //negative 17 | SR &= ~(SR_NEG|SR_ZERO); 18 | ram[0] = 0xA9; 19 | ram[1] = 0x80; 20 | instructions = 1; run(); 21 | if(!(A == 0x80 && !(SR&SR_ZERO) && SR&SR_NEG)) return -3; 22 | 23 | return 0; 24 | } 25 | 26 | int testLdaZeropage() { 27 | //zero 28 | SR &= ~(SR_NEG|SR_ZERO); 29 | ram[0] = 0xA5; 30 | ram[1] = 0x02; 31 | ram[2] = 0x00; 32 | instructions = 1; run(); 33 | if(!(A == 0x00 && SR&SR_ZERO && !(SR&SR_NEG))) return -1; 34 | 35 | //normal 36 | SR &= ~(SR_NEG|SR_ZERO); 37 | ram[0] = 0xA5; 38 | ram[1] = 0x02; 39 | ram[2] = 0x20; 40 | instructions = 1; run(); 41 | if(!(A == 0x20 && !(SR&SR_ZERO) && !(SR&SR_NEG))) return -2; 42 | 43 | //negative 44 | SR &= ~(SR_NEG|SR_ZERO); 45 | ram[0] = 0xA5; 46 | ram[1] = 0x02; 47 | ram[2] = 0x80; 48 | instructions = 1; run(); 49 | if(!(A == 0x80 && !(SR&SR_ZERO) && SR&SR_NEG)) return -3; 50 | 51 | return 0; 52 | } 53 | 54 | int testLdaZeropageX() { 55 | X = 0x01; Y = 0x00; 56 | 57 | //zero 58 | SR &= ~(SR_NEG|SR_ZERO); 59 | ram[0] = 0xB5; 60 | ram[1] = 0x01; 61 | ram[2] = 0x00; 62 | instructions = 1; run(); 63 | if(!(A == 0x00 && SR&SR_ZERO && !(SR&SR_NEG))) return -1; 64 | 65 | //normal 66 | SR &= ~(SR_NEG|SR_ZERO); 67 | ram[0] = 0xB5; 68 | ram[1] = 0x01; 69 | ram[2] = 0x20; 70 | instructions = 1; run(); 71 | if(!(A == 0x20 && !(SR&SR_ZERO) && !(SR&SR_NEG))) return -2; 72 | 73 | //negative 74 | SR &= ~(SR_NEG|SR_ZERO); 75 | ram[0] = 0xB5; 76 | ram[1] = 0x01; 77 | ram[2] = 0x80; 78 | instructions = 1; run(); 79 | if(!(A == 0x80 && !(SR&SR_ZERO) && SR&SR_NEG)) return -3; 80 | 81 | return 0; 82 | } 83 | 84 | int testLdaAbsolute() { 85 | //zero 86 | SR &= ~(SR_NEG|SR_ZERO); 87 | ram[0] = 0xAD; 88 | ram[1] = 0x03; 89 | ram[2] = 0x00; 90 | ram[3] = 0x00; 91 | instructions = 1; run(); 92 | if(!(A == 0x00 && SR&SR_ZERO && !(SR&SR_NEG))) return -1; 93 | 94 | //normal 95 | SR &= ~(SR_NEG|SR_ZERO); 96 | ram[0] = 0xAD; 97 | ram[1] = 0x03; 98 | ram[2] = 0x00; 99 | ram[3] = 0x20; 100 | instructions = 1; run(); 101 | if(!(A == 0x20 && !(SR&SR_ZERO) && !(SR&SR_NEG))) return -2; 102 | 103 | //negative 104 | SR &= ~(SR_NEG|SR_ZERO); 105 | ram[0] = 0xAD; 106 | ram[1] = 0x03; 107 | ram[2] = 0x00; 108 | ram[3] = 0x80; 109 | instructions = 1; run(); 110 | if(!(A == 0x80 && !(SR&SR_ZERO) && SR&SR_NEG)) return -3; 111 | 112 | return 0; 113 | } 114 | 115 | int testLdaAbsoluteX() { 116 | X = 0x01; Y = 0x00; 117 | 118 | //zero 119 | SR &= ~(SR_NEG|SR_ZERO); 120 | ram[0] = 0xBD; 121 | ram[1] = 0x02; 122 | ram[2] = 0x00; 123 | ram[3] = 0x00; 124 | instructions = 1; run(); 125 | if(!(A == 0x00 && SR&SR_ZERO && !(SR&SR_NEG))) return -1; 126 | 127 | //normal 128 | SR &= ~(SR_NEG|SR_ZERO); 129 | ram[0] = 0xBD; 130 | ram[1] = 0x02; 131 | ram[2] = 0x00; 132 | ram[3] = 0x20; 133 | instructions = 1; run(); 134 | if(!(A == 0x20 && !(SR&SR_ZERO) && !(SR&SR_NEG))) return -2; 135 | 136 | //negative 137 | SR &= ~(SR_NEG|SR_ZERO); 138 | ram[0] = 0xBD; 139 | ram[1] = 0x02; 140 | ram[2] = 0x00; 141 | ram[3] = 0x80; 142 | instructions = 1; run(); 143 | if(!(A == 0x80 && !(SR&SR_ZERO) && SR&SR_NEG)) return -3; 144 | 145 | 146 | return 0; 147 | } 148 | 149 | int testLdaAbsoluteY() { 150 | Y = 0x01; X = 0x00; 151 | 152 | //zero 153 | SR &= ~(SR_NEG|SR_ZERO); 154 | ram[0] = 0xB9; 155 | ram[1] = 0x02; 156 | ram[2] = 0x00; 157 | ram[3] = 0x00; 158 | instructions = 1; run(); 159 | if(!(A == 0x00 && SR&SR_ZERO && !(SR&SR_NEG))) return -1; 160 | 161 | //normal 162 | SR &= ~(SR_NEG|SR_ZERO); 163 | ram[0] = 0xB9; 164 | ram[1] = 0x02; 165 | ram[2] = 0x00; 166 | ram[3] = 0x20; 167 | instructions = 1; run(); 168 | if(!(A == 0x20 && !(SR&SR_ZERO) && !(SR&SR_NEG))) return -2; 169 | 170 | //negative 171 | SR &= ~(SR_NEG|SR_ZERO); 172 | ram[0] = 0xB9; 173 | ram[1] = 0x02; 174 | ram[2] = 0x00; 175 | ram[3] = 0x80; 176 | instructions = 1; run(); 177 | if(!(A == 0x80 && !(SR&SR_ZERO) && SR&SR_NEG)) return -3; 178 | 179 | return 0; 180 | } 181 | 182 | int testLdaIndirectX() { 183 | X = 0x01; Y = 0x00; 184 | 185 | //zero 186 | SR &= ~(SR_NEG|SR_ZERO); 187 | ram[0] = 0xA1; 188 | ram[1] = 0x02; 189 | ram[2] = 0x02; 190 | ram[3] = 0x00; 191 | instructions = 1; run(); 192 | if(!(A == 0x00 && SR&SR_ZERO && !(SR&SR_NEG))) return -1; 193 | 194 | //normal 195 | SR &= ~(SR_NEG|SR_ZERO); 196 | ram[0] = 0xA1; 197 | ram[1] = 0x02; 198 | ram[2] = 0x02; 199 | ram[3] = 0x20; 200 | instructions = 1; run(); 201 | if(!(A == 0x20 && !(SR&SR_ZERO) && !(SR&SR_NEG))) return -2; 202 | 203 | //negative 204 | SR &= ~(SR_NEG|SR_ZERO); 205 | ram[0] = 0xA1; 206 | ram[1] = 0x02; 207 | ram[2] = 0x02; 208 | ram[3] = 0x80; 209 | instructions = 1; run(); 210 | if(!(A == 0x80 && !(SR&SR_ZERO) && SR&SR_NEG)) return -3; 211 | 212 | return 0; 213 | } 214 | 215 | int testLdaIndirectY() { 216 | Y = 0x01; X = 0x00; 217 | 218 | //zero 219 | SR &= ~(SR_NEG|SR_ZERO); 220 | ram[0] = 0xB1; 221 | ram[1] = 0x02; 222 | ram[2] = 0x03; 223 | ram[3] = 0x00; 224 | ram[4] = 0x00; 225 | instructions = 1; run(); 226 | if(!(A == 0x00 && SR&SR_ZERO && !(SR&SR_NEG))) return -1; 227 | 228 | //normal 229 | SR &= ~(SR_NEG|SR_ZERO); 230 | ram[0] = 0xB1; 231 | ram[1] = 0x02; 232 | ram[2] = 0x03; 233 | ram[3] = 0x00; 234 | ram[4] = 0x20; 235 | instructions = 1; run(); 236 | if(!(A == 0x20 && !(SR&SR_ZERO) && !(SR&SR_NEG))) return -2; 237 | 238 | //negative 239 | SR &= ~(SR_NEG|SR_ZERO); 240 | ram[0] = 0xB1; 241 | ram[1] = 0x02; 242 | ram[2] = 0x03; 243 | ram[3] = 0x00; 244 | ram[4] = 0x80; 245 | instructions = 1; run(); 246 | if(!(A == 0x80 && !(SR&SR_ZERO) && SR&SR_NEG)) return -3; 247 | 248 | return 0; 249 | } 250 | 251 | int testLdxImmediate() { 252 | //zero 253 | SR &= ~(SR_NEG|SR_ZERO); 254 | ram[0] = 0xA2; 255 | ram[1] = 0x00; 256 | instructions = 1; run(); 257 | if(!(X == 0x00 && SR&SR_ZERO && !(SR&SR_NEG))) return -1; 258 | 259 | //normal 260 | SR &= ~(SR_NEG|SR_ZERO); 261 | ram[0] = 0xA2; 262 | ram[1] = 0x20; 263 | instructions = 1; run(); 264 | if(!(X == 0x20 && !(SR&SR_ZERO) && !(SR&SR_NEG))) return -2; 265 | 266 | //negative 267 | SR &= ~(SR_NEG|SR_ZERO); 268 | ram[0] = 0xA2; 269 | ram[1] = 0x80; 270 | instructions = 1; run(); 271 | if(!(X == 0x80 && !(SR&SR_ZERO) && SR&SR_NEG)) return -3; 272 | 273 | return 0; 274 | } 275 | 276 | int testLdxZeropage() { 277 | //zero 278 | SR &= ~(SR_NEG|SR_ZERO); 279 | ram[0] = 0xA6; 280 | ram[1] = 0x02; 281 | ram[2] = 0x00; 282 | instructions = 1; run(); 283 | if(!(X == 0x00 && SR&SR_ZERO && !(SR&SR_NEG))) return -1; 284 | 285 | //normal 286 | SR &= ~(SR_NEG|SR_ZERO); 287 | ram[0] = 0xA6; 288 | ram[1] = 0x02; 289 | ram[2] = 0x20; 290 | instructions = 1; run(); 291 | if(!(X == 0x20 && !(SR&SR_ZERO) && !(SR&SR_NEG))) return -2; 292 | 293 | //negative 294 | SR &= ~(SR_NEG|SR_ZERO); 295 | ram[0] = 0xA6; 296 | ram[1] = 0x02; 297 | ram[2] = 0x80; 298 | instructions = 1; run(); 299 | if(!(X == 0x80 && !(SR&SR_ZERO) && SR&SR_NEG)) return -3; 300 | 301 | return 0; 302 | } 303 | 304 | int testLdxZeropageY() { 305 | Y = 0x01; X = 0x00; 306 | 307 | //zero 308 | SR &= ~(SR_NEG|SR_ZERO); 309 | ram[0] = 0xB6; 310 | ram[1] = 0x01; 311 | ram[2] = 0x00; 312 | instructions = 1; run(); 313 | if(!(X == 0x00 && SR&SR_ZERO && !(SR&SR_NEG))) return -1; 314 | 315 | //normal 316 | Y = 0x01; 317 | SR &= ~(SR_NEG|SR_ZERO); 318 | ram[0] = 0xB6; 319 | ram[1] = 0x01; 320 | ram[2] = 0x20; 321 | instructions = 1; run(); 322 | if(!(X == 0x20 && !(SR&SR_ZERO) && !(SR&SR_NEG))) return -2; 323 | 324 | //negative 325 | SR &= ~(SR_NEG|SR_ZERO); 326 | ram[0] = 0xB6; 327 | ram[1] = 0x01; 328 | ram[2] = 0x80; 329 | instructions = 1; run(); 330 | if(!(X == 0x80 && !(SR&SR_ZERO) && SR&SR_NEG)) return -3; 331 | 332 | return 0; 333 | } 334 | 335 | int testLdxAbsolute() { 336 | //zero 337 | SR &= ~(SR_NEG|SR_ZERO); 338 | ram[0] = 0xAE; 339 | ram[1] = 0x03; 340 | ram[2] = 0x00; 341 | ram[3] = 0x00; 342 | instructions = 1; run(); 343 | if(!(X == 0x00 && SR&SR_ZERO && !(SR&SR_NEG))) return -1; 344 | 345 | //normal 346 | SR &= ~(SR_NEG|SR_ZERO); 347 | ram[0] = 0xAE; 348 | ram[1] = 0x03; 349 | ram[2] = 0x00; 350 | ram[3] = 0x20; 351 | instructions = 1; run(); 352 | if(!(X == 0x20 && !(SR&SR_ZERO) && !(SR&SR_NEG))) return -2; 353 | 354 | //negative 355 | SR &= ~(SR_NEG|SR_ZERO); 356 | ram[0] = 0xAE; 357 | ram[1] = 0x03; 358 | ram[2] = 0x00; 359 | ram[3] = 0x80; 360 | instructions = 1; run(); 361 | if(!(X == 0x80 && !(SR&SR_ZERO) && SR&SR_NEG)) return -3; 362 | 363 | return 0; 364 | } 365 | 366 | int testLdxAbsoluteY() { 367 | Y = 0x01; X = 0x00; 368 | 369 | //zero 370 | SR &= ~(SR_NEG|SR_ZERO); 371 | ram[0] = 0xBE; 372 | ram[1] = 0x02; 373 | ram[2] = 0x00; 374 | ram[3] = 0x00; 375 | instructions = 1; run(); 376 | if(!(X == 0x00 && SR&SR_ZERO && !(SR&SR_NEG))) return -1; 377 | 378 | //normal 379 | SR &= ~(SR_NEG|SR_ZERO); 380 | ram[0] = 0xBE; 381 | ram[1] = 0x02; 382 | ram[2] = 0x00; 383 | ram[3] = 0x20; 384 | instructions = 1; run(); 385 | if(!(X == 0x20 && !(SR&SR_ZERO) && !(SR&SR_NEG))) return -2; 386 | 387 | //negative 388 | SR &= ~(SR_NEG|SR_ZERO); 389 | ram[0] = 0xBE; 390 | ram[1] = 0x02; 391 | ram[2] = 0x00; 392 | ram[3] = 0x80; 393 | instructions = 1; run(); 394 | if(!(X == 0x80 && !(SR&SR_ZERO) && SR&SR_NEG)) return -3; 395 | 396 | return 0; 397 | } 398 | 399 | int testLdyImmediate() { 400 | //zero 401 | SR &= ~(SR_NEG|SR_ZERO); 402 | ram[0] = 0xA0; 403 | ram[1] = 0x00; 404 | instructions = 1; run(); 405 | if(!(Y == 0x00 && SR&SR_ZERO && !(SR&SR_NEG))) return -1; 406 | 407 | //normal 408 | SR &= ~(SR_NEG|SR_ZERO); 409 | ram[0] = 0xA0; 410 | ram[1] = 0x20; 411 | instructions = 1; run(); 412 | if(!(Y == 0x20 && !(SR&SR_ZERO) && !(SR&SR_NEG))) return -2; 413 | 414 | //negative 415 | SR &= ~(SR_NEG|SR_ZERO); 416 | ram[0] = 0xA0; 417 | ram[1] = 0x80; 418 | instructions = 1; run(); 419 | if(!(Y == 0x80 && !(SR&SR_ZERO) && SR&SR_NEG)) return -3; 420 | 421 | return 0; 422 | } 423 | 424 | int testLdyZeropage() { 425 | //zero 426 | SR &= ~(SR_NEG|SR_ZERO); 427 | ram[0] = 0xA4; 428 | ram[1] = 0x02; 429 | ram[2] = 0x00; 430 | instructions = 1; run(); 431 | if(!(Y == 0x00 && SR&SR_ZERO && !(SR&SR_NEG))) return -1; 432 | 433 | //normal 434 | SR &= ~(SR_NEG|SR_ZERO); 435 | ram[0] = 0xA4; 436 | ram[1] = 0x02; 437 | ram[2] = 0x20; 438 | instructions = 1; run(); 439 | if(!(Y == 0x20 && !(SR&SR_ZERO) && !(SR&SR_NEG))) return -2; 440 | 441 | //negative 442 | SR &= ~(SR_NEG|SR_ZERO); 443 | ram[0] = 0xA4; 444 | ram[1] = 0x02; 445 | ram[2] = 0x80; 446 | instructions = 1; run(); 447 | if(!(Y == 0x80 && !(SR&SR_ZERO) && SR&SR_NEG)) return -3; 448 | 449 | return 0; 450 | } 451 | 452 | int testLdyZeropageX() { 453 | X = 0x01; Y = 0x00; 454 | 455 | //zero 456 | SR &= ~(SR_NEG|SR_ZERO); 457 | ram[0] = 0xB4; 458 | ram[1] = 0x01; 459 | ram[2] = 0x00; 460 | instructions = 1; run(); 461 | if(!(Y == 0x00 && SR&SR_ZERO && !(SR&SR_NEG))) return -1; 462 | 463 | //normal 464 | SR &= ~(SR_NEG|SR_ZERO); 465 | ram[0] = 0xB4; 466 | ram[1] = 0x01; 467 | ram[2] = 0x20; 468 | instructions = 1; run(); 469 | if(!(Y == 0x20 && !(SR&SR_ZERO) && !(SR&SR_NEG))) return -2; 470 | 471 | //negative 472 | SR &= ~(SR_NEG|SR_ZERO); 473 | ram[0] = 0xB4; 474 | ram[1] = 0x01; 475 | ram[2] = 0x80; 476 | instructions = 1; run(); 477 | if(!(Y == 0x80 && !(SR&SR_ZERO) && SR&SR_NEG)) return -3; 478 | 479 | return 0; 480 | } 481 | 482 | int testLdyAbsolute() { 483 | X = 0x01; 484 | 485 | //zero 486 | SR &= ~(SR_NEG|SR_ZERO); 487 | ram[0] = 0xAC; 488 | ram[1] = 0x03; 489 | ram[2] = 0x00; 490 | ram[3] = 0x00; 491 | instructions = 1; run(); 492 | if(!(Y == 0x00 && SR&SR_ZERO && !(SR&SR_NEG))) return -1; 493 | 494 | //normal 495 | SR &= ~(SR_NEG|SR_ZERO); 496 | ram[0] = 0xAC; 497 | ram[1] = 0x03; 498 | ram[2] = 0x00; 499 | ram[3] = 0x20; 500 | instructions = 1; run(); 501 | if(!(Y == 0x20 && !(SR&SR_ZERO) && !(SR&SR_NEG))) return -2; 502 | 503 | //negative 504 | SR &= ~(SR_NEG|SR_ZERO); 505 | ram[0] = 0xAC; 506 | ram[1] = 0x03; 507 | ram[2] = 0x00; 508 | ram[3] = 0x80; 509 | instructions = 1; run(); 510 | if(!(Y == 0x80 && !(SR&SR_ZERO) && SR&SR_NEG)) return -3; 511 | 512 | return 0; 513 | } 514 | 515 | int testLdyAbsoluteX() { 516 | X = 0x01; Y = 0x00; 517 | 518 | //zero 519 | SR &= ~(SR_NEG|SR_ZERO); 520 | ram[0] = 0xBC; 521 | ram[1] = 0x02; 522 | ram[2] = 0x00; 523 | ram[3] = 0x00; 524 | instructions = 1; run(); 525 | if(!(Y == 0x00 && SR&SR_ZERO && !(SR&SR_NEG))) return -1; 526 | 527 | //normal 528 | SR &= ~(SR_NEG|SR_ZERO); 529 | ram[0] = 0xBC; 530 | ram[1] = 0x02; 531 | ram[2] = 0x00; 532 | ram[3] = 0x20; 533 | instructions = 1; run(); 534 | if(!(Y == 0x20 && !(SR&SR_ZERO) && !(SR&SR_NEG))) return -2; 535 | 536 | //negative 537 | SR &= ~(SR_NEG|SR_ZERO); 538 | ram[0] = 0xBC; 539 | ram[1] = 0x02; 540 | ram[2] = 0x00; 541 | ram[3] = 0x80; 542 | instructions = 1; run(); 543 | if(!(Y == 0x80 && !(SR&SR_ZERO) && SR&SR_NEG)) return -3; 544 | 545 | return 0; 546 | } -------------------------------------------------------------------------------- /6502tests/test/testAdc.c: -------------------------------------------------------------------------------- 1 | int testAdcImmediate() { 2 | //no carry 3 | A = 0x00; 4 | SR&=(~SR_CARRY); 5 | ram[0] = 0x69; 6 | ram[1] = 0x01; 7 | instructions = 1; run(); 8 | if(!(A == 0x01 && !SR&SR_NEG && !SR&SR_ZERO && !SR&SR_CARRY && !SR&SR_OVER)) return -1; 9 | 10 | //with carry 11 | A = 0x00; 12 | SR|=SR_CARRY; 13 | ram[0] = 0x69; 14 | ram[1] = 0x01; 15 | instructions = 1; run(); 16 | if(!(A == 0x02 && !(SR&SR_NEG) && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -2; 17 | 18 | //negative result 19 | A = 0xFE; 20 | SR&=(~SR_CARRY); 21 | ram[0] = 0x69; 22 | ram[1] = 0xFE; 23 | instructions = 1; run(); 24 | if(!(A == 0xFC && SR&SR_NEG && !(SR&SR_ZERO) && SR&SR_CARRY && !(SR&SR_OVER))) return -3; 25 | 26 | //overflow result 27 | A = 0x80; 28 | SR&=(~SR_CARRY); 29 | ram[0] = 0x69; 30 | ram[1] = 0xFF; 31 | instructions = 1; run(); 32 | if(!(A == 0x7F && !(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY && SR&SR_OVER)) return -4; 33 | 34 | //zero result 35 | A = 0xFF; //-1 36 | SR&=(~SR_CARRY); 37 | ram[0] = 0x69; 38 | ram[1] = 0x01; //+1 39 | instructions = 1; run(); 40 | if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY && !(SR&SR_OVER))) return -5; 41 | 42 | //carry result 43 | A = 0xF0; //+70 44 | SR&=(~SR_CARRY); 45 | ram[0] = 0x69; 46 | ram[1] = 0xF0; //+70 47 | instructions = 1; run(); 48 | if(!(A == 0xE0 && SR&SR_NEG && !(SR&SR_ZERO) && SR&SR_CARRY && !(SR&SR_OVER))) return -6; 49 | 50 | return 0; 51 | } 52 | 53 | int testAdcZeropage() { 54 | //no carry 55 | A = 0x00; 56 | SR &= (~SR_CARRY); 57 | ram[0] = 0x65; 58 | ram[1] = 0x02; 59 | ram[2] = 0x01; 60 | instructions = 1; run(); 61 | if(!(A == 0x01 && !(SR&SR_NEG) && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1; 62 | 63 | //with carry 64 | A = 0x00; 65 | SR |= SR_CARRY; 66 | ram[0] = 0x65; 67 | ram[1] = 0x02; 68 | ram[2] = 0x01; 69 | instructions = 1; run(); 70 | if(!(A == 0x02 && !(SR&SR_NEG) && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -2; 71 | 72 | //negative result 73 | A = 0xFE; 74 | SR &= (~SR_CARRY); 75 | ram[0] = 0x65; 76 | ram[1] = 0x02; 77 | ram[2] = 0xFE; 78 | instructions = 1; run(); 79 | if(!(A == 0xFC && SR&SR_NEG && !(SR&SR_ZERO) && SR&SR_CARRY && !(SR&SR_OVER))) return -3; 80 | 81 | //overflow result 82 | A = 0x80; 83 | SR &= (~SR_CARRY); 84 | ram[0] = 0x65; 85 | ram[1] = 0x02; 86 | ram[2] = 0xFF; 87 | instructions = 1; run(); 88 | if(!(A == 0x7F && !(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY && SR&SR_OVER)) return -4; 89 | 90 | //zero result 91 | A = 0xFF; //-1 92 | SR &= (~SR_CARRY); 93 | ram[0] = 0x65; 94 | ram[1] = 0x02; 95 | ram[2] = 0x01; //+1 96 | instructions = 1; run(); 97 | if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY && !(SR&SR_OVER))) return -5; 98 | 99 | //carry result 100 | A = 0xF0; //+70 101 | SR &= (~SR_CARRY); 102 | ram[0] = 0x65; 103 | ram[1] = 0x02; 104 | ram[2] = 0xF0; //+70 105 | instructions = 1; run(); 106 | if(!(A == 0xE0 && SR&SR_NEG && !(SR&SR_ZERO) && SR&SR_CARRY && !(SR&SR_OVER))) return -6; 107 | 108 | return 0; 109 | } 110 | 111 | int testAdcZeropageX() { 112 | X = 0x01; Y=0x00; 113 | 114 | //no carry 115 | A = 0x00; 116 | SR &= (~SR_CARRY); 117 | ram[0] = 0x75; 118 | ram[1] = 0x02; 119 | ram[3] = 0x01; 120 | instructions = 1; run(); 121 | if(!(A == 0x01 && !(SR&SR_NEG) && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1; 122 | 123 | //with carry 124 | A = 0x00; 125 | SR |= SR_CARRY; 126 | ram[0] = 0x75; 127 | ram[1] = 0x02; 128 | ram[3] = 0x01; 129 | instructions = 1; run(); 130 | if(!(A == 0x02 && !(SR&SR_NEG) && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -2; 131 | 132 | //negative result 133 | A = 0xFE; 134 | SR &= (~SR_CARRY); 135 | ram[0] = 0x75; 136 | ram[1] = 0x02; 137 | ram[3] = 0xFE; 138 | instructions = 1; run(); 139 | if(!(A == 0xFC && SR&SR_NEG && !(SR&SR_ZERO) && SR&SR_CARRY && !(SR&SR_OVER))) return -3; 140 | 141 | //overflow result 142 | A = 0x80; 143 | SR &= (~SR_CARRY); 144 | ram[0] = 0x75; 145 | ram[1] = 0x02; 146 | ram[3] = 0xFF; 147 | instructions = 1; run(); 148 | if(!(A == 0x7F && !(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY && SR&SR_OVER)) return -4; 149 | 150 | //zero result 151 | A = 0xFF; //-1 152 | SR &= (~SR_CARRY); 153 | ram[0] = 0x75; 154 | ram[1] = 0x02; 155 | ram[3] = 0x01; //+1 156 | instructions = 1; run(); 157 | if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY && !(SR&SR_OVER))) return -5; 158 | 159 | //carry result 160 | A = 0xF0; //+70 161 | SR &= (~SR_CARRY); 162 | ram[0] = 0x75; 163 | ram[1] = 0x02; 164 | ram[3] = 0xF0; //+70 165 | instructions = 1; run(); 166 | if(!(A == 0xE0 && SR&SR_NEG && !(SR&SR_ZERO) && SR&SR_CARRY && !(SR&SR_OVER))) return -6; 167 | 168 | return 0; 169 | } 170 | 171 | int testAdcAbsolute() { 172 | //no carry 173 | A = 0x00; 174 | SR &= (~SR_CARRY); 175 | ram[0] = 0x6D; 176 | ram[1] = 0x03; 177 | ram[2] = 0x00; 178 | ram[3] = 0x01; 179 | instructions = 1; run(); 180 | if(!(A == 0x01 && !(SR&SR_NEG) && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1; 181 | 182 | //with carry 183 | A = 0x00; 184 | SR |= SR_CARRY; 185 | ram[0] = 0x6D; 186 | ram[1] = 0x03; 187 | ram[2] = 0x00; 188 | ram[3] = 0x01; 189 | instructions = 1; run(); 190 | if(!(A == 0x02 && !(SR&SR_NEG) && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -2; 191 | 192 | //negative result 193 | A = 0xFE; 194 | SR &= (~SR_CARRY); 195 | ram[0] = 0x6D; 196 | ram[1] = 0x03; 197 | ram[2] = 0x00; 198 | ram[3] = 0xFE; 199 | instructions = 1; run(); 200 | if(!(A == 0xFC && SR&SR_NEG && !(SR&SR_ZERO) && SR&SR_CARRY && !(SR&SR_OVER))) return -3; 201 | 202 | //overflow result 203 | A = 0x80; 204 | SR &= (~SR_CARRY); 205 | ram[0] = 0x6D; 206 | ram[1] = 0x03; 207 | ram[2] = 0x00; 208 | ram[3] = 0xFF; 209 | instructions = 1; run(); 210 | if(!(A == 0x7F && !(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY && SR&SR_OVER)) return -4; 211 | 212 | //zero result 213 | A = 0xFF; //-1 214 | SR &= (~SR_CARRY); 215 | ram[0] = 0x6D; 216 | ram[1] = 0x03; 217 | ram[2] = 0x00; 218 | ram[3] = 0x01; //+1 219 | instructions = 1; run(); 220 | if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY && !(SR&SR_OVER))) return -5; 221 | 222 | //carry result 223 | A = 0xF0; //+70 224 | SR &= (~SR_CARRY); 225 | ram[0] = 0x6D; 226 | ram[1] = 0x03; 227 | ram[2] = 0x00; 228 | ram[3] = 0xF0; //+70 229 | instructions = 1; run(); 230 | if(!(A == 0xE0 && SR&SR_NEG && !(SR&SR_ZERO) && SR&SR_CARRY && !(SR&SR_OVER))) return -6; 231 | 232 | return 0; 233 | } 234 | 235 | int testAdcAbsoluteX() { 236 | X = 0x01; Y = 0x00; 237 | 238 | //no carry 239 | A = 0x00; 240 | SR &= (~SR_CARRY); 241 | ram[0] = 0x7D; 242 | ram[1] = 0x02; 243 | ram[2] = 0x00; 244 | ram[3] = 0x01; 245 | instructions = 1; run(); 246 | if(!(A == 0x01 && !(SR&SR_NEG) && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1; 247 | 248 | //with carry 249 | A = 0x00; 250 | SR |= SR_CARRY; 251 | ram[0] = 0x7D; 252 | ram[1] = 0x02; 253 | ram[2] = 0x00; 254 | ram[3] = 0x01; 255 | instructions = 1; run(); 256 | if(!(A == 0x02 && !(SR&SR_NEG) && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -2; 257 | 258 | //negative result 259 | A = 0xFE; 260 | SR &= (~SR_CARRY); 261 | ram[0] = 0x7D; 262 | ram[1] = 0x02; 263 | ram[2] = 0x00; 264 | ram[3] = 0xFE; 265 | instructions = 1; run(); 266 | if(!(A == 0xFC && SR&SR_NEG && !(SR&SR_ZERO) && SR&SR_CARRY && !(SR&SR_OVER))) return -3; 267 | 268 | //overflow result 269 | A = 0x80; 270 | SR &= (~SR_CARRY); 271 | ram[0] = 0x7D; 272 | ram[1] = 0x02; 273 | ram[2] = 0x00; 274 | ram[3] = 0xFF; 275 | instructions = 1; run(); 276 | if(!(A == 0x7F && !(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY && SR&SR_OVER)) return -4; 277 | 278 | //zero result 279 | A = 0xFF; //-1 280 | SR &= (~SR_CARRY); 281 | ram[0] = 0x7D; 282 | ram[1] = 0x02; 283 | ram[2] = 0x00; 284 | ram[3] = 0x01; //+1 285 | instructions = 1; run(); 286 | if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY && !(SR&SR_OVER))) return -5; 287 | 288 | //carry result 289 | A = 0xF0; //+70 290 | SR &= (~SR_CARRY); 291 | ram[0] = 0x7D; 292 | ram[1] = 0x02; 293 | ram[2] = 0x00; 294 | ram[3] = 0xF0; //+70 295 | instructions = 1; run(); 296 | if(!(A == 0xE0 && SR&SR_NEG && !(SR&SR_ZERO) && SR&SR_CARRY && !(SR&SR_OVER))) return -6; 297 | 298 | return 0; 299 | } 300 | 301 | int testAdcAbsoluteY() { 302 | Y = 0x01; X = 0x00; 303 | 304 | //no carry 305 | A = 0x00; 306 | SR &= (~SR_CARRY); 307 | ram[0] = 0x79; 308 | ram[1] = 0x02; 309 | ram[2] = 0x00; 310 | ram[3] = 0x01; 311 | instructions = 1; run(); 312 | if(!(A == 0x01 && !(SR&SR_NEG) && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1; 313 | 314 | //with carry 315 | A = 0x00; 316 | SR |= SR_CARRY; 317 | ram[0] = 0x79; 318 | ram[1] = 0x02; 319 | ram[2] = 0x00; 320 | ram[3] = 0x01; 321 | instructions = 1; run(); 322 | if(!(A == 0x02 && !(SR&SR_NEG) && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -2; 323 | 324 | //negative result 325 | A = 0xFE; 326 | SR &= (~SR_CARRY); 327 | ram[0] = 0x79; 328 | ram[1] = 0x02; 329 | ram[2] = 0x00; 330 | ram[3] = 0xFE; 331 | instructions = 1; run(); 332 | if(!(A == 0xFC && SR&SR_NEG && !(SR&SR_ZERO) && SR&SR_CARRY && !(SR&SR_OVER))) return -3; 333 | 334 | //overflow result 335 | A = 0x80; 336 | SR &= (~SR_CARRY); 337 | ram[0] = 0x79; 338 | ram[1] = 0x02; 339 | ram[2] = 0x00; 340 | ram[3] = 0xFF; 341 | instructions = 1; run(); 342 | if(!(A == 0x7F && !(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY && SR&SR_OVER)) return -4; 343 | 344 | //zero result 345 | A = 0xFF; //-1 346 | SR &= (~SR_CARRY); 347 | ram[0] = 0x79; 348 | ram[1] = 0x02; 349 | ram[2] = 0x00; 350 | ram[3] = 0x01; //+1 351 | instructions = 1; run(); 352 | if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY && !(SR&SR_OVER))) return -5; 353 | 354 | //carry result 355 | A = 0xF0; //+70 356 | SR &= (~SR_CARRY); 357 | ram[0] = 0x79; 358 | ram[1] = 0x02; 359 | ram[2] = 0x00; 360 | ram[3] = 0xF0; //+70 361 | instructions = 1; run(); 362 | if(!(A == 0xE0 && SR&SR_NEG && !(SR&SR_ZERO) && SR&SR_CARRY && !(SR&SR_OVER))) return -6; 363 | 364 | return 0; 365 | } 366 | 367 | int testAdcIndirectX() { 368 | X = 0x01; Y = 0x00; 369 | 370 | //no carry 371 | A = 0x00; 372 | SR &= (~SR_CARRY); 373 | ram[0] = 0x61; 374 | ram[1] = 0x02; 375 | ram[2] = 0x02; 376 | ram[3] = 0x01; 377 | instructions = 1; run(); 378 | if(!(A == 0x01 && !(SR&SR_NEG) && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1; 379 | 380 | //with carry 381 | A = 0x00; 382 | SR |= SR_CARRY; 383 | ram[0] = 0x61; 384 | ram[1] = 0x02; 385 | ram[2] = 0x02; 386 | ram[3] = 0x01; 387 | instructions = 1; run(); 388 | if(!(A == 0x02 && !(SR&SR_NEG) && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -2; 389 | 390 | //negative result 391 | A = 0xFE; 392 | SR &= (~SR_CARRY); 393 | ram[0] = 0x61; 394 | ram[1] = 0x02; 395 | ram[2] = 0x02; 396 | ram[3] = 0xFE; 397 | instructions = 1; run(); 398 | if(!(A == 0xFC && SR&SR_NEG && !(SR&SR_ZERO) && SR&SR_CARRY && !(SR&SR_OVER))) return -3; 399 | 400 | //overflow result 401 | A = 0x80; 402 | SR &= (~SR_CARRY); 403 | ram[0] = 0x61; 404 | ram[1] = 0x02; 405 | ram[2] = 0x02; 406 | ram[3] = 0xFF; 407 | instructions = 1; run(); 408 | if(!(A == 0x7F && !(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY && SR&SR_OVER)) return -4; 409 | 410 | //zero result 411 | A = 0xFF; //-1 412 | SR &= (~SR_CARRY); 413 | ram[0] = 0x61; 414 | ram[1] = 0x02; 415 | ram[2] = 0x02; 416 | ram[3] = 0x01; //+1 417 | instructions = 1; run(); 418 | if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY && !(SR&SR_OVER))) return -5; 419 | 420 | //carry result 421 | A = 0xF0; //+70 422 | SR &= (~SR_CARRY); 423 | ram[0] = 0x61; 424 | ram[1] = 0x02; 425 | ram[2] = 0x02; 426 | ram[3] = 0xF0; //+70 427 | instructions = 1; run(); 428 | if(!(A == 0xE0 && SR&SR_NEG && !(SR&SR_ZERO) && SR&SR_CARRY && !(SR&SR_OVER))) return -6; 429 | 430 | return 0; 431 | } 432 | 433 | int testAdcIndirectY() { 434 | Y = 0x01; X = 0x00; 435 | 436 | //no carry 437 | A = 0x00; 438 | SR &= (~SR_CARRY); 439 | ram[0] = 0x71; 440 | ram[1] = 0x02; 441 | ram[2] = 0x03; 442 | ram[3] = 0x00; 443 | ram[4] = 0x01; 444 | instructions = 1; run(); 445 | if(!(A == 0x01 && !(SR&SR_NEG) && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1; 446 | 447 | //with carry 448 | A = 0x00; 449 | SR |= SR_CARRY; 450 | ram[0] = 0x71; 451 | ram[1] = 0x02; 452 | ram[2] = 0x03; 453 | ram[3] = 0x00; 454 | ram[4] = 0x01; 455 | instructions = 1; run(); 456 | if(!(A == 0x02 && !(SR&SR_NEG) && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -2; 457 | 458 | //negative result 459 | A = 0xFE; 460 | SR &= (~SR_CARRY); 461 | ram[0] = 0x71; 462 | ram[1] = 0x02; 463 | ram[2] = 0x03; 464 | ram[3] = 0x00; 465 | ram[4] = 0xFE; 466 | instructions = 1; run(); 467 | if(!(A == 0xFC && SR&SR_NEG && !(SR&SR_ZERO) && SR&SR_CARRY && !(SR&SR_OVER))) return -3; 468 | 469 | //overflow result 470 | A = 0x80; 471 | SR &= (~SR_CARRY); 472 | ram[0] = 0x71; 473 | ram[1] = 0x02; 474 | ram[2] = 0x03; 475 | ram[3] = 0x00; 476 | ram[4] = 0xFF; 477 | instructions = 1; run(); 478 | if(!(A == 0x7F && !(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY && SR&SR_OVER)) return -4; 479 | 480 | //zero result 481 | A = 0xFF; //-1 482 | SR &= (~SR_CARRY); 483 | ram[0] = 0x71; 484 | ram[1] = 0x02; 485 | ram[2] = 0x03; 486 | ram[3] = 0x00; 487 | ram[4] = 0x01; 488 | instructions = 1; run(); 489 | if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY && !(SR&SR_OVER))) return -5; 490 | 491 | //carry result 492 | A = 0xF0; //+70 493 | SR &= (~SR_CARRY); 494 | ram[0] = 0x71; 495 | ram[1] = 0x02; 496 | ram[2] = 0x03; 497 | ram[3] = 0x00; 498 | ram[4] = 0xF0; 499 | instructions = 1; run(); 500 | if(!(A == 0xE0 && SR&SR_NEG && !(SR&SR_ZERO) && SR&SR_CARRY && !(SR&SR_OVER))) return -6; 501 | 502 | return 0; 503 | } -------------------------------------------------------------------------------- /APPLEII/cpu.ino: -------------------------------------------------------------------------------- 1 | // μ6502 - Barebones 6502 Emulator By Damian Peckett 2 | // dpeckett.com, 3 | 4 | // Address Modes 5 | #define AD_IMP 0x01 6 | #define AD_A 0x02 7 | #define AD_ABS 0x03 8 | #define AD_ABSX 0x04 9 | #define AD_ABSY 0x05 10 | #define AD_IMM 0x06 11 | #define AD_IND 0x07 12 | #define AD_INDX 0x08 13 | #define AD_INDY 0x09 14 | #define AD_REL 0x0A 15 | #define AD_ZPG 0x0B 16 | #define AD_ZPGX 0x0C 17 | #define AD_ZPGY 0x0D 18 | 19 | // SR Flag Modes 20 | #define FL_NONE 0x00 21 | #define FL_Z 0x20 22 | #define FL_ZN 0xA0 23 | #define FL_ZNC 0xB0 24 | #define FL_ZC 0x30 25 | #define FL_ALL 0xF0 26 | 27 | //Unimplemented ops 28 | #define UNDF 0x00 29 | 30 | //Other constants 31 | #define SR_FIXED_BITS 0x20 32 | #define SR_CARRY 0x01 33 | #define SR_ZERO 0x02 34 | #define SR_INT 0x04 35 | #define SR_DEC 0x08 36 | #define SR_BRK 0x10 37 | #define SR_OVER 0x40 38 | #define SR_NEG 0x80 39 | 40 | //Stack pointer base address 41 | #define STP_BASE 0x100 42 | 43 | //high nibble SR flags, low nibble address mode 44 | const unsigned char flags[] PROGMEM = { 45 | AD_IMP, AD_INDX, UNDF, UNDF, UNDF, FL_ZN|AD_ZPG, FL_ZNC|AD_ZPG, UNDF, AD_IMP, FL_ZN|AD_IMM, FL_ZNC|AD_A, UNDF, UNDF, FL_ZN|AD_ABS, FL_ZNC|AD_ABS, UNDF, 46 | AD_REL, FL_ZN|AD_INDY, UNDF, UNDF, UNDF, FL_ZN|AD_ZPGX, FL_ZNC|AD_ZPGX, UNDF, AD_IMP, FL_ZN|AD_ABSY, UNDF, UNDF, UNDF, FL_ZN|AD_ABSX, FL_ZNC|AD_ABSX, UNDF, 47 | AD_ABS, FL_ZN|AD_INDX, UNDF, UNDF, FL_Z|AD_ZPG, FL_ZN|AD_ZPG, FL_ZNC|AD_ZPG, UNDF, AD_IMP, FL_ZN|AD_IMM, FL_ZNC|AD_A, UNDF, FL_Z|AD_ABS, FL_ZN|AD_ABS, FL_ZNC|AD_ABS, UNDF, 48 | AD_REL, FL_ZN|AD_INDY, UNDF, UNDF, UNDF, FL_ZN|AD_ZPGX, FL_ZNC|AD_ZPGX, UNDF, AD_IMP, FL_ZN|AD_ABSY, UNDF, UNDF, UNDF, FL_ZN|AD_ABSX, FL_ZNC|AD_ABSX, UNDF, 49 | AD_IMP, FL_ZN|AD_INDX, UNDF, UNDF, UNDF, FL_ZN|AD_ZPG, FL_ZNC|AD_ZPG, UNDF, AD_IMP, FL_ZN|AD_IMM, FL_ZNC|AD_A, UNDF, AD_ABS, FL_ZN|AD_ABS, FL_ZNC|AD_ABS, UNDF, 50 | AD_REL, FL_ZN|AD_INDY, UNDF, UNDF, UNDF, FL_ZN|AD_ZPGX, FL_ZNC|AD_ZPGX, UNDF, AD_IMP, FL_ZN|AD_ABSY, UNDF, UNDF, UNDF, FL_ZN|AD_ABSX, FL_ZNC|AD_ABSX, UNDF, 51 | AD_IMP, FL_ALL|AD_INDX, UNDF, UNDF, UNDF, FL_ALL|AD_ZPG, FL_ZNC|AD_ZPG, UNDF, FL_ZN|AD_IMP, FL_ALL|AD_IMM, FL_ZNC|AD_A,UNDF, AD_IND, FL_ALL|AD_ABS, FL_ZNC|AD_ABS, UNDF, 52 | AD_REL, FL_ALL|AD_INDY, UNDF, UNDF, UNDF, FL_ALL|AD_ZPGX, FL_ZNC|AD_ZPGX, UNDF, AD_IMP, FL_ALL|AD_ABSY, UNDF, UNDF, UNDF, FL_ALL|AD_ABSX, FL_ZNC|AD_ABSX, UNDF, 53 | UNDF, AD_INDX, UNDF, UNDF, AD_ZPG, AD_ZPG, AD_ZPG, UNDF, FL_ZN|AD_IMP, UNDF, FL_ZN|AD_IMP, UNDF, AD_ABS, AD_ABS, AD_ABS, UNDF, 54 | AD_REL, AD_INDY, UNDF, UNDF, AD_ZPGX, AD_ZPGX, AD_ZPGY, UNDF, FL_ZN|AD_IMP, AD_ABSY, AD_IMP, UNDF, UNDF, AD_ABSX, UNDF, UNDF, 55 | FL_ZN|AD_IMM, FL_ZN|AD_INDX, FL_ZN|AD_IMM, UNDF, FL_ZN|AD_ZPG, FL_ZN|AD_ZPG, FL_ZN|AD_ZPG, UNDF, FL_ZN|AD_IMP, FL_ZN|AD_IMM, FL_ZN|AD_IMP, UNDF, FL_ZN|AD_ABS, FL_ZN|AD_ABS, FL_ZN|AD_ABS, UNDF, 56 | AD_REL, FL_ZN|AD_INDY, UNDF, UNDF, FL_ZN|AD_ZPGX, FL_ZN|AD_ZPGX, FL_ZN|AD_ZPGY, UNDF, AD_IMP, FL_ZN|AD_ABSY, FL_ZN|AD_IMP, UNDF, FL_ZN|AD_ABSX, FL_ZN|AD_ABSX, FL_ZN|AD_ABSY, UNDF, 57 | FL_ZNC|AD_IMM, FL_ZNC|AD_INDX, UNDF, UNDF, FL_ZNC|AD_ZPG, FL_ZNC|AD_ZPG, FL_ZN|AD_ZPG, UNDF, FL_ZN|AD_IMP, FL_ZNC|AD_IMM, FL_ZN|AD_IMP, UNDF, FL_ZNC|AD_ABS, FL_ZNC|AD_ABS, FL_ZN|AD_ABS, UNDF, 58 | AD_REL, FL_ZNC|AD_INDY, UNDF, UNDF, UNDF, FL_ZNC|AD_ZPGX, FL_ZN|AD_ZPGX, UNDF, AD_IMP, FL_ZNC|AD_ABSY, UNDF, UNDF, UNDF, FL_ZNC|AD_ABSX, FL_ZN|AD_ABSX, UNDF, 59 | FL_ZNC|AD_IMM, FL_ALL|AD_INDX, UNDF, UNDF, FL_ZNC|AD_ZPG, FL_ALL|AD_ZPG, FL_ZN|AD_ZPG, UNDF, FL_ZN|AD_IMP, FL_ALL|AD_IMM, AD_IMP, UNDF, FL_ZNC|AD_ABS, FL_ALL|AD_ABS, FL_ZN|AD_ABS, UNDF, 60 | AD_REL, FL_ALL|AD_INDY, UNDF, UNDF, UNDF, FL_ALL|AD_ZPGX, FL_ZN|AD_ZPGX, UNDF, AD_IMP, FL_ALL|AD_ABSY, UNDF, UNDF, UNDF, FL_ALL|AD_ABSX, FL_ZN|AD_ABSX, UNDF 61 | }; 62 | 63 | // CPU registers 64 | unsigned short PC; 65 | unsigned char STP = 0xFD, A = 0x00, X = 0x00, Y = 0x00, SR = SR_FIXED_BITS; 66 | 67 | //Execution variables 68 | unsigned char opcode, opflags; 69 | unsigned short argument_addr; 70 | 71 | //Temporary variables for flag generation 72 | unsigned char value8; 73 | unsigned short value16, value16_2, result; 74 | 75 | void setflags() { 76 | // Mask out affected flags 77 | switch(opflags&0xF0) { 78 | case 0xA0: SR&=0x7D; break; 79 | case 0xB0: SR&=0x7C; break; 80 | case 0x30: SR&=0xFC; break; 81 | case 0xF0: SR&=0x3C; break; 82 | case 0x20: SR&=0xFD; break; 83 | } 84 | 85 | // Set various status flags 86 | if(opflags&0x80) SR |= (result&0x0080); //negative 87 | if(opflags&0x20) SR |= (((result&0xFF) == 0)?0x02:0); //zero 88 | if(opflags&0x10) SR |= ((result&0xFF00)?0x01:0); //carry 89 | if(opflags&0x40) SR |= ((result^((unsigned short)A))&(result^value16)&0x0080)>>1; 90 | } 91 | 92 | // Stack functions 93 | void push16(unsigned short pushval) { 94 | write8(STP_BASE + (STP--), (pushval>>8)&0xFF); 95 | write8(STP_BASE + (STP--), pushval&0xFF); 96 | } 97 | 98 | void push8(unsigned char pushval) { 99 | write8(STP_BASE + (STP--), pushval); 100 | } 101 | 102 | unsigned short pull16() { 103 | value16 = read8(STP_BASE + (++STP)) | ((unsigned short)read8(STP_BASE + (++STP))<< 8); 104 | return value16; 105 | } 106 | 107 | unsigned char pull8() { 108 | return read8(STP_BASE + (++STP)); 109 | } 110 | 111 | void run() { 112 | // Load the reset vector 113 | PC = read16(0xFFFC); 114 | STP = 0xFD; 115 | 116 | for(;;) { 117 | // Routines for hooking apple ][ monitor routines 118 | program_hooks(PC); 119 | 120 | // Get opcode / addressing mode 121 | opcode = read8(PC++); 122 | opflags = pgm_read_byte_near(flags+opcode); 123 | 124 | // Addressing modes 125 | switch(opflags&0x0F) { 126 | case AD_IMP: case AD_A: argument_addr = 0xFFFF; break; 127 | case AD_ABS: 128 | argument_addr = read16(PC); 129 | PC += 2; 130 | break; 131 | case AD_ABSX: 132 | argument_addr = read16(PC) + (unsigned short)X; 133 | PC += 2; 134 | break; 135 | case AD_ABSY: 136 | argument_addr = read16(PC) + (unsigned short)Y; 137 | PC += 2; 138 | break; 139 | case AD_IMM: 140 | argument_addr = PC++; 141 | break; 142 | case AD_IND: 143 | argument_addr = read16(PC); 144 | value16 = (argument_addr&0xFF00) | ((argument_addr+1)&0x00FF); // Page wrap 145 | argument_addr = (unsigned short)read8(argument_addr) | ((unsigned short)read8(value16) << 8); 146 | PC+=2; 147 | break; 148 | case AD_INDX: 149 | argument_addr = ((unsigned short)read8(PC++) + (unsigned short)X)&0xFF; 150 | value16 = (argument_addr&0xFF00) | ((argument_addr+1)&0x00FF); // Page wrap 151 | argument_addr = (unsigned short)read8(argument_addr) | ((unsigned short)read8(value16) << 8); 152 | break; 153 | case AD_INDY: 154 | argument_addr = (unsigned short)read8(PC++); 155 | value16 = (argument_addr&0xFF00) | ((argument_addr+1)&0x00FF); // Page wrap 156 | argument_addr = (unsigned short)read8(argument_addr) | ((unsigned short)read8(value16) << 8); 157 | argument_addr += Y; 158 | break; 159 | case AD_REL: 160 | argument_addr = (unsigned short)read8(PC++); 161 | argument_addr |= ((argument_addr&0x80)?0xFF00:0); 162 | break; 163 | case AD_ZPG: 164 | argument_addr = (unsigned short)read8(PC++); 165 | break; 166 | case AD_ZPGX: 167 | argument_addr = ((unsigned short)read8(PC++) + (unsigned short)X)&0xFF; 168 | break; 169 | case AD_ZPGY: 170 | argument_addr = ((unsigned short)read8(PC++) + (unsigned short)Y)&0xFF; 171 | break; 172 | } 173 | 174 | //opcodes 175 | switch(opcode) { 176 | //ADC 177 | case 0x69: case 0x65: case 0x75: 178 | case 0x6D: case 0x7D: case 0x79: 179 | case 0x61: case 0x71: 180 | value16 = (unsigned short)read8(argument_addr); 181 | result = (unsigned short)A + value16 + (unsigned short)(SR&SR_CARRY); 182 | setflags(); 183 | A = result&0xFF; 184 | break; 185 | //AND 186 | case 0x29: case 0x25: case 0x35: 187 | case 0x2D: case 0x3D: case 0x39: 188 | case 0x21: case 0x31: 189 | result = A&read8(argument_addr); 190 | A = result&0xFF; 191 | setflags(); 192 | break; 193 | //ASL A 194 | case 0x0A: 195 | value16 = (unsigned short)A; 196 | result = value16<<1; 197 | setflags(); 198 | A = result&0xFF; 199 | break; 200 | //ASL 201 | case 0x06: case 0x16: case 0x0E: 202 | case 0x1E: 203 | value16 = read8(argument_addr); 204 | result = value16<<1; 205 | setflags(); 206 | write8(argument_addr, result&0xFF); 207 | break; 208 | //BCC 209 | case 0x90: 210 | if(!(SR&SR_CARRY)) PC += argument_addr; 211 | break; 212 | //BCS 213 | case 0xB0: 214 | if((SR&SR_CARRY)) PC += argument_addr; 215 | break; 216 | //BEQ 217 | case 0xF0: 218 | if((SR&SR_ZERO)) PC += argument_addr; 219 | break; 220 | //BNE 221 | case 0xD0: 222 | if(!(SR&SR_ZERO)) PC += argument_addr; 223 | break; 224 | //BIT 225 | case 0x24: case 0x2C: 226 | value8 = read8(argument_addr); 227 | result = A & value8; 228 | setflags(); 229 | SR = (SR&0x3F) | (value8&0xC0); 230 | break; 231 | //BMI 232 | case 0x30: 233 | if((SR&SR_NEG)) PC += argument_addr; 234 | break; 235 | //BPL 236 | case 0x10: 237 | if(!(SR&SR_NEG)) PC += argument_addr; 238 | break; 239 | //BRK 240 | case 0x00: 241 | PC++; 242 | push16(PC); 243 | push8(SR|SR_BRK); 244 | SR|=SR_INT; 245 | PC = read16(0xFFFE); 246 | break; 247 | //BVC 248 | case 0x50: 249 | if(!(SR&SR_OVER)) PC += argument_addr; 250 | break; 251 | //BVS 252 | case 0x70: 253 | if(SR&SR_OVER) PC += argument_addr; 254 | break; 255 | //CLC 256 | case 0x18: 257 | SR&=0xFE; 258 | break; 259 | //CLD 260 | case 0xD8: 261 | SR&=0xF7; 262 | break; 263 | //CLI 264 | case 0x58: 265 | SR&=0xFB; 266 | break; 267 | //CLV 268 | case 0xB8: 269 | SR&=0xBF; 270 | break; 271 | //CMP 272 | case 0xC9: case 0xC5: case 0xD5: 273 | case 0xCD: case 0xDD: case 0xD9: 274 | case 0xC1: case 0xD1: 275 | value16 = ((unsigned short)read8(argument_addr)) ^ 0x00FF; 276 | result = (unsigned short)A + value16 + (unsigned short)1; 277 | setflags(); 278 | break; 279 | //CPX 280 | case 0xE0: case 0xE4: case 0xEC: 281 | value16 = ((unsigned short)read8(argument_addr)) ^ 0x00FF; 282 | result = (unsigned short)X + value16 + (unsigned short)1; 283 | setflags(); 284 | break; 285 | //CPY 286 | case 0xC0: case 0xC4: case 0xCC: 287 | value16 = ((unsigned short)read8(argument_addr)) ^ 0x00FF; 288 | result = (unsigned short)Y + value16 + (unsigned short)1; 289 | setflags(); 290 | break; 291 | //DEC 292 | case 0xC6: case 0xD6: case 0xCE: 293 | case 0xDE: 294 | value16 = (unsigned short)read8(argument_addr); 295 | result = value16 - 1; 296 | setflags(); 297 | write8(argument_addr, result&0xFF); 298 | break; 299 | //DEX 300 | case 0xCA: 301 | result = --X; 302 | setflags(); 303 | break; 304 | //DEY 305 | case 0x88: 306 | result = --Y; 307 | setflags(); 308 | break; 309 | //EOR 310 | case 0x49: case 0x45: case 0x55: 311 | case 0x4D: case 0x5D: case 0x59: 312 | case 0x41: case 0x51: 313 | value8 = read8(argument_addr); 314 | result = A^value8; 315 | setflags(); 316 | A = result&0xFF; 317 | break; 318 | //INC 319 | case 0xE6: case 0xF6: case 0xEE: 320 | case 0xFE: 321 | value16 = (unsigned short)read8(argument_addr); 322 | result = value16 + 1; 323 | setflags(); 324 | write8(argument_addr, result&0xFF); 325 | break; 326 | //INX 327 | case 0xE8: 328 | result = ++X; 329 | setflags(); 330 | break; 331 | //INY 332 | case 0xC8: 333 | result = ++Y; 334 | setflags(); 335 | break; 336 | //JMP 337 | case 0x4C: case 0x6C: 338 | PC = argument_addr; 339 | break; 340 | //JSR 341 | case 0x20: 342 | push16(PC-1); 343 | PC = argument_addr; 344 | break; 345 | //LDA 346 | case 0xA9: case 0xA5: case 0xB5: 347 | case 0xAD: case 0xBD: case 0xB9: 348 | case 0xA1: case 0xB1: 349 | A = read8(argument_addr); 350 | result = A; 351 | setflags(); 352 | break; 353 | //LDX 354 | case 0xA2: case 0xA6: case 0xB6: 355 | case 0xAE: case 0xBE: 356 | X = read8(argument_addr); 357 | result = X; 358 | setflags(); 359 | break; 360 | //LDY 361 | case 0xA0: case 0xA4: case 0xB4: 362 | case 0xAC: case 0xBC: 363 | Y = read8(argument_addr); 364 | result = Y; 365 | setflags(); 366 | break; 367 | //LSR A 368 | case 0x4A: 369 | value8 = A; 370 | result = value8 >> 1; 371 | result |= (value8&0x1)?0x8000:0; 372 | setflags(); 373 | A = result&0xFF; 374 | break; 375 | //LSR 376 | case 0x46: case 0x56: case 0x4E: 377 | case 0x5E: 378 | value8 = read8(argument_addr); 379 | result = value8 >> 1; 380 | result |= (value8&0x1)?0x8000:0; 381 | setflags(); 382 | write8(argument_addr, result&0xFF); 383 | break; 384 | //NOP 385 | case 0xEA: 386 | break; 387 | //ORA 388 | case 0x09: case 0x05: case 0x15: 389 | case 0x0D: case 0x1D: case 0x19: 390 | case 0x01: case 0x11: 391 | value8 = read8(argument_addr); 392 | result = A | value8; 393 | setflags(); 394 | A = result&0xFF; 395 | break; 396 | //PHA 397 | case 0x48: 398 | push8(A); 399 | break; 400 | //PHP 401 | case 0x08: 402 | push8(SR|SR_BRK); 403 | break; 404 | //PLA 405 | case 0x68: 406 | result = pull8(); 407 | setflags(); 408 | A = result; 409 | break; 410 | //PLP 411 | case 0x28: 412 | SR = pull8() | SR_FIXED_BITS; 413 | break; 414 | //ROL A 415 | case 0x2A: 416 | value16 = (unsigned short)A; 417 | result = (value16 << 1) | (SR&SR_CARRY); 418 | setflags(); 419 | A = result&0xFF; 420 | break; 421 | //ROL 422 | case 0x26: case 0x36: case 0x2E: 423 | case 0x3E: 424 | value16 = (unsigned short)read8(argument_addr); 425 | result = (value16 << 1) | (SR&SR_CARRY); 426 | setflags(); 427 | write8(argument_addr, result&0xFF); 428 | break; 429 | //ROR A 430 | case 0x6A: 431 | value16 = (unsigned short)A; 432 | result = (value16 >> 1) | ((SR&SR_CARRY) << 7); 433 | result |= (value16&0x1)?0x8000:0; 434 | setflags(); 435 | A = result&0xFF; 436 | break; 437 | //ROR 438 | case 0x66: case 0x76: case 0x6E: 439 | case 0x7E: 440 | value16 = (unsigned short)read8(argument_addr); 441 | result = (value16 >> 1) | ((SR&SR_CARRY) << 7); 442 | result |= (value16&0x1)?0x8000:0; 443 | setflags(); 444 | write8(argument_addr, result&0xFF); 445 | break; 446 | //RTI 447 | case 0x40: 448 | SR = pull8(); 449 | PC = pull16(); 450 | break; 451 | //RTS 452 | case 0x60: 453 | PC = pull16() + 1; 454 | break; 455 | //SBC 456 | case 0xE9: case 0xE5: case 0xF5: 457 | case 0xED: case 0xFD: case 0xF9: 458 | case 0xE1: case 0xF1: 459 | value16 = ((unsigned short)read8(argument_addr)) ^ 0x00FF; 460 | result = (unsigned short)A + value16 + (unsigned short)(SR&SR_CARRY); 461 | setflags(); 462 | A = result&0xFF; 463 | break; 464 | //SEC 465 | case 0x38: 466 | SR |= SR_CARRY; 467 | break; 468 | //SED 469 | case 0xF8: 470 | SR |= SR_DEC; 471 | break; 472 | //SEI 473 | case 0x78: 474 | SR |= SR_INT; 475 | break; 476 | //STA 477 | case 0x85: case 0x95: case 0x8D: 478 | case 0x9D: case 0x99: case 0x81: 479 | case 0x91: 480 | write8(argument_addr, A); 481 | break; 482 | //STX 483 | case 0x86: case 0x96: case 0x8E: 484 | write8(argument_addr, X); 485 | break; 486 | //STY 487 | case 0x84: case 0x94: case 0x8C: 488 | write8(argument_addr, Y); 489 | break; 490 | //TAX 491 | case 0xAA: 492 | X = A; 493 | result = A; 494 | setflags(); 495 | break; 496 | //TAY 497 | case 0xA8: 498 | Y = A; 499 | result = A; 500 | setflags(); 501 | break; 502 | //TSX 503 | case 0xBA: 504 | X = STP; 505 | result = STP; 506 | setflags(); 507 | break; 508 | //TXA 509 | case 0x8A: 510 | A = X; 511 | result = X; 512 | setflags(); 513 | break; 514 | //TXS 515 | case 0x9A: 516 | STP = X; 517 | result = X; 518 | setflags(); 519 | break; 520 | //TYA 521 | case 0x98: 522 | A = Y; 523 | result = Y; 524 | setflags(); 525 | break; 526 | } 527 | } 528 | } 529 | -------------------------------------------------------------------------------- /APPLEII/memory.ino: -------------------------------------------------------------------------------- 1 | const unsigned char rom[] PROGMEM = { //$E000 - FFFF 2 | 0x20, 0x00, 0xf0, 0x4c, 0xb3, 0xe2, 0x85, 0x33, 3 | 0x4c, 0xed, 0xfd, 0x60, 0x8a, 0x29, 0x20, 0xf0, 4 | 0x23, 0xa9, 0xa0, 0x85, 0xe4, 0x4c, 0xed, 0xfd, 5 | 0xa9, 0x20, 0xc5, 0x24, 0xb0, 0x0c, 0xa9, 0x8d, 6 | 0xa0, 0x07, 0x20, 0xed, 0xfd, 0xa9, 0xa0, 0x88, 7 | 0xd0, 0xf8, 0xa0, 0x00, 0xb1, 0xe2, 0xe6, 0xe2, 8 | 0xd0, 0x02, 0xe6, 0xe3, 0x60, 0x20, 0x15, 0xe7, 9 | 0x20, 0x76, 0xe5, 0xa5, 0xe2, 0xc5, 0xe6, 0xa5, 10 | 0xe3, 0xe5, 0xe7, 0xb0, 0xef, 0x20, 0x6d, 0xe0, 11 | 0x4c, 0x3b, 0xe0, 0xa5, 0xca, 0x85, 0xe2, 0xa5, 12 | 0xcb, 0x85, 0xe3, 0xa5, 0x4c, 0x85, 0xe6, 0xa5, 13 | 0x4d, 0x85, 0xe7, 0xd0, 0xde, 0x20, 0x15, 0xe7, 14 | 0x20, 0x6d, 0xe5, 0xa5, 0xe4, 0x85, 0xe2, 0xa5, 15 | 0xe5, 0x85, 0xe3, 0xb0, 0xc7, 0x86, 0xd8, 0xa9, 16 | 0xa0, 0x85, 0xfa, 0x20, 0x2a, 0xe0, 0x98, 0x85, 17 | 0xe4, 0x20, 0x2a, 0xe0, 0xaa, 0x20, 0x2a, 0xe0, 18 | 0x20, 0x1b, 0xe5, 0x20, 0x18, 0xe0, 0x84, 0xfa, 19 | 0xaa, 0x10, 0x18, 0x0a, 0x10, 0xe9, 0xa5, 0xe4, 20 | 0xd0, 0x03, 0x20, 0x11, 0xe0, 0x8a, 0x20, 0xed, 21 | 0xfd, 0xa9, 0x25, 0x20, 0x1a, 0xe0, 0xaa, 0x30, 22 | 0xf5, 0x85, 0xe4, 0xc9, 0x01, 0xd0, 0x05, 0xa6, 23 | 0xd8, 0x4c, 0x8e, 0xfd, 0x48, 0x84, 0xce, 0xa2, 24 | 0xed, 0x86, 0xcf, 0xc9, 0x51, 0x90, 0x04, 0xc6, 25 | 0xcf, 0xe9, 0x50, 0x48, 0xb1, 0xce, 0xaa, 0x88, 26 | 0xb1, 0xce, 0x10, 0xfa, 0xe0, 0xc0, 0xb0, 0x04, 27 | 0xe0, 0x00, 0x30, 0xf2, 0xaa, 0x68, 0xe9, 0x01, 28 | 0xd0, 0xe9, 0x24, 0xe4, 0x30, 0x03, 0x20, 0xf8, 29 | 0xef, 0xb1, 0xce, 0x10, 0x10, 0xaa, 0x29, 0x3f, 30 | 0x85, 0xe4, 0x18, 0x69, 0xa0, 0x20, 0xed, 0xfd, 31 | 0x88, 0xe0, 0xc0, 0x90, 0xec, 0x20, 0x0c, 0xe0, 32 | 0x68, 0xc9, 0x5d, 0xf0, 0xa4, 0xc9, 0x28, 0xd0, 33 | 0x8a, 0xf0, 0x9e, 0x20, 0x18, 0xe1, 0x95, 0x50, 34 | 0xd5, 0x78, 0x90, 0x11, 0xa0, 0x2b, 0x4c, 0xe0, 35 | 0xe3, 0x20, 0x34, 0xee, 0xd5, 0x50, 0x90, 0xf4, 36 | 0x20, 0xe4, 0xef, 0x95, 0x78, 0x4c, 0x23, 0xe8, 37 | 0x20, 0x34, 0xee, 0xf0, 0xe7, 0x38, 0xe9, 0x01, 38 | 0x60, 0x20, 0x18, 0xe1, 0x95, 0x50, 0x18, 0xf5, 39 | 0x78, 0x4c, 0x02, 0xe1, 0xa0, 0x14, 0xd0, 0xd6, 40 | 0x20, 0x18, 0xe1, 0xe8, 0xb5, 0x50, 0x85, 0xda, 41 | 0x65, 0xce, 0x48, 0xa8, 0xb5, 0x78, 0x85, 0xdb, 42 | 0x65, 0xcf, 0x48, 0xc4, 0xca, 0xe5, 0xcb, 0xb0, 43 | 0xe3, 0xa5, 0xda, 0x69, 0xfe, 0x85, 0xda, 0xa9, 44 | 0xff, 0xa8, 0x65, 0xdb, 0x85, 0xdb, 0xc8, 0xb1, 45 | 0xda, 0xd9, 0xcc, 0x00, 0xd0, 0x0f, 0x98, 0xf0, 46 | 0xf5, 0x68, 0x91, 0xda, 0x99, 0xcc, 0x00, 0x88, 47 | 0x10, 0xf7, 0xe8, 0x60, 0xea, 0xa0, 0x80, 0xd0, 48 | 0x95, 0xa9, 0x00, 0x20, 0x0a, 0xe7, 0xa0, 0x02, 49 | 0x94, 0x78, 0x20, 0x0a, 0xe7, 0x86, 0xd8, 0xaa, 50 | 0xe6, 0x33, 0x20, 0x51, 0xf3, 0xc6, 0x33, 0x8a, 51 | 0xa6, 0xd8, 0x95, 0x78, 0xb5, 0x51, 0x85, 0xce, 52 | 0xb5, 0x79, 0x85, 0xcf, 0xe8, 0xe8, 0x20, 0xbc, 53 | 0xe1, 0xb5, 0x4e, 0xd5, 0x76, 0xb0, 0x15, 0xf6, 54 | 0x4e, 0xa8, 0xb1, 0xce, 0xb4, 0x50, 0xc4, 0xe4, 55 | 0x90, 0x04, 0xa0, 0x83, 0xd0, 0xc1, 0x91, 0xda, 56 | 0xf6, 0x50, 0x90, 0xe5, 0xb4, 0x50, 0x8a, 0x91, 57 | 0xda, 0x4c, 0x23, 0xf2, 0xb5, 0x51, 0x85, 0xda, 58 | 0x38, 0xe9, 0x02, 0x85, 0xe4, 0xb5, 0x79, 0x85, 59 | 0xdb, 0xe9, 0x00, 0x85, 0xe5, 0xa0, 0x00, 0xb1, 60 | 0xe4, 0x18, 0xe5, 0xda, 0x85, 0xe4, 0x60, 0xb5, 61 | 0x53, 0x85, 0xce, 0xb5, 0x7b, 0x85, 0xcf, 0xb5, 62 | 0x51, 0x85, 0xda, 0xb5, 0x79, 0x85, 0xdb, 0xe8, 63 | 0xe8, 0xe8, 0xa0, 0x00, 0x94, 0x78, 0x94, 0xa0, 64 | 0xc8, 0x94, 0x50, 0xb5, 0x4d, 0xd5, 0x75, 0x08, 65 | 0x48, 0xb5, 0x4f, 0xd5, 0x77, 0x90, 0x07, 0x68, 66 | 0x28, 0xb0, 0x02, 0x56, 0x50, 0x60, 0xa8, 0xb1, 67 | 0xce, 0x85, 0xe4, 0x68, 0xa8, 0x28, 0xb0, 0xf3, 68 | 0xb1, 0xda, 0xc5, 0xe4, 0xd0, 0xed, 0xf6, 0x4f, 69 | 0xf6, 0x4d, 0xb0, 0xd7, 0x20, 0xd7, 0xe1, 0x4c, 70 | 0x36, 0xe7, 0x20, 0x54, 0xe2, 0x06, 0xce, 0x26, 71 | 0xcf, 0x90, 0x0d, 0x18, 0xa5, 0xe6, 0x65, 0xda, 72 | 0x85, 0xe6, 0xa5, 0xe7, 0x65, 0xdb, 0x85, 0xe7, 73 | 0x88, 0xf0, 0x09, 0x06, 0xe6, 0x26, 0xe7, 0x10, 74 | 0xe4, 0x4c, 0x7e, 0xe7, 0xa5, 0xe6, 0x20, 0x08, 75 | 0xe7, 0xa5, 0xe7, 0x95, 0xa0, 0x06, 0xe5, 0x90, 76 | 0x28, 0x4c, 0x6f, 0xe7, 0xa9, 0x55, 0x85, 0xe5, 77 | 0x20, 0x5b, 0xe2, 0xa5, 0xce, 0x85, 0xda, 0xa5, 78 | 0xcf, 0x85, 0xdb, 0x20, 0x15, 0xe7, 0x84, 0xe6, 79 | 0x84, 0xe7, 0xa5, 0xcf, 0x10, 0x09, 0xca, 0x06, 80 | 0xe5, 0x20, 0x6f, 0xe7, 0x20, 0x15, 0xe7, 0xa0, 81 | 0x10, 0x60, 0x20, 0x6c, 0xee, 0xf0, 0xc5, 0xff, 82 | 0xe6, 0x33, 0xa0, 0x00, 0x20, 0xce, 0xe3, 0xc6, 83 | 0x33, 0x60, 0x20, 0x34, 0xee, 0x4a, 0x08, 0x20, 84 | 0x47, 0xf8, 0x20, 0x34, 0xee, 0xa8, 0xb1, 0x26, 85 | 0x28, 0x90, 0x04, 0x4a, 0x4a, 0x4a, 0x4a, 0x29, 86 | 0x0f, 0xa0, 0x00, 0x20, 0x08, 0xe7, 0x94, 0xa0, 87 | 0x88, 0x84, 0xd7, 0x60, 0xff, 0xff, 0xff, 0xff, 88 | 0x20, 0xd3, 0xef, 0x20, 0x8e, 0xfd, 0x46, 0xd9, 89 | 0xa9, 0xbe, 0x20, 0x06, 0xe0, 0xa0, 0x00, 0x84, 90 | 0xfa, 0x24, 0xf8, 0x10, 0x0c, 0xa6, 0xf6, 0xa5, 91 | 0xf7, 0x20, 0x1b, 0xe5, 0xa9, 0xa0, 0x20, 0xed, 92 | 0xfd, 0xa2, 0xff, 0x9a, 0x20, 0xce, 0xe3, 0x84, 93 | 0xf1, 0x8a, 0x85, 0xc8, 0xa2, 0x20, 0x20, 0x91, 94 | 0xe4, 0xa5, 0xc8, 0x69, 0x00, 0x85, 0xe0, 0xa9, 95 | 0x00, 0xaa, 0x69, 0x02, 0x85, 0xe1, 0xa1, 0xe0, 96 | 0x29, 0xf0, 0xc9, 0xb0, 0xf0, 0x03, 0x4c, 0x83, 97 | 0xe8, 0xa0, 0x02, 0xb1, 0xe0, 0x99, 0xcd, 0x00, 98 | 0x88, 0xd0, 0xf8, 0x20, 0x8a, 0xe3, 0xa5, 0xf1, 99 | 0xe5, 0xc8, 0xc9, 0x04, 0xf0, 0xa8, 0x91, 0xe0, 100 | 0xa5, 0xca, 0xf1, 0xe0, 0x85, 0xe4, 0xa5, 0xcb, 101 | 0xe9, 0x00, 0x85, 0xe5, 0xa5, 0xe4, 0xc5, 0xcc, 102 | 0xa5, 0xe5, 0xe5, 0xcd, 0x90, 0x45, 0xa5, 0xca, 103 | 0xf1, 0xe0, 0x85, 0xe6, 0xa5, 0xcb, 0xe9, 0x00, 104 | 0x85, 0xe7, 0xb1, 0xca, 0x91, 0xe6, 0xe6, 0xca, 105 | 0xd0, 0x02, 0xe6, 0xcb, 0xa5, 0xe2, 0xc5, 0xca, 106 | 0xa5, 0xe3, 0xe5, 0xcb, 0xb0, 0xe0, 0xb5, 0xe4, 107 | 0x95, 0xca, 0xca, 0x10, 0xf9, 0xb1, 0xe0, 0xa8, 108 | 0x88, 0xb1, 0xe0, 0x91, 0xe6, 0x98, 0xd0, 0xf8, 109 | 0x24, 0xf8, 0x10, 0x09, 0xb5, 0xf7, 0x75, 0xf5, 110 | 0x95, 0xf7, 0xe8, 0xf0, 0xf7, 0x10, 0x7e, 0x00, 111 | 0x00, 0x00, 0x00, 0xa0, 0x14, 0xd0, 0x71, 0x20, 112 | 0x15, 0xe7, 0xa5, 0xe2, 0x85, 0xe6, 0xa5, 0xe3, 113 | 0x85, 0xe7, 0x20, 0x75, 0xe5, 0xa5, 0xe2, 0x85, 114 | 0xe4, 0xa5, 0xe3, 0x85, 0xe5, 0xd0, 0x0e, 0x20, 115 | 0x15, 0xe7, 0x20, 0x6d, 0xe5, 0xa5, 0xe6, 0x85, 116 | 0xe2, 0xa5, 0xe7, 0x85, 0xe3, 0xa0, 0x00, 0xa5, 117 | 0xca, 0xc5, 0xe4, 0xa5, 0xcb, 0xe5, 0xe5, 0xb0, 118 | 0x16, 0xa5, 0xe4, 0xd0, 0x02, 0xc6, 0xe5, 0xc6, 119 | 0xe4, 0xa5, 0xe6, 0xd0, 0x02, 0xc6, 0xe7, 0xc6, 120 | 0xe6, 0xb1, 0xe4, 0x91, 0xe6, 0x90, 0xe0, 0xa5, 121 | 0xe6, 0x85, 0xca, 0xa5, 0xe7, 0x85, 0xcb, 0x60, 122 | 0x20, 0xed, 0xfd, 0xc8, 0xb9, 0x00, 0xeb, 0x30, 123 | 0xf7, 0x09, 0x80, 0x4c, 0xed, 0xfd, 0x98, 0xaa, 124 | 0x20, 0x75, 0xfd, 0x8a, 0xa8, 0xa9, 0xdf, 0x99, 125 | 0x00, 0x02, 0xa2, 0xff, 0x60, 0x60, 0xa0, 0x06, 126 | 0x20, 0xd3, 0xee, 0x24, 0xd9, 0x30, 0x03, 0x4c, 127 | 0xb6, 0xe2, 0x4c, 0x9a, 0xeb, 0x2a, 0x69, 0xa0, 128 | 0xdd, 0x00, 0x02, 0xd0, 0x53, 0xb1, 0xfe, 0x0a, 129 | 0x30, 0x06, 0x88, 0xb1, 0xfe, 0x30, 0x29, 0xc8, 130 | 0x86, 0xc8, 0x98, 0x48, 0xa2, 0x00, 0xa1, 0xfe, 131 | 0xaa, 0x4a, 0x49, 0x40, 0x11, 0xfe, 0xc9, 0xc0, 132 | 0x90, 0x01, 0xe8, 0xc8, 0xd0, 0xf3, 0x68, 0xa8, 133 | 0x8a, 0x4c, 0xf8, 0xf2, 0xe6, 0xf1, 0xa6, 0xf1, 134 | 0xf0, 0xbc, 0x9d, 0x00, 0x02, 0x60, 0xa6, 0xc8, 135 | 0xa9, 0xa0, 0xe8, 0xdd, 0x00, 0x02, 0xb0, 0xfa, 136 | 0xb1, 0xfe, 0x29, 0x3f, 0x4a, 0xd0, 0xb6, 0xbd, 137 | 0x00, 0x02, 0xb0, 0x06, 0x69, 0x3f, 0xc9, 0x1a, 138 | 0x90, 0x6f, 0x69, 0x4f, 0xc9, 0x0a, 0x90, 0x69, 139 | 0xa6, 0xfd, 0xc8, 0xb1, 0xfe, 0x29, 0xe0, 0xc9, 140 | 0x20, 0xf0, 0x7a, 0xb5, 0xa8, 0x85, 0xc8, 0xb5, 141 | 0xd1, 0x85, 0xf1, 0x88, 0xb1, 0xfe, 0x0a, 0x10, 142 | 0xfa, 0x88, 0xb0, 0x38, 0x0a, 0x30, 0x35, 0xb4, 143 | 0x58, 0x84, 0xff, 0xb4, 0x80, 0xe8, 0x10, 0xda, 144 | 0xf0, 0xb3, 0xc9, 0x7e, 0xb0, 0x22, 0xca, 0x10, 145 | 0x04, 0xa0, 0x06, 0x10, 0x29, 0x94, 0x80, 0xa4, 146 | 0xff, 0x94, 0x58, 0xa4, 0xc8, 0x94, 0xa8, 0xa4, 147 | 0xf1, 0x94, 0xd1, 0x29, 0x1f, 0xa8, 0xb9, 0x97, 148 | 0xf1, 0x0a, 0xa8, 0xa9, 0x76, 0x2a, 0x85, 0xff, 149 | 0xd0, 0x01, 0xc8, 0xc8, 0x86, 0xfd, 0xb1, 0xfe, 150 | 0x30, 0x84, 0xd0, 0x05, 0xa0, 0x0e, 0x4c, 0xe0, 151 | 0xe3, 0xc9, 0x03, 0xb0, 0xc3, 0x4a, 0xa6, 0xc8, 152 | 0xe8, 0xbd, 0x00, 0x02, 0x90, 0x04, 0xc9, 0xa2, 153 | 0xf0, 0x0a, 0xc9, 0xdf, 0xf0, 0x06, 0x86, 0xc8, 154 | 0x20, 0x1c, 0xe4, 0xc8, 0x88, 0xa6, 0xfd, 0xb1, 155 | 0xfe, 0x88, 0x0a, 0x10, 0xcf, 0xb4, 0x58, 0x84, 156 | 0xff, 0xb4, 0x80, 0xe8, 0xb1, 0xfe, 0x29, 0x9f, 157 | 0xd0, 0xed, 0x85, 0xf2, 0x85, 0xf3, 0x98, 0x48, 158 | 0x86, 0xfd, 0xb4, 0xd0, 0x84, 0xc9, 0x18, 0xa9, 159 | 0x0a, 0x85, 0xf9, 0xa2, 0x00, 0xc8, 0xb9, 0x00, 160 | 0x02, 0x29, 0x0f, 0x65, 0xf2, 0x48, 0x8a, 0x65, 161 | 0xf3, 0x30, 0x1c, 0xaa, 0x68, 0xc6, 0xf9, 0xd0, 162 | 0xf2, 0x85, 0xf2, 0x86, 0xf3, 0xc4, 0xf1, 0xd0, 163 | 0xde, 0xa4, 0xc9, 0xc8, 0x84, 0xf1, 0x20, 0x1c, 164 | 0xe4, 0x68, 0xa8, 0xa5, 0xf3, 0xb0, 0xa9, 0xa0, 165 | 0x00, 0x10, 0x8b, 0x85, 0xf3, 0x86, 0xf2, 0xa2, 166 | 0x04, 0x86, 0xc9, 0xa9, 0xb0, 0x85, 0xf9, 0xa5, 167 | 0xf2, 0xdd, 0x63, 0xe5, 0xa5, 0xf3, 0xfd, 0x68, 168 | 0xe5, 0x90, 0x0d, 0x85, 0xf3, 0xa5, 0xf2, 0xfd, 169 | 0x63, 0xe5, 0x85, 0xf2, 0xe6, 0xf9, 0xd0, 0xe7, 170 | 0xa5, 0xf9, 0xe8, 0xca, 0xf0, 0x0e, 0xc9, 0xb0, 171 | 0xf0, 0x02, 0x85, 0xc9, 0x24, 0xc9, 0x30, 0x04, 172 | 0xa5, 0xfa, 0xf0, 0x0b, 0x20, 0xed, 0xfd, 0x24, 173 | 0xf8, 0x10, 0x04, 0x99, 0x00, 0x02, 0xc8, 0xca, 174 | 0x10, 0xc1, 0x60, 0x01, 0x0a, 0x64, 0xe8, 0x10, 175 | 0x00, 0x00, 0x00, 0x03, 0x27, 0xa5, 0xca, 0x85, 176 | 0xe6, 0xa5, 0xcb, 0x85, 0xe7, 0xe8, 0xa5, 0xe7, 177 | 0x85, 0xe5, 0xa5, 0xe6, 0x85, 0xe4, 0xc5, 0x4c, 178 | 0xa5, 0xe5, 0xe5, 0x4d, 0xb0, 0x26, 0xa0, 0x01, 179 | 0xb1, 0xe4, 0xe5, 0xce, 0xc8, 0xb1, 0xe4, 0xe5, 180 | 0xcf, 0xb0, 0x19, 0xa0, 0x00, 0xa5, 0xe6, 0x71, 181 | 0xe4, 0x85, 0xe6, 0x90, 0x03, 0xe6, 0xe7, 0x18, 182 | 0xc8, 0xa5, 0xce, 0xf1, 0xe4, 0xc8, 0xa5, 0xcf, 183 | 0xf1, 0xe4, 0xb0, 0xca, 0x60, 0x46, 0xf8, 0xa5, 184 | 0x4c, 0x85, 0xca, 0xa5, 0x4d, 0x85, 0xcb, 0xa5, 185 | 0x4a, 0x85, 0xcc, 0xa5, 0x4b, 0x85, 0xcd, 0xa9, 186 | 0x00, 0x85, 0xfb, 0x85, 0xfc, 0x85, 0xfe, 0xa9, 187 | 0x00, 0x85, 0x1d, 0x60, 0xa5, 0xd0, 0x4c, 0x6b, 188 | 0xe3, 0xa0, 0xff, 0x84, 0xd8, 0xc8, 0xb1, 0xe0, 189 | 0x30, 0x06, 0xc9, 0x40, 0xd0, 0x68, 0x85, 0xd8, 190 | 0xd1, 0xd0, 0xf0, 0xf1, 0xb1, 0xd0, 0xc8, 0x4a, 191 | 0xd0, 0xfa, 0xb1, 0xd0, 0x48, 0xc8, 0xb1, 0xd0, 192 | 0xa8, 0x68, 0x85, 0xd0, 0x84, 0xd1, 0xc5, 0xcc, 193 | 0xd0, 0xd7, 0xc4, 0xcd, 0xd0, 0xd3, 0xa0, 0x00, 194 | 0xc8, 0xb1, 0xe0, 0x30, 0xfb, 0x49, 0x40, 0xf0, 195 | 0xf7, 0x98, 0x69, 0x04, 0x48, 0x65, 0xd0, 0xa8, 196 | 0xa5, 0xd1, 0x69, 0x00, 0x48, 0xc4, 0xca, 0xe5, 197 | 0xcb, 0xb0, 0xb3, 0x84, 0xcc, 0x68, 0x85, 0xcd, 198 | 0x68, 0xa8, 0xa9, 0x00, 0x88, 0x91, 0xd0, 0x88, 199 | 0x91, 0xd0, 0x88, 0xa5, 0xcd, 0x91, 0xd0, 0x88, 200 | 0xa5, 0xcc, 0x91, 0xd0, 0x88, 0xa9, 0x00, 0x91, 201 | 0xd0, 0x88, 0x30, 0x97, 0xb1, 0xe0, 0xd0, 0xf7, 202 | 0xa5, 0x4a, 0xa4, 0x4b, 0xd0, 0xac, 0xb1, 0xd0, 203 | 0xc9, 0x40, 0xb0, 0x9a, 0x95, 0x9f, 0x98, 0x69, 204 | 0x03, 0x48, 0x65, 0xd0, 0x20, 0x0a, 0xe7, 0x20, 205 | 0xff, 0xe6, 0x88, 0xd0, 0xfa, 0x98, 0x65, 0xd1, 206 | 0x95, 0x78, 0x68, 0x24, 0xd8, 0x30, 0x1d, 0xa8, 207 | 0xa9, 0x00, 0x20, 0x0a, 0xe7, 0x95, 0x78, 0xb1, 208 | 0xd0, 0x10, 0x0f, 0xf6, 0x78, 0xc8, 0xd0, 0xf7, 209 | 0x09, 0xa9, 0x00, 0x85, 0xd4, 0x85, 0xd5, 0xa2, 210 | 0x20, 0x48, 0xa0, 0x00, 0xb1, 0xe0, 0x10, 0x18, 211 | 0x0a, 0x30, 0xb5, 0x20, 0xff, 0xe6, 0x20, 0x08, 212 | 0xe7, 0x20, 0xff, 0xe6, 0x95, 0xa0, 0x24, 0xd4, 213 | 0x10, 0x01, 0xca, 0x20, 0xff, 0xe6, 0xb0, 0xe6, 214 | 0xc9, 0x28, 0xd0, 0x1f, 0xa5, 0xe0, 0x20, 0x0a, 215 | 0xe7, 0xa5, 0xe1, 0x95, 0x78, 0x24, 0xd4, 0x30, 216 | 0x0b, 0xa9, 0x01, 0x20, 0x0a, 0xe7, 0xa9, 0x00, 217 | 0x95, 0x78, 0xf6, 0x78, 0x20, 0xff, 0xe6, 0x30, 218 | 0xf9, 0xb0, 0xd3, 0x24, 0xd4, 0x10, 0x06, 0xc9, 219 | 0x04, 0xb0, 0xd0, 0x46, 0xd4, 0xa8, 0x85, 0xd6, 220 | 0xb9, 0x80, 0xe9, 0x29, 0x55, 0x0a, 0x85, 0xd7, 221 | 0x68, 0xa8, 0xb9, 0x80, 0xe9, 0x29, 0xaa, 0xc5, 222 | 0xd7, 0xb0, 0x09, 0x98, 0x48, 0x20, 0xeb, 0xf3, 223 | 0xa5, 0xd6, 0x90, 0x95, 0xb9, 0x00, 0xea, 0x85, 224 | 0xce, 0xb9, 0x80, 0xea, 0x85, 0xcf, 0x20, 0xfc, 225 | 0xe6, 0x4c, 0xd8, 0xe6, 0x6c, 0xce, 0x00, 0xe6, 226 | 0xe0, 0xd0, 0x02, 0xe6, 0xe1, 0xb1, 0xe0, 0x60, 227 | 0x94, 0x77, 0xca, 0x30, 0x03, 0x95, 0x50, 0x60, 228 | 0xa0, 0x66, 0x4c, 0xe0, 0xe3, 0xa0, 0x00, 0xb5, 229 | 0x50, 0x85, 0xce, 0xb5, 0xa0, 0x85, 0xcf, 0xb5, 230 | 0x78, 0xf0, 0x0e, 0x85, 0xcf, 0xb1, 0xce, 0x48, 231 | 0xc8, 0xb1, 0xce, 0x85, 0xcf, 0x68, 0x85, 0xce, 232 | 0x88, 0xe8, 0x60, 0x20, 0x4a, 0xe7, 0x20, 0x15, 233 | 0xe7, 0x98, 0x20, 0x08, 0xe7, 0x95, 0xa0, 0xc5, 234 | 0xce, 0xd0, 0x06, 0xc5, 0xcf, 0xd0, 0x02, 0xf6, 235 | 0x50, 0x60, 0x20, 0x82, 0xe7, 0x20, 0x59, 0xe7, 236 | 0x20, 0x15, 0xe7, 0x24, 0xcf, 0x30, 0x1b, 0xca, 237 | 0x60, 0x20, 0x15, 0xe7, 0xa5, 0xcf, 0xd0, 0x04, 238 | 0xa5, 0xce, 0xf0, 0xf3, 0xa9, 0xff, 0x20, 0x08, 239 | 0xe7, 0x95, 0xa0, 0x24, 0xcf, 0x30, 0xe9, 0x20, 240 | 0x15, 0xe7, 0x98, 0x38, 0xe5, 0xce, 0x20, 0x08, 241 | 0xe7, 0x98, 0xe5, 0xcf, 0x50, 0x23, 0xa0, 0x00, 242 | 0x10, 0x90, 0x20, 0x6f, 0xe7, 0x20, 0x15, 0xe7, 243 | 0xa5, 0xce, 0x85, 0xda, 0xa5, 0xcf, 0x85, 0xdb, 244 | 0x20, 0x15, 0xe7, 0x18, 0xa5, 0xce, 0x65, 0xda, 245 | 0x20, 0x08, 0xe7, 0xa5, 0xcf, 0x65, 0xdb, 0x70, 246 | 0xdd, 0x95, 0xa0, 0x60, 0x20, 0x34, 0xee, 0xa8, 247 | 0xd0, 0x03, 0x4c, 0xcb, 0xee, 0x88, 0x4c, 0xf4, 248 | 0xf3, 0xa5, 0x24, 0x09, 0x07, 0xa8, 0xc8, 0xd0, 249 | 0xf5, 0xc8, 0xd0, 0xf5, 0xb0, 0xf9, 0x60, 0x00, 250 | 0x00, 0x20, 0xb1, 0xe7, 0x20, 0x15, 0xe7, 0xa5, 251 | 0xcf, 0x10, 0x0a, 0xa9, 0xad, 0x20, 0xed, 0xfd, 252 | 0x20, 0x72, 0xe7, 0x50, 0xef, 0x88, 0x84, 0xd5, 253 | 0x86, 0xcf, 0xa6, 0xce, 0x20, 0x1b, 0xe5, 0xa6, 254 | 0xcf, 0x60, 0x20, 0x15, 0xe7, 0xa5, 0xce, 0x85, 255 | 0xf6, 0xa5, 0xcf, 0x85, 0xf7, 0x88, 0x84, 0xf8, 256 | 0xc8, 0xa9, 0x0a, 0x85, 0xf4, 0x84, 0xf5, 0x60, 257 | 0x20, 0x15, 0xe7, 0xa5, 0xce, 0xa4, 0xcf, 0x10, 258 | 0xf2, 0x20, 0x15, 0xe7, 0xb5, 0x50, 0x85, 0xda, 259 | 0xb5, 0x78, 0x85, 0xdb, 0xa5, 0xce, 0x91, 0xda, 260 | 0xc8, 0xa5, 0xcf, 0x4c, 0x07, 0xf2, 0x60, 0x68, 261 | 0x68, 0x24, 0xd5, 0x10, 0x05, 0x20, 0x8e, 0xfd, 262 | 0x46, 0xd5, 0x60, 0xa0, 0xff, 0x84, 0xd7, 0x60, 263 | 0x20, 0xcd, 0xef, 0xf0, 0x07, 0xa9, 0x25, 0x85, 264 | 0xd6, 0x88, 0x84, 0xd4, 0xe8, 0x60, 0xa5, 0xca, 265 | 0xa4, 0xcb, 0xd0, 0x5a, 0xa0, 0x41, 0xa5, 0xfc, 266 | 0xc9, 0x10, 0xb0, 0x5e, 0xa8, 0xe6, 0xfc, 0xa5, 267 | 0xe0, 0x99, 0x00, 0x01, 0xa5, 0xe1, 0x99, 0x10, 268 | 0x01, 0xa5, 0xdc, 0x99, 0x20, 0x01, 0xa5, 0xdd, 269 | 0x99, 0x30, 0x01, 0x20, 0x15, 0xe7, 0x20, 0x6d, 270 | 0xe5, 0x90, 0x04, 0xa0, 0x37, 0xd0, 0x3b, 0xa5, 271 | 0xe4, 0xa4, 0xe5, 0x85, 0xdc, 0x84, 0xdd, 0x18, 272 | 0x69, 0x03, 0x90, 0x01, 0xc8, 0xa2, 0xff, 0x86, 273 | 0xd9, 0x9a, 0x85, 0xe0, 0x84, 0xe1, 0x20, 0x2e, 274 | 0xf0, 0xa0, 0x00, 0x20, 0x79, 0xe6, 0x24, 0xd9, 275 | 0x10, 0x49, 0x18, 0xa0, 0x00, 0xa5, 0xdc, 0x71, 276 | 0xdc, 0xa4, 0xdd, 0x90, 0x01, 0xc8, 0xc5, 0x4c, 277 | 0xd0, 0xd1, 0xc4, 0x4d, 0xd0, 0xcd, 0xa0, 0x31, 278 | 0x46, 0xd9, 0x4c, 0xe0, 0xe3, 0xa0, 0x4a, 0xa5, 279 | 0xfc, 0xf0, 0xf7, 0xc6, 0xfc, 0xa8, 0xb9, 0x1f, 280 | 0x01, 0x85, 0xdc, 0xb9, 0x2f, 0x01, 0x85, 0xdd, 281 | 0xbe, 0xff, 0x00, 0xb9, 0x0f, 0x01, 0xa8, 0x8a, 282 | 0x4c, 0x75, 0xe8, 0xa0, 0x63, 0x20, 0xc4, 0xe3, 283 | 0xa0, 0x01, 0xb1, 0xdc, 0xaa, 0xc8, 0xb1, 0xdc, 284 | 0x20, 0x1b, 0xe5, 0x4c, 0xb3, 0xe2, 0xc6, 0xfb, 285 | 0xa0, 0x5b, 0xa5, 0xfb, 0xf0, 0xc4, 0xa8, 0xb5, 286 | 0x50, 0xd9, 0x3f, 0x01, 0xd0, 0xf0, 0xb5, 0x78, 287 | 0xd9, 0x4f, 0x01, 0xd0, 0xe9, 0xb9, 0x5f, 0x01, 288 | 0x85, 0xda, 0xb9, 0x6f, 0x01, 0x85, 0xdb, 0x20, 289 | 0x15, 0xe7, 0xca, 0x20, 0x93, 0xe7, 0x20, 0x01, 290 | 0xe8, 0xca, 0xa4, 0xfb, 0xb9, 0xcf, 0x01, 0x95, 291 | 0x9f, 0xb9, 0xbf, 0x01, 0xa0, 0x00, 0x20, 0x08, 292 | 0xe7, 0x20, 0x82, 0xe7, 0x20, 0x59, 0xe7, 0x20, 293 | 0x15, 0xe7, 0xa4, 0xfb, 0xa5, 0xce, 0xf0, 0x05, 294 | 0x59, 0x6f, 0x01, 0x10, 0x12, 0xb9, 0x7f, 0x01, 295 | 0x85, 0xdc, 0xb9, 0x8f, 0x01, 0x85, 0xdd, 0xbe, 296 | 0x9f, 0x01, 0xb9, 0xaf, 0x01, 0xd0, 0x87, 0xc6, 297 | 0xfb, 0x60, 0xa0, 0x54, 0xa5, 0xfb, 0xc9, 0x10, 298 | 0xf0, 0x9a, 0xe6, 0xfb, 0xa8, 0xb5, 0x50, 0x99, 299 | 0x40, 0x01, 0xb5, 0x78, 0x4c, 0x88, 0xf2, 0x60, 300 | 0x20, 0x15, 0xe7, 0xa4, 0xfb, 0xa5, 0xce, 0x99, 301 | 0xbf, 0x01, 0xa5, 0xcf, 0x99, 0xcf, 0x01, 0xa9, 302 | 0x01, 0x99, 0x5f, 0x01, 0xa9, 0x00, 0x99, 0x6f, 303 | 0x01, 0xa5, 0xdc, 0x99, 0x7f, 0x01, 0xa5, 0xdd, 304 | 0x99, 0x8f, 0x01, 0xa5, 0xe0, 0x99, 0x9f, 0x01, 305 | 0xa5, 0xe1, 0x99, 0xaf, 0x01, 0x60, 0x20, 0x15, 306 | 0x00, 0x00, 0x00, 0xab, 0x03, 0x03, 0x03, 0x03, 307 | 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 308 | 0x03, 0x03, 0x3f, 0x3f, 0xc0, 0xc0, 0x3c, 0x3c, 309 | 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x30, 0x0f, 0xc0, 310 | 0xc3, 0xff, 0x55, 0x00, 0xab, 0xab, 0x03, 0x03, 311 | 0xff, 0xff, 0x55, 0xff, 0xff, 0x55, 0xcf, 0xcf, 312 | 0xcf, 0xcf, 0xcf, 0xff, 0x55, 0xc6, 0xc6, 0xc6, 313 | 0x55, 0xf0, 0xf0, 0xcf, 0xcf, 0x55, 0x01, 0x55, 314 | 0xff, 0xff, 0x55, 0x03, 0x03, 0x03, 0x03, 0x03, 315 | 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 316 | 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 317 | 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0xab, 0x03, 318 | 0x57, 0x03, 0x03, 0x03, 0x03, 0x07, 0x03, 0x03, 319 | 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 320 | 0x03, 0x03, 0xaa, 0xff, 0x03, 0x03, 0x03, 0x03, 321 | 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 322 | 0x17, 0xff, 0xff, 0x19, 0xdf, 0x42, 0x0a, 0xf2, 323 | 0xec, 0x87, 0x6f, 0xad, 0xb7, 0xe2, 0xf8, 0x54, 324 | 0x4d, 0xc9, 0x85, 0x82, 0x22, 0x10, 0x33, 0x4a, 325 | 0x5b, 0x4e, 0x53, 0x4a, 0x49, 0x66, 0x6d, 0x7a, 326 | 0x71, 0xff, 0x23, 0x09, 0x5b, 0x16, 0xb6, 0xcb, 327 | 0xff, 0xff, 0xfb, 0xff, 0xff, 0x24, 0xf6, 0x4e, 328 | 0x59, 0x50, 0x3b, 0xff, 0x23, 0xa3, 0x6f, 0x36, 329 | 0x23, 0xd7, 0x1c, 0x22, 0x1d, 0x8a, 0xab, 0x23, 330 | 0xff, 0xff, 0x21, 0x30, 0x1e, 0x03, 0xc4, 0x20, 331 | 0x00, 0xc1, 0xba, 0x39, 0x40, 0xa0, 0x30, 0x1e, 332 | 0xa4, 0xd3, 0xb6, 0xbc, 0xaa, 0x3a, 0x01, 0x50, 333 | 0x79, 0xd8, 0xd8, 0xa5, 0x3c, 0xff, 0x16, 0x5b, 334 | 0x28, 0x03, 0xc4, 0x1d, 0x08, 0x00, 0x4e, 0x00, 335 | 0x3e, 0x00, 0xa6, 0xb0, 0x00, 0xbc, 0xc6, 0x57, 336 | 0x8c, 0x01, 0x27, 0xff, 0x5d, 0x35, 0x4b, 0x67, 337 | 0xe0, 0xe1, 0x76, 0x04, 0x05, 0x71, 0xc9, 0x1a, 338 | 0xe8, 0xff, 0xff, 0xe8, 0xf0, 0xf1, 0xf3, 0xef, 339 | 0xef, 0xe3, 0xe3, 0xe5, 0xe5, 0xe7, 0xe7, 0xee, 340 | 0xf0, 0xf0, 0xe7, 0xe7, 0xe2, 0xef, 0xe7, 0xe7, 341 | 0xf2, 0xf2, 0xf2, 0xe7, 0xf2, 0xf2, 0xf2, 0xe2, 342 | 0xf3, 0xff, 0xe8, 0xe1, 0xe8, 0xe8, 0xef, 0xeb, 343 | 0xff, 0xff, 0xe0, 0xff, 0xff, 0xef, 0xee, 0xef, 344 | 0xe7, 0xe7, 0xf3, 0xff, 0xe8, 0xe7, 0xe7, 0xe7, 345 | 0xe8, 0xe1, 0xe2, 0xee, 0xf3, 0xe2, 0xe2, 0xe8, 346 | 0xff, 0xff, 0xe1, 0xe1, 0xef, 0xee, 0xe7, 0xe8, 347 | 0xee, 0xe7, 0xf3, 0xfb, 0xfb, 0xee, 0xe1, 0xef, 348 | 0xe7, 0xe8, 0xef, 0xef, 0xeb, 0xe9, 0xe8, 0xe9, 349 | 0xf2, 0xe8, 0xe8, 0xe8, 0xe8, 0xff, 0xe8, 0xe8, 350 | 0xe8, 0xee, 0xe7, 0xe8, 0xef, 0xef, 0xee, 0xef, 351 | 0xee, 0xef, 0xee, 0xee, 0xef, 0xee, 0xee, 0xee, 352 | 0xe1, 0xe8, 0xe8, 0xff, 0xe0, 0xe0, 0xe0, 0xf1, 353 | 0xf2, 0xf2, 0xf1, 0xf3, 0xf3, 0xf1, 0xf3, 0xf4, 354 | 0xbe, 0xb3, 0xb2, 0xb7, 0xb6, 0x37, 0xd4, 0xcf, 355 | 0xcf, 0xa0, 0xcc, 0xcf, 0xce, 0x47, 0xd3, 0xd9, 356 | 0xce, 0xd4, 0xc1, 0x58, 0xcd, 0xc5, 0xcd, 0xa0, 357 | 0xc6, 0xd5, 0xcc, 0x4c, 0xd4, 0xcf, 0xcf, 0xa0, 358 | 0xcd, 0xc1, 0xce, 0xd9, 0xa0, 0xd0, 0xc1, 0xd2, 359 | 0xc5, 0xce, 0x53, 0xd3, 0xd4, 0xd2, 0xc9, 0xce, 360 | 0x47, 0xce, 0xcf, 0xa0, 0xc5, 0xce, 0x44, 0xc2, 361 | 0xc1, 0xc4, 0xa0, 0xc2, 0xd2, 0xc1, 0xce, 0xc3, 362 | 0x48, 0xb1, 0xb6, 0xa0, 0xc7, 0xcf, 0xd3, 0xd5, 363 | 0xc2, 0x53, 0xc2, 0xc1, 0xc4, 0xa0, 0xd2, 0xc5, 364 | 0xd4, 0xd5, 0xd2, 0x4e, 0xb1, 0xb6, 0xa0, 0xc6, 365 | 0xcf, 0xd2, 0x53, 0xc2, 0xc1, 0xc4, 0xa0, 0xce, 366 | 0xc5, 0xd8, 0x54, 0xd3, 0xd4, 0xcf, 0xd0, 0xd0, 367 | 0xc5, 0xc4, 0xa0, 0xc1, 0xd4, 0x20, 0xaa, 0xaa, 368 | 0xaa, 0x20, 0xa0, 0xc5, 0xd2, 0xd2, 0x0d, 0xbe, 369 | 0xb2, 0xb5, 0x35, 0xd2, 0xc1, 0xce, 0xc7, 0x45, 370 | 0xc4, 0xc9, 0x4d, 0xd3, 0xd4, 0xd2, 0xa0, 0xcf, 371 | 0xd6, 0xc6, 0x4c, 0xdc, 0x0d, 0xd2, 0xc5, 0xd4, 372 | 0xd9, 0xd0, 0xc5, 0xa0, 0xcc, 0xc9, 0xce, 0xc5, 373 | 0x8d, 0x3f, 0x46, 0xd9, 0x90, 0x03, 0x4c, 0xc3, 374 | 0xe8, 0xa6, 0xcf, 0x9a, 0xa6, 0xce, 0xa0, 0x8d, 375 | 0xd0, 0x02, 0xa0, 0x99, 0x20, 0xc4, 0xe3, 0x86, 376 | 0xce, 0xba, 0x86, 0xcf, 0x20, 0x66, 0xf3, 0x84, 377 | 0xf1, 0xa9, 0xff, 0x85, 0xc8, 0x0a, 0x85, 0xd9, 378 | 0xa2, 0x20, 0xa9, 0x15, 0x20, 0x91, 0xe4, 0xe6, 379 | 0xd9, 0xa6, 0xce, 0xa4, 0xc8, 0x0a, 0x85, 0xce, 380 | 0xc8, 0xb9, 0x00, 0x02, 0xc9, 0x80, 0xf0, 0xd2, 381 | 0x49, 0xb0, 0xc9, 0x0a, 0xb0, 0xf0, 0xc8, 0xc8, 382 | 0x84, 0xc8, 0xb9, 0x00, 0x02, 0x48, 0xb9, 0xff, 383 | 0x01, 0xa0, 0x00, 0x20, 0x08, 0xe7, 0x68, 0x95, 384 | 0xa0, 0xa5, 0xce, 0xc9, 0x33, 0xd0, 0x03, 0x20, 385 | 0x6f, 0xe7, 0x4c, 0x01, 0xe8, 0xff, 0xff, 0xff, 386 | 0x50, 0x20, 0x4f, 0xc0, 0xf4, 0xa1, 0xe4, 0xaf, 387 | 0xad, 0xf2, 0xaf, 0xe4, 0xae, 0xa1, 0xf0, 0xa5, 388 | 0xb4, 0xb3, 0xef, 0xb4, 0xee, 0xa5, 0xa8, 0xb4, 389 | 0x5c, 0x80, 0x00, 0x40, 0x60, 0x8d, 0x60, 0x8b, 390 | 0x7f, 0x1d, 0x20, 0x7e, 0x8c, 0x33, 0x00, 0x00, 391 | 0x60, 0x03, 0xbf, 0x12, 0x47, 0x83, 0xae, 0xa9, 392 | 0x67, 0x83, 0xb2, 0xb0, 0xe5, 0xa3, 0xa1, 0xb2, 393 | 0xb4, 0x79, 0xb0, 0xb3, 0xa4, 0x69, 0xb0, 0xb3, 394 | 0xa4, 0xe5, 0xa3, 0xa1, 0xb2, 0xb4, 0xaf, 0xae, 395 | 0x79, 0xb0, 0xb3, 0xa4, 0xaf, 0xae, 0x69, 0xb0, 396 | 0xb3, 0xa4, 0xaf, 0xae, 0xf0, 0xaf, 0xb0, 0xf4, 397 | 0xb3, 0xa9, 0xac, 0x60, 0x8c, 0x20, 0xb4, 0xb3, 398 | 0xa9, 0xac, 0x00, 0x40, 0x89, 0xc9, 0x47, 0x9d, 399 | 0x17, 0x68, 0x9d, 0x0a, 0x58, 0x7b, 0x67, 0xa2, 400 | 0xa1, 0xb4, 0xb6, 0x67, 0xb4, 0xa1, 0x07, 0x8c, 401 | 0x07, 0xae, 0xa9, 0xac, 0xb6, 0x67, 0xb4, 0xa1, 402 | 0x07, 0x8c, 0x07, 0xae, 0xa9, 0xac, 0xa8, 0x67, 403 | 0x8c, 0x07, 0xb4, 0xaf, 0xac, 0xb0, 0x67, 0x9d, 404 | 0xb2, 0xaf, 0xac, 0xaf, 0xa3, 0x67, 0x8c, 0x07, 405 | 0xa5, 0xab, 0xaf, 0xb0, 0xf4, 0xae, 0xa9, 0xb2, 406 | 0xb0, 0x7f, 0x0e, 0x27, 0xb4, 0xae, 0xa9, 0xb2, 407 | 0xb0, 0x7f, 0x0e, 0x28, 0xb4, 0xae, 0xa9, 0xb2, 408 | 0xb0, 0x64, 0x07, 0xa6, 0xa9, 0x67, 0xaf, 0xb4, 409 | 0xaf, 0xa7, 0x78, 0xb4, 0xa5, 0xac, 0x6b, 0x7f, 410 | 0x02, 0xad, 0xa5, 0xb2, 0x67, 0xa2, 0xb5, 0xb3, 411 | 0xaf, 0xa7, 0xee, 0xb2, 0xb5, 0xb4, 0xa5, 0xb2, 412 | 0x7e, 0x8c, 0x39, 0xb4, 0xb8, 0xa5, 0xae, 0x67, 413 | 0xb0, 0xa5, 0xb4, 0xb3, 0x27, 0xaf, 0xb4, 0x07, 414 | 0x9d, 0x19, 0xb2, 0xaf, 0xa6, 0x7f, 0x05, 0x37, 415 | 0xb4, 0xb5, 0xb0, 0xae, 0xa9, 0x7f, 0x05, 0x28, 416 | 0xb4, 0xb5, 0xb0, 0xae, 0xa9, 0x7f, 0x05, 0x2a, 417 | 0xb4, 0xb5, 0xb0, 0xae, 0xa9, 0xe4, 0xae, 0xa5, 418 | 0x00, 0x47, 0xa2, 0xa1, 0xb4, 0x7f, 0x0d, 0x30, 419 | 0xad, 0xa9, 0xa4, 0x7f, 0x0d, 0x23, 0xad, 0xa9, 420 | 0xa4, 0x67, 0xac, 0xac, 0xa1, 0xa3, 0xf2, 0xa7, 421 | 0xf4, 0xb8, 0xa5, 0xb4, 0x00, 0x4d, 0xcc, 0x67, 422 | 0x8c, 0x68, 0x8c, 0xdb, 0x67, 0x9b, 0x68, 0x9b, 423 | 0x50, 0x8c, 0x63, 0x8c, 0x7f, 0x01, 0x51, 0x07, 424 | 0x88, 0x29, 0x84, 0x80, 0xc4, 0x19, 0x57, 0x71, 425 | 0x07, 0x88, 0x14, 0x71, 0x07, 0x8c, 0x07, 0x88, 426 | 0xae, 0xb2, 0xa3, 0xb3, 0x71, 0x08, 0x88, 0xa3, 427 | 0xb3, 0xa1, 0x71, 0x08, 0x88, 0xae, 0xa5, 0xac, 428 | 0x68, 0x83, 0x08, 0x68, 0x9d, 0x08, 0x71, 0x07, 429 | 0x88, 0x60, 0x75, 0xb4, 0xaf, 0xae, 0x75, 0x8d, 430 | 0x75, 0x8b, 0x51, 0x07, 0x88, 0x19, 0xb8, 0xa4, 431 | 0xae, 0xb2, 0xec, 0xa4, 0xb0, 0xf3, 0xa2, 0xa1, 432 | 0xee, 0xa7, 0xb3, 0xe4, 0xae, 0xb2, 0xeb, 0xa5, 433 | 0xa5, 0xb0, 0x51, 0x07, 0x88, 0x39, 0x81, 0xc1, 434 | 0x4f, 0x7f, 0x0f, 0x2f, 0x00, 0x51, 0x06, 0x88, 435 | 0x29, 0xc2, 0x0c, 0x82, 0x57, 0x8c, 0x6a, 0x8c, 436 | 0x42, 0xae, 0xa5, 0xa8, 0xb4, 0x60, 0xae, 0xa5, 437 | 0xa8, 0xb4, 0x4f, 0x7e, 0x1e, 0x35, 0x8c, 0x27, 438 | 0x51, 0x07, 0x88, 0x09, 0x8b, 0xfe, 0xe4, 0xaf, 439 | 0xad, 0xf2, 0xaf, 0xe4, 0xae, 0xa1, 0xdc, 0xde, 440 | 0x9c, 0xdd, 0x9c, 0xde, 0xdd, 0x9e, 0xc3, 0xdd, 441 | 0xcf, 0xca, 0xcd, 0xcb, 0x00, 0x47, 0x9a, 0xad, 442 | 0xa5, 0xad, 0xaf, 0xac, 0x67, 0x9a, 0xad, 0xa5, 443 | 0xad, 0xa9, 0xa8, 0xee, 0xa1, 0xad, 0x60, 0x8c, 444 | 0x20, 0xaf, 0xb4, 0xb5, 0xa1, 0xf2, 0xac, 0xa3, 445 | 0xf7, 0xa5, 0xae, 0x60, 0x8c, 0x20, 0xac, 0xa5, 446 | 0xa4, 0xee, 0xb5, 0xb2, 0x60, 0xae, 0xb5, 0xb2, 447 | 0xee, 0xaf, 0xa3, 0xe5, 0xb6, 0xa1, 0xb3, 0xe4, 448 | 0xa1, 0xaf, 0xac, 0x7a, 0x7e, 0x9a, 0x22, 0x20, 449 | 0x00, 0x60, 0x03, 0xbf, 0x60, 0x03, 0xbf, 0x1f, 450 | 0x20, 0xb1, 0xe7, 0xe8, 0xe8, 0xb5, 0x4f, 0x85, 451 | 0xda, 0xb5, 0x77, 0x85, 0xdb, 0xb4, 0x4e, 0x98, 452 | 0xd5, 0x76, 0xb0, 0x09, 0xb1, 0xda, 0x20, 0xed, 453 | 0xfd, 0xc8, 0x4c, 0x0f, 0xee, 0xa9, 0xff, 0x85, 454 | 0xd5, 0x60, 0xe8, 0xa9, 0x00, 0x95, 0x78, 0x95, 455 | 0xa0, 0xb5, 0x77, 0x38, 0xf5, 0x4f, 0x95, 0x50, 456 | 0x4c, 0x23, 0xe8, 0xff, 0x20, 0x15, 0xe7, 0xa5, 457 | 0xcf, 0xd0, 0x28, 0xa5, 0xce, 0x60, 0x20, 0x34, 458 | 0xee, 0xa4, 0xc8, 0xc9, 0x30, 0xb0, 0x21, 0xc0, 459 | 0x28, 0xb0, 0x1d, 0x4c, 0x00, 0xf8, 0x20, 0x34, 460 | 0xee, 0x4c, 0x64, 0xf8, 0x46, 0xf8, 0x60, 0x20, 461 | 0xb3, 0xf3, 0xc9, 0x18, 0xb0, 0x0a, 0x85, 0x25, 462 | 0x4c, 0x22, 0xfc, 0xa0, 0x77, 0x4c, 0xe0, 0xe3, 463 | 0xa0, 0x7b, 0xd0, 0xf9, 0x20, 0x54, 0xe2, 0xa5, 464 | 0xda, 0xd0, 0x07, 0xa5, 0xdb, 0xd0, 0x03, 0x4c, 465 | 0x7e, 0xe7, 0x06, 0xce, 0x26, 0xcf, 0x26, 0xe6, 466 | 0x26, 0xe7, 0xa5, 0xe6, 0xc5, 0xda, 0xa5, 0xe7, 467 | 0xe5, 0xdb, 0x90, 0x0a, 0x85, 0xe7, 0xa5, 0xe6, 468 | 0xe5, 0xda, 0x85, 0xe6, 0xe6, 0xce, 0x88, 0xd0, 469 | 0xe1, 0x60, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 470 | 0x20, 0x15, 0xe7, 0x6c, 0xce, 0x00, 0x20, 0x34, 471 | 0xee, 0xc5, 0xc8, 0x90, 0xbb, 0x85, 0x2c, 0x60, 472 | 0x20, 0x34, 0xee, 0xc9, 0x30, 0xb0, 0xb1, 0xa4, 473 | 0xc8, 0x4c, 0x19, 0xf8, 0x20, 0x34, 0xee, 0xc5, 474 | 0xc8, 0x90, 0xa5, 0x85, 0x2d, 0x60, 0x20, 0x34, 475 | 0xee, 0xc9, 0x28, 0xb0, 0x9b, 0xa8, 0xa5, 0xc8, 476 | 0x4c, 0x28, 0xf8, 0x98, 0xaa, 0xa0, 0x6e, 0x20, 477 | 0xc4, 0xe3, 0x8a, 0xa8, 0x20, 0xc4, 0xe3, 0xa0, 478 | 0x72, 0x4c, 0x61, 0xf1, 0x20, 0x3f, 0xf2, 0x06, 479 | 0xce, 0x26, 0xcf, 0x30, 0xfa, 0xb0, 0xdc, 0xd0, 480 | 0x04, 0xc5, 0xce, 0xb0, 0xd6, 0x60, 0x20, 0x15, 481 | 0xe7, 0xb1, 0xce, 0x94, 0x9f, 0x4c, 0x08, 0xe7, 482 | 0x20, 0x34, 0xee, 0xa5, 0xce, 0x85, 0xc8, 0x60, 483 | 0x20, 0x15, 0xe7, 0xa5, 0xc8, 0x91, 0xce, 0x60, 484 | 0x20, 0x6c, 0xee, 0xa5, 0xce, 0x85, 0xe6, 0xa5, 485 | 0xcf, 0x85, 0xe7, 0x4c, 0x44, 0xe2, 0x20, 0xe4, 486 | 0xee, 0x4c, 0x34, 0xe1, 0x20, 0xe4, 0xee, 0xb4, 487 | 0x78, 0xb5, 0x50, 0x69, 0xfe, 0xb0, 0x01, 0x88, 488 | 0x85, 0xda, 0x84, 0xdb, 0x18, 0x65, 0xce, 0x95, 489 | 0x50, 0x98, 0x65, 0xcf, 0x95, 0x78, 0xa0, 0x00, 490 | 0xb5, 0x50, 0xd1, 0xda, 0xc8, 0xb5, 0x78, 0xf1, 491 | 0xda, 0xb0, 0x80, 0x4c, 0x23, 0xe8, 0x20, 0x15, 492 | 0xe7, 0xa5, 0x4e, 0x20, 0x08, 0xe7, 0xa5, 0x4f, 493 | 0xd0, 0x04, 0xc5, 0x4e, 0x69, 0x00, 0x29, 0x7f, 494 | 0x85, 0x4f, 0x95, 0xa0, 0xa0, 0x11, 0xa5, 0x4f, 495 | 0x0a, 0x18, 0x69, 0x40, 0x0a, 0x26, 0x4e, 0x26, 496 | 0x4f, 0x88, 0xd0, 0xf2, 0xa5, 0xce, 0x20, 0x08, 497 | 0xe7, 0xa5, 0xcf, 0x95, 0xa0, 0x4c, 0x7a, 0xe2, 498 | 0x20, 0x15, 0xe7, 0xa4, 0xce, 0xc4, 0x4a, 0xa5, 499 | 0xcf, 0xe5, 0x4b, 0x90, 0x1e, 0x84, 0x4c, 0xa5, 500 | 0xcf, 0x85, 0x4d, 0x4c, 0xad, 0xe5, 0x20, 0x15, 501 | 0xe7, 0xa4, 0xce, 0xc4, 0x4c, 0xa5, 0xcf, 0xe5, 502 | 0x4d, 0xb0, 0x08, 0x84, 0x4a, 0xa5, 0xcf, 0x85, 503 | 0x4b, 0x90, 0xe8, 0x4c, 0xcb, 0xee, 0xff, 0xff, 504 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x20, 0x71, 505 | 0xe1, 0x4c, 0xbf, 0xef, 0x20, 0x03, 0xee, 0xa9, 506 | 0xff, 0x85, 0xc8, 0xa9, 0x80, 0x8d, 0x00, 0x02, 507 | 0x60, 0x20, 0x36, 0xe7, 0xe8, 0x20, 0x36, 0xe7, 508 | 0xb5, 0x50, 0x60, 0xa9, 0x00, 0x85, 0x4a, 0x85, 509 | 0x4c, 0xa9, 0x08, 0x85, 0x4b, 0xa9, 0x10, 0x85, 510 | 0x4d, 0x4c, 0xad, 0xe5, 0xd5, 0x78, 0xd0, 0x01, 511 | 0x18, 0x4c, 0x02, 0xe1, 0x20, 0xb7, 0xe5, 0x4c, 512 | 0x36, 0xe8, 0x20, 0xb7, 0xe5, 0x4c, 0x5b, 0xe8, 513 | 0xe0, 0x80, 0xd0, 0x01, 0x88, 0x4c, 0x0c, 0xe0, 514 | 0xa0, 0x00, 0x84, 0xa0, 0x84, 0x4a, 0x84, 0x4c, 515 | 0xa9, 0x08, 0x85, 0x4b, 0x85, 0x4d, 0xe6, 0x4d, 516 | 0xb1, 0x4c, 0x49, 0xff, 0x91, 0x4c, 0xd1, 0x4c, 517 | 0xd0, 0x08, 0x49, 0xff, 0x91, 0x4c, 0xd1, 0x4c, 518 | 0xf0, 0xec, 0x4c, 0xad, 0xe5, 0x4c, 0x79, 0xf1, 519 | 0x20, 0x32, 0xf0, 0x4c, 0xbe, 0xe8, 0xa6, 0xe0, 520 | 0xa5, 0xe1, 0xac, 0x00, 0xc0, 0xc0, 0x83, 0xd0, 521 | 0xec, 0x2c, 0x10, 0xc0, 0x86, 0x50, 0x85, 0x51, 522 | 0xa5, 0xdc, 0x85, 0x78, 0xa5, 0xdd, 0x85, 0x79, 523 | 0x4c, 0xc3, 0xe8, 0xff, 0xff, 0x20, 0x15, 0xe7, 524 | 0x86, 0xd8, 0xa2, 0xfe, 0x38, 0xb5, 0xd0, 0x95, 525 | 0xe6, 0xb5, 0x4e, 0xf5, 0xd0, 0x95, 0xdc, 0xe8, 526 | 0xd0, 0xf3, 0x90, 0x4b, 0xca, 0xb5, 0xcb, 0x95, 527 | 0xe7, 0xf5, 0xdb, 0x95, 0xe5, 0xe8, 0xf0, 0xf5, 528 | 0x90, 0x0a, 0xa5, 0xcc, 0xc5, 0xe4, 0xa5, 0xcd, 529 | 0xe5, 0xe5, 0x90, 0x13, 0x4c, 0x6b, 0xe3, 0xb1, 530 | 0xe6, 0x91, 0xe4, 0xe6, 0xe4, 0xd0, 0x02, 0xe6, 531 | 0xe5, 0xe6, 0xe6, 0xd0, 0x02, 0xe6, 0xe7, 0xa5, 532 | 0xe6, 0xc5, 0x4c, 0xa5, 0xe7, 0xe5, 0x4d, 0x90, 533 | 0xe6, 0xa2, 0xfe, 0xb5, 0xe6, 0x95, 0x4e, 0xb5, 534 | 0xcc, 0xf5, 0xdc, 0x95, 0xcc, 0xe8, 0xd0, 0xf3, 535 | 0xa6, 0xd8, 0x60, 0xb1, 0x4c, 0x91, 0xce, 0xa5, 536 | 0xce, 0xd0, 0x02, 0xc6, 0xcf, 0xc6, 0xce, 0xa5, 537 | 0x4c, 0xd0, 0x02, 0xc6, 0x4d, 0xc6, 0x4c, 0xc5, 538 | 0xca, 0xa5, 0x4d, 0xe5, 0xcb, 0x90, 0xe4, 0xb0, 539 | 0xd0, 0x20, 0x15, 0xe7, 0xa4, 0xce, 0xc0, 0xca, 540 | 0xa5, 0xcf, 0xe5, 0xcb, 0xb0, 0xa6, 0x84, 0x4a, 541 | 0xa5, 0xcf, 0x85, 0x4b, 0x4c, 0xb7, 0xe5, 0x86, 542 | 0xd8, 0x20, 0x1e, 0xf1, 0x20, 0xfd, 0xfe, 0xa2, 543 | 0xff, 0x38, 0xb5, 0x4d, 0xf5, 0xcf, 0x95, 0xdb, 544 | 0xe8, 0xf0, 0xf7, 0x90, 0x87, 0xa5, 0xcc, 0xc5, 545 | 0xda, 0xa5, 0xcd, 0xe5, 0xdb, 0xb0, 0xd5, 0xa5, 546 | 0xce, 0xd0, 0x04, 0xa5, 0xcf, 0xf0, 0x11, 0xa5, 547 | 0xda, 0x85, 0xca, 0xa5, 0xdb, 0x85, 0xcb, 0x20, 548 | 0x2c, 0xf1, 0x20, 0xfd, 0xfe, 0xa6, 0xd8, 0x60, 549 | 0x20, 0x3a, 0xff, 0x4c, 0x15, 0xf1, 0xa0, 0xce, 550 | 0x84, 0x3c, 0xc8, 0x84, 0x3e, 0xa0, 0x00, 0x84, 551 | 0x3d, 0x84, 0x3f, 0x60, 0xb5, 0xca, 0x95, 0x3c, 552 | 0xb4, 0x4c, 0x94, 0x3e, 0xca, 0x10, 0xf5, 0xa5, 553 | 0x3e, 0xd0, 0x02, 0xc6, 0x3f, 0xc6, 0x3e, 0x60, 554 | 0x86, 0xd8, 0x38, 0xa2, 0xff, 0xb5, 0x4d, 0xf5, 555 | 0xcb, 0x95, 0xcf, 0xe8, 0xf0, 0xf7, 0x20, 0x1e, 556 | 0xf1, 0x20, 0xcd, 0xfe, 0xa2, 0x01, 0x20, 0x2c, 557 | 0xf1, 0xa9, 0x1a, 0x20, 0xcf, 0xfe, 0xa6, 0xd8, 558 | 0x60, 0x20, 0xc4, 0xe3, 0x4c, 0x3a, 0xff, 0xa5, 559 | 0xfc, 0xd0, 0x03, 0x4c, 0xa5, 0xe8, 0xc6, 0xfc, 560 | 0x60, 0xa9, 0xff, 0x85, 0xa0, 0x60, 0x46, 0xa0, 561 | 0x60, 0x24, 0xa0, 0x10, 0x19, 0xa9, 0xa3, 0x20, 562 | 0xed, 0xfd, 0xa0, 0x01, 0xb1, 0xdc, 0xaa, 0xc8, 563 | 0xb1, 0xdc, 0x20, 0x1b, 0xe5, 0xa9, 0xa0, 0x4c, 564 | 0xed, 0xfd, 0xa5, 0xdc, 0xa4, 0xdd, 0x60, 0xc1, 565 | 0x00, 0x7f, 0xd1, 0xcc, 0xc7, 0xcf, 0xce, 0xc5, 566 | 0x9a, 0x98, 0x8d, 0x96, 0x95, 0x93, 0xbf, 0xb2, 567 | 0x32, 0x12, 0x0f, 0xbc, 0xb0, 0xac, 0xbe, 0x35, 568 | 0x0c, 0x61, 0x30, 0x10, 0x0b, 0xdd, 0xfb, 0xa0, 569 | 0x00, 0x20, 0xc7, 0xe7, 0xa9, 0xa0, 0x4c, 0xed, 570 | 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 571 | 0x00, 0xa4, 0x4a, 0xa5, 0x4b, 0x48, 0xc4, 0xda, 572 | 0xe5, 0xdb, 0xb0, 0x1c, 0x68, 0x84, 0xd0, 0x85, 573 | 0xd1, 0xa0, 0xff, 0xc8, 0xb1, 0xd0, 0x30, 0xfb, 574 | 0xc9, 0x40, 0xf0, 0xf7, 0xc8, 0xc8, 0xb1, 0xd0, 575 | 0x48, 0x88, 0xb1, 0xd0, 0xa8, 0x68, 0xd0, 0xdd, 576 | 0x68, 0xa0, 0x00, 0xb1, 0xd0, 0x30, 0x05, 0x4a, 577 | 0xf0, 0x08, 0xa9, 0xa4, 0x20, 0xed, 0xfd, 0xc8, 578 | 0xd0, 0xf1, 0xa9, 0xbd, 0x4c, 0xed, 0xfd, 0x91, 579 | 0xda, 0xe8, 0xb5, 0x9f, 0xf0, 0x30, 0x4c, 0xd5, 580 | 0xf3, 0xa0, 0x30, 0x07, 0xa5, 0xdc, 0xa4, 0xdd, 581 | 0x20, 0x7d, 0xf1, 0x20, 0xc9, 0xf1, 0xa6, 0xd8, 582 | 0x4c, 0xb7, 0xf1, 0xe8, 0xe8, 0xb5, 0x9f, 0xf0, 583 | 0x1f, 0x4c, 0xe0, 0xf3, 0x30, 0x07, 0xa5, 0xdc, 584 | 0xa4, 0xdd, 0x20, 0x7d, 0xf1, 0x20, 0xc9, 0xf1, 585 | 0xa6, 0xd8, 0x4c, 0x09, 0xf4, 0xe8, 0x60, 0x20, 586 | 0x15, 0xe7, 0xe6, 0xce, 0xd0, 0x02, 0xe6, 0xcf, 587 | 0x60, 0x20, 0x5b, 0xf2, 0xd0, 0x15, 0x20, 0x53, 588 | 0xf2, 0xd0, 0x10, 0x20, 0x82, 0xe7, 0x20, 0x6f, 589 | 0xe7, 0x50, 0x03, 0x20, 0x82, 0xe7, 0x20, 0x59, 590 | 0xe7, 0x56, 0x50, 0x4c, 0x36, 0xe7, 0x20, 0xc9, 591 | 0xef, 0x15, 0x4f, 0x10, 0x05, 0x20, 0xc9, 0xef, 592 | 0x35, 0x4f, 0x95, 0x50, 0x10, 0xed, 0x4c, 0xc9, 593 | 0xef, 0x20, 0x15, 0xe7, 0xa4, 0xfb, 0xa5, 0xce, 594 | 0x99, 0x5f, 0x01, 0xa5, 0xcf, 0x4c, 0x66, 0xe9, 595 | 0x99, 0x50, 0x01, 0x88, 0x30, 0x51, 0xb9, 0x40, 596 | 0x01, 0xd5, 0x50, 0xd0, 0xf6, 0xb9, 0x50, 0x01, 597 | 0xd5, 0x78, 0xd0, 0xef, 0xc6, 0xfb, 0xb9, 0x41, 598 | 0x01, 0x99, 0x40, 0x01, 0xb9, 0x51, 0x01, 0x99, 599 | 0x50, 0x01, 0xb9, 0xc1, 0x01, 0x99, 0xc0, 0x01, 600 | 0xb9, 0xd1, 0x01, 0x99, 0xd0, 0x01, 0xb9, 0x61, 601 | 0x01, 0x99, 0x60, 0x01, 0xb9, 0x71, 0x01, 0x99, 602 | 0x70, 0x01, 0xb9, 0x81, 0x01, 0x99, 0x80, 0x01, 603 | 0xb9, 0x91, 0x01, 0x99, 0x90, 0x01, 0xb9, 0xa1, 604 | 0x01, 0x99, 0xa0, 0x01, 0xb9, 0xa1, 0x01, 0x99, 605 | 0xa0, 0x01, 0xc8, 0xc4, 0xfb, 0x90, 0xbf, 0x60, 606 | 0xe8, 0xa9, 0x00, 0x48, 0xb5, 0x50, 0x38, 0xe9, 607 | 0x03, 0x85, 0xce, 0xb5, 0x78, 0xe9, 0x00, 0x85, 608 | 0xcf, 0x68, 0xa0, 0x00, 0x91, 0xce, 0xe8, 0x60, 609 | 0xc9, 0x85, 0xb0, 0x03, 0x4c, 0xc0, 0xe4, 0xa0, 610 | 0x02, 0x4c, 0x48, 0xe4, 0xe8, 0xa9, 0x01, 0xd0, 611 | 0xda, 0xe8, 0xa5, 0x78, 0x85, 0xdc, 0xa5, 0x79, 612 | 0x85, 0xdd, 0xa5, 0x50, 0xa4, 0x51, 0x4c, 0x75, 613 | 0xe8, 0xa9, 0x01, 0xd0, 0xc6, 0xb5, 0x50, 0xd5, 614 | 0x78, 0x90, 0x03, 0x4c, 0x68, 0xee, 0xa8, 0xb5, 615 | 0x51, 0x85, 0xce, 0xb5, 0x79, 0x85, 0xcf, 0xb1, 616 | 0xce, 0xa0, 0x00, 0xe8, 0xe8, 0x20, 0x08, 0xe7, 617 | 0x4c, 0x04, 0xf4, 0x20, 0x34, 0xee, 0x86, 0xd8, 618 | 0x29, 0x03, 0xaa, 0x20, 0x1e, 0xfb, 0xa6, 0xd8, 619 | 0x98, 0xa0, 0x00, 0x20, 0x08, 0xe7, 0x94, 0xa0, 620 | 0x60, 0x20, 0x75, 0xfd, 0x8a, 0x48, 0xbd, 0x00, 621 | 0x02, 0xc9, 0x83, 0xd0, 0x03, 0x4c, 0x03, 0xe0, 622 | 0xca, 0x10, 0xf3, 0x68, 0xaa, 0x60, 0x20, 0x80, 623 | 0xe2, 0x98, 0xaa, 0x20, 0x54, 0xf3, 0x8a, 0xa8, 624 | 0x60, 0x20, 0x15, 0xe7, 0xa5, 0xcf, 0x10, 0x08, 625 | 0x98, 0xca, 0x20, 0x08, 0xe7, 0x94, 0xa0, 0x60, 626 | 0x85, 0xd1, 0xa5, 0xce, 0x85, 0xd0, 0x20, 0x15, 627 | 0xe7, 0xa5, 0xce, 0x85, 0xd2, 0xa5, 0xcf, 0x85, 628 | 0xd3, 0xa9, 0x01, 0x20, 0x08, 0xe7, 0x94, 0xa0, 629 | 0xa5, 0xd0, 0xd0, 0x04, 0xc6, 0xd1, 0x30, 0xdf, 630 | 0xc6, 0xd0, 0xa5, 0xd2, 0xa0, 0x00, 0x20, 0x08, 631 | 0xe7, 0xa5, 0xd3, 0x95, 0xa0, 0x20, 0x22, 0xe2, 632 | 0x4c, 0x98, 0xf3, 0x20, 0x34, 0xee, 0x18, 0x69, 633 | 0xff, 0x60, 0x20, 0xb1, 0xe7, 0x46, 0xd5, 0x60, 634 | 0x86, 0xd9, 0x9a, 0x20, 0x2e, 0xf0, 0x4c, 0x83, 635 | 0xe8, 0x20, 0x34, 0xee, 0x86, 0xd8, 0x20, 0x95, 636 | 0xfe, 0xa6, 0xd8, 0x60, 0xfe, 0x24, 0xd9, 0x10, 637 | 0xe0, 0x86, 0xd8, 0x24, 0xa0, 0x4c, 0x12, 0xf2, 638 | 0x24, 0xd9, 0x10, 0xd5, 0x86, 0xd8, 0x24, 0xa0, 639 | 0x4c, 0x2c, 0xf2, 0xa0, 0x00, 0x4c, 0xff, 0xe6, 640 | 0xa8, 0x20, 0x8e, 0xfd, 0x98, 0x38, 0xe5, 0x21, 641 | 0xb0, 0xf6, 0x84, 0x24, 0x60, 0x00, 0x00, 0x00, 642 | 0xff, 0xff, 0xff, 0xff, 0x94, 0xa0, 0x4c, 0x23, 643 | 0xe8, 0xa0, 0x00, 0xf0, 0x04, 0x20, 0xed, 0xfd, 644 | 0xc8, 0xb1, 0xda, 0x30, 0xf8, 0xa9, 0xff, 0x85, 645 | 0xd5, 0x60, 0x20, 0x34, 0xee, 0x86, 0xd8, 0x20, 646 | 0x8b, 0xfe, 0xa6, 0xd8, 0x60, 0x18, 0xa2, 0x02, 647 | 0xb5, 0xf9, 0x75, 0xf5, 0x95, 0xf9, 0xca, 0x10, 648 | 0xf7, 0x60, 0x06, 0xf3, 0x20, 0x37, 0xf4, 0x24, 649 | 0xf9, 0x10, 0x05, 0x20, 0xa4, 0xf4, 0xe6, 0xf3, 650 | 0x38, 0xa2, 0x04, 0x94, 0xfb, 0xb5, 0xf7, 0xb4, 651 | 0xf3, 0x94, 0xf7, 0x95, 0xf3, 0xca, 0xd0, 0xf3, 652 | 0x60, 0xa9, 0x8e, 0x85, 0xf8, 0xa5, 0xf9, 0xc9, 653 | 0xc0, 0x30, 0x0c, 0xc6, 0xf8, 0x06, 0xfb, 0x26, 654 | 0xfa, 0x26, 0xf9, 0xa5, 0xf8, 0xd0, 0xee, 0x60, 655 | 0x20, 0xa4, 0xf4, 0x20, 0x7b, 0xf4, 0xa5, 0xf4, 656 | 0xc5, 0xf8, 0xd0, 0xf7, 0x20, 0x25, 0xf4, 0x50, 657 | 0xea, 0x70, 0x05, 0x90, 0xc4, 0xa5, 0xf9, 0x0a, 658 | 0xe6, 0xf8, 0xf0, 0x75, 0xa2, 0xfa, 0x76, 0xff, 659 | 0xe8, 0xd0, 0xfb, 0x60, 0x20, 0x32, 0xf4, 0x65, 660 | 0xf8, 0x20, 0xe2, 0xf4, 0x18, 0x20, 0x84, 0xf4, 661 | 0x90, 0x03, 0x20, 0x25, 0xf4, 0x88, 0x10, 0xf5, 662 | 0x46, 0xf3, 0x90, 0xbf, 0x38, 0xa2, 0x03, 0xa9, 663 | 0x00, 0xf5, 0xf8, 0x95, 0xf8, 0xca, 0xd0, 0xf7, 664 | 0xf0, 0xc5, 0x20, 0x32, 0xf4, 0xe5, 0xf8, 0x20, 665 | 0xe2, 0xf4, 0x38, 0xa2, 0x02, 0xb5, 0xf5, 0xf5, 666 | 0xfc, 0x48, 0xca, 0x10, 0xf8, 0xa2, 0xfd, 0x68, 667 | 0x90, 0x02, 0x95, 0xf8, 0xe8, 0xd0, 0xf8, 0x26, 668 | 0xfb, 0x26, 0xfa, 0x26, 0xf9, 0x06, 0xf7, 0x26, 669 | 0xf6, 0x26, 0xf5, 0xb0, 0x1c, 0x88, 0xd0, 0xda, 670 | 0xf0, 0xbe, 0x86, 0xfb, 0x86, 0xfa, 0x86, 0xf9, 671 | 0xb0, 0x0d, 0x30, 0x04, 0x68, 0x68, 0x90, 0xb2, 672 | 0x49, 0x80, 0x85, 0xf8, 0xa0, 0x17, 0x60, 0x10, 673 | 0xf7, 0x4c, 0xf5, 0x03, 0xff, 0xff, 0xff, 0xff, 674 | 0xe9, 0x81, 0x4a, 0xd0, 0x14, 0xa4, 0x3f, 0xa6, 675 | 0x3e, 0xd0, 0x01, 0x88, 0xca, 0x8a, 0x18, 0xe5, 676 | 0x3a, 0x85, 0x3e, 0x10, 0x01, 0xc8, 0x98, 0xe5, 677 | 0x3b, 0xd0, 0x6b, 0xa4, 0x2f, 0xb9, 0x3d, 0x00, 678 | 0x91, 0x3a, 0x88, 0x10, 0xf8, 0x20, 0x1a, 0xfc, 679 | 0x20, 0x1a, 0xfc, 0x20, 0xd0, 0xf8, 0x20, 0x53, 680 | 0xf9, 0x84, 0x3b, 0x85, 0x3a, 0x4c, 0x95, 0xf5, 681 | 0x20, 0xbe, 0xff, 0xa4, 0x34, 0x20, 0xa7, 0xff, 682 | 0x84, 0x34, 0xa0, 0x17, 0x88, 0x30, 0x4b, 0xd9, 683 | 0xcc, 0xff, 0xd0, 0xf8, 0xc0, 0x15, 0xd0, 0xe8, 684 | 0xa5, 0x31, 0xa0, 0x00, 0xc6, 0x34, 0x20, 0x00, 685 | 0xfe, 0x4c, 0x95, 0xf5, 0xa5, 0x3d, 0x20, 0x8e, 686 | 0xf8, 0xaa, 0xbd, 0x00, 0xfa, 0xc5, 0x42, 0xd0, 687 | 0x13, 0xbd, 0xc0, 0xf9, 0xc5, 0x43, 0xd0, 0x0c, 688 | 0xa5, 0x44, 0xa4, 0x2e, 0xc0, 0x9d, 0xf0, 0x88, 689 | 0xc5, 0x2e, 0xf0, 0x9f, 0xc6, 0x3d, 0xd0, 0xdc, 690 | 0xe6, 0x44, 0xc6, 0x35, 0xf0, 0xd6, 0xa4, 0x34, 691 | 0x98, 0xaa, 0x20, 0x4a, 0xf9, 0xa9, 0xde, 0x20, 692 | 0xed, 0xfd, 0x20, 0x3a, 0xff, 0xa9, 0xa1, 0x85, 693 | 0x33, 0x20, 0x67, 0xfd, 0x20, 0xc7, 0xff, 0xad, 694 | 0x00, 0x02, 0xc9, 0xa0, 0xf0, 0x13, 0xc8, 0xc9, 695 | 0xa4, 0xf0, 0x92, 0x88, 0x20, 0xa7, 0xff, 0xc9, 696 | 0x93, 0xd0, 0xd5, 0x8a, 0xf0, 0xd2, 0x20, 0x78, 697 | 0xfe, 0xa9, 0x03, 0x85, 0x3d, 0x20, 0x34, 0xf6, 698 | 0x0a, 0xe9, 0xbe, 0xc9, 0xc2, 0x90, 0xc1, 0x0a, 699 | 0x0a, 0xa2, 0x04, 0x0a, 0x26, 0x42, 0x26, 0x43, 700 | 0xca, 0x10, 0xf8, 0xc6, 0x3d, 0xf0, 0xf4, 0x10, 701 | 0xe4, 0xa2, 0x05, 0x20, 0x34, 0xf6, 0x84, 0x34, 702 | 0xdd, 0xb4, 0xf9, 0xd0, 0x13, 0x20, 0x34, 0xf6, 703 | 0xdd, 0xba, 0xf9, 0xf0, 0x0d, 0xbd, 0xba, 0xf9, 704 | 0xf0, 0x07, 0xc9, 0xa4, 0xf0, 0x03, 0xa4, 0x34, 705 | 0x18, 0x88, 0x26, 0x44, 0xe0, 0x03, 0xd0, 0x0d, 706 | 0x20, 0xa7, 0xff, 0xa5, 0x3f, 0xf0, 0x01, 0xe8, 707 | 0x86, 0x35, 0xa2, 0x03, 0x88, 0x86, 0x3d, 0xca, 708 | 0x10, 0xc9, 0xa5, 0x44, 0x0a, 0x0a, 0x05, 0x35, 709 | 0xc9, 0x20, 0xb0, 0x06, 0xa6, 0x35, 0xf0, 0x02, 710 | 0x09, 0x80, 0x85, 0x44, 0x84, 0x34, 0xb9, 0x00, 711 | 0x02, 0xc9, 0xbb, 0xf0, 0x04, 0xc9, 0x8d, 0xd0, 712 | 0x80, 0x4c, 0x5c, 0xf5, 0xb9, 0x00, 0x02, 0xc8, 713 | 0xc9, 0xa0, 0xf0, 0xf8, 0x60, 0x20, 0x7d, 0xf4, 714 | 0xa5, 0xf8, 0x10, 0x13, 0xc9, 0x8e, 0xd0, 0xf5, 715 | 0x24, 0xf9, 0x10, 0x0a, 0xa5, 0xfb, 0xf0, 0x06, 716 | 0xe6, 0xfa, 0xd0, 0x02, 0xe6, 0xf9, 0x60, 0xa9, 717 | 0x00, 0x85, 0xf9, 0x85, 0xfa, 0x60, 0xff, 0xff, 718 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x4c, 0x92, 719 | 0xf5, 0x84, 0x58, 0x86, 0x57, 0x85, 0x56, 0x08, 720 | 0x68, 0x85, 0x59, 0xba, 0xe8, 0xe8, 0xbd, 0x00, 721 | 0x01, 0x0a, 0x0a, 0x0a, 0x0a, 0x60, 0xa4, 0x58, 722 | 0xa6, 0x57, 0xa5, 0x59, 0x48, 0xa5, 0x56, 0x28, 723 | 0x60, 0x20, 0x4a, 0xff, 0x68, 0x85, 0x1e, 0x68, 724 | 0x85, 0x1f, 0x20, 0x98, 0xf6, 0x4c, 0x92, 0xf6, 725 | 0xe6, 0x1e, 0xd0, 0x02, 0xe6, 0x1f, 0xa9, 0xf7, 726 | 0x48, 0xa0, 0x00, 0xb1, 0x1e, 0x29, 0x0f, 0x0a, 727 | 0xaa, 0x4a, 0x51, 0x1e, 0xf0, 0x0b, 0x86, 0x1d, 728 | 0x4a, 0x4a, 0x4a, 0xa8, 0xb9, 0xe1, 0xf6, 0x48, 729 | 0x60, 0xe6, 0x1e, 0xd0, 0x02, 0xe6, 0x1f, 0xbd, 730 | 0xe4, 0xf6, 0x48, 0xa5, 0x1d, 0x4a, 0x60, 0x68, 731 | 0x68, 0x20, 0x3f, 0xff, 0x6c, 0x1e, 0x00, 0xb1, 732 | 0x1e, 0x95, 0x01, 0x88, 0xb1, 0x1e, 0x95, 0x00, 733 | 0x98, 0x38, 0x65, 0x1e, 0x85, 0x1e, 0x90, 0x02, 734 | 0xe6, 0x1f, 0x60, 0x02, 0xf9, 0x04, 0x9d, 0x0d, 735 | 0x9e, 0x25, 0xaf, 0x16, 0xb2, 0x47, 0xb9, 0x51, 736 | 0xc0, 0x2f, 0xc9, 0x5b, 0xd2, 0x85, 0xdd, 0x6e, 737 | 0x05, 0x33, 0xe8, 0x70, 0x93, 0x1e, 0xe7, 0x65, 738 | 0xe7, 0xe7, 0xe7, 0x10, 0xca, 0xb5, 0x00, 0x85, 739 | 0x00, 0xb5, 0x01, 0x85, 0x01, 0x60, 0xa5, 0x00, 740 | 0x95, 0x00, 0xa5, 0x01, 0x95, 0x01, 0x60, 0xa5, 741 | 0x00, 0x81, 0x00, 0xa0, 0x00, 0x84, 0x1d, 0xf6, 742 | 0x00, 0xd0, 0x02, 0xf6, 0x01, 0x60, 0xa1, 0x00, 743 | 0x85, 0x00, 0xa0, 0x00, 0x84, 0x01, 0xf0, 0xed, 744 | 0xa0, 0x00, 0xf0, 0x06, 0x20, 0x66, 0xf7, 0xa1, 745 | 0x00, 0xa8, 0x20, 0x66, 0xf7, 0xa1, 0x00, 0x85, 746 | 0x00, 0x84, 0x01, 0xa0, 0x00, 0x84, 0x1d, 0x60, 747 | 0x20, 0x26, 0xf7, 0xa1, 0x00, 0x85, 0x01, 0x4c, 748 | 0x1f, 0xf7, 0x20, 0x17, 0xf7, 0xa5, 0x01, 0x81, 749 | 0x00, 0x4c, 0x1f, 0xf7, 0x20, 0x66, 0xf7, 0xa5, 750 | 0x00, 0x81, 0x00, 0x4c, 0x43, 0xf7, 0xb5, 0x00, 751 | 0xd0, 0x02, 0xd6, 0x01, 0xd6, 0x00, 0x60, 0xa0, 752 | 0x00, 0x38, 0xa5, 0x00, 0xf5, 0x00, 0x99, 0x00, 753 | 0x00, 0xa5, 0x01, 0xf5, 0x01, 0x99, 0x01, 0x00, 754 | 0x98, 0x69, 0x00, 0x85, 0x1d, 0x60, 0xa5, 0x00, 755 | 0x75, 0x00, 0x85, 0x00, 0xa5, 0x01, 0x75, 0x01, 756 | 0xa0, 0x00, 0xf0, 0xe9, 0xa5, 0x1e, 0x20, 0x19, 757 | 0xf7, 0xa5, 0x1f, 0x20, 0x19, 0xf7, 0x18, 0xb0, 758 | 0x0e, 0xb1, 0x1e, 0x10, 0x01, 0x88, 0x65, 0x1e, 759 | 0x85, 0x1e, 0x98, 0x65, 0x1f, 0x85, 0x1f, 0x60, 760 | 0xb0, 0xec, 0x60, 0x0a, 0xaa, 0xb5, 0x01, 0x10, 761 | 0xe8, 0x60, 0x0a, 0xaa, 0xb5, 0x01, 0x30, 0xe1, 762 | 0x60, 0x0a, 0xaa, 0xb5, 0x00, 0x15, 0x01, 0xf0, 763 | 0xd8, 0x60, 0x0a, 0xaa, 0xb5, 0x00, 0x15, 0x01, 764 | 0xd0, 0xcf, 0x60, 0x0a, 0xaa, 0xb5, 0x00, 0x35, 765 | 0x01, 0x49, 0xff, 0xf0, 0xc4, 0x60, 0x0a, 0xaa, 766 | 0xb5, 0x00, 0x35, 0x01, 0x49, 0xff, 0xd0, 0xb9, 767 | 0x60, 0xa2, 0x18, 0x20, 0x66, 0xf7, 0xa1, 0x00, 768 | 0x85, 0x1f, 0x20, 0x66, 0xf7, 0xa1, 0x00, 0x85, 769 | 0x1e, 0x60, 0x4c, 0xc7, 0xf6, 0xf6, 0xff, 0xff, 770 | 0x4a, 0x08, 0x20, 0x47, 0xf8, 0x28, 0xa9, 0x0f, 771 | 0x90, 0x02, 0x69, 0xe0, 0x85, 0x2e, 0xb1, 0x26, 772 | 0x45, 0x30, 0x25, 0x2e, 0x51, 0x26, 0x91, 0x26, 773 | 0x60, 0x20, 0x00, 0xf8, 0xc4, 0x2c, 0xb0, 0x11, 774 | 0xc8, 0x20, 0x0e, 0xf8, 0x90, 0xf6, 0x69, 0x01, 775 | 0x48, 0x20, 0x00, 0xf8, 0x68, 0xc5, 0x2d, 0x90, 776 | 0xf5, 0x60, 0xa0, 0x2f, 0xd0, 0x02, 0xa0, 0x27, 777 | 0x84, 0x2d, 0xa0, 0x27, 0xa9, 0x00, 0x85, 0x30, 778 | 0x20, 0x28, 0xf8, 0x88, 0x10, 0xf6, 0x60, 0x48, 779 | 0x4a, 0x29, 0x03, 0x09, 0x04, 0x85, 0x27, 0x68, 780 | 0x29, 0x18, 0x90, 0x02, 0x69, 0x7f, 0x85, 0x26, 781 | 0x0a, 0x0a, 0x05, 0x26, 0x85, 0x26, 0x60, 0xa5, 782 | 0x30, 0x18, 0x69, 0x03, 0x29, 0x0f, 0x85, 0x30, 783 | 0x0a, 0x0a, 0x0a, 0x0a, 0x05, 0x30, 0x85, 0x30, 784 | 0x60, 0x4a, 0x08, 0x20, 0x47, 0xf8, 0xb1, 0x26, 785 | 0x28, 0x90, 0x04, 0x4a, 0x4a, 0x4a, 0x4a, 0x29, 786 | 0x0f, 0x60, 0xa6, 0x3a, 0xa4, 0x3b, 0x20, 0x96, 787 | 0xfd, 0x20, 0x48, 0xf9, 0xa1, 0x3a, 0xa8, 0x4a, 788 | 0x90, 0x09, 0x6a, 0xb0, 0x10, 0xc9, 0xa2, 0xf0, 789 | 0x0c, 0x29, 0x87, 0x4a, 0xaa, 0xbd, 0x62, 0xf9, 790 | 0x20, 0x79, 0xf8, 0xd0, 0x04, 0xa0, 0x80, 0xa9, 791 | 0x00, 0xaa, 0xbd, 0xa6, 0xf9, 0x85, 0x2e, 0x29, 792 | 0x03, 0x85, 0x2f, 0x98, 0x29, 0x8f, 0xaa, 0x98, 793 | 0xa0, 0x03, 0xe0, 0x8a, 0xf0, 0x0b, 0x4a, 0x90, 794 | 0x08, 0x4a, 0x4a, 0x09, 0x20, 0x88, 0xd0, 0xfa, 795 | 0xc8, 0x88, 0xd0, 0xf2, 0x60, 0xff, 0xff, 0xff, 796 | 0x20, 0x82, 0xf8, 0x48, 0xb1, 0x3a, 0x20, 0xda, 797 | 0xfd, 0xa2, 0x01, 0x20, 0x4a, 0xf9, 0xc4, 0x2f, 798 | 0xc8, 0x90, 0xf1, 0xa2, 0x03, 0xc0, 0x04, 0x90, 799 | 0xf2, 0x68, 0xa8, 0xb9, 0xc0, 0xf9, 0x85, 0x2c, 800 | 0xb9, 0x00, 0xfa, 0x85, 0x2d, 0xa9, 0x00, 0xa0, 801 | 0x05, 0x06, 0x2d, 0x26, 0x2c, 0x2a, 0x88, 0xd0, 802 | 0xf8, 0x69, 0xbf, 0x20, 0xed, 0xfd, 0xca, 0xd0, 803 | 0xec, 0x20, 0x48, 0xf9, 0xa4, 0x2f, 0xa2, 0x06, 804 | 0xe0, 0x03, 0xf0, 0x1c, 0x06, 0x2e, 0x90, 0x0e, 805 | 0xbd, 0xb3, 0xf9, 0x20, 0xed, 0xfd, 0xbd, 0xb9, 806 | 0xf9, 0xf0, 0x03, 0x20, 0xed, 0xfd, 0xca, 0xd0, 807 | 0xe7, 0x60, 0x88, 0x30, 0xe7, 0x20, 0xda, 0xfd, 808 | 0xa5, 0x2e, 0xc9, 0xe8, 0xb1, 0x3a, 0x90, 0xf2, 809 | 0x20, 0x56, 0xf9, 0xaa, 0xe8, 0xd0, 0x01, 0xc8, 810 | 0x98, 0x20, 0xda, 0xfd, 0x8a, 0x4c, 0xda, 0xfd, 811 | 0xa2, 0x03, 0xa9, 0xa0, 0x20, 0xed, 0xfd, 0xca, 812 | 0xd0, 0xf8, 0x60, 0x38, 0xa5, 0x2f, 0xa4, 0x3b, 813 | 0xaa, 0x10, 0x01, 0x88, 0x65, 0x3a, 0x90, 0x01, 814 | 0xc8, 0x60, 0x04, 0x20, 0x54, 0x30, 0x0d, 0x80, 815 | 0x04, 0x90, 0x03, 0x22, 0x54, 0x33, 0x0d, 0x80, 816 | 0x04, 0x90, 0x04, 0x20, 0x54, 0x33, 0x0d, 0x80, 817 | 0x04, 0x90, 0x04, 0x20, 0x54, 0x3b, 0x0d, 0x80, 818 | 0x04, 0x90, 0x00, 0x22, 0x44, 0x33, 0x0d, 0xc8, 819 | 0x44, 0x00, 0x11, 0x22, 0x44, 0x33, 0x0d, 0xc8, 820 | 0x44, 0xa9, 0x01, 0x22, 0x44, 0x33, 0x0d, 0x80, 821 | 0x04, 0x90, 0x01, 0x22, 0x44, 0x33, 0x0d, 0x80, 822 | 0x04, 0x90, 0x26, 0x31, 0x87, 0x9a, 0x00, 0x21, 823 | 0x81, 0x82, 0x00, 0x00, 0x59, 0x4d, 0x91, 0x92, 824 | 0x86, 0x4a, 0x85, 0x9d, 0xac, 0xa9, 0xac, 0xa3, 825 | 0xa8, 0xa4, 0xd9, 0x00, 0xd8, 0xa4, 0xa4, 0x00, 826 | 0x1c, 0x8a, 0x1c, 0x23, 0x5d, 0x8b, 0x1b, 0xa1, 827 | 0x9d, 0x8a, 0x1d, 0x23, 0x9d, 0x8b, 0x1d, 0xa1, 828 | 0x00, 0x29, 0x19, 0xae, 0x69, 0xa8, 0x19, 0x23, 829 | 0x24, 0x53, 0x1b, 0x23, 0x24, 0x53, 0x19, 0xa1, 830 | 0x00, 0x1a, 0x5b, 0x5b, 0xa5, 0x69, 0x24, 0x24, 831 | 0xae, 0xae, 0xa8, 0xad, 0x29, 0x00, 0x7c, 0x00, 832 | 0x15, 0x9c, 0x6d, 0x9c, 0xa5, 0x69, 0x29, 0x53, 833 | 0x84, 0x13, 0x34, 0x11, 0xa5, 0x69, 0x23, 0xa0, 834 | 0xd8, 0x62, 0x5a, 0x48, 0x26, 0x62, 0x94, 0x88, 835 | 0x54, 0x44, 0xc8, 0x54, 0x68, 0x44, 0xe8, 0x94, 836 | 0x00, 0xb4, 0x08, 0x84, 0x74, 0xb4, 0x28, 0x6e, 837 | 0x74, 0xf4, 0xcc, 0x4a, 0x72, 0xf2, 0xa4, 0x8a, 838 | 0x00, 0xaa, 0xa2, 0xa2, 0x74, 0x74, 0x74, 0x72, 839 | 0x44, 0x68, 0xb2, 0x32, 0xb2, 0x00, 0x22, 0x00, 840 | 0x1a, 0x1a, 0x26, 0x26, 0x72, 0x72, 0x88, 0xc8, 841 | 0xc4, 0xca, 0x26, 0x48, 0x44, 0x44, 0xa2, 0xc8, 842 | 0xff, 0xff, 0xff, 0x20, 0xd0, 0xf8, 0x68, 0x85, 843 | 0x2c, 0x68, 0x85, 0x2d, 0xa2, 0x08, 0xbd, 0x10, 844 | 0xfb, 0x95, 0x3c, 0xca, 0xd0, 0xf8, 0xa1, 0x3a, 845 | 0xf0, 0x42, 0xa4, 0x2f, 0xc9, 0x20, 0xf0, 0x59, 846 | 0xc9, 0x60, 0xf0, 0x45, 0xc9, 0x4c, 0xf0, 0x5c, 847 | 0xc9, 0x6c, 0xf0, 0x59, 0xc9, 0x40, 0xf0, 0x35, 848 | 0x29, 0x1f, 0x49, 0x14, 0xc9, 0x04, 0xf0, 0x02, 849 | 0xb1, 0x3a, 0x99, 0x3c, 0x00, 0x88, 0x10, 0xf8, 850 | 0x20, 0x3f, 0xff, 0x4c, 0x3c, 0x00, 0x85, 0x45, 851 | 0x68, 0x48, 0x0a, 0x0a, 0x0a, 0x30, 0x03, 0x6c, 852 | 0xfe, 0x03, 0x28, 0x20, 0x4c, 0xff, 0x68, 0x85, 853 | 0x3a, 0x68, 0x85, 0x3b, 0x20, 0x82, 0xf8, 0x20, 854 | 0xda, 0xfa, 0x4c, 0x65, 0xff, 0x18, 0x68, 0x85, 855 | 0x48, 0x68, 0x85, 0x3a, 0x68, 0x85, 0x3b, 0xa5, 856 | 0x2f, 0x20, 0x56, 0xf9, 0x84, 0x3b, 0x18, 0x90, 857 | 0x14, 0x18, 0x20, 0x54, 0xf9, 0xaa, 0x98, 0x48, 858 | 0x8a, 0x48, 0xa0, 0x02, 0x18, 0xb1, 0x3a, 0xaa, 859 | 0x88, 0xb1, 0x3a, 0x86, 0x3b, 0x85, 0x3a, 0xb0, 860 | 0xf3, 0xa5, 0x2d, 0x48, 0xa5, 0x2c, 0x48, 0x20, 861 | 0x8e, 0xfd, 0xa9, 0x45, 0x85, 0x40, 0xa9, 0x00, 862 | 0x85, 0x41, 0xa2, 0xfb, 0xa9, 0xa0, 0x20, 0xed, 863 | 0xfd, 0xbd, 0x1e, 0xfa, 0x20, 0xed, 0xfd, 0xa9, 864 | 0xbd, 0x20, 0xed, 0xfd, 0xb5, 0x4a, 0x20, 0xda, 865 | 0xfd, 0xe8, 0x30, 0xe8, 0x60, 0x18, 0xa0, 0x01, 866 | 0xb1, 0x3a, 0x20, 0x56, 0xf9, 0x85, 0x3a, 0x98, 867 | 0x38, 0xb0, 0xa2, 0x20, 0x4a, 0xff, 0x38, 0xb0, 868 | 0x9e, 0xea, 0xea, 0x4c, 0x0b, 0xfb, 0x4c, 0xfd, 869 | 0xfa, 0xc1, 0xd8, 0xd9, 0xd0, 0xd3, 0xad, 0x70, 870 | 0xc0, 0xa0, 0x00, 0xea, 0xea, 0xbd, 0x64, 0xc0, 871 | 0x10, 0x04, 0xc8, 0xd0, 0xf8, 0x88, 0x60, 0xa9, 872 | 0x00, 0x85, 0x48, 0xad, 0x56, 0xc0, 0xad, 0x54, 873 | 0xc0, 0xad, 0x51, 0xc0, 0xa9, 0x00, 0xf0, 0x0b, 874 | 0xad, 0x50, 0xc0, 0xad, 0x53, 0xc0, 0x20, 0x36, 875 | 0xf8, 0xa9, 0x14, 0x85, 0x22, 0xa9, 0x00, 0x85, 876 | 0x20, 0xa9, 0x20, 0x85, 0x21, 0xa9, 0x0f, 0x85, 877 | 0x23, 0xa9, 0x0e, 0x85, 0x25, 0x4c, 0x22, 0xfc, 878 | 0x20, 0xa4, 0xfb, 0xa0, 0x10, 0xa5, 0x50, 0x4a, 879 | 0x90, 0x0c, 0x18, 0xa2, 0xfe, 0xb5, 0x54, 0x75, 880 | 0x56, 0x95, 0x54, 0xe8, 0xd0, 0xf7, 0xa2, 0x03, 881 | 0x76, 0x50, 0xca, 0x10, 0xfb, 0x88, 0xd0, 0xe5, 882 | 0x60, 0x20, 0xa4, 0xfb, 0xa0, 0x10, 0x06, 0x50, 883 | 0x26, 0x51, 0x26, 0x52, 0x26, 0x53, 0x38, 0xa5, 884 | 0x52, 0xe5, 0x54, 0xaa, 0xa5, 0x53, 0xe5, 0x55, 885 | 0x90, 0x06, 0x86, 0x52, 0x85, 0x53, 0xe6, 0x50, 886 | 0x88, 0xd0, 0xe3, 0x60, 0xa0, 0x00, 0x84, 0x2f, 887 | 0xa2, 0x54, 0x20, 0xaf, 0xfb, 0xa2, 0x50, 0xb5, 888 | 0x01, 0x10, 0x0d, 0x38, 0x98, 0xf5, 0x00, 0x95, 889 | 0x00, 0x98, 0xf5, 0x01, 0x95, 0x01, 0xe6, 0x2f, 890 | 0x60, 0x48, 0x4a, 0x29, 0x03, 0x09, 0x04, 0x85, 891 | 0x29, 0x68, 0x29, 0x18, 0x90, 0x02, 0x69, 0x7f, 892 | 0x85, 0x28, 0x0a, 0x0a, 0x05, 0x28, 0x85, 0x28, 893 | 0x60, 0xc9, 0x87, 0xd0, 0x12, 0xa9, 0x40, 0x20, 894 | 0xa8, 0xfc, 0xa0, 0xc0, 0xa9, 0x0c, 0x20, 0xa8, 895 | 0xfc, 0xad, 0x30, 0xc0, 0x88, 0xd0, 0xf5, 0x60, 896 | 0xa4, 0x24, 0x91, 0x28, 0xe6, 0x24, 0xa5, 0x24, 897 | 0xc5, 0x21, 0xb0, 0x66, 0x60, 0xc9, 0xa0, 0xb0, 898 | 0xef, 0xa8, 0x10, 0xec, 0xc9, 0x8d, 0xf0, 0x5a, 899 | 0xc9, 0x8a, 0xf0, 0x5a, 0xc9, 0x88, 0xd0, 0xc9, 900 | 0xc6, 0x24, 0x10, 0xe8, 0xa5, 0x21, 0x85, 0x24, 901 | 0xc6, 0x24, 0xa5, 0x22, 0xc5, 0x25, 0xb0, 0x0b, 902 | 0xc6, 0x25, 0xa5, 0x25, 0x20, 0xc1, 0xfb, 0x65, 903 | 0x20, 0x85, 0x28, 0x60, 0x49, 0xc0, 0xf0, 0x28, 904 | 0x69, 0xfd, 0x90, 0xc0, 0xf0, 0xda, 0x69, 0xfd, 905 | 0x90, 0x2c, 0xf0, 0xde, 0x69, 0xfd, 0x90, 0x5c, 906 | 0xd0, 0xe9, 0xa4, 0x24, 0xa5, 0x25, 0x48, 0x20, 907 | 0x24, 0xfc, 0x20, 0x9e, 0xfc, 0xa0, 0x00, 0x68, 908 | 0x69, 0x00, 0xc5, 0x23, 0x90, 0xf0, 0xb0, 0xca, 909 | 0xa5, 0x22, 0x85, 0x25, 0xa0, 0x00, 0x84, 0x24, 910 | 0xf0, 0xe4, 0xa9, 0x00, 0x85, 0x24, 0xe6, 0x25, 911 | 0xa5, 0x25, 0xc5, 0x23, 0x90, 0xb6, 0xc6, 0x25, 912 | 0xa5, 0x22, 0x48, 0x20, 0x24, 0xfc, 0xa5, 0x28, 913 | 0x85, 0x2a, 0xa5, 0x29, 0x85, 0x2b, 0xa4, 0x21, 914 | 0x88, 0x68, 0x69, 0x01, 0xc5, 0x23, 0xb0, 0x0d, 915 | 0x48, 0x20, 0x24, 0xfc, 0xb1, 0x28, 0x91, 0x2a, 916 | 0x88, 0x10, 0xf9, 0x30, 0xe1, 0xa0, 0x00, 0x20, 917 | 0x9e, 0xfc, 0xb0, 0x86, 0xa4, 0x24, 0xa9, 0xa0, 918 | 0x91, 0x28, 0xc8, 0xc4, 0x21, 0x90, 0xf9, 0x60, 919 | 0x38, 0x48, 0xe9, 0x01, 0xd0, 0xfc, 0x68, 0xa9, 920 | 0x00, 0x60, 0xea, 0xea, 0xe6, 0x42, 0xd0, 0x02, 921 | 0xe6, 0x43, 0xa5, 0x3c, 0xc5, 0x3e, 0xa5, 0x3d, 922 | 0xe5, 0x3f, 0xe6, 0x3c, 0xd0, 0x02, 0xe6, 0x3d, 923 | 0x60, 0xa0, 0x4b, 0x20, 0xdb, 0xfc, 0xd0, 0xf9, 924 | 0x69, 0xfe, 0xb0, 0xf5, 0xa0, 0x21, 0x20, 0xdb, 925 | 0xfc, 0xc8, 0xc8, 0x88, 0xd0, 0xfd, 0x90, 0x05, 926 | 0xa0, 0x32, 0x88, 0xd0, 0xfd, 0xac, 0x20, 0xc0, 927 | 0xa0, 0x2c, 0xca, 0x60, 0xa2, 0x08, 0x48, 0x20, 928 | 0xfa, 0xfc, 0x68, 0x2a, 0xa0, 0x3a, 0xca, 0xd0, 929 | 0xf5, 0x60, 0x20, 0xfd, 0xfc, 0x88, 0xad, 0x60, 930 | 0xc0, 0x45, 0x2f, 0x10, 0xf8, 0x45, 0x2f, 0x85, 931 | 0x2f, 0xc0, 0x80, 0x60, 0xa4, 0x24, 0xb1, 0x28, 932 | 0x48, 0x29, 0x3f, 0x09, 0x40, 0x91, 0x28, 0x68, 933 | 0x6c, 0x38, 0x00, 0xe6, 0x4e, 0xd0, 0x02, 0xe6, 934 | 0x4f, 0x2c, 0x00, 0xc0, 0x10, 0xf5, 0x91, 0x28, 935 | 0xad, 0x00, 0xc0, 0x2c, 0x10, 0xc0, 0x60, 0x20, 936 | 0x0c, 0xfd, 0x20, 0x2c, 0xfc, 0x20, 0x0c, 0xfd, 937 | 0xc9, 0x9b, 0xf0, 0xf3, 0x60, 0xa5, 0x32, 0x48, 938 | 0xa9, 0xff, 0x85, 0x32, 0xbd, 0x00, 0x02, 0x20, 939 | 0xed, 0xfd, 0x68, 0x85, 0x32, 0xbd, 0x00, 0x02, 940 | 0xc9, 0x88, 0xf0, 0x1d, 0xc9, 0x98, 0xf0, 0x0a, 941 | 0xe0, 0xf8, 0x90, 0x03, 0x20, 0x3a, 0xff, 0xe8, 942 | 0xd0, 0x13, 0xa9, 0xdc, 0x20, 0xed, 0xfd, 0x20, 943 | 0x8e, 0xfd, 0xa5, 0x33, 0x20, 0xed, 0xfd, 0xa2, 944 | 0x01, 0x8a, 0xf0, 0xf3, 0xca, 0x20, 0x35, 0xfd, 945 | 0xc9, 0x95, 0xd0, 0x02, 0xb1, 0x28, 0xc9, 0xe0, 946 | 0x90, 0x02, 0x29, 0xdf, 0x9d, 0x00, 0x02, 0xc9, 947 | 0x8d, 0xd0, 0xb2, 0x20, 0x9c, 0xfc, 0xa9, 0x8d, 948 | 0xd0, 0x5b, 0xa4, 0x3d, 0xa6, 0x3c, 0x20, 0x8e, 949 | 0xfd, 0x20, 0x40, 0xf9, 0xa0, 0x00, 0xa9, 0xad, 950 | 0x4c, 0xed, 0xfd, 0xa5, 0x3c, 0x09, 0x07, 0x85, 951 | 0x3e, 0xa5, 0x3d, 0x85, 0x3f, 0xa5, 0x3c, 0x29, 952 | 0x07, 0xd0, 0x03, 0x20, 0x92, 0xfd, 0xa9, 0xa0, 953 | 0x20, 0xed, 0xfd, 0xb1, 0x3c, 0x20, 0xda, 0xfd, 954 | 0x20, 0xba, 0xfc, 0x90, 0xe8, 0x60, 0x4a, 0x90, 955 | 0xea, 0x4a, 0x4a, 0xa5, 0x3e, 0x90, 0x02, 0x49, 956 | 0xff, 0x65, 0x3c, 0x48, 0xa9, 0xbd, 0x20, 0xed, 957 | 0xfd, 0x68, 0x48, 0x4a, 0x4a, 0x4a, 0x4a, 0x20, 958 | 0xe5, 0xfd, 0x68, 0x29, 0x0f, 0x09, 0xb0, 0xc9, 959 | 0xba, 0x90, 0x02, 0x69, 0x06, 0x6c, 0x36, 0x00, 960 | 0xc9, 0xa0, 0x90, 0x02, 0x25, 0x32, 0x84, 0x35, 961 | 0x48, 0x20, 0xfd, 0xfb, 0x68, 0xa4, 0x35, 0x60, 962 | 0xc6, 0x34, 0xf0, 0x9f, 0xca, 0xd0, 0x16, 0xc9, 963 | 0xba, 0xd0, 0xbb, 0x85, 0x31, 0xa5, 0x3e, 0x91, 964 | 0x40, 0xe6, 0x40, 0xd0, 0x02, 0xe6, 0x41, 0x60, 965 | 0xa4, 0x34, 0xb9, 0xff, 0x01, 0x85, 0x31, 0x60, 966 | 0xa2, 0x01, 0xb5, 0x3e, 0x95, 0x42, 0x95, 0x44, 967 | 0xca, 0x10, 0xf7, 0x60, 0xb1, 0x3c, 0x91, 0x42, 968 | 0x20, 0xb4, 0xfc, 0x90, 0xf7, 0x60, 0xb1, 0x3c, 969 | 0xd1, 0x42, 0xf0, 0x1c, 0x20, 0x92, 0xfd, 0xb1, 970 | 0x3c, 0x20, 0xda, 0xfd, 0xa9, 0xa0, 0x20, 0xed, 971 | 0xfd, 0xa9, 0xa8, 0x20, 0xed, 0xfd, 0xb1, 0x42, 972 | 0x20, 0xda, 0xfd, 0xa9, 0xa9, 0x20, 0xed, 0xfd, 973 | 0x20, 0xb4, 0xfc, 0x90, 0xd9, 0x60, 0x20, 0x75, 974 | 0xfe, 0xa9, 0x14, 0x48, 0x20, 0xd0, 0xf8, 0x20, 975 | 0x53, 0xf9, 0x85, 0x3a, 0x84, 0x3b, 0x68, 0x38, 976 | 0xe9, 0x01, 0xd0, 0xef, 0x60, 0x8a, 0xf0, 0x07, 977 | 0xb5, 0x3c, 0x95, 0x3a, 0xca, 0x10, 0xf9, 0x60, 978 | 0xa0, 0x3f, 0xd0, 0x02, 0xa0, 0xff, 0x84, 0x32, 979 | 0x60, 0xa9, 0x00, 0x85, 0x3e, 0xa2, 0x38, 0xa0, 980 | 0x1b, 0xd0, 0x08, 0xa9, 0x00, 0x85, 0x3e, 0xa2, 981 | 0x36, 0xa0, 0xf0, 0xa5, 0x3e, 0x29, 0x0f, 0xf0, 982 | 0x06, 0x09, 0xc0, 0xa0, 0x00, 0xf0, 0x02, 0xa9, 983 | 0xfd, 0x94, 0x00, 0x95, 0x01, 0x60, 0xea, 0xea, 984 | 0x4c, 0x00, 0xe0, 0x4c, 0x03, 0xe0, 0x20, 0x75, 985 | 0xfe, 0x20, 0x3f, 0xff, 0x6c, 0x3a, 0x00, 0x4c, 986 | 0xd7, 0xfa, 0xc6, 0x34, 0x20, 0x75, 0xfe, 0x4c, 987 | 0x43, 0xfa, 0x4c, 0xf8, 0x03, 0xa9, 0x40, 0x20, 988 | 0xc9, 0xfc, 0xa0, 0x27, 0xa2, 0x00, 0x41, 0x3c, 989 | 0x48, 0xa1, 0x3c, 0x20, 0xed, 0xfe, 0x20, 0xba, 990 | 0xfc, 0xa0, 0x1d, 0x68, 0x90, 0xee, 0xa0, 0x22, 991 | 0x20, 0xed, 0xfe, 0xf0, 0x4d, 0xa2, 0x10, 0x0a, 992 | 0x20, 0xd6, 0xfc, 0xd0, 0xfa, 0x60, 0x20, 0x00, 993 | 0xfe, 0x68, 0x68, 0xd0, 0x6c, 0x20, 0xfa, 0xfc, 994 | 0xa9, 0x16, 0x20, 0xc9, 0xfc, 0x85, 0x2e, 0x20, 995 | 0xfa, 0xfc, 0xa0, 0x24, 0x20, 0xfd, 0xfc, 0xb0, 996 | 0xf9, 0x20, 0xfd, 0xfc, 0xa0, 0x3b, 0x20, 0xec, 997 | 0xfc, 0x81, 0x3c, 0x45, 0x2e, 0x85, 0x2e, 0x20, 998 | 0xba, 0xfc, 0xa0, 0x35, 0x90, 0xf0, 0x20, 0xec, 999 | 0xfc, 0xc5, 0x2e, 0xf0, 0x0d, 0xa9, 0xc5, 0x20, 1000 | 0xed, 0xfd, 0xa9, 0xd2, 0x20, 0xed, 0xfd, 0x20, 1001 | 0xed, 0xfd, 0xa9, 0x87, 0x4c, 0xed, 0xfd, 0xa5, 1002 | 0x48, 0x48, 0xa5, 0x45, 0xa6, 0x46, 0xa4, 0x47, 1003 | 0x28, 0x60, 0x85, 0x45, 0x86, 0x46, 0x84, 0x47, 1004 | 0x08, 0x68, 0x85, 0x48, 0xba, 0x86, 0x49, 0xd8, 1005 | 0x60, 0x20, 0x84, 0xfe, 0x20, 0x2f, 0xfb, 0x20, 1006 | 0x93, 0xfe, 0x20, 0x89, 0xfe, 0xd8, 0x20, 0x3a, 1007 | 0xff, 0xa9, 0xaa, 0x85, 0x33, 0x20, 0x67, 0xfd, 1008 | 0x20, 0xc7, 0xff, 0x20, 0xa7, 0xff, 0x84, 0x34, 1009 | 0xa0, 0x17, 0x88, 0x30, 0xe8, 0xd9, 0xcc, 0xff, 1010 | 0xd0, 0xf8, 0x20, 0xbe, 0xff, 0xa4, 0x34, 0x4c, 1011 | 0x73, 0xff, 0xa2, 0x03, 0x0a, 0x0a, 0x0a, 0x0a, 1012 | 0x0a, 0x26, 0x3e, 0x26, 0x3f, 0xca, 0x10, 0xf8, 1013 | 0xa5, 0x31, 0xd0, 0x06, 0xb5, 0x3f, 0x95, 0x3d, 1014 | 0x95, 0x41, 0xe8, 0xf0, 0xf3, 0xd0, 0x06, 0xa2, 1015 | 0x00, 0x86, 0x3e, 0x86, 0x3f, 0xb9, 0x00, 0x02, 1016 | 0xc8, 0x49, 0xb0, 0xc9, 0x0a, 0x90, 0xd3, 0x69, 1017 | 0x88, 0xc9, 0xfa, 0xb0, 0xcd, 0x60, 0xa9, 0xfe, 1018 | 0x48, 0xb9, 0xe3, 0xff, 0x48, 0xa5, 0x31, 0xa0, 1019 | 0x00, 0x84, 0x31, 0x60, 0xbc, 0xb2, 0xbe, 0xed, 1020 | 0xef, 0xc4, 0xec, 0xa9, 0xbb, 0xa6, 0xa4, 0x06, 1021 | 0x95, 0x07, 0x02, 0x05, 0xf0, 0x00, 0xeb, 0x93, 1022 | 0xa7, 0xc6, 0x99, 0xb2, 0xc9, 0xbe, 0xc1, 0x35, 1023 | 0x8c, 0xc3, 0x96, 0xaf, 0x17, 0x17, 0x2b, 0x1f, 1024 | 0x83, 0x7f, 0x5d, 0xcc, 0xb5, 0xfc, 0x17, 0x17, 1025 | 0xf5, 0x03, 0xfb, 0x03, 0x59, 0xff, 0x86, 0xfa 1026 | }; 1027 | 1028 | unsigned char ram[1024]; 1029 | // Free memory for storing BASIC programs 1030 | unsigned char basic[512]; 1031 | 1032 | unsigned char read8(unsigned short address) { 1033 | unsigned char page = address>>8; 1034 | if(page < 0x04) { 1035 | return ram[address]; 1036 | } else if (page >= 0x04 && page < 0x08) { 1037 | return screenRead(address); 1038 | } else if (page >= 0x08 && page < 0x10) { 1039 | return basic[address-0x800]; 1040 | } else if (page >= 0xE0) { 1041 | return pgm_read_byte_near(rom+address-0xE000); 1042 | } else { 1043 | // Keyboard Data 1044 | if(address == 0xC000) return keyboard_read(); 1045 | // Keyboard Strobe 1046 | if(address == 0xC010) keyboard_strobe(); 1047 | // Speaker toggle 1048 | if(address == 0xC030) speaker_toggle(); 1049 | return 0; 1050 | } 1051 | } 1052 | 1053 | unsigned short read16(unsigned short address) { 1054 | return (unsigned short)read8(address) | (((unsigned short)read8(address+1))<<8); 1055 | } 1056 | 1057 | void write8(unsigned short address, unsigned char value) { 1058 | unsigned char page = address>>8; 1059 | if(page < 0x04) { 1060 | ram[address] = value; 1061 | } else if(page >= 0x04 && page < 0x08) { 1062 | screenWrite(address, value); 1063 | } else if (page >= 0x08 && page < 0x10) { 1064 | basic[address-0x800] = value; 1065 | } else { 1066 | // Keyboard Strobe 1067 | if(address == 0xC010) keyboard_strobe(); 1068 | // Speaker toggle 1069 | if(address == 0xC030) speaker_toggle(); 1070 | } 1071 | } 1072 | 1073 | void write16(unsigned short address, unsigned short value) { 1074 | write8(address, value&0x00FF); 1075 | write8(address+1, (value>>8)&0x00FF); 1076 | } 1077 | 1078 | --------------------------------------------------------------------------------