mirror of
https://github.com/dpeckett/arduino-appleii.git
synced 2024-12-26 10:32:54 +00:00
First Commit
Uploading Current Source To Github
This commit is contained in:
parent
909e1ac9e2
commit
2798ae6d16
313
6502tests/test.c
Normal file
313
6502tests/test.c
Normal file
@ -0,0 +1,313 @@
|
||||
/*
|
||||
|
||||
Bunch of unit tests I wrote during the development of the emulator.
|
||||
These are very nasty and not really release worthy but someone might
|
||||
find them useful!
|
||||
|
||||
Copyright (c) 2015, Damian Peckett <damian.peckett@gmail.com>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
//TEST Functions
|
||||
|
||||
#include "test/testAdc.c"
|
||||
#include "test/testAnd.c"
|
||||
#include "test/testAsl.c"
|
||||
#include "test/testBcc.c"
|
||||
#include "test/testBcs.c"
|
||||
#include "test/testBeq.c"
|
||||
#include "test/testBit.c"
|
||||
#include "test/testBmi.c"
|
||||
#include "test/testBne.c"
|
||||
#include "test/testBpl.c"
|
||||
#include "test/testBrk.c"
|
||||
#include "test/testBvc.c"
|
||||
#include "test/testBvs.c"
|
||||
#include "test/testClear.c"
|
||||
#include "test/testCmp.c"
|
||||
#include "test/testCpx.c"
|
||||
#include "test/testCpy.c"
|
||||
#include "test/testDec.c"
|
||||
#include "test/testEor.c"
|
||||
#include "test/testInc.c"
|
||||
#include "test/testJmp.c"
|
||||
#include "test/testLd.c"
|
||||
#include "test/testLsr.c"
|
||||
#include "test/testOra.c"
|
||||
#include "test/testPha.c"
|
||||
#include "test/testPhp.c"
|
||||
#include "test/testPla.c"
|
||||
#include "test/testPlp.c"
|
||||
#include "test/testRol.c"
|
||||
#include "test/testRor.c"
|
||||
#include "test/testRti.c"
|
||||
#include "test/testRts.c"
|
||||
#include "test/testSbc.c"
|
||||
#include "test/testSet.c"
|
||||
#include "test/testSta.c"
|
||||
#include "test/testSt.c"
|
||||
#include "test/testTransfer.c"
|
||||
|
||||
void testAdc() {
|
||||
printf("testAdcImmediate: %d\r\n", testAdcImmediate());
|
||||
printf("testAdcZeropage: %d\r\n", testAdcZeropage());
|
||||
printf("testAdcZeropageX: %d\r\n", testAdcZeropageX());
|
||||
printf("testAdcAbsolute: %d\r\n", testAdcAbsolute());
|
||||
printf("testAdcAbsoluteX: %d\r\n", testAdcAbsoluteX());
|
||||
printf("testAdcAbsoluteY: %d\r\n", testAdcAbsoluteY());
|
||||
printf("testAdcIndirectX: %d\r\n", testAdcIndirectX());
|
||||
printf("testAdcIndirectY: %d\r\n", testAdcIndirectY());
|
||||
}
|
||||
|
||||
void testAnd() {
|
||||
printf("testAndImmediate: %d\r\n", testAndImmediate());
|
||||
printf("testAndZeropage: %d\r\n", testAndZeropage());
|
||||
printf("testAndZeropageX: %d\r\n", testAndZeropageX());
|
||||
printf("testAndAbsolute: %d\r\n", testAndAbsolute());
|
||||
printf("testAndAbsoluteX: %d\r\n", testAndAbsoluteX());
|
||||
printf("testAndAbsoluteY: %d\r\n", testAndAbsoluteY());
|
||||
printf("testAndIndirectX: %d\r\n", testAndIndirectX());
|
||||
printf("testAndIndirectY: %d\r\n", testAndIndirectY());
|
||||
}
|
||||
|
||||
void testAsl() {
|
||||
printf("testAslImplied: %d\r\n", testAslImplied());
|
||||
printf("testAslZeropage: %d\r\n", testAslZeropage());
|
||||
printf("testAslZeropageX: %d\r\n", testAslZeropageX());
|
||||
printf("testAslAbsolute: %d\r\n", testAslAbsolute());
|
||||
printf("testAslAbsoluteX: %d\r\n", testAslAbsoluteX());
|
||||
}
|
||||
|
||||
void testBranches() {
|
||||
printf("testBccImplied: %d\r\n", testBccImplied());
|
||||
printf("testBcsImplied: %d\r\n", testBcsImplied());
|
||||
printf("testBeqImplied: %d\r\n", testBeqImplied());
|
||||
printf("testBmiImplied: %d\r\n", testBmiImplied());
|
||||
printf("testBneImplied: %d\r\n", testBneImplied());
|
||||
printf("testBplImplied: %d\r\n", testBplImplied());
|
||||
printf("testBvcImplied: %d\r\n", testBvcImplied());
|
||||
printf("testBvsImplied: %d\r\n", testBvsImplied());
|
||||
}
|
||||
|
||||
void testBit() {
|
||||
printf("testBitZeropage: %d\r\n", testBitZeropage());
|
||||
printf("testBitAbsolute: %d\r\n", testBitAbsolute());
|
||||
}
|
||||
|
||||
void testBrk() {
|
||||
printf("testBrkImplied: %d\r\n", testBrkImplied());
|
||||
}
|
||||
|
||||
void testClear() {
|
||||
printf("testClcImplied: %d\r\n", testClcImplied());
|
||||
printf("testCldImplied: %d\r\n", testCldImplied());
|
||||
printf("testCliImplied: %d\r\n", testCliImplied());
|
||||
printf("testClvImplied: %d\r\n", testClvImplied());
|
||||
}
|
||||
|
||||
void testCompare() {
|
||||
printf("testCmpImmediate: %d\r\n", testCmpImmediate());
|
||||
printf("testCmpZeropage: %d\r\n", testCmpZeropage());
|
||||
printf("testCmpZeropageX: %d\r\n", testCmpZeropageX());
|
||||
printf("testCmpAbsolute: %d\r\n", testCmpAbsolute());
|
||||
printf("testCmpAbsoluteX: %d\r\n", testCmpAbsoluteX());
|
||||
printf("testCmpAbsoluteY: %d\r\n", testCmpAbsoluteY());
|
||||
printf("testCmpIndirectX: %d\r\n", testCmpIndirectX());
|
||||
printf("testCmpIndirectY: %d\r\n", testCmpIndirectY());
|
||||
printf("testCpxImmediate: %d\r\n", testCpxImmediate());
|
||||
printf("testCpxZeropage: %d\r\n", testCpxZeropage());
|
||||
printf("testCpxAbsolute: %d\r\n", testCpxAbsolute());
|
||||
printf("testCpyImmediate: %d\r\n", testCpyImmediate());
|
||||
printf("testCpyZeropage: %d\r\n", testCpyZeropage());
|
||||
printf("testCpyAbsolute: %d\r\n", testCpyAbsolute());
|
||||
}
|
||||
|
||||
void testDec() {
|
||||
printf("testDecZeropage: %d\r\n", testDecZeropage());
|
||||
printf("testDecZeropageX: %d\r\n", testDecZeropageX());
|
||||
printf("testDecAbsolute: %d\r\n", testDecAbsolute());
|
||||
printf("testDexImplied: %d\r\n", testDexImplied());
|
||||
printf("testDeyImplied: %d\r\n", testDeyImplied());
|
||||
}
|
||||
|
||||
void testEor() {
|
||||
printf("testEorImmediate: %d\r\n", testEorImmediate());
|
||||
printf("testEorZeropage: %d\r\n", testEorZeropage());
|
||||
printf("testEorZeropageX: %d\r\n", testEorZeropageX());
|
||||
printf("testEorAbsolute: %d\r\n", testEorAbsolute());
|
||||
printf("testEorAbsoluteX: %d\r\n", testEorAbsoluteX());
|
||||
printf("testEorAbsoluteY: %d\r\n", testEorAbsoluteY());
|
||||
printf("testEorIndirectX: %d\r\n", testEorIndirectX());
|
||||
printf("testEorIndirectY: %d\r\n", testEorIndirectY());
|
||||
}
|
||||
|
||||
void testInc() {
|
||||
printf("testIncZeropage: %d\r\n", testIncZeropage());
|
||||
printf("testIncZeropageX: %d\r\n", testIncZeropageX());
|
||||
printf("testIncAbsolute: %d\r\n", testIncAbsolute());
|
||||
printf("testInxImplied: %d\r\n", testInxImplied());
|
||||
printf("testInyImplied: %d\r\n", testInyImplied());
|
||||
}
|
||||
|
||||
void testJmp() {
|
||||
printf("testJmpAbsolute: %d\r\n", testJmpAbsolute());
|
||||
printf("testJmpIndirect: %d\r\n", testJmpIndirect());
|
||||
printf("testJsrAbsolute: %d\r\n", testJsrAbsolute());
|
||||
}
|
||||
|
||||
void testLoads() {
|
||||
printf("testLdaImmediate: %d\r\n", testLdaImmediate());
|
||||
printf("testLdaZeropage: %d\r\n", testLdaZeropage());
|
||||
printf("testLdaZeropageX: %d\r\n", testLdaZeropageX());
|
||||
printf("testLdaAbsolute: %d\r\n", testLdaAbsolute());
|
||||
printf("testLdaAbsoluteX: %d\r\n", testLdaAbsoluteX());
|
||||
printf("testLdaAbsoluteY: %d\r\n", testLdaAbsoluteY());
|
||||
printf("testLdaIndirectX: %d\r\n", testJmpAbsolute());
|
||||
printf("testLdaIndirectY: %d\r\n", testLdaIndirectY());
|
||||
printf("testLdxImmediate: %d\r\n", testLdxImmediate());
|
||||
printf("testLdxZeropage: %d\r\n", testLdxZeropage());
|
||||
printf("testLdxZeropageY: %d\r\n", testLdxZeropageY());
|
||||
printf("testLdxAbsolute: %d\r\n", testLdxAbsolute());
|
||||
printf("testLdxAbsoluteY: %d\r\n", testLdxAbsoluteY());
|
||||
printf("testLdyImmediate: %d\r\n", testLdyImmediate());
|
||||
printf("testLdyZeropage: %d\r\n", testLdyZeropage());
|
||||
printf("testLdyZeropageX: %d\r\n", testLdyZeropageX());
|
||||
printf("testLdyAbsolute: %d\r\n", testLdyAbsolute());
|
||||
printf("testLdyAbsoluteX: %d\r\n", testLdyAbsoluteX());
|
||||
}
|
||||
|
||||
void testLsr() {
|
||||
printf("testLsrImplied: %d\r\n", testLsrImplied());
|
||||
printf("testLsrZeropage: %d\r\n", testLsrZeropage());
|
||||
printf("testLdyZeropageX: %d\r\n", testLsrZeropageX());
|
||||
printf("testLsrAbsolute: %d\r\n", testLsrAbsolute());
|
||||
printf("testLsrAbsoluteX: %d\r\n", testLsrAbsoluteX());
|
||||
}
|
||||
|
||||
void testOra() {
|
||||
printf("testOraImmediate: %d\r\n", testOraImmediate());
|
||||
printf("testOraZeropage: %d\r\n", testOraZeropage());
|
||||
printf("testOraZeropageX: %d\r\n", testOraZeropageX());
|
||||
printf("testOraAbsolute: %d\r\n", testOraAbsolute());
|
||||
printf("testOraAbsoluteX: %d\r\n", testOraAbsoluteX());
|
||||
printf("testOraAbsoluteY: %d\r\n", testOraAbsoluteY());
|
||||
printf("testOraIndirectX: %d\r\n", testOraIndirectX());
|
||||
printf("testOraIndirectY: %d\r\n", testOraIndirectY());
|
||||
}
|
||||
|
||||
void testStack() {
|
||||
printf("testPhaImplied: %d\r\n", testPhaImplied());
|
||||
printf("testPhpImplied: %d\r\n", testPhpImplied());
|
||||
printf("testPlaImplied: %d\r\n", testPlaImplied());
|
||||
printf("testPlpImplied: %d\r\n", testPlpImplied());
|
||||
}
|
||||
|
||||
void testRotate() {
|
||||
printf("testRolImplied: %d\r\n", testRolImplied());
|
||||
printf("testRolZeropage: %d\r\n", testRolZeropage());
|
||||
printf("testRolZeropageX: %d\r\n", testRolZeropageX());
|
||||
printf("testRolAbsolute: %d\r\n", testRolAbsolute());
|
||||
printf("testRolAbsoluteX: %d\r\n", testRolAbsoluteX());
|
||||
printf("testRorImplied: %d\r\n", testRorImplied());
|
||||
printf("testRorZeropage: %d\r\n", testRorZeropage());
|
||||
printf("testRorZeropageX: %d\r\n", testRorZeropageX());
|
||||
printf("testRorAbsolute: %d\r\n", testRorAbsolute());
|
||||
printf("testRorAbsoluteX: %d\r\n", testRorAbsoluteX());
|
||||
}
|
||||
|
||||
void testReturn() {
|
||||
printf("testRtiImplied: %d\r\n", testRtiImplied());
|
||||
printf("testRtsImplied: %d\r\n", testRtsImplied());
|
||||
}
|
||||
|
||||
void testSbc() {
|
||||
printf("testSbcImmediate: %d\r\n", testSbcImmediate());
|
||||
printf("testSbcZeropage: %d\r\n", testSbcZeropage());
|
||||
printf("testSbcZeropageX: %d\r\n", testSbcZeropageX());
|
||||
printf("testSbcAbsolute: %d\r\n", testSbcAbsolute());
|
||||
printf("testSbcAbsoluteX: %d\r\n", testSbcAbsoluteX());
|
||||
printf("testSbcAbsoluteY: %d\r\n", testSbcAbsoluteY());
|
||||
printf("testSbcIndirectX: %d\r\n", testSbcIndirectX());
|
||||
printf("testSbcIndirectY: %d\r\n", testSbcIndirectY());
|
||||
}
|
||||
|
||||
void testSet() {
|
||||
printf("testSecImplied: %d\r\n", testSecImplied());
|
||||
printf("testSedImplied: %d\r\n", testSedImplied());
|
||||
printf("testSeiImplied: %d\r\n", testSeiImplied());
|
||||
}
|
||||
|
||||
void testSta() {
|
||||
printf("testStaZeropage: %d\r\n", testStaZeropage());
|
||||
printf("testStaZeropageX: %d\r\n", testStaZeropageX());
|
||||
printf("testStaAbsolute: %d\r\n", testStaAbsolute());
|
||||
printf("testStaAbsoluteX: %d\r\n", testStaAbsoluteX());
|
||||
printf("testStaAbsoluteY: %d\r\n", testStaAbsoluteY());
|
||||
printf("testStaIndirectX: %d\r\n", testStaIndirectX());
|
||||
printf("testStaIndirectY: %d\r\n", testStaIndirectY());
|
||||
}
|
||||
|
||||
void testStores() {
|
||||
printf("testStxZeropage: %d\r\n", testStxZeropage());
|
||||
printf("testStxZeropageY: %d\r\n", testStxZeropageY());
|
||||
printf("testStxAbsolute: %d\r\n", testStxAbsolute());
|
||||
printf("testStyZeropage: %d\r\n", testStyZeropage());
|
||||
printf("testStyZeropageX: %d\r\n", testStyZeropageX());
|
||||
printf("testStyAbsolute: %d\r\n", testStyAbsolute());
|
||||
}
|
||||
|
||||
void testTransfer() {
|
||||
printf("testTaxImplied: %d\r\n", testTaxImplied());
|
||||
printf("testTayImplied: %d\r\n", testTayImplied());
|
||||
printf("testTsxImplied: %d\r\n", testTsxImplied());
|
||||
printf("testTxaImplied: %d\r\n", testTxaImplied());
|
||||
printf("testTxsImplied: %d\r\n", testTxsImplied());
|
||||
printf("testTyaImplied: %d\r\n", testTyaImplied());
|
||||
}
|
||||
|
||||
int main() {
|
||||
testAnd();
|
||||
testAdc();
|
||||
testAsl();
|
||||
testBranches();
|
||||
testBit();
|
||||
testBrk();
|
||||
testClear();
|
||||
testCompare();
|
||||
testDec();
|
||||
testEor();
|
||||
testInc();
|
||||
testJmp();
|
||||
testLoads();
|
||||
testLsr();
|
||||
testOra();
|
||||
testStack();
|
||||
testRotate();
|
||||
testReturn();
|
||||
testSbc();
|
||||
testSet();
|
||||
testSta();
|
||||
testStores();
|
||||
testTransfer();
|
||||
return 0;
|
||||
}
|
10
6502tests/test/test.iml
Normal file
10
6502tests/test/test.iml
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
|
503
6502tests/test/testAdc.c
Normal file
503
6502tests/test/testAdc.c
Normal file
@ -0,0 +1,503 @@
|
||||
int testAdcImmediate() {
|
||||
//no carry
|
||||
A = 0x00;
|
||||
SR&=(~SR_CARRY);
|
||||
ram[0] = 0x69;
|
||||
ram[1] = 0x01;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x01 && !SR&SR_NEG && !SR&SR_ZERO && !SR&SR_CARRY && !SR&SR_OVER)) return -1;
|
||||
|
||||
//with carry
|
||||
A = 0x00;
|
||||
SR|=SR_CARRY;
|
||||
ram[0] = 0x69;
|
||||
ram[1] = 0x01;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x02 && !(SR&SR_NEG) && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -2;
|
||||
|
||||
//negative result
|
||||
A = 0xFE;
|
||||
SR&=(~SR_CARRY);
|
||||
ram[0] = 0x69;
|
||||
ram[1] = 0xFE;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0xFC && SR&SR_NEG && !(SR&SR_ZERO) && SR&SR_CARRY && !(SR&SR_OVER))) return -3;
|
||||
|
||||
//overflow result
|
||||
A = 0x80;
|
||||
SR&=(~SR_CARRY);
|
||||
ram[0] = 0x69;
|
||||
ram[1] = 0xFF;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x7F && !(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY && SR&SR_OVER)) return -4;
|
||||
|
||||
//zero result
|
||||
A = 0xFF; //-1
|
||||
SR&=(~SR_CARRY);
|
||||
ram[0] = 0x69;
|
||||
ram[1] = 0x01; //+1
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY && !(SR&SR_OVER))) return -5;
|
||||
|
||||
//carry result
|
||||
A = 0xF0; //+70
|
||||
SR&=(~SR_CARRY);
|
||||
ram[0] = 0x69;
|
||||
ram[1] = 0xF0; //+70
|
||||
instructions = 1; run();
|
||||
if(!(A == 0xE0 && SR&SR_NEG && !(SR&SR_ZERO) && SR&SR_CARRY && !(SR&SR_OVER))) return -6;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testAdcZeropage() {
|
||||
//no carry
|
||||
A = 0x00;
|
||||
SR &= (~SR_CARRY);
|
||||
ram[0] = 0x65;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x01;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x01 && !(SR&SR_NEG) && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1;
|
||||
|
||||
//with carry
|
||||
A = 0x00;
|
||||
SR |= SR_CARRY;
|
||||
ram[0] = 0x65;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x01;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x02 && !(SR&SR_NEG) && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -2;
|
||||
|
||||
//negative result
|
||||
A = 0xFE;
|
||||
SR &= (~SR_CARRY);
|
||||
ram[0] = 0x65;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0xFE;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0xFC && SR&SR_NEG && !(SR&SR_ZERO) && SR&SR_CARRY && !(SR&SR_OVER))) return -3;
|
||||
|
||||
//overflow result
|
||||
A = 0x80;
|
||||
SR &= (~SR_CARRY);
|
||||
ram[0] = 0x65;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0xFF;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x7F && !(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY && SR&SR_OVER)) return -4;
|
||||
|
||||
//zero result
|
||||
A = 0xFF; //-1
|
||||
SR &= (~SR_CARRY);
|
||||
ram[0] = 0x65;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x01; //+1
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY && !(SR&SR_OVER))) return -5;
|
||||
|
||||
//carry result
|
||||
A = 0xF0; //+70
|
||||
SR &= (~SR_CARRY);
|
||||
ram[0] = 0x65;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0xF0; //+70
|
||||
instructions = 1; run();
|
||||
if(!(A == 0xE0 && SR&SR_NEG && !(SR&SR_ZERO) && SR&SR_CARRY && !(SR&SR_OVER))) return -6;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testAdcZeropageX() {
|
||||
X = 0x01; Y=0x00;
|
||||
|
||||
//no carry
|
||||
A = 0x00;
|
||||
SR &= (~SR_CARRY);
|
||||
ram[0] = 0x75;
|
||||
ram[1] = 0x02;
|
||||
ram[3] = 0x01;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x01 && !(SR&SR_NEG) && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1;
|
||||
|
||||
//with carry
|
||||
A = 0x00;
|
||||
SR |= SR_CARRY;
|
||||
ram[0] = 0x75;
|
||||
ram[1] = 0x02;
|
||||
ram[3] = 0x01;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x02 && !(SR&SR_NEG) && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -2;
|
||||
|
||||
//negative result
|
||||
A = 0xFE;
|
||||
SR &= (~SR_CARRY);
|
||||
ram[0] = 0x75;
|
||||
ram[1] = 0x02;
|
||||
ram[3] = 0xFE;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0xFC && SR&SR_NEG && !(SR&SR_ZERO) && SR&SR_CARRY && !(SR&SR_OVER))) return -3;
|
||||
|
||||
//overflow result
|
||||
A = 0x80;
|
||||
SR &= (~SR_CARRY);
|
||||
ram[0] = 0x75;
|
||||
ram[1] = 0x02;
|
||||
ram[3] = 0xFF;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x7F && !(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY && SR&SR_OVER)) return -4;
|
||||
|
||||
//zero result
|
||||
A = 0xFF; //-1
|
||||
SR &= (~SR_CARRY);
|
||||
ram[0] = 0x75;
|
||||
ram[1] = 0x02;
|
||||
ram[3] = 0x01; //+1
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY && !(SR&SR_OVER))) return -5;
|
||||
|
||||
//carry result
|
||||
A = 0xF0; //+70
|
||||
SR &= (~SR_CARRY);
|
||||
ram[0] = 0x75;
|
||||
ram[1] = 0x02;
|
||||
ram[3] = 0xF0; //+70
|
||||
instructions = 1; run();
|
||||
if(!(A == 0xE0 && SR&SR_NEG && !(SR&SR_ZERO) && SR&SR_CARRY && !(SR&SR_OVER))) return -6;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testAdcAbsolute() {
|
||||
//no carry
|
||||
A = 0x00;
|
||||
SR &= (~SR_CARRY);
|
||||
ram[0] = 0x6D;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x01;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x01 && !(SR&SR_NEG) && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1;
|
||||
|
||||
//with carry
|
||||
A = 0x00;
|
||||
SR |= SR_CARRY;
|
||||
ram[0] = 0x6D;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x01;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x02 && !(SR&SR_NEG) && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -2;
|
||||
|
||||
//negative result
|
||||
A = 0xFE;
|
||||
SR &= (~SR_CARRY);
|
||||
ram[0] = 0x6D;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0xFE;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0xFC && SR&SR_NEG && !(SR&SR_ZERO) && SR&SR_CARRY && !(SR&SR_OVER))) return -3;
|
||||
|
||||
//overflow result
|
||||
A = 0x80;
|
||||
SR &= (~SR_CARRY);
|
||||
ram[0] = 0x6D;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0xFF;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x7F && !(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY && SR&SR_OVER)) return -4;
|
||||
|
||||
//zero result
|
||||
A = 0xFF; //-1
|
||||
SR &= (~SR_CARRY);
|
||||
ram[0] = 0x6D;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x01; //+1
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY && !(SR&SR_OVER))) return -5;
|
||||
|
||||
//carry result
|
||||
A = 0xF0; //+70
|
||||
SR &= (~SR_CARRY);
|
||||
ram[0] = 0x6D;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0xF0; //+70
|
||||
instructions = 1; run();
|
||||
if(!(A == 0xE0 && SR&SR_NEG && !(SR&SR_ZERO) && SR&SR_CARRY && !(SR&SR_OVER))) return -6;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testAdcAbsoluteX() {
|
||||
X = 0x01; Y = 0x00;
|
||||
|
||||
//no carry
|
||||
A = 0x00;
|
||||
SR &= (~SR_CARRY);
|
||||
ram[0] = 0x7D;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x01;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x01 && !(SR&SR_NEG) && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1;
|
||||
|
||||
//with carry
|
||||
A = 0x00;
|
||||
SR |= SR_CARRY;
|
||||
ram[0] = 0x7D;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x01;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x02 && !(SR&SR_NEG) && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -2;
|
||||
|
||||
//negative result
|
||||
A = 0xFE;
|
||||
SR &= (~SR_CARRY);
|
||||
ram[0] = 0x7D;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0xFE;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0xFC && SR&SR_NEG && !(SR&SR_ZERO) && SR&SR_CARRY && !(SR&SR_OVER))) return -3;
|
||||
|
||||
//overflow result
|
||||
A = 0x80;
|
||||
SR &= (~SR_CARRY);
|
||||
ram[0] = 0x7D;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0xFF;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x7F && !(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY && SR&SR_OVER)) return -4;
|
||||
|
||||
//zero result
|
||||
A = 0xFF; //-1
|
||||
SR &= (~SR_CARRY);
|
||||
ram[0] = 0x7D;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x01; //+1
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY && !(SR&SR_OVER))) return -5;
|
||||
|
||||
//carry result
|
||||
A = 0xF0; //+70
|
||||
SR &= (~SR_CARRY);
|
||||
ram[0] = 0x7D;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0xF0; //+70
|
||||
instructions = 1; run();
|
||||
if(!(A == 0xE0 && SR&SR_NEG && !(SR&SR_ZERO) && SR&SR_CARRY && !(SR&SR_OVER))) return -6;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testAdcAbsoluteY() {
|
||||
Y = 0x01; X = 0x00;
|
||||
|
||||
//no carry
|
||||
A = 0x00;
|
||||
SR &= (~SR_CARRY);
|
||||
ram[0] = 0x79;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x01;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x01 && !(SR&SR_NEG) && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1;
|
||||
|
||||
//with carry
|
||||
A = 0x00;
|
||||
SR |= SR_CARRY;
|
||||
ram[0] = 0x79;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x01;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x02 && !(SR&SR_NEG) && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -2;
|
||||
|
||||
//negative result
|
||||
A = 0xFE;
|
||||
SR &= (~SR_CARRY);
|
||||
ram[0] = 0x79;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0xFE;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0xFC && SR&SR_NEG && !(SR&SR_ZERO) && SR&SR_CARRY && !(SR&SR_OVER))) return -3;
|
||||
|
||||
//overflow result
|
||||
A = 0x80;
|
||||
SR &= (~SR_CARRY);
|
||||
ram[0] = 0x79;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0xFF;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x7F && !(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY && SR&SR_OVER)) return -4;
|
||||
|
||||
//zero result
|
||||
A = 0xFF; //-1
|
||||
SR &= (~SR_CARRY);
|
||||
ram[0] = 0x79;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x01; //+1
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY && !(SR&SR_OVER))) return -5;
|
||||
|
||||
//carry result
|
||||
A = 0xF0; //+70
|
||||
SR &= (~SR_CARRY);
|
||||
ram[0] = 0x79;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0xF0; //+70
|
||||
instructions = 1; run();
|
||||
if(!(A == 0xE0 && SR&SR_NEG && !(SR&SR_ZERO) && SR&SR_CARRY && !(SR&SR_OVER))) return -6;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testAdcIndirectX() {
|
||||
X = 0x01; Y = 0x00;
|
||||
|
||||
//no carry
|
||||
A = 0x00;
|
||||
SR &= (~SR_CARRY);
|
||||
ram[0] = 0x61;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x02;
|
||||
ram[3] = 0x01;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x01 && !(SR&SR_NEG) && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1;
|
||||
|
||||
//with carry
|
||||
A = 0x00;
|
||||
SR |= SR_CARRY;
|
||||
ram[0] = 0x61;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x02;
|
||||
ram[3] = 0x01;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x02 && !(SR&SR_NEG) && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -2;
|
||||
|
||||
//negative result
|
||||
A = 0xFE;
|
||||
SR &= (~SR_CARRY);
|
||||
ram[0] = 0x61;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x02;
|
||||
ram[3] = 0xFE;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0xFC && SR&SR_NEG && !(SR&SR_ZERO) && SR&SR_CARRY && !(SR&SR_OVER))) return -3;
|
||||
|
||||
//overflow result
|
||||
A = 0x80;
|
||||
SR &= (~SR_CARRY);
|
||||
ram[0] = 0x61;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x02;
|
||||
ram[3] = 0xFF;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x7F && !(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY && SR&SR_OVER)) return -4;
|
||||
|
||||
//zero result
|
||||
A = 0xFF; //-1
|
||||
SR &= (~SR_CARRY);
|
||||
ram[0] = 0x61;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x02;
|
||||
ram[3] = 0x01; //+1
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY && !(SR&SR_OVER))) return -5;
|
||||
|
||||
//carry result
|
||||
A = 0xF0; //+70
|
||||
SR &= (~SR_CARRY);
|
||||
ram[0] = 0x61;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x02;
|
||||
ram[3] = 0xF0; //+70
|
||||
instructions = 1; run();
|
||||
if(!(A == 0xE0 && SR&SR_NEG && !(SR&SR_ZERO) && SR&SR_CARRY && !(SR&SR_OVER))) return -6;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testAdcIndirectY() {
|
||||
Y = 0x01; X = 0x00;
|
||||
|
||||
//no carry
|
||||
A = 0x00;
|
||||
SR &= (~SR_CARRY);
|
||||
ram[0] = 0x71;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x03;
|
||||
ram[3] = 0x00;
|
||||
ram[4] = 0x01;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x01 && !(SR&SR_NEG) && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1;
|
||||
|
||||
//with carry
|
||||
A = 0x00;
|
||||
SR |= SR_CARRY;
|
||||
ram[0] = 0x71;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x03;
|
||||
ram[3] = 0x00;
|
||||
ram[4] = 0x01;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x02 && !(SR&SR_NEG) && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -2;
|
||||
|
||||
//negative result
|
||||
A = 0xFE;
|
||||
SR &= (~SR_CARRY);
|
||||
ram[0] = 0x71;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x03;
|
||||
ram[3] = 0x00;
|
||||
ram[4] = 0xFE;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0xFC && SR&SR_NEG && !(SR&SR_ZERO) && SR&SR_CARRY && !(SR&SR_OVER))) return -3;
|
||||
|
||||
//overflow result
|
||||
A = 0x80;
|
||||
SR &= (~SR_CARRY);
|
||||
ram[0] = 0x71;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x03;
|
||||
ram[3] = 0x00;
|
||||
ram[4] = 0xFF;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x7F && !(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY && SR&SR_OVER)) return -4;
|
||||
|
||||
//zero result
|
||||
A = 0xFF; //-1
|
||||
SR &= (~SR_CARRY);
|
||||
ram[0] = 0x71;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x03;
|
||||
ram[3] = 0x00;
|
||||
ram[4] = 0x01;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY && !(SR&SR_OVER))) return -5;
|
||||
|
||||
//carry result
|
||||
A = 0xF0; //+70
|
||||
SR &= (~SR_CARRY);
|
||||
ram[0] = 0x71;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x03;
|
||||
ram[3] = 0x00;
|
||||
ram[4] = 0xF0;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0xE0 && SR&SR_NEG && !(SR&SR_ZERO) && SR&SR_CARRY && !(SR&SR_OVER))) return -6;
|
||||
|
||||
return 0;
|
||||
}
|
174
6502tests/test/testAnd.c
Normal file
174
6502tests/test/testAnd.c
Normal file
@ -0,0 +1,174 @@
|
||||
int testAndImmediate() {
|
||||
A = 0xFF;
|
||||
|
||||
//all high
|
||||
ram[0] = 0x29;
|
||||
ram[1] = 0xFF;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1;
|
||||
|
||||
//all low
|
||||
ram[0] = 0x29;
|
||||
ram[1] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testAndZeropage() {
|
||||
A = 0xFF;
|
||||
|
||||
//all high
|
||||
ram[0] = 0x25;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0xFF;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1;
|
||||
|
||||
//all low
|
||||
ram[0] = 0x25;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testAndZeropageX() {
|
||||
X = 0x01; Y = 0x00;
|
||||
A = 0xFF;
|
||||
|
||||
//all high
|
||||
ram[0] = 0x35;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0xFF;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1;
|
||||
|
||||
//all low
|
||||
ram[0] = 0x35;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testAndAbsolute() {
|
||||
A = 0xFF;
|
||||
|
||||
//all high
|
||||
ram[0] = 0x2D;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0xFF;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1;
|
||||
|
||||
//all low
|
||||
ram[0] = 0x2D;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testAndAbsoluteX() {
|
||||
A = 0xFF;
|
||||
X = 0x01; Y = 0x00;
|
||||
|
||||
//all high
|
||||
ram[0] = 0x3D;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0xFF;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1;
|
||||
|
||||
//all low
|
||||
ram[0] = 0x3D;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testAndAbsoluteY() {
|
||||
A = 0xFF;
|
||||
Y = 0x01; X = 0x00;
|
||||
|
||||
//all high
|
||||
ram[0] = 0x39;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0xFF;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1;
|
||||
|
||||
//all low
|
||||
ram[0] = 0x39;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testAndIndirectX() {
|
||||
A = 0xFF;
|
||||
X = 0x01; Y = 0x00;
|
||||
|
||||
//all high
|
||||
ram[0] = 0x21;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x02;
|
||||
ram[3] = 0xFF;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1;
|
||||
|
||||
//all low
|
||||
ram[0] = 0x21;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x02;
|
||||
ram[3] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testAndIndirectY() {
|
||||
A = 0xFF;
|
||||
Y = 0x01; X = 0x00;
|
||||
|
||||
//all high
|
||||
ram[0] = 0x31;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x03;
|
||||
ram[3] = 0x00;
|
||||
ram[4] = 0xFF;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1;
|
||||
|
||||
//all low
|
||||
ram[0] = 0x31;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x03;
|
||||
ram[3] = 0x00;
|
||||
ram[4] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
131
6502tests/test/testAsl.c
Normal file
131
6502tests/test/testAsl.c
Normal file
@ -0,0 +1,131 @@
|
||||
int testAslImplied() {
|
||||
//normal
|
||||
A = 0x01;
|
||||
ram[0] = 0x0A;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x02 && !(SR&SR_NEG) && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1;
|
||||
|
||||
//carry and zero
|
||||
A = 0x80;
|
||||
ram[0] = 0x0A;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY && !(SR&SR_OVER))) return -2;
|
||||
|
||||
//carry and negative
|
||||
A = 0xC0;
|
||||
ram[0] = 0x0A;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x80 && SR&SR_NEG && !(SR&SR_ZERO) && SR&SR_CARRY && !(SR&SR_OVER))) return -3;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testAslZeropage() {
|
||||
//normal
|
||||
ram[0] = 0x06;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x01;
|
||||
instructions = 1; run();
|
||||
if(!(ram[2] == 0x02 && !(SR&SR_NEG) && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1;
|
||||
|
||||
//carry and zero
|
||||
ram[0] = 0x06;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x80;
|
||||
instructions = 1; run();
|
||||
if(!(ram[2] == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY && !(SR&SR_OVER))) return -2;
|
||||
|
||||
//carry and negative
|
||||
ram[0] = 0x06;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0xC0;
|
||||
instructions = 1; run();
|
||||
if(!(ram[2] == 0x80 && SR&SR_NEG && !(SR&SR_ZERO) && SR&SR_CARRY && !(SR&SR_OVER))) return -3;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testAslZeropageX() {
|
||||
X = 0x01; Y = 0x00;
|
||||
|
||||
//normal
|
||||
ram[0] = 0x16;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x01;
|
||||
instructions = 1; run();
|
||||
if(!(ram[2] == 0x02 && !(SR&SR_NEG) && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1;
|
||||
|
||||
//carry and zero
|
||||
ram[0] = 0x16;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x80;
|
||||
instructions = 1; run();
|
||||
if(!(ram[2] == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY && !(SR&SR_OVER))) return -2;
|
||||
|
||||
//carry and negative
|
||||
ram[0] = 0x16;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0xC0;
|
||||
instructions = 1; run();
|
||||
if(!(ram[2] == 0x80 && SR&SR_NEG && !(SR&SR_ZERO) && SR&SR_CARRY && !(SR&SR_OVER))) return -3;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testAslAbsolute() {
|
||||
//normal
|
||||
ram[0] = 0x0E;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x01;
|
||||
instructions = 1; run();
|
||||
if(!(ram[3] == 0x02 && !(SR&SR_NEG) && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1;
|
||||
|
||||
//carry and zero
|
||||
ram[0] = 0x0E;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x80;
|
||||
instructions = 1; run();
|
||||
if(!(ram[3] == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY && !(SR&SR_OVER))) return -2;
|
||||
|
||||
//carry and negative
|
||||
ram[0] = 0x0E;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0xC0;
|
||||
instructions = 1; run();
|
||||
if(!(ram[3] == 0x80 && SR&SR_NEG && !(SR&SR_ZERO) && SR&SR_CARRY && !(SR&SR_OVER))) return -3;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testAslAbsoluteX() {
|
||||
X = 0x01; Y = 0x00;
|
||||
|
||||
//normal
|
||||
ram[0] = 0x1E;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x01;
|
||||
instructions = 1; run();
|
||||
if(!(ram[3] == 0x02 && !(SR&SR_NEG) && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1;
|
||||
|
||||
//carry and zero
|
||||
ram[0] = 0x1E;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x80;
|
||||
instructions = 1; run();
|
||||
if(!(ram[3] == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY && !(SR&SR_OVER))) return -2;
|
||||
|
||||
//carry and negative
|
||||
ram[0] = 0x1E;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0xC0;
|
||||
instructions = 1; run();
|
||||
if(!(ram[3] == 0x80 && SR&SR_NEG && !(SR&SR_ZERO) && SR&SR_CARRY && !(SR&SR_OVER))) return -3;
|
||||
|
||||
return 0;
|
||||
}
|
23
6502tests/test/testBcc.c
Normal file
23
6502tests/test/testBcc.c
Normal file
@ -0,0 +1,23 @@
|
||||
int testBccImplied() {
|
||||
SR|=SR_CARRY;
|
||||
SR&=(~SR_DEC);
|
||||
ram[0] = 0x90;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0xF8; //SED
|
||||
instructions = 4;
|
||||
run();
|
||||
if((SR&SR_DEC) > 0) return -1;
|
||||
|
||||
SR&=(~SR_CARRY);
|
||||
SR&=(~SR_DEC);
|
||||
ram[0] = 0x90;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0xF8;
|
||||
instructions = 4;
|
||||
run();
|
||||
if((SR&SR_DEC) == 0) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
23
6502tests/test/testBcs.c
Normal file
23
6502tests/test/testBcs.c
Normal file
@ -0,0 +1,23 @@
|
||||
int testBcsImplied() {
|
||||
SR|=SR_CARRY;
|
||||
SR&=(~SR_DEC);
|
||||
ram[0] = 0xB0;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0xF8; //SED
|
||||
instructions = 4;
|
||||
run();
|
||||
if((SR&SR_DEC) == 0) return -1;
|
||||
|
||||
SR&=(~SR_CARRY);
|
||||
SR&=(~SR_DEC);
|
||||
ram[0] = 0xB0;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0xF8;
|
||||
instructions = 4;
|
||||
run();
|
||||
if((SR&SR_DEC) > 0) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
22
6502tests/test/testBeq.c
Normal file
22
6502tests/test/testBeq.c
Normal file
@ -0,0 +1,22 @@
|
||||
int testBeqImplied() {
|
||||
SR|=SR_ZERO;
|
||||
SR&=(~SR_DEC);
|
||||
ram[0] = 0xF0;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0xF8; //SED
|
||||
instructions = 4;
|
||||
run();
|
||||
if((SR&SR_DEC) == 0) return -1;
|
||||
|
||||
SR&=(~SR_ZERO);
|
||||
SR&=(~SR_DEC);
|
||||
ram[0] = 0xF0;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0xF8;
|
||||
instructions = 4; run();
|
||||
if(SR&SR_DEC) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
45
6502tests/test/testBit.c
Normal file
45
6502tests/test/testBit.c
Normal file
@ -0,0 +1,45 @@
|
||||
int testBitZeropage() {
|
||||
//bits set
|
||||
A = 0x00;
|
||||
ram[0] = 0x24;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0xFF;
|
||||
instructions = 2;
|
||||
run();
|
||||
if(!(SR&SR_NEG && SR&SR_ZERO && SR&SR_OVER)) return -1;
|
||||
|
||||
//bits unset
|
||||
A = 0x01;
|
||||
ram[0] = 0x24;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x01;
|
||||
instructions = 2;
|
||||
run();
|
||||
if(!(!(SR&SR_NEG) && !(SR&SR_ZERO) && !(SR&SR_OVER))) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testBitAbsolute() {
|
||||
//bits set
|
||||
A = 0x00;
|
||||
ram[0] = 0x24;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0xFF;
|
||||
instructions = 2;
|
||||
run();
|
||||
if(!(SR&SR_NEG && SR&SR_ZERO && !(SR&SR_CARRY) && SR&SR_OVER)) return -1;
|
||||
|
||||
//bits unset
|
||||
A = 0x01;
|
||||
ram[0] = 0x24;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x01;
|
||||
instructions = 2;
|
||||
run();
|
||||
if(!(!(SR&SR_NEG) && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
21
6502tests/test/testBmi.c
Normal file
21
6502tests/test/testBmi.c
Normal file
@ -0,0 +1,21 @@
|
||||
int testBmiImplied() {
|
||||
SR |= SR_NEG;
|
||||
SR &= (~SR_DEC);
|
||||
ram[0] = 0x30;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0xF8; //SED
|
||||
instructions = 4; run();
|
||||
if(!(SR&SR_DEC)) return -1;
|
||||
|
||||
SR &= (~SR_NEG);
|
||||
SR &= (~SR_DEC);
|
||||
ram[0] = 0x30;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0xF8;
|
||||
instructions = 4; run();
|
||||
if(SR&SR_DEC) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
21
6502tests/test/testBne.c
Normal file
21
6502tests/test/testBne.c
Normal file
@ -0,0 +1,21 @@
|
||||
int testBneImplied() {
|
||||
SR &= (~SR_ZERO);
|
||||
SR &= (~SR_DEC);
|
||||
ram[0] = 0xD0;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0xF8; //SED
|
||||
instructions = 4; run();
|
||||
if(!(SR&SR_DEC)) return -1;
|
||||
|
||||
SR |= SR_ZERO;
|
||||
SR &= (~SR_DEC);
|
||||
ram[0] = 0xD0;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0xF8;
|
||||
instructions = 4; run();
|
||||
if(SR&SR_DEC) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
21
6502tests/test/testBpl.c
Normal file
21
6502tests/test/testBpl.c
Normal file
@ -0,0 +1,21 @@
|
||||
int testBplImplied() {
|
||||
SR |= SR_NEG;
|
||||
SR &= (~SR_DEC);
|
||||
ram[0] = 0x10;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0xF8; //SED
|
||||
instructions = 4; run();
|
||||
if(SR&SR_DEC) return -1;
|
||||
|
||||
SR &= (~SR_NEG);
|
||||
SR &= (~SR_DEC);
|
||||
ram[0] = 0x10;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0xF8;
|
||||
instructions = 4; run();
|
||||
if(!(SR&SR_DEC)) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
8
6502tests/test/testBrk.c
Normal file
8
6502tests/test/testBrk.c
Normal file
@ -0,0 +1,8 @@
|
||||
int testBrkImplied() {
|
||||
SR &= (~SR_INT);
|
||||
SP = 0xFF;
|
||||
ram[0] = 0x00;
|
||||
instructions = 4; run();
|
||||
if(!(SR&SR_INT) || PC != (read8(0xFFFE)|((unsigned short)read8(0xFFFF)<<8)) || SP != 0xFC) return -1;
|
||||
return 0;
|
||||
}
|
21
6502tests/test/testBvc.c
Normal file
21
6502tests/test/testBvc.c
Normal file
@ -0,0 +1,21 @@
|
||||
int testBvcImplied() {
|
||||
SR |= SR_OVER;
|
||||
SR &= (~SR_DEC);
|
||||
ram[0] = 0x50;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0xF8; //SED
|
||||
instructions = 4; run();
|
||||
if(SR&SR_DEC) return -1;
|
||||
|
||||
SR &= (~SR_OVER);
|
||||
SR &= (~SR_DEC);
|
||||
ram[0] = 0x50;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0xF8;
|
||||
instructions = 4; run();
|
||||
if(!(SR&SR_DEC)) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
21
6502tests/test/testBvs.c
Normal file
21
6502tests/test/testBvs.c
Normal file
@ -0,0 +1,21 @@
|
||||
int testBvsImplied() {
|
||||
SR |= SR_OVER;
|
||||
SR &= (~SR_DEC);
|
||||
ram[0] = 0x70;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0xF8; //SED
|
||||
instructions = 4; run();
|
||||
if(!(SR&SR_DEC)) return -1;
|
||||
|
||||
SR &= (~SR_OVER);
|
||||
SR &= (~SR_DEC);
|
||||
ram[0] = 0x70;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0xF8;
|
||||
instructions = 4; run();
|
||||
if(SR&SR_DEC) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
31
6502tests/test/testClear.c
Normal file
31
6502tests/test/testClear.c
Normal file
@ -0,0 +1,31 @@
|
||||
int testClcImplied() {
|
||||
SR |= SR_CARRY;
|
||||
ram[0] = 0x18;
|
||||
instructions = 1; run();
|
||||
if(SR&SR_CARRY) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testCldImplied() {
|
||||
SR |= SR_DEC;
|
||||
ram[0] = 0xD8;
|
||||
instructions = 1; run();
|
||||
if(SR&SR_DEC) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testCliImplied() {
|
||||
SR |= SR_INT;
|
||||
ram[0] = 0x58;
|
||||
instructions = 1; run();
|
||||
if(SR&SR_INT) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testClvImplied() {
|
||||
SR |= SR_OVER;
|
||||
ram[0] = 0xB8;
|
||||
instructions = 1; run();
|
||||
if(SR&SR_OVER) return -1;
|
||||
return 0;
|
||||
}
|
320
6502tests/test/testCmp.c
Normal file
320
6502tests/test/testCmp.c
Normal file
@ -0,0 +1,320 @@
|
||||
int testCmpImmediate() {
|
||||
//no difference
|
||||
SR |= SR_ZERO;
|
||||
SR |= SR_CARRY;
|
||||
SR |= SR_NEG;
|
||||
A = 0x10;
|
||||
ram[0] = 0xC9;
|
||||
ram[1] = 0x10;
|
||||
instructions = 2; run();
|
||||
if(!(!(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY)) return -1;
|
||||
|
||||
//less
|
||||
SR |= SR_ZERO;
|
||||
SR |= SR_CARRY;
|
||||
SR |= SR_NEG;
|
||||
A = 0x10;
|
||||
ram[0] = 0xC9;
|
||||
ram[1] = 0x04;
|
||||
instructions = 2; run();
|
||||
if(!(!(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY)) return -2;
|
||||
|
||||
//more
|
||||
SR |= SR_ZERO;
|
||||
SR |= SR_CARRY;
|
||||
SR |= SR_NEG;
|
||||
A = 0x04;
|
||||
ram[0] = 0xC9;
|
||||
ram[1] = 0x10;
|
||||
instructions = 2; run();
|
||||
if(!(SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY))) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testCmpZeropage() {
|
||||
//no difference
|
||||
SR |= SR_ZERO;
|
||||
SR |= SR_CARRY;
|
||||
SR |= SR_NEG;
|
||||
A = 0x10;
|
||||
ram[0] = 0xC5;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x10;
|
||||
instructions = 2; run();
|
||||
if(!(!(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY)) return -1;
|
||||
|
||||
//less
|
||||
SR |= SR_ZERO;
|
||||
SR |= SR_CARRY;
|
||||
SR |= SR_NEG;
|
||||
A = 0x10;
|
||||
ram[0] = 0xC5;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x04;
|
||||
instructions = 2; run();
|
||||
if(!(!(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY)) return -2;
|
||||
|
||||
//more
|
||||
SR |= SR_ZERO;
|
||||
SR |= SR_CARRY;
|
||||
SR |= SR_NEG;
|
||||
A = 0x04;
|
||||
ram[0] = 0xC5;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x10;
|
||||
instructions = 2; run();
|
||||
if(!(SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY))) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testCmpZeropageX() {
|
||||
X = 0x01; Y = 0x00;
|
||||
|
||||
//no difference
|
||||
SR |= SR_ZERO;
|
||||
SR |= SR_CARRY;
|
||||
SR |= SR_NEG;
|
||||
A = 0x10;
|
||||
ram[0] = 0xD5;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x10;
|
||||
instructions = 2; run();
|
||||
if(!(!(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY)) return -1;
|
||||
|
||||
//less
|
||||
SR |= SR_ZERO;
|
||||
SR |= SR_CARRY;
|
||||
SR |= SR_NEG;
|
||||
A = 0x10;
|
||||
ram[0] = 0xD5;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x04;
|
||||
instructions = 2; run();
|
||||
if(!(!(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY)) return -2;
|
||||
|
||||
//more
|
||||
SR |= SR_ZERO;
|
||||
SR |= SR_CARRY;
|
||||
SR |= SR_NEG;
|
||||
A = 0x04;
|
||||
ram[0] = 0xD5;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x10;
|
||||
instructions = 2; run();
|
||||
if(!(SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY))) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testCmpAbsolute() {
|
||||
//no difference
|
||||
SR |= SR_ZERO;
|
||||
SR |= SR_CARRY;
|
||||
SR |= SR_NEG;
|
||||
A = 0x10;
|
||||
ram[0] = 0xCD;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x10;
|
||||
instructions = 2; run();
|
||||
if(!(!(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY)) return -1;
|
||||
|
||||
//less
|
||||
SR |= SR_ZERO;
|
||||
SR |= SR_CARRY;
|
||||
SR |= SR_NEG;
|
||||
A = 0x10;
|
||||
ram[0] = 0xCD;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x04;
|
||||
instructions = 2; run();
|
||||
if(!(!(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY)) return -2;
|
||||
|
||||
//more
|
||||
SR |= SR_ZERO;
|
||||
SR |= SR_CARRY;
|
||||
SR |= SR_NEG;
|
||||
A = 0x04;
|
||||
ram[0] = 0xCD;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x10;
|
||||
instructions = 2; run();
|
||||
if(!(SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY))) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testCmpAbsoluteX() {
|
||||
X = 0x01; Y = 0x00;
|
||||
|
||||
//no difference
|
||||
SR |= SR_ZERO;
|
||||
SR |= SR_CARRY;
|
||||
SR |= SR_NEG;
|
||||
A = 0x10;
|
||||
ram[0] = 0xDD;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x10;
|
||||
instructions = 2; run();
|
||||
if(!(!(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY)) return -1;
|
||||
|
||||
//less
|
||||
SR |= SR_ZERO;
|
||||
SR |= SR_CARRY;
|
||||
SR |= SR_NEG;
|
||||
A = 0x10;
|
||||
ram[0] = 0xDD;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x04;
|
||||
instructions = 2; run();
|
||||
if(!(!(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY)) return -2;
|
||||
|
||||
//more
|
||||
SR |= SR_ZERO;
|
||||
SR |= SR_CARRY;
|
||||
SR |= SR_NEG;
|
||||
A = 0x04;
|
||||
ram[0] = 0xDD;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x10;
|
||||
instructions = 2; run();
|
||||
if(!(SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY))) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testCmpAbsoluteY() {
|
||||
Y = 0x01; X = 0x00;
|
||||
|
||||
//no difference
|
||||
SR |= SR_ZERO;
|
||||
SR |= SR_CARRY;
|
||||
SR |= SR_NEG;
|
||||
A = 0x10;
|
||||
ram[0] = 0xD9;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x10;
|
||||
instructions = 2; run();
|
||||
if(!(!(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY)) return -1;
|
||||
|
||||
//less
|
||||
SR |= SR_ZERO;
|
||||
SR |= SR_CARRY;
|
||||
SR |= SR_NEG;
|
||||
A = 0x10;
|
||||
ram[0] = 0xD9;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x04;
|
||||
instructions = 2; run();
|
||||
if(!(!(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY)) return -2;
|
||||
|
||||
//more
|
||||
SR |= SR_ZERO;
|
||||
SR |= SR_CARRY;
|
||||
SR |= SR_NEG;
|
||||
A = 0x04;
|
||||
ram[0] = 0xD9;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x10;
|
||||
instructions = 2; run();
|
||||
if(!(SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY))) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testCmpIndirectX() {
|
||||
X = 0x01; Y = 0x00;
|
||||
|
||||
//no difference
|
||||
SR |= SR_ZERO;
|
||||
SR |= SR_CARRY;
|
||||
SR |= SR_NEG;
|
||||
A = 0x10;
|
||||
ram[0] = 0xC1;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x02;
|
||||
ram[3] = 0x10;
|
||||
instructions = 2; run();
|
||||
if(!(!(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY)) return -1;
|
||||
|
||||
//less
|
||||
SR |= SR_ZERO;
|
||||
SR |= SR_CARRY;
|
||||
SR |= SR_NEG;
|
||||
A = 0x10;
|
||||
ram[0] = 0xC1;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x02;
|
||||
ram[3] = 0x04;
|
||||
instructions = 2; run();
|
||||
if(!(!(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY)) return -2;
|
||||
|
||||
//more
|
||||
SR |= SR_ZERO;
|
||||
SR |= SR_CARRY;
|
||||
SR |= SR_NEG;
|
||||
A = 0x04;
|
||||
ram[0] = 0xC1;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x02;
|
||||
ram[3] = 0x10;
|
||||
instructions = 2; run();
|
||||
if(!(SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY))) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testCmpIndirectY() {
|
||||
Y = 0x01; X = 0x00;
|
||||
|
||||
//no difference
|
||||
SR |= SR_ZERO;
|
||||
SR |= SR_CARRY;
|
||||
SR |= SR_NEG;
|
||||
A = 0x10;
|
||||
ram[0] = 0xD1;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x03;
|
||||
ram[3] = 0x00;
|
||||
ram[4] = 0x10;
|
||||
instructions = 2; run();
|
||||
if(!(!(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY)) return -1;
|
||||
|
||||
//less
|
||||
SR |= SR_ZERO;
|
||||
SR |= SR_CARRY;
|
||||
SR |= SR_NEG;
|
||||
A = 0x10;
|
||||
ram[0] = 0xD1;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x03;
|
||||
ram[3] = 0x00;
|
||||
ram[4] = 0x04;
|
||||
instructions = 2; run();
|
||||
if(!(!(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY)) return -2;
|
||||
|
||||
//more
|
||||
SR |= SR_ZERO;
|
||||
SR |= SR_CARRY;
|
||||
SR |= SR_NEG;
|
||||
A = 0x04;
|
||||
ram[0] = 0xD1;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x03;
|
||||
ram[3] = 0x00;
|
||||
ram[4] = 0x10;
|
||||
instructions = 2; run();
|
||||
if(!(SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY))) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
110
6502tests/test/testCpx.c
Normal file
110
6502tests/test/testCpx.c
Normal file
@ -0,0 +1,110 @@
|
||||
int testCpxImmediate() {
|
||||
//no difference
|
||||
SR |= SR_ZERO;
|
||||
SR |= SR_CARRY;
|
||||
SR |= SR_NEG;
|
||||
X = 0x10;
|
||||
ram[0] = 0xE0;
|
||||
ram[1] = 0x10;
|
||||
instructions = 2; run();
|
||||
if(!(!(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY)) return -1;
|
||||
|
||||
//less
|
||||
SR |= SR_ZERO;
|
||||
SR |= SR_CARRY;
|
||||
SR |= SR_NEG;
|
||||
X = 0x10;
|
||||
ram[0] = 0xE0;
|
||||
ram[1] = 0x04;
|
||||
instructions = 2; run();
|
||||
if(!(!(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY)) return -2;
|
||||
|
||||
//more
|
||||
SR |= SR_ZERO;
|
||||
SR |= SR_CARRY;
|
||||
SR |= SR_NEG;
|
||||
X = 0x04;
|
||||
ram[0] = 0xE0;
|
||||
ram[1] = 0x10;
|
||||
instructions = 2; run();
|
||||
if(!(SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY))) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testCpxZeropage() {
|
||||
//no difference
|
||||
SR |= SR_ZERO;
|
||||
SR |= SR_CARRY;
|
||||
SR |= SR_NEG;
|
||||
X = 0x10;
|
||||
ram[0] = 0xE4;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x10;
|
||||
instructions = 2; run();
|
||||
if(!(!(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY)) return -1;
|
||||
|
||||
//less
|
||||
SR |= SR_ZERO;
|
||||
SR |= SR_CARRY;
|
||||
SR |= SR_NEG;
|
||||
X = 0x10;
|
||||
ram[0] = 0xE4;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x04;
|
||||
instructions = 2; run();
|
||||
if(!(!(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY)) return -2;
|
||||
|
||||
//more
|
||||
SR |= SR_ZERO;
|
||||
SR |= SR_CARRY;
|
||||
SR |= SR_NEG;
|
||||
X = 0x04;
|
||||
ram[0] = 0xE4;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x10;
|
||||
instructions = 2; run();
|
||||
if(!(SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY))) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testCpxAbsolute() {
|
||||
//no difference
|
||||
SR |= SR_ZERO;
|
||||
SR |= SR_CARRY;
|
||||
SR |= SR_NEG;
|
||||
X = 0x10;
|
||||
ram[0] = 0xEC;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x10;
|
||||
instructions = 2; run();
|
||||
if(!(!(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY)) return -1;
|
||||
|
||||
//less
|
||||
SR |= SR_ZERO;
|
||||
SR |= SR_CARRY;
|
||||
SR |= SR_NEG;
|
||||
X = 0x10;
|
||||
ram[0] = 0xEC;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x04;
|
||||
instructions = 2; run();
|
||||
if(!(!(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY)) return -2;
|
||||
|
||||
//more
|
||||
SR |= SR_ZERO;
|
||||
SR |= SR_CARRY;
|
||||
SR |= SR_NEG;
|
||||
X = 0x04;
|
||||
ram[0] = 0xEC;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x10;
|
||||
instructions = 2; run();
|
||||
if(!(SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY))) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
110
6502tests/test/testCpy.c
Normal file
110
6502tests/test/testCpy.c
Normal file
@ -0,0 +1,110 @@
|
||||
int testCpyImmediate() {
|
||||
//no difference
|
||||
SR |= SR_ZERO;
|
||||
SR |= SR_CARRY;
|
||||
SR |= SR_NEG;
|
||||
Y = 0x10;
|
||||
ram[0] = 0xC0;
|
||||
ram[1] = 0x10;
|
||||
instructions = 2; run();
|
||||
if(!(!(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY)) return -1;
|
||||
|
||||
//less
|
||||
SR |= SR_ZERO;
|
||||
SR |= SR_CARRY;
|
||||
SR |= SR_NEG;
|
||||
Y = 0x10;
|
||||
ram[0] = 0xC0;
|
||||
ram[1] = 0x04;
|
||||
instructions = 2; run();
|
||||
if(!(!(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY)) return -2;
|
||||
|
||||
//more
|
||||
SR |= SR_ZERO;
|
||||
SR |= SR_CARRY;
|
||||
SR |= SR_NEG;
|
||||
Y = 0x04;
|
||||
ram[0] = 0xC0;
|
||||
ram[1] = 0x10;
|
||||
instructions = 2; run();
|
||||
if(!(SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY))) return -3;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testCpyZeropage() {
|
||||
//no difference
|
||||
SR |= SR_ZERO;
|
||||
SR |= SR_CARRY;
|
||||
SR |= SR_NEG;
|
||||
Y = 0x10;
|
||||
ram[0] = 0xC4;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x10;
|
||||
instructions = 2; run();
|
||||
if(!(!(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY)) return -1;
|
||||
|
||||
//less
|
||||
SR |= SR_ZERO;
|
||||
SR |= SR_CARRY;
|
||||
SR |= SR_NEG;
|
||||
Y = 0x10;
|
||||
ram[0] = 0xC4;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x04;
|
||||
instructions = 2; run();
|
||||
if(!(!(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY)) return -2;
|
||||
|
||||
//more
|
||||
SR |= SR_ZERO;
|
||||
SR |= SR_CARRY;
|
||||
SR |= SR_NEG;
|
||||
Y = 0x04;
|
||||
ram[0] = 0xC4;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x10;
|
||||
instructions = 2; run();
|
||||
if(!(SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY))) return -3;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testCpyAbsolute() {
|
||||
//no difference
|
||||
SR |= SR_ZERO;
|
||||
SR |= SR_CARRY;
|
||||
SR |= SR_NEG;
|
||||
Y = 0x10;
|
||||
ram[0] = 0xCC;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x10;
|
||||
instructions = 2; run();
|
||||
if(!(!(SR&SR_NEG) && SR&SR_ZERO && SR&SR_CARRY)) return -1;
|
||||
|
||||
//less
|
||||
SR |= SR_ZERO;
|
||||
SR |= SR_CARRY;
|
||||
SR |= SR_NEG;
|
||||
Y = 0x10;
|
||||
ram[0] = 0xCC;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x04;
|
||||
instructions = 2; run();
|
||||
if(!(!(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY)) return -2;
|
||||
|
||||
//more
|
||||
SR |= SR_ZERO;
|
||||
SR |= SR_CARRY;
|
||||
SR |= SR_NEG;
|
||||
Y = 0x04;
|
||||
ram[0] = 0xCC;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x10;
|
||||
instructions = 2; run();
|
||||
if(!(SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY))) return -3;
|
||||
|
||||
return 0;
|
||||
}
|
105
6502tests/test/testDec.c
Normal file
105
6502tests/test/testDec.c
Normal file
@ -0,0 +1,105 @@
|
||||
int testDecZeropage() {
|
||||
ram[0] = 0xC6;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x01;
|
||||
instructions = 1; run();
|
||||
if(!(ram[2] == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO)) return -1;
|
||||
|
||||
//wrap
|
||||
ram[0] = 0xC6;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(!(ram[2] == 0xFF && SR&SR_NEG && !(SR&SR_ZERO))) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testDecZeropageX() {
|
||||
X = 0x01; Y = 0x00;
|
||||
|
||||
ram[0] = 0xD6;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x01;
|
||||
instructions = 1; run();
|
||||
if(!(ram[2] == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO)) return -1;
|
||||
|
||||
//wrap
|
||||
ram[0] = 0xD6;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(!(ram[2] == 0xFF && SR&SR_NEG && !(SR&SR_ZERO))) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testDecAbsolute() {
|
||||
ram[0] = 0xCE;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x01;
|
||||
instructions = 1; run();
|
||||
if(!(ram[3] == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO)) return -1;
|
||||
|
||||
//wrap
|
||||
ram[0] = 0xCE;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(!(ram[3] == 0xFF && SR&SR_NEG && !(SR&SR_ZERO))) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testDecAbsoluteX() {
|
||||
X = 0x01; Y = 0x00;
|
||||
|
||||
ram[0] = 0xDE;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x01;
|
||||
instructions = 1; run();
|
||||
if(!(ram[3] == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO)) return -1;
|
||||
|
||||
//wrap
|
||||
ram[0] = 0xDE;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(!(ram[3] == 0xFF && SR&SR_NEG && !(SR&SR_ZERO))) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testDexImplied() {
|
||||
X = 0x01;
|
||||
ram[0] = 0xCA;
|
||||
instructions = 1; run();
|
||||
if(!(X == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO)) return -1;
|
||||
|
||||
//wrap
|
||||
X = 0x00;
|
||||
ram[0] = 0xCA;
|
||||
instructions = 1; run();
|
||||
if(!(X == 0xFF && SR&SR_NEG && !(SR&SR_ZERO))) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testDeyImplied() {
|
||||
Y = 0x01;
|
||||
ram[0] = 0x88;
|
||||
instructions = 1; run();
|
||||
if(!(Y == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO)) return -1;
|
||||
|
||||
//wrap
|
||||
X = 0x00;
|
||||
ram[0] = 0x88;
|
||||
instructions = 1; run();
|
||||
if(!(Y == 0xFF && SR&SR_NEG && !(SR&SR_ZERO))) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
89
6502tests/test/testEor.c
Normal file
89
6502tests/test/testEor.c
Normal file
@ -0,0 +1,89 @@
|
||||
int testEorImmediate() {
|
||||
A = 0xCE;
|
||||
ram[0] = 0x49;
|
||||
ram[1] = 0x20;
|
||||
instructions = 1; run();
|
||||
if(!(A == (0xCE^0x20) && !(SR&SR_ZERO) && SR&SR_NEG)) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testEorZeropage() {
|
||||
A = 0xCE;
|
||||
ram[0] = 0x45;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x20;
|
||||
instructions = 1; run();
|
||||
if(!(A == (0xCE^0x20) && !(SR&SR_ZERO) && SR&SR_NEG)) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testEorZeropageX() {
|
||||
X = 0x01; Y = 0x00;
|
||||
A = 0xCE;
|
||||
ram[0] = 0x55;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x20;
|
||||
instructions = 1; run();
|
||||
if(!(A == (0xCE^0x20) && !(SR&SR_ZERO) && SR&SR_NEG)) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testEorAbsolute() {
|
||||
A = 0xCE;
|
||||
ram[0] = 0x4D;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x20;
|
||||
instructions = 1; run();
|
||||
if(!(A == (0xCE^0x20) && !(SR&SR_ZERO) && SR&SR_NEG)) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testEorAbsoluteX() {
|
||||
X = 0x01; Y = 0x00;
|
||||
A = 0xCE;
|
||||
ram[0] = 0x5D;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x20;
|
||||
instructions = 1; run();
|
||||
if(!(A == (0xCE^0x20) && !(SR&SR_ZERO) && SR&SR_NEG)) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testEorAbsoluteY() {
|
||||
Y = 0x01; X = 0x00;
|
||||
A = 0xCE;
|
||||
ram[0] = 0x59;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x20;
|
||||
instructions = 1; run();
|
||||
if(!(A == (0xCE^0x20) && !(SR&SR_ZERO) && SR&SR_NEG)) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testEorIndirectX() {
|
||||
X = 0x01; Y = 0x00;
|
||||
A = 0xCE;
|
||||
ram[0] = 0x41;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x02;
|
||||
ram[3] = 0x20;
|
||||
instructions = 1; run();
|
||||
if(!(A == (0xCE^0x20) && !(SR&SR_ZERO) && SR&SR_NEG)) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testEorIndirectY() {
|
||||
Y = 0x01; X = 0x00;
|
||||
A = 0xCE;
|
||||
ram[0] = 0x51;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x03;
|
||||
ram[3] = 0x00;
|
||||
ram[4] = 0x20;
|
||||
instructions = 1; run();
|
||||
if(!(A == (0xCE^0x20) && !(SR&SR_ZERO) && SR&SR_NEG)) return -1;
|
||||
return 0;
|
||||
}
|
105
6502tests/test/testInc.c
Normal file
105
6502tests/test/testInc.c
Normal file
@ -0,0 +1,105 @@
|
||||
int testIncZeropage() {
|
||||
ram[0] = 0xE6;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0xFE;
|
||||
instructions = 1; run();
|
||||
if(!(ram[2] == 0xFF && SR&SR_NEG && !(SR&SR_ZERO))) return -1;
|
||||
|
||||
//wrap
|
||||
ram[0] = 0xE6;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0xFF;
|
||||
instructions = 1; run();
|
||||
if(!(ram[2] == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO)) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testIncZeropageX() {
|
||||
X = 0x01; Y = 0x00;
|
||||
|
||||
ram[0] = 0xF6;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0xFE;
|
||||
instructions = 1; run();
|
||||
if(!(ram[2] == 0xFF && SR&SR_NEG && !(SR&SR_ZERO))) return -1;
|
||||
|
||||
//wrap
|
||||
ram[0] = 0xF6;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0xFF;
|
||||
instructions = 1; run();
|
||||
if(!(ram[2] == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO)) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testIncAbsolute() {
|
||||
ram[0] = 0xEE;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0xFE;
|
||||
instructions = 1; run();
|
||||
if(!(ram[3] == 0xFF && SR&SR_NEG && !(SR&SR_ZERO))) return -1;
|
||||
|
||||
//wrap
|
||||
ram[0] = 0xEE;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0xFF;
|
||||
instructions = 1; run();
|
||||
if(!(ram[3] == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO)) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testIncAbsoluteX() {
|
||||
X = 0x01; Y = 0x00;
|
||||
|
||||
ram[0] = 0xFE;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0xFE;
|
||||
instructions = 1; run();
|
||||
if(!(ram[3] == 0x02 && SR&SR_NEG && !(SR&SR_ZERO))) return -1;
|
||||
|
||||
//wrap
|
||||
ram[0] = 0xFE;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0xFF;
|
||||
instructions = 1; run();
|
||||
if(!(ram[3] == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO)) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testInxImplied() {
|
||||
X = 0xFE;
|
||||
ram[0] = 0xE8;
|
||||
instructions = 1; run();
|
||||
if(!(X == 0xFF && SR&SR_NEG && !(SR&SR_ZERO))) return -1;
|
||||
|
||||
//wrap
|
||||
X = 0xFF;
|
||||
ram[0] = 0xE8;
|
||||
instructions = 1; run();
|
||||
if(!(X == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO)) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testInyImplied() {
|
||||
Y = 0xFE;
|
||||
ram[0] = 0xC8;
|
||||
instructions = 1; run();
|
||||
if(!(Y == 0xFF && SR&SR_NEG && !(SR&SR_ZERO))) return -1;
|
||||
|
||||
//wrap
|
||||
Y = 0xFF;
|
||||
ram[0] = 0xC8;
|
||||
instructions = 1; run();
|
||||
if(!(Y == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO)) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
37
6502tests/test/testJmp.c
Normal file
37
6502tests/test/testJmp.c
Normal file
@ -0,0 +1,37 @@
|
||||
int testJmpAbsolute() {
|
||||
SR &= (~SR_DEC);
|
||||
ram[0] = 0x4C;
|
||||
ram[1] = 0x04;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x00;
|
||||
ram[4] = 0xF8;
|
||||
instructions = 5; run();
|
||||
if(!(SR&SR_DEC)) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testJmpIndirect() {
|
||||
SR &= (~SR_DEC);
|
||||
ram[0] = 0x4C;
|
||||
ram[1] = 0x04;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x00;
|
||||
ram[4] = 0x06;
|
||||
ram[5] = 0x00;
|
||||
ram[6] = 0xF8;
|
||||
instructions = 7; run();
|
||||
if(!(SR&SR_DEC)) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testJsrAbsolute() {
|
||||
SR &= (~SR_DEC);
|
||||
ram[0] = 0x20;
|
||||
ram[1] = 0x04;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x00;
|
||||
ram[4] = 0xF8;
|
||||
instructions = 5; run();
|
||||
if(!(SR&SR_DEC && pull16() == 0x0002)) return -1;
|
||||
return 0;
|
||||
}
|
546
6502tests/test/testLd.c
Normal file
546
6502tests/test/testLd.c
Normal file
@ -0,0 +1,546 @@
|
||||
int testLdaImmediate() {
|
||||
//zero
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xA9;
|
||||
ram[1] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x00 && SR&SR_ZERO && !(SR&SR_NEG))) return -1;
|
||||
|
||||
//normal
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xA9;
|
||||
ram[1] = 0x20;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x20 && !(SR&SR_ZERO) && !(SR&SR_NEG))) return -2;
|
||||
|
||||
//negative
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xA9;
|
||||
ram[1] = 0x80;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x80 && !(SR&SR_ZERO) && SR&SR_NEG)) return -3;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testLdaZeropage() {
|
||||
//zero
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xA5;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x00 && SR&SR_ZERO && !(SR&SR_NEG))) return -1;
|
||||
|
||||
//normal
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xA5;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x20;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x20 && !(SR&SR_ZERO) && !(SR&SR_NEG))) return -2;
|
||||
|
||||
//negative
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xA5;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x80;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x80 && !(SR&SR_ZERO) && SR&SR_NEG)) return -3;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testLdaZeropageX() {
|
||||
X = 0x01; Y = 0x00;
|
||||
|
||||
//zero
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xB5;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x00 && SR&SR_ZERO && !(SR&SR_NEG))) return -1;
|
||||
|
||||
//normal
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xB5;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x20;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x20 && !(SR&SR_ZERO) && !(SR&SR_NEG))) return -2;
|
||||
|
||||
//negative
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xB5;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x80;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x80 && !(SR&SR_ZERO) && SR&SR_NEG)) return -3;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testLdaAbsolute() {
|
||||
//zero
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xAD;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x00 && SR&SR_ZERO && !(SR&SR_NEG))) return -1;
|
||||
|
||||
//normal
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xAD;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x20;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x20 && !(SR&SR_ZERO) && !(SR&SR_NEG))) return -2;
|
||||
|
||||
//negative
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xAD;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x80;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x80 && !(SR&SR_ZERO) && SR&SR_NEG)) return -3;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testLdaAbsoluteX() {
|
||||
X = 0x01; Y = 0x00;
|
||||
|
||||
//zero
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xBD;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x00 && SR&SR_ZERO && !(SR&SR_NEG))) return -1;
|
||||
|
||||
//normal
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xBD;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x20;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x20 && !(SR&SR_ZERO) && !(SR&SR_NEG))) return -2;
|
||||
|
||||
//negative
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xBD;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x80;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x80 && !(SR&SR_ZERO) && SR&SR_NEG)) return -3;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testLdaAbsoluteY() {
|
||||
Y = 0x01; X = 0x00;
|
||||
|
||||
//zero
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xB9;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x00 && SR&SR_ZERO && !(SR&SR_NEG))) return -1;
|
||||
|
||||
//normal
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xB9;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x20;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x20 && !(SR&SR_ZERO) && !(SR&SR_NEG))) return -2;
|
||||
|
||||
//negative
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xB9;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x80;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x80 && !(SR&SR_ZERO) && SR&SR_NEG)) return -3;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testLdaIndirectX() {
|
||||
X = 0x01; Y = 0x00;
|
||||
|
||||
//zero
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xA1;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x02;
|
||||
ram[3] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x00 && SR&SR_ZERO && !(SR&SR_NEG))) return -1;
|
||||
|
||||
//normal
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xA1;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x02;
|
||||
ram[3] = 0x20;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x20 && !(SR&SR_ZERO) && !(SR&SR_NEG))) return -2;
|
||||
|
||||
//negative
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xA1;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x02;
|
||||
ram[3] = 0x80;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x80 && !(SR&SR_ZERO) && SR&SR_NEG)) return -3;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testLdaIndirectY() {
|
||||
Y = 0x01; X = 0x00;
|
||||
|
||||
//zero
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xB1;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x03;
|
||||
ram[3] = 0x00;
|
||||
ram[4] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x00 && SR&SR_ZERO && !(SR&SR_NEG))) return -1;
|
||||
|
||||
//normal
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xB1;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x03;
|
||||
ram[3] = 0x00;
|
||||
ram[4] = 0x20;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x20 && !(SR&SR_ZERO) && !(SR&SR_NEG))) return -2;
|
||||
|
||||
//negative
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xB1;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x03;
|
||||
ram[3] = 0x00;
|
||||
ram[4] = 0x80;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x80 && !(SR&SR_ZERO) && SR&SR_NEG)) return -3;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testLdxImmediate() {
|
||||
//zero
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xA2;
|
||||
ram[1] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(!(X == 0x00 && SR&SR_ZERO && !(SR&SR_NEG))) return -1;
|
||||
|
||||
//normal
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xA2;
|
||||
ram[1] = 0x20;
|
||||
instructions = 1; run();
|
||||
if(!(X == 0x20 && !(SR&SR_ZERO) && !(SR&SR_NEG))) return -2;
|
||||
|
||||
//negative
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xA2;
|
||||
ram[1] = 0x80;
|
||||
instructions = 1; run();
|
||||
if(!(X == 0x80 && !(SR&SR_ZERO) && SR&SR_NEG)) return -3;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testLdxZeropage() {
|
||||
//zero
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xA6;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(!(X == 0x00 && SR&SR_ZERO && !(SR&SR_NEG))) return -1;
|
||||
|
||||
//normal
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xA6;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x20;
|
||||
instructions = 1; run();
|
||||
if(!(X == 0x20 && !(SR&SR_ZERO) && !(SR&SR_NEG))) return -2;
|
||||
|
||||
//negative
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xA6;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x80;
|
||||
instructions = 1; run();
|
||||
if(!(X == 0x80 && !(SR&SR_ZERO) && SR&SR_NEG)) return -3;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testLdxZeropageY() {
|
||||
Y = 0x01; X = 0x00;
|
||||
|
||||
//zero
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xB6;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(!(X == 0x00 && SR&SR_ZERO && !(SR&SR_NEG))) return -1;
|
||||
|
||||
//normal
|
||||
Y = 0x01;
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xB6;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x20;
|
||||
instructions = 1; run();
|
||||
if(!(X == 0x20 && !(SR&SR_ZERO) && !(SR&SR_NEG))) return -2;
|
||||
|
||||
//negative
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xB6;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x80;
|
||||
instructions = 1; run();
|
||||
if(!(X == 0x80 && !(SR&SR_ZERO) && SR&SR_NEG)) return -3;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testLdxAbsolute() {
|
||||
//zero
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xAE;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(!(X == 0x00 && SR&SR_ZERO && !(SR&SR_NEG))) return -1;
|
||||
|
||||
//normal
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xAE;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x20;
|
||||
instructions = 1; run();
|
||||
if(!(X == 0x20 && !(SR&SR_ZERO) && !(SR&SR_NEG))) return -2;
|
||||
|
||||
//negative
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xAE;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x80;
|
||||
instructions = 1; run();
|
||||
if(!(X == 0x80 && !(SR&SR_ZERO) && SR&SR_NEG)) return -3;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testLdxAbsoluteY() {
|
||||
Y = 0x01; X = 0x00;
|
||||
|
||||
//zero
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xBE;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(!(X == 0x00 && SR&SR_ZERO && !(SR&SR_NEG))) return -1;
|
||||
|
||||
//normal
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xBE;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x20;
|
||||
instructions = 1; run();
|
||||
if(!(X == 0x20 && !(SR&SR_ZERO) && !(SR&SR_NEG))) return -2;
|
||||
|
||||
//negative
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xBE;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x80;
|
||||
instructions = 1; run();
|
||||
if(!(X == 0x80 && !(SR&SR_ZERO) && SR&SR_NEG)) return -3;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testLdyImmediate() {
|
||||
//zero
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xA0;
|
||||
ram[1] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(!(Y == 0x00 && SR&SR_ZERO && !(SR&SR_NEG))) return -1;
|
||||
|
||||
//normal
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xA0;
|
||||
ram[1] = 0x20;
|
||||
instructions = 1; run();
|
||||
if(!(Y == 0x20 && !(SR&SR_ZERO) && !(SR&SR_NEG))) return -2;
|
||||
|
||||
//negative
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xA0;
|
||||
ram[1] = 0x80;
|
||||
instructions = 1; run();
|
||||
if(!(Y == 0x80 && !(SR&SR_ZERO) && SR&SR_NEG)) return -3;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testLdyZeropage() {
|
||||
//zero
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xA4;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(!(Y == 0x00 && SR&SR_ZERO && !(SR&SR_NEG))) return -1;
|
||||
|
||||
//normal
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xA4;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x20;
|
||||
instructions = 1; run();
|
||||
if(!(Y == 0x20 && !(SR&SR_ZERO) && !(SR&SR_NEG))) return -2;
|
||||
|
||||
//negative
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xA4;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x80;
|
||||
instructions = 1; run();
|
||||
if(!(Y == 0x80 && !(SR&SR_ZERO) && SR&SR_NEG)) return -3;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testLdyZeropageX() {
|
||||
X = 0x01; Y = 0x00;
|
||||
|
||||
//zero
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xB4;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(!(Y == 0x00 && SR&SR_ZERO && !(SR&SR_NEG))) return -1;
|
||||
|
||||
//normal
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xB4;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x20;
|
||||
instructions = 1; run();
|
||||
if(!(Y == 0x20 && !(SR&SR_ZERO) && !(SR&SR_NEG))) return -2;
|
||||
|
||||
//negative
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xB4;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x80;
|
||||
instructions = 1; run();
|
||||
if(!(Y == 0x80 && !(SR&SR_ZERO) && SR&SR_NEG)) return -3;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testLdyAbsolute() {
|
||||
X = 0x01;
|
||||
|
||||
//zero
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xAC;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(!(Y == 0x00 && SR&SR_ZERO && !(SR&SR_NEG))) return -1;
|
||||
|
||||
//normal
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xAC;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x20;
|
||||
instructions = 1; run();
|
||||
if(!(Y == 0x20 && !(SR&SR_ZERO) && !(SR&SR_NEG))) return -2;
|
||||
|
||||
//negative
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xAC;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x80;
|
||||
instructions = 1; run();
|
||||
if(!(Y == 0x80 && !(SR&SR_ZERO) && SR&SR_NEG)) return -3;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testLdyAbsoluteX() {
|
||||
X = 0x01; Y = 0x00;
|
||||
|
||||
//zero
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xBC;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(!(Y == 0x00 && SR&SR_ZERO && !(SR&SR_NEG))) return -1;
|
||||
|
||||
//normal
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xBC;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x20;
|
||||
instructions = 1; run();
|
||||
if(!(Y == 0x20 && !(SR&SR_ZERO) && !(SR&SR_NEG))) return -2;
|
||||
|
||||
//negative
|
||||
SR &= ~(SR_NEG|SR_ZERO);
|
||||
ram[0] = 0xBC;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x80;
|
||||
instructions = 1; run();
|
||||
if(!(Y == 0x80 && !(SR&SR_ZERO) && SR&SR_NEG)) return -3;
|
||||
|
||||
return 0;
|
||||
}
|
103
6502tests/test/testLsr.c
Normal file
103
6502tests/test/testLsr.c
Normal file
@ -0,0 +1,103 @@
|
||||
int testLsrImplied() {
|
||||
SR &= (~SR_DEC);
|
||||
SR &= (~SR_NEG);
|
||||
|
||||
//zero
|
||||
SR |= SR_CARRY;
|
||||
A = 0x01;
|
||||
ram[0] = 0x4A;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x00 && SR&SR_ZERO && SR&SR_CARRY && !(SR&SR_NEG))) return -1;
|
||||
|
||||
//carry out
|
||||
A = 0x80;
|
||||
ram[0] = 0x4A;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x40 && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_NEG))) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testLsrZeropage() {
|
||||
//zero
|
||||
SR |= SR_CARRY;
|
||||
ram[0] = 0x46;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x01;
|
||||
instructions = 1; run();
|
||||
if(!(ram[2] == 0x00 && SR&SR_ZERO && SR&SR_CARRY && !(SR&SR_NEG))) return -1;
|
||||
|
||||
//carry out
|
||||
ram[0] = 0x46;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x80;
|
||||
instructions = 1; run();
|
||||
if(!(ram[2] == 0x40 && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_NEG))) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testLsrZeropageX() {
|
||||
X = 0x01; Y = 0x00;
|
||||
|
||||
//zero
|
||||
SR |= SR_CARRY;
|
||||
ram[0] = 0x56;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x01;
|
||||
instructions = 1; run();
|
||||
if(!(ram[2] == 0x00 && SR&SR_ZERO && SR&SR_CARRY && !(SR&SR_NEG))) return -1;
|
||||
|
||||
//carry out
|
||||
ram[0] = 0x56;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x80;
|
||||
instructions = 1; run();
|
||||
if(!(ram[2] == 0x40 && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_NEG))) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testLsrAbsolute() {
|
||||
//zero
|
||||
SR |= SR_CARRY;
|
||||
ram[0] = 0x4E;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x01;
|
||||
instructions = 1; run();
|
||||
if(!(ram[3] == 0x00 && SR&SR_ZERO && SR&SR_CARRY && !(SR&SR_NEG))) return -1;
|
||||
|
||||
//carry out
|
||||
ram[0] = 0x4E;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x80;
|
||||
instructions = 1; run();
|
||||
if(!(ram[3] == 0x40 && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_NEG))) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testLsrAbsoluteX() {
|
||||
X = 0x01; Y = 0x00;
|
||||
|
||||
//zero
|
||||
SR |= SR_CARRY;
|
||||
ram[0] = 0x5E;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x01;
|
||||
instructions = 1; run();
|
||||
if(!(ram[3] == 0x00 && SR&SR_ZERO && SR&SR_CARRY && !(SR&SR_NEG))) return -1;
|
||||
|
||||
//carry out
|
||||
ram[0] = 0x5E;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x80;
|
||||
instructions = 1; run();
|
||||
if(!(ram[3] == 0x40 && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_NEG))) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
178
6502tests/test/testOra.c
Normal file
178
6502tests/test/testOra.c
Normal file
@ -0,0 +1,178 @@
|
||||
int testOraImmediate() {
|
||||
//all set
|
||||
A = 0xFF;
|
||||
ram[0] = 0x09;
|
||||
ram[1] = 0x0F;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO))) return -1;
|
||||
|
||||
//zero
|
||||
A = 0x00;
|
||||
ram[0] = 0x09;
|
||||
ram[1] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO)) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testOraZeropage() {
|
||||
//all set
|
||||
A = 0xFF;
|
||||
ram[0] = 0x05;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x0F;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO))) return -1;
|
||||
|
||||
//zero
|
||||
A = 0x00;
|
||||
ram[0] = 0x05;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO)) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testOraZeropageX() {
|
||||
X = 0x01; Y = 0x00;
|
||||
|
||||
//all set
|
||||
A = 0xFF;
|
||||
ram[0] = 0x15;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x0F;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO))) return -1;
|
||||
|
||||
//zero
|
||||
A = 0x00;
|
||||
ram[0] = 0x15;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO)) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testOraAbsolute() {
|
||||
//all set
|
||||
A = 0xFF;
|
||||
ram[0] = 0x0D;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x0F;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO))) return -1;
|
||||
|
||||
//zero
|
||||
A = 0x00;
|
||||
ram[0] = 0x0D;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO)) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testOraAbsoluteX() {
|
||||
X = 0x01; Y = 0x00;
|
||||
|
||||
//all set
|
||||
A = 0xFF;
|
||||
ram[0] = 0x1D;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x0F;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO))) return -1;
|
||||
|
||||
//zero
|
||||
A = 0x00;
|
||||
ram[0] = 0x1D;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO)) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testOraAbsoluteY() {
|
||||
X = 0x00; Y = 0x01;
|
||||
|
||||
//all set
|
||||
A = 0xFF;
|
||||
ram[0] = 0x19;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x0F;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO))) return -1;
|
||||
|
||||
//zero
|
||||
A = 0x00;
|
||||
ram[0] = 0x19;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO)) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testOraIndirectX() {
|
||||
X = 0x01; Y = 0x00;
|
||||
|
||||
//all set
|
||||
A = 0xFF;
|
||||
ram[0] = 0x01;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x02;
|
||||
ram[3] = 0x0F;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO))) return -1;
|
||||
|
||||
//zero
|
||||
A = 0x00;
|
||||
ram[0] = 0x01;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x02;
|
||||
ram[3] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO)) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testOraIndirectY() {
|
||||
Y = 0x01; X = 0x00;
|
||||
|
||||
//all set
|
||||
A = 0xFF;
|
||||
ram[0] = 0x11;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x03;
|
||||
ram[3] = 0x00;
|
||||
ram[4] = 0x0F;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO))) return -1;
|
||||
|
||||
//zero
|
||||
A = 0x00;
|
||||
ram[0] = 0x11;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x02;
|
||||
ram[3] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x00 && !(SR&SR_NEG) && SR&SR_ZERO)) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
8
6502tests/test/testPha.c
Normal file
8
6502tests/test/testPha.c
Normal file
@ -0,0 +1,8 @@
|
||||
int testPhaImplied() {
|
||||
unsigned short beginSp = SP;
|
||||
A = 0x23;
|
||||
ram[0] = 0x48;
|
||||
instructions = 1; run();
|
||||
if(!((beginSp-SP) == 1 && pull8() == 0x23)) return -1;
|
||||
return 0;
|
||||
}
|
15
6502tests/test/testPhp.c
Normal file
15
6502tests/test/testPhp.c
Normal file
@ -0,0 +1,15 @@
|
||||
int testPhpImplied() {
|
||||
//random pattern
|
||||
SR |= SR_NEG; SR &= (~SR_OVER); SR |= SR_DEC; SR &= (~SR_INT); SR |= SR_ZERO; SR &= (~SR_CARRY);
|
||||
ram[0] = 0x08;
|
||||
instructions = 1; run();
|
||||
if(!(pull8() == 0xBA)) return -1;
|
||||
|
||||
//all set
|
||||
SR = 0xFF;
|
||||
ram[0] = 0x08;
|
||||
instructions = 1; run();
|
||||
if(!(pull8() == 0xFF)) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
17
6502tests/test/testPla.c
Normal file
17
6502tests/test/testPla.c
Normal file
@ -0,0 +1,17 @@
|
||||
int testPlaImplied() {
|
||||
//no flags
|
||||
A = 0x00;
|
||||
push8(0x23);
|
||||
ram[0] = 0x68;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x23 && !(SR&SR_ZERO) && !(SR&SR_NEG))) return -1;
|
||||
|
||||
//zero flag
|
||||
A = 0x23;
|
||||
push8(0x00);
|
||||
ram[0] = 0x68;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x00 && SR&SR_ZERO && !(SR&SR_NEG))) return -1;
|
||||
|
||||
return 0;
|
||||
}
|
8
6502tests/test/testPlp.c
Normal file
8
6502tests/test/testPlp.c
Normal file
@ -0,0 +1,8 @@
|
||||
int testPlpImplied() {
|
||||
SR = 0x20;
|
||||
push8(0xBA);
|
||||
ram[0] = 0x28;
|
||||
instructions = 1; run();
|
||||
if(!(SR&SR_NEG && !(SR&SR_OVER) && SR&SR_DEC && !(SR&SR_INT) && SR&SR_ZERO && !(SR&SR_CARRY))) return -1;
|
||||
return 0;
|
||||
}
|
105
6502tests/test/testRol.c
Normal file
105
6502tests/test/testRol.c
Normal file
@ -0,0 +1,105 @@
|
||||
int testRolImplied() {
|
||||
//rotate in
|
||||
A = 0x81;
|
||||
SR |= SR_CARRY;
|
||||
ram[0] = 0x2A;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x03 && !(SR&SR_ZERO) && !(SR&SR_NEG) && SR&SR_CARRY)) return -1;
|
||||
|
||||
//rotate out
|
||||
A = 0x80;
|
||||
SR &= (~SR_CARRY);
|
||||
ram[0] = 0x2A;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x00 && SR&SR_ZERO && !(SR&SR_NEG) && SR&SR_CARRY)) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testRolZeropage() {
|
||||
//rotate in
|
||||
SR |= SR_CARRY;
|
||||
ram[0] = 0x26;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x81;
|
||||
instructions = 1; run();
|
||||
if(!(ram[2] == 0x03 && !(SR&SR_ZERO) && !(SR&SR_NEG) && SR&SR_CARRY)) return -1;
|
||||
|
||||
//rotate out
|
||||
SR &= (~SR_CARRY);
|
||||
ram[0] = 0x26;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x80;
|
||||
instructions = 1; run();
|
||||
if(!(ram[2] == 0x00 && SR&SR_ZERO && !(SR&SR_NEG) && SR&SR_CARRY)) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testRolZeropageX() {
|
||||
X = 0x01; Y = 0x00;
|
||||
|
||||
//rotate in
|
||||
SR |= SR_CARRY;
|
||||
ram[0] = 0x36;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x81;
|
||||
instructions = 1; run();
|
||||
if(!(ram[2] == 0x03 && !(SR&SR_ZERO) && !(SR&SR_NEG) && SR&SR_CARRY)) return -1;
|
||||
|
||||
//rotate out
|
||||
SR &= (~SR_CARRY);
|
||||
ram[0] = 0x36;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x80;
|
||||
instructions = 1; run();
|
||||
if(!(ram[2] == 0x00 && SR&SR_ZERO && !(SR&SR_NEG) && SR&SR_CARRY)) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testRolAbsolute() {
|
||||
//rotate in
|
||||
SR |= SR_CARRY;
|
||||
ram[0] = 0x2E;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x81;
|
||||
instructions = 1; run();
|
||||
if(!(ram[3] == 0x03 && !(SR&SR_ZERO) && !(SR&SR_NEG) && SR&SR_CARRY)) return -1;
|
||||
|
||||
//rotate out
|
||||
SR &= (~SR_CARRY);
|
||||
ram[0] = 0x2E;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x80;
|
||||
instructions = 1; run();
|
||||
if(!(ram[3] == 0x00 && SR&SR_ZERO && !(SR&SR_NEG) && SR&SR_CARRY)) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testRolAbsoluteX() {
|
||||
X = 0x01; Y = 0x00;
|
||||
|
||||
//rotate in
|
||||
SR |= SR_CARRY;
|
||||
ram[0] = 0x3E;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x81;
|
||||
instructions = 1; run();
|
||||
if(!(ram[3] == 0x03 && !(SR&SR_ZERO) && !(SR&SR_NEG) && SR&SR_CARRY)) return -1;
|
||||
|
||||
//rotate out
|
||||
SR &= (~SR_CARRY);
|
||||
ram[0] = 0x3E;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x80;
|
||||
instructions = 1; run();
|
||||
if(!(ram[3] == 0x00 && SR&SR_ZERO && !(SR&SR_NEG) && SR&SR_CARRY)) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
105
6502tests/test/testRor.c
Normal file
105
6502tests/test/testRor.c
Normal file
@ -0,0 +1,105 @@
|
||||
int testRorImplied() {
|
||||
//rotate in
|
||||
A = 0x81;
|
||||
SR |= SR_CARRY;
|
||||
ram[0] = 0x6A;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0xC0 && !(SR&SR_ZERO) && SR&SR_NEG && SR&SR_CARRY)) return -1;
|
||||
|
||||
//rotate out
|
||||
A = 0x01;
|
||||
SR &= (~SR_CARRY);
|
||||
ram[0] = 0x6A;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x00 && SR&SR_ZERO && !(SR&SR_NEG) && SR&SR_CARRY)) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testRorZeropage() {
|
||||
//rotate in
|
||||
SR |= SR_CARRY;
|
||||
ram[0] = 0x66;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x81;
|
||||
instructions = 1; run();
|
||||
if(!(ram[2] == 0xC0 && !(SR&SR_ZERO) && SR&SR_NEG && SR&SR_CARRY)) return -1;
|
||||
|
||||
//rotate out
|
||||
SR &= (~SR_CARRY);
|
||||
ram[0] = 0x66;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x01;
|
||||
instructions = 1; run();
|
||||
if(!(ram[2] == 0x00 && SR&SR_ZERO && !(SR&SR_NEG) && SR&SR_CARRY)) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testRorZeropageX() {
|
||||
X = 0x01; Y = 0x00;
|
||||
|
||||
//rotate in
|
||||
SR |= SR_CARRY;
|
||||
ram[0] = 0x76;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x81;
|
||||
instructions = 1; run();
|
||||
if(!(ram[2] == 0xC0 && !(SR&SR_ZERO) && SR&SR_NEG && SR&SR_CARRY)) return -1;
|
||||
|
||||
//rotate out
|
||||
SR &= (~SR_CARRY);
|
||||
ram[0] = 0x76;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x01;
|
||||
instructions = 1; run();
|
||||
if(!(ram[2] == 0x00 && SR&SR_ZERO && !(SR&SR_NEG) && SR&SR_CARRY)) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testRorAbsolute() {
|
||||
//rotate in
|
||||
SR |= SR_CARRY;
|
||||
ram[0] = 0x6E;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x81;
|
||||
instructions = 1; run();
|
||||
if(!(ram[3] == 0xC0 && !(SR&SR_ZERO) && SR&SR_NEG && SR&SR_CARRY)) return -1;
|
||||
|
||||
//rotate out
|
||||
SR &= (~SR_CARRY);
|
||||
ram[0] = 0x6E;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x01;
|
||||
instructions = 1; run();
|
||||
if(!(ram[3] == 0x00 && SR&SR_ZERO && !(SR&SR_NEG) && SR&SR_CARRY)) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testRorAbsoluteX() {
|
||||
X = 0x01; Y = 0x00;
|
||||
|
||||
//rotate in
|
||||
SR |= SR_CARRY;
|
||||
ram[0] = 0x7E;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x81;
|
||||
instructions = 1; run();
|
||||
if(!(ram[3] == 0xC0 && !(SR&SR_ZERO) && SR&SR_NEG && SR&SR_CARRY)) return -1;
|
||||
|
||||
//rotate out
|
||||
SR &= (~SR_CARRY);
|
||||
ram[0] = 0x7E;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x01;
|
||||
instructions = 1; run();
|
||||
if(!(ram[3] == 0x00 && SR&SR_ZERO && !(SR&SR_NEG) && SR&SR_CARRY)) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
9
6502tests/test/testRti.c
Normal file
9
6502tests/test/testRti.c
Normal file
@ -0,0 +1,9 @@
|
||||
int testRtiImplied() {
|
||||
push8(0x00); //high byte pc
|
||||
push8(0x02); // low byte pc
|
||||
push8(0xBA); //SR
|
||||
ram[0] = 0x40;
|
||||
instructions = 1; run();
|
||||
if(!(SR&SR_NEG && !(SR&SR_OVER) && SR&SR_DEC && !(SR&SR_INT) && SR&SR_ZERO && !(SR&SR_CARRY) && PC == 0x02)) return -1;
|
||||
return 0;
|
||||
}
|
8
6502tests/test/testRts.c
Normal file
8
6502tests/test/testRts.c
Normal file
@ -0,0 +1,8 @@
|
||||
int testRtsImplied() {
|
||||
push8(0x00); //high byte pc
|
||||
push8(0x02); // low byte pc
|
||||
ram[0] = 0x60;
|
||||
instructions = 1; run();
|
||||
if(!(PC == 0x03)) return -1;
|
||||
return 0;
|
||||
}
|
283
6502tests/test/testSbc.c
Normal file
283
6502tests/test/testSbc.c
Normal file
@ -0,0 +1,283 @@
|
||||
int testSbcImmediate() {
|
||||
SR &= (~SR_DEC);
|
||||
|
||||
//no overflow
|
||||
SR |= SR_CARRY;
|
||||
A = 0x00;
|
||||
ram[0] = 0xE9;
|
||||
ram[1] = 0x01;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1;
|
||||
|
||||
//overflow
|
||||
SR |= SR_CARRY;
|
||||
A = 0x7F;
|
||||
ram[0] = 0xE9;
|
||||
ram[1] = 0xFF;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x80 && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && SR&SR_OVER)) return -2;
|
||||
|
||||
//no borrow
|
||||
SR &= (~SR_CARRY);
|
||||
A = 0xC0;
|
||||
ram[0] = 0xE9;
|
||||
ram[1] = 0x40;
|
||||
instructions = 1; run();
|
||||
//overflow differs from 2nd sim ...
|
||||
if(!(A == 0x7F && !(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY && SR&SR_OVER)) return -3;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testSbcZeropage() {
|
||||
//no overflow
|
||||
SR |= SR_CARRY;
|
||||
A = 0x00;
|
||||
ram[0] = 0xE5;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x01;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1;
|
||||
|
||||
//overflow
|
||||
SR |= SR_CARRY;
|
||||
A = 0x7F;
|
||||
ram[0] = 0xE5;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0xFF;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x80 && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && SR&SR_OVER)) return -2;
|
||||
|
||||
//no borrow
|
||||
SR &= (~SR_CARRY);
|
||||
A = 0xC0;
|
||||
ram[0] = 0xE5;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x40;
|
||||
instructions = 1; run();
|
||||
//overflow differs from 2nd sim ...
|
||||
if(!(A == 0x7F && !(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY && SR&SR_OVER)) return -3;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testSbcZeropageX() {
|
||||
X = 0x01; Y = 0x00;
|
||||
|
||||
//no overflow
|
||||
SR |= SR_CARRY;
|
||||
A = 0x00;
|
||||
ram[0] = 0xF5;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x01;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1;
|
||||
|
||||
//overflow
|
||||
SR |= SR_CARRY;
|
||||
A = 0x7F;
|
||||
ram[0] = 0xF5;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0xFF;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x80 && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && SR&SR_OVER)) return -2;
|
||||
|
||||
//no borrow
|
||||
SR &= (~SR_CARRY);
|
||||
A = 0xC0;
|
||||
ram[0] = 0xF5;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x40;
|
||||
instructions = 1; run();
|
||||
//overflow differs from 2nd sim ...
|
||||
if(!(A == 0x7F && !(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY && SR&SR_OVER)) return -3;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testSbcAbsolute() {
|
||||
//no overflow
|
||||
SR |= SR_CARRY;
|
||||
A = 0x00;
|
||||
ram[0] = 0xED;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x01;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1;
|
||||
|
||||
//overflow
|
||||
SR |= SR_CARRY;
|
||||
A = 0x7F;
|
||||
ram[0] = 0xED;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0xFF;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x80 && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && SR&SR_OVER)) return -2;
|
||||
|
||||
//no borrow
|
||||
SR &= (~SR_CARRY);
|
||||
A = 0xC0;
|
||||
ram[0] = 0xED;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x40;
|
||||
instructions = 1; run();
|
||||
//overflow differs from 2nd sim ...
|
||||
if(!(A == 0x7F && !(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY && SR&SR_OVER)) return -3;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testSbcAbsoluteX() {
|
||||
X = 0x01; Y = 0x00;
|
||||
|
||||
//no overflow
|
||||
SR |= SR_CARRY;
|
||||
A = 0x00;
|
||||
ram[0] = 0xFD;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x01;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1;
|
||||
|
||||
//overflow
|
||||
SR |= SR_CARRY;
|
||||
A = 0x7F;
|
||||
ram[0] = 0xFD;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0xFF;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x80 && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && SR&SR_OVER)) return -2;
|
||||
|
||||
//no borrow
|
||||
SR &= (~SR_CARRY);
|
||||
A = 0xC0;
|
||||
ram[0] = 0xFD;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x40;
|
||||
instructions = 1; run();
|
||||
//overflow differs from 2nd sim ...
|
||||
if(!(A == 0x7F && !(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY && SR&SR_OVER)) return -3;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testSbcAbsoluteY() {
|
||||
Y = 0x01; X = 0x00;
|
||||
|
||||
//no overflow
|
||||
SR |= SR_CARRY;
|
||||
A = 0x00;
|
||||
ram[0] = 0xF9;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x01;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1;
|
||||
|
||||
//overflow
|
||||
SR |= SR_CARRY;
|
||||
A = 0x7F;
|
||||
ram[0] = 0xF9;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0xFF;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x80 && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && SR&SR_OVER)) return -2;
|
||||
|
||||
//no borrow
|
||||
SR &= (~SR_CARRY);
|
||||
A = 0xC0;
|
||||
ram[0] = 0xF9;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x40;
|
||||
instructions = 1; run();
|
||||
//overflow differs from 2nd sim ...
|
||||
if(!(A == 0x7F && !(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY && SR&SR_OVER)) return -3;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testSbcIndirectX() {
|
||||
X = 0x01; Y = 0x00;
|
||||
|
||||
//no overflow
|
||||
SR |= SR_CARRY;
|
||||
A = 0x00;
|
||||
ram[0] = 0xE1;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x02;
|
||||
ram[3] = 0x01;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1;
|
||||
|
||||
//overflow
|
||||
SR |= SR_CARRY;
|
||||
A = 0x7F;
|
||||
ram[0] = 0xE1;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x02;
|
||||
ram[3] = 0xFF;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x80 && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && SR&SR_OVER)) return -2;
|
||||
|
||||
//no borrow
|
||||
SR &= (~SR_CARRY);
|
||||
A = 0xC0;
|
||||
ram[0] = 0xE1;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x02;
|
||||
ram[3] = 0x40;
|
||||
instructions = 1; run();
|
||||
//overflow differs from 2nd sim ...
|
||||
if(!(A == 0x7F && !(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY && SR&SR_OVER)) return -3;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testSbcIndirectY() {
|
||||
Y = 0x01; X = 0x00;
|
||||
|
||||
//no overflow
|
||||
SR |= SR_CARRY;
|
||||
A = 0x00;
|
||||
ram[0] = 0xF1;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x03;
|
||||
ram[3] = 0x00;
|
||||
ram[4] = 0x01;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0xFF && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && !(SR&SR_OVER))) return -1;
|
||||
|
||||
//overflow
|
||||
SR |= SR_CARRY;
|
||||
A = 0x7F;
|
||||
ram[0] = 0xF1;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x03;
|
||||
ram[3] = 0x00;
|
||||
ram[4] = 0xFF;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x80 && SR&SR_NEG && !(SR&SR_ZERO) && !(SR&SR_CARRY) && SR&SR_OVER)) return -2;
|
||||
|
||||
//no borrow
|
||||
SR &= (~SR_CARRY);
|
||||
A = 0xC0;
|
||||
ram[0] = 0xF1;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x03;
|
||||
ram[3] = 0x00;
|
||||
ram[4] = 0x40;
|
||||
instructions = 1; run();
|
||||
//overflow differs from 2nd sim ...
|
||||
if(!(A == 0x7F && !(SR&SR_NEG) && !(SR&SR_ZERO) && SR&SR_CARRY && SR&SR_OVER)) return -3;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
23
6502tests/test/testSet.c
Normal file
23
6502tests/test/testSet.c
Normal file
@ -0,0 +1,23 @@
|
||||
int testSecImplied() {
|
||||
SR &= (~SR_CARRY);
|
||||
ram[0] = 0x38;
|
||||
instructions = 1; run();
|
||||
if(!(SR&SR_CARRY)) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testSedImplied() {
|
||||
SR &= (~SR_DEC);
|
||||
ram[0] = 0xF8;
|
||||
instructions = 1; run();
|
||||
if(!(SR&SR_DEC)) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testSeiImplied() {
|
||||
SR &= (~SR_INT);
|
||||
ram[0] = 0x78;
|
||||
instructions = 1; run();
|
||||
if(!(SR&SR_INT)) return -1;
|
||||
return 0;
|
||||
}
|
63
6502tests/test/testSt.c
Normal file
63
6502tests/test/testSt.c
Normal file
@ -0,0 +1,63 @@
|
||||
int testStxZeropage() {
|
||||
X = 0x23;
|
||||
ram[0] = 0x86;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(ram[2] != 0x23) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testStxZeropageY() {
|
||||
Y = 0x01;
|
||||
X = 0x23;
|
||||
ram[0] = 0x96;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(ram[2] != 0x23) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testStxAbsolute() {
|
||||
X = 0x23;
|
||||
ram[0] = 0x8E;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(ram[3] != 0x23) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testStyZeropage() {
|
||||
Y = 0x23;
|
||||
ram[0] = 0x84;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(ram[2] != 0x23) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testStyZeropageX() {
|
||||
X = 0x01;
|
||||
Y = 0x23;
|
||||
ram[0] = 0x94;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(ram[2] != 0x23) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testStyAbsolute() {
|
||||
Y = 0x23;
|
||||
ram[0] = 0x8C;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(ram[3] != 0x23) return -1;
|
||||
return 0;
|
||||
}
|
80
6502tests/test/testSta.c
Normal file
80
6502tests/test/testSta.c
Normal file
@ -0,0 +1,80 @@
|
||||
int testStaZeropage() {
|
||||
A = 0x23;
|
||||
ram[0] = 0x85;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(ram[2] != 0x23) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testStaZeropageX() {
|
||||
X = 0x01; Y = 0x00;
|
||||
A = 0x23;
|
||||
ram[0] = 0x95;
|
||||
ram[1] = 0x01;
|
||||
ram[2] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(ram[2] != 0x23) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testStaAbsolute() {
|
||||
A = 0x23;
|
||||
ram[0] = 0x8D;
|
||||
ram[1] = 0x03;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(ram[3] != 0x23) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testStaAbsoluteX() {
|
||||
X = 0x01; Y = 0x00;
|
||||
A = 0x23;
|
||||
ram[0] = 0x9D;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(ram[3] != 0x23) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testStaAbsoluteY() {
|
||||
Y = 0x01; X = 0x00;
|
||||
A = 0x23;
|
||||
ram[0] = 0x99;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x00;
|
||||
ram[3] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(ram[3] != 0x23) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testStaIndirectX() {
|
||||
X = 0x01; Y = 0x00;
|
||||
A = 0x23;
|
||||
ram[0] = 0x81;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x02;
|
||||
ram[3] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(ram[3] != 0x23) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testStaIndirectY() {
|
||||
Y = 0x01; X = 0x00;
|
||||
A = 0x23;
|
||||
ram[0] = 0x91;
|
||||
ram[1] = 0x02;
|
||||
ram[2] = 0x03;
|
||||
ram[3] = 0x00;
|
||||
ram[4] = 0x00;
|
||||
instructions = 1; run();
|
||||
if(ram[4] != 0x23) return -1;
|
||||
return 0;
|
||||
}
|
79
6502tests/test/testTransfer.c
Normal file
79
6502tests/test/testTransfer.c
Normal file
@ -0,0 +1,79 @@
|
||||
int testTaxImplied() {
|
||||
//normal
|
||||
X = 0; A = 0x23;
|
||||
ram[0] = 0xAA;
|
||||
instructions = 1; run();
|
||||
if(!(X == 0x23 && !(SR&SR_NEG) && !(SR&SR_ZERO)))return -1;
|
||||
//negative
|
||||
X = 0; A = 0xFE;
|
||||
ram[0] = 0xAA;
|
||||
instructions = 1; run();
|
||||
if(!(X == 0xFE && SR&SR_NEG && !(SR&SR_ZERO)))return -2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testTayImplied() {
|
||||
//normal
|
||||
Y = 0; A = 0x23;
|
||||
ram[0] = 0xA8;
|
||||
instructions = 1; run();
|
||||
if(!(Y == 0x23 && !(SR&SR_NEG) && !(SR&SR_ZERO)))return -1;
|
||||
//negative
|
||||
Y = 0; A = 0xFE;
|
||||
ram[0] = 0xA8;
|
||||
instructions = 1; run();
|
||||
if(!(Y == 0xFE && SR&SR_NEG && !(SR&SR_ZERO)))return -2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testTsxImplied() {
|
||||
//normal
|
||||
X = 0; SP = 0x23;
|
||||
ram[0] = 0xBA;
|
||||
instructions = 1; run();
|
||||
if(!(X == 0x23 && !(SR&SR_NEG) && !(SR&SR_ZERO)))return -1;
|
||||
//negative
|
||||
X = 0; SP = 0xFE;
|
||||
ram[0] = 0xBA;
|
||||
instructions = 1; run();
|
||||
if(!(X == 0xFE && SR&SR_NEG && !(SR&SR_ZERO)))return -2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testTxaImplied() {
|
||||
//normal
|
||||
A = 0; X = 0x23;
|
||||
ram[0] = 0x8A;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x23 && !(SR&SR_NEG) && !(SR&SR_ZERO)))return -1;
|
||||
//negative
|
||||
A = 0; X = 0xFE;
|
||||
ram[0] = 0x8A;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0xFE && SR&SR_NEG && !(SR&SR_ZERO)))return -2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testTxsImplied() {
|
||||
//normal
|
||||
SR = SR_FIXED_BITS;
|
||||
X = 0x00; SP = 0x00;
|
||||
ram[0] = 0x9A;
|
||||
instructions = 1; run();
|
||||
if(!(SP == 0x23 && !(SR&SR_ZERO)))return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int testTyaImplied() {
|
||||
//normal
|
||||
A = 0; Y = 0x23;
|
||||
ram[0] = 0x98;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0x23 && !(SR&SR_NEG) && !(SR&SR_ZERO)))return -1;
|
||||
//negative
|
||||
A = 0; Y = 0xFE;
|
||||
ram[0] = 0x98;
|
||||
instructions = 1; run();
|
||||
if(!(A == 0xFE && SR&SR_NEG && !(SR&SR_ZERO)))return -2;
|
||||
return 0;
|
||||
}
|
42
APPLEII/APPLEII.ino
Normal file
42
APPLEII/APPLEII.ino
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
Copyright (c) 2015, Damian Peckett <damian.peckett@gmail.com>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
All firmware is property of Apple Computer and is recreated here for
|
||||
historical purposes only.
|
||||
*/
|
||||
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
clearScreen();
|
||||
speaker_begin();
|
||||
cassette_begin();
|
||||
keyboard_begin();
|
||||
sei();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
run();
|
||||
}
|
168
APPLEII/cassette.ino
Normal file
168
APPLEII/cassette.ino
Normal file
@ -0,0 +1,168 @@
|
||||
// Share speaker pin for output
|
||||
#define CASSETTE_READ_PIN A5
|
||||
#define SPEAKER_PIN 5
|
||||
|
||||
#ifndef cbi
|
||||
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
|
||||
#endif
|
||||
#ifndef sbi
|
||||
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
|
||||
#endif
|
||||
|
||||
void cassette_header(unsigned short periods) {
|
||||
// Header Tone
|
||||
for(int i = 0; i < periods*128; ++i) {
|
||||
digitalWrite(SPEAKER_PIN, HIGH);
|
||||
delayMicroseconds(650);
|
||||
digitalWrite(SPEAKER_PIN, LOW);
|
||||
delayMicroseconds(650);
|
||||
}
|
||||
// Sync pulse, one half cycle at 2500hz and then 2000hz
|
||||
// 2500 hz
|
||||
digitalWrite(SPEAKER_PIN, HIGH);
|
||||
delayMicroseconds(200);
|
||||
// 2000 hz
|
||||
digitalWrite(SPEAKER_PIN, LOW);
|
||||
delayMicroseconds(250);
|
||||
}
|
||||
|
||||
void cassette_write_byte(unsigned char val) {
|
||||
// Shift it out, MSB first
|
||||
digitalWrite(SPEAKER_PIN, HIGH);
|
||||
delayMicroseconds((val&0x80) ? 500 : 250);
|
||||
digitalWrite(SPEAKER_PIN, LOW);
|
||||
delayMicroseconds((val&0x80) ? 500 : 250);
|
||||
//bit 6
|
||||
digitalWrite(SPEAKER_PIN, HIGH);
|
||||
delayMicroseconds((val&0x40) ? 500 : 250);
|
||||
digitalWrite(SPEAKER_PIN, LOW);
|
||||
delayMicroseconds((val&0x40) ? 500 : 250);
|
||||
//bit 5
|
||||
digitalWrite(SPEAKER_PIN, HIGH);
|
||||
delayMicroseconds((val&0x20) ? 500 : 250);
|
||||
digitalWrite(SPEAKER_PIN, LOW);
|
||||
delayMicroseconds((val&0x20) ? 500 : 250);
|
||||
//bit 4
|
||||
digitalWrite(SPEAKER_PIN, HIGH);
|
||||
delayMicroseconds((val&0x10) ? 500 : 250);
|
||||
digitalWrite(SPEAKER_PIN, LOW);
|
||||
delayMicroseconds((val&0x10) ? 500 : 250);
|
||||
//bit 3
|
||||
digitalWrite(SPEAKER_PIN, HIGH);
|
||||
delayMicroseconds((val&0x08) ? 500 : 250);
|
||||
digitalWrite(SPEAKER_PIN, LOW);
|
||||
delayMicroseconds((val&0x08) ? 500 : 250);
|
||||
//bit 2
|
||||
digitalWrite(SPEAKER_PIN, HIGH);
|
||||
delayMicroseconds((val&0x04) ? 500 : 250);
|
||||
digitalWrite(SPEAKER_PIN, LOW);
|
||||
delayMicroseconds((val&0x04) ? 500 : 250);
|
||||
//bit 1
|
||||
digitalWrite(SPEAKER_PIN, HIGH);
|
||||
delayMicroseconds((val&0x02) ? 500 : 250);
|
||||
digitalWrite(SPEAKER_PIN, LOW);
|
||||
delayMicroseconds((val&0x02) ? 500 : 250);
|
||||
//bit 0
|
||||
digitalWrite(SPEAKER_PIN, HIGH);
|
||||
delayMicroseconds((val&0x01) ? 500 : 250);
|
||||
digitalWrite(SPEAKER_PIN, LOW);
|
||||
delayMicroseconds((val&0x01) ? 500 : 250);
|
||||
}
|
||||
|
||||
void cassette_write_block(unsigned short A1, unsigned short A2) {
|
||||
unsigned char checksum = 0xFF, val = 0;
|
||||
for(unsigned short addr = A1; addr <= A2; ++addr) {
|
||||
val = read8(addr);
|
||||
cassette_write_byte(val);
|
||||
checksum ^= val;
|
||||
}
|
||||
cassette_write_byte(checksum);
|
||||
// High idle for a little while, make sure all bits cleared
|
||||
digitalWrite(SPEAKER_PIN, HIGH);
|
||||
delay(10);
|
||||
digitalWrite(SPEAKER_PIN, LOW);
|
||||
}
|
||||
|
||||
// Used to track center voltage
|
||||
float cassette_center_voltage = 512;
|
||||
// implement zero crossing detector
|
||||
boolean cassette_read_state() {
|
||||
static boolean zerocross_state = false;
|
||||
// get value
|
||||
short adc = (analogRead(CASSETTE_READ_PIN) - (short)cassette_center_voltage);
|
||||
// bias drift correction
|
||||
cassette_center_voltage += adc*0.05f;
|
||||
// ~7mv hysteresis
|
||||
if(zerocross_state && adc < -7) zerocross_state = false;
|
||||
else if(!zerocross_state && adc > 7) zerocross_state = true;
|
||||
return zerocross_state;
|
||||
}
|
||||
|
||||
// figure out the duration of zero crossing
|
||||
short cassette_read_transition() {
|
||||
unsigned long start_time;
|
||||
static boolean last = false;
|
||||
boolean cur = last;
|
||||
// loop until state transition
|
||||
for(start_time = micros();cur == last;) cur = cassette_read_state();
|
||||
// update transition tracking
|
||||
last = cur;
|
||||
//return duration of transition us
|
||||
return micros() - start_time;
|
||||
}
|
||||
|
||||
// Based loosely on steve wozniaks original algorithm
|
||||
boolean cassette_read_block(unsigned short A1, unsigned short A2) {
|
||||
short bitperiod;
|
||||
unsigned char val, checksum = 0xFF, datachecksum = 0x00;
|
||||
|
||||
// Calibrate the zero crossing detector
|
||||
for(short i = 0; i < 10000; ++i) cassette_read_state();
|
||||
|
||||
// find tape in edge
|
||||
cassette_read_transition();
|
||||
cassette_read_transition();
|
||||
|
||||
// Small delay to allow things to settle
|
||||
delay(500);
|
||||
|
||||
//wait for sync bit, short zero
|
||||
while(cassette_read_transition() > 300);
|
||||
|
||||
// skip second cycle of sync bit
|
||||
cassette_read_transition();
|
||||
|
||||
// start reading data
|
||||
for(unsigned short addr = A1; addr <= A2; ++addr) {
|
||||
// zero our byte of memory
|
||||
val = 0;
|
||||
for(unsigned char i = 8; i != 0; --i) {
|
||||
bitperiod = (cassette_read_transition() + cassette_read_transition()) / 2;
|
||||
if(bitperiod > 300) val |= _BV(i-1);
|
||||
}
|
||||
// write byte to memory
|
||||
write8(addr, val);
|
||||
// update checksum
|
||||
checksum ^= val;
|
||||
}
|
||||
|
||||
// Read checksum
|
||||
for(unsigned char i = 8; i != 0; --i) {
|
||||
bitperiod = (cassette_read_transition() + cassette_read_transition()) / 2;
|
||||
if(bitperiod > 300) datachecksum |= _BV(i-1);
|
||||
}
|
||||
|
||||
//return whether the data passes error checking
|
||||
return (datachecksum == checksum);
|
||||
}
|
||||
|
||||
void cassette_begin() {
|
||||
// ADC prescale, 77khz
|
||||
sbi(ADCSRA,ADPS2);
|
||||
cbi(ADCSRA,ADPS1);
|
||||
cbi(ADCSRA,ADPS0);
|
||||
// internal pullup on analog pin
|
||||
digitalWrite(CASSETTE_READ_PIN, HIGH);
|
||||
// use 1.1v internal analog reference
|
||||
analogReference(INTERNAL);
|
||||
}
|
528
APPLEII/cpu.ino
Normal file
528
APPLEII/cpu.ino
Normal file
@ -0,0 +1,528 @@
|
||||
// μ6502 - Barebones 6502 Emulator By Damian Peckett
|
||||
// dpeckett.com, <damian.peckett@gmail.com>
|
||||
|
||||
// Address Modes
|
||||
#define AD_IMP 0x01
|
||||
#define AD_A 0x02
|
||||
#define AD_ABS 0x03
|
||||
#define AD_ABSX 0x04
|
||||
#define AD_ABSY 0x05
|
||||
#define AD_IMM 0x06
|
||||
#define AD_IND 0x07
|
||||
#define AD_INDX 0x08
|
||||
#define AD_INDY 0x09
|
||||
#define AD_REL 0x0A
|
||||
#define AD_ZPG 0x0B
|
||||
#define AD_ZPGX 0x0C
|
||||
#define AD_ZPGY 0x0D
|
||||
|
||||
// SR Flag Modes
|
||||
#define FL_NONE 0x00
|
||||
#define FL_Z 0x20
|
||||
#define FL_ZN 0xA0
|
||||
#define FL_ZNC 0xB0
|
||||
#define FL_ZC 0x30
|
||||
#define FL_ALL 0xF0
|
||||
|
||||
//Unimplemented ops
|
||||
#define UNDF 0x00
|
||||
|
||||
//Other constants
|
||||
#define SR_FIXED_BITS 0x20
|
||||
#define SR_CARRY 0x01
|
||||
#define SR_ZERO 0x02
|
||||
#define SR_INT 0x04
|
||||
#define SR_DEC 0x08
|
||||
#define SR_BRK 0x10
|
||||
#define SR_OVER 0x40
|
||||
#define SR_NEG 0x80
|
||||
|
||||
//Stack pointer base address
|
||||
#define STP_BASE 0x100
|
||||
|
||||
//high nibble SR flags, low nibble address mode
|
||||
const unsigned char flags[] PROGMEM = {
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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,
|
||||
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
|
||||
};
|
||||
|
||||
// CPU registers
|
||||
unsigned short PC;
|
||||
unsigned char STP = 0xFD, A = 0x00, X = 0x00, Y = 0x00, SR = SR_FIXED_BITS;
|
||||
|
||||
//Execution variables
|
||||
unsigned char opcode, opflags;
|
||||
unsigned short argument_addr;
|
||||
|
||||
//Temporary variables for flag generation
|
||||
unsigned char value8;
|
||||
unsigned short value16, value16_2, result;
|
||||
|
||||
void setflags() {
|
||||
// Mask out affected flags
|
||||
switch(opflags&0xF0) {
|
||||
case 0xA0: SR&=0x7D; break;
|
||||
case 0xB0: SR&=0x7C; break;
|
||||
case 0x30: SR&=0xFC; break;
|
||||
case 0xF0: SR&=0x3C; break;
|
||||
case 0x20: SR&=0xFD; break;
|
||||
}
|
||||
|
||||
// Set various status flags
|
||||
if(opflags&0x80) SR |= (result&0x0080); //negative
|
||||
if(opflags&0x20) SR |= (((result&0xFF) == 0)?0x02:0); //zero
|
||||
if(opflags&0x10) SR |= ((result&0xFF00)?0x01:0); //carry
|
||||
if(opflags&0x40) SR |= ((result^((unsigned short)A))&(result^value16)&0x0080)>>1;
|
||||
}
|
||||
|
||||
// Stack functions
|
||||
void push16(unsigned short pushval) {
|
||||
write8(STP_BASE + (STP--), (pushval>>8)&0xFF);
|
||||
write8(STP_BASE + (STP--), pushval&0xFF);
|
||||
}
|
||||
|
||||
void push8(unsigned char pushval) {
|
||||
write8(STP_BASE + (STP--), pushval);
|
||||
}
|
||||
|
||||
unsigned short pull16() {
|
||||
value16 = read8(STP_BASE + (++STP)) | ((unsigned short)read8(STP_BASE + (++STP))<< 8);
|
||||
return value16;
|
||||
}
|
||||
|
||||
unsigned char pull8() {
|
||||
return read8(STP_BASE + (++STP));
|
||||
}
|
||||
|
||||
void run() {
|
||||
// Load the reset vector
|
||||
PC = read16(0xFFFC);
|
||||
STP = 0xFD;
|
||||
|
||||
for(;;) {
|
||||
// Routines for hooking apple ][ monitor routines
|
||||
program_hooks(PC);
|
||||
|
||||
// Get opcode / addressing mode
|
||||
opcode = read8(PC++);
|
||||
opflags = pgm_read_byte_near(flags+opcode);
|
||||
|
||||
// Addressing modes
|
||||
switch(opflags&0x0F) {
|
||||
case AD_IMP: case AD_A: argument_addr = 0xFFFF; break;
|
||||
case AD_ABS:
|
||||
argument_addr = read16(PC);
|
||||
PC += 2;
|
||||
break;
|
||||
case AD_ABSX:
|
||||
argument_addr = read16(PC) + (unsigned short)X;
|
||||
PC += 2;
|
||||
break;
|
||||
case AD_ABSY:
|
||||
argument_addr = read16(PC) + (unsigned short)Y;
|
||||
PC += 2;
|
||||
break;
|
||||
case AD_IMM:
|
||||
argument_addr = PC++;
|
||||
break;
|
||||
case AD_IND:
|
||||
argument_addr = read16(PC);
|
||||
value16 = (argument_addr&0xFF00) | ((argument_addr+1)&0x00FF); // Page wrap
|
||||
argument_addr = (unsigned short)read8(argument_addr) | ((unsigned short)read8(value16) << 8);
|
||||
PC+=2;
|
||||
break;
|
||||
case AD_INDX:
|
||||
argument_addr = ((unsigned short)read8(PC++) + (unsigned short)X)&0xFF;
|
||||
value16 = (argument_addr&0xFF00) | ((argument_addr+1)&0x00FF); // Page wrap
|
||||
argument_addr = (unsigned short)read8(argument_addr) | ((unsigned short)read8(value16) << 8);
|
||||
break;
|
||||
case AD_INDY:
|
||||
argument_addr = (unsigned short)read8(PC++);
|
||||
value16 = (argument_addr&0xFF00) | ((argument_addr+1)&0x00FF); // Page wrap
|
||||
argument_addr = (unsigned short)read8(argument_addr) | ((unsigned short)read8(value16) << 8);
|
||||
argument_addr += Y;
|
||||
break;
|
||||
case AD_REL:
|
||||
argument_addr = (unsigned short)read8(PC++);
|
||||
argument_addr |= ((argument_addr&0x80)?0xFF00:0);
|
||||
break;
|
||||
case AD_ZPG:
|
||||
argument_addr = (unsigned short)read8(PC++);
|
||||
break;
|
||||
case AD_ZPGX:
|
||||
argument_addr = ((unsigned short)read8(PC++) + (unsigned short)X)&0xFF;
|
||||
break;
|
||||
case AD_ZPGY:
|
||||
argument_addr = ((unsigned short)read8(PC++) + (unsigned short)Y)&0xFF;
|
||||
break;
|
||||
}
|
||||
|
||||
//opcodes
|
||||
switch(opcode) {
|
||||
//ADC
|
||||
case 0x69: case 0x65: case 0x75:
|
||||
case 0x6D: case 0x7D: case 0x79:
|
||||
case 0x61: case 0x71:
|
||||
value16 = (unsigned short)read8(argument_addr);
|
||||
result = (unsigned short)A + value16 + (unsigned short)(SR&SR_CARRY);
|
||||
setflags();
|
||||
A = result&0xFF;
|
||||
break;
|
||||
//AND
|
||||
case 0x29: case 0x25: case 0x35:
|
||||
case 0x2D: case 0x3D: case 0x39:
|
||||
case 0x21: case 0x31:
|
||||
result = A&read8(argument_addr);
|
||||
A = result&0xFF;
|
||||
setflags();
|
||||
break;
|
||||
//ASL A
|
||||
case 0x0A:
|
||||
value16 = (unsigned short)A;
|
||||
result = value16<<1;
|
||||
setflags();
|
||||
A = result&0xFF;
|
||||
break;
|
||||
//ASL
|
||||
case 0x06: case 0x16: case 0x0E:
|
||||
case 0x1E:
|
||||
value16 = read8(argument_addr);
|
||||
result = value16<<1;
|
||||
setflags();
|
||||
write8(argument_addr, result&0xFF);
|
||||
break;
|
||||
//BCC
|
||||
case 0x90:
|
||||
if(!(SR&SR_CARRY)) PC += argument_addr;
|
||||
break;
|
||||
//BCS
|
||||
case 0xB0:
|
||||
if((SR&SR_CARRY)) PC += argument_addr;
|
||||
break;
|
||||
//BEQ
|
||||
case 0xF0:
|
||||
if((SR&SR_ZERO)) PC += argument_addr;
|
||||
break;
|
||||
//BNE
|
||||
case 0xD0:
|
||||
if(!(SR&SR_ZERO)) PC += argument_addr;
|
||||
break;
|
||||
//BIT
|
||||
case 0x24: case 0x2C:
|
||||
value8 = read8(argument_addr);
|
||||
result = A & value8;
|
||||
setflags();
|
||||
SR = (SR&0x3F) | (value8&0xC0);
|
||||
break;
|
||||
//BMI
|
||||
case 0x30:
|
||||
if((SR&SR_NEG)) PC += argument_addr;
|
||||
break;
|
||||
//BPL
|
||||
case 0x10:
|
||||
if(!(SR&SR_NEG)) PC += argument_addr;
|
||||
break;
|
||||
//BRK
|
||||
case 0x00:
|
||||
PC++;
|
||||
push16(PC);
|
||||
push8(SR|SR_BRK);
|
||||
SR|=SR_INT;
|
||||
PC = read16(0xFFFE);
|
||||
break;
|
||||
//BVC
|
||||
case 0x50:
|
||||
if(!(SR&SR_OVER)) PC += argument_addr;
|
||||
break;
|
||||
//BVS
|
||||
case 0x70:
|
||||
if(SR&SR_OVER) PC += argument_addr;
|
||||
break;
|
||||
//CLC
|
||||
case 0x18:
|
||||
SR&=0xFE;
|
||||
break;
|
||||
//CLD
|
||||
case 0xD8:
|
||||
SR&=0xF7;
|
||||
break;
|
||||
//CLI
|
||||
case 0x58:
|
||||
SR&=0xFB;
|
||||
break;
|
||||
//CLV
|
||||
case 0xB8:
|
||||
SR&=0xBF;
|
||||
break;
|
||||
//CMP
|
||||
case 0xC9: case 0xC5: case 0xD5:
|
||||
case 0xCD: case 0xDD: case 0xD9:
|
||||
case 0xC1: case 0xD1:
|
||||
value16 = ((unsigned short)read8(argument_addr)) ^ 0x00FF;
|
||||
result = (unsigned short)A + value16 + (unsigned short)1;
|
||||
setflags();
|
||||
break;
|
||||
//CPX
|
||||
case 0xE0: case 0xE4: case 0xEC:
|
||||
value16 = ((unsigned short)read8(argument_addr)) ^ 0x00FF;
|
||||
result = (unsigned short)X + value16 + (unsigned short)1;
|
||||
setflags();
|
||||
break;
|
||||
//CPY
|
||||
case 0xC0: case 0xC4: case 0xCC:
|
||||
value16 = ((unsigned short)read8(argument_addr)) ^ 0x00FF;
|
||||
result = (unsigned short)Y + value16 + (unsigned short)1;
|
||||
setflags();
|
||||
break;
|
||||
//DEC
|
||||
case 0xC6: case 0xD6: case 0xCE:
|
||||
case 0xDE:
|
||||
value16 = (unsigned short)read8(argument_addr);
|
||||
result = value16 - 1;
|
||||
setflags();
|
||||
write8(argument_addr, result&0xFF);
|
||||
break;
|
||||
//DEX
|
||||
case 0xCA:
|
||||
result = --X;
|
||||
setflags();
|
||||
break;
|
||||
//DEY
|
||||
case 0x88:
|
||||
result = --Y;
|
||||
setflags();
|
||||
break;
|
||||
//EOR
|
||||
case 0x49: case 0x45: case 0x55:
|
||||
case 0x4D: case 0x5D: case 0x59:
|
||||
case 0x41: case 0x51:
|
||||
value8 = read8(argument_addr);
|
||||
result = A^value8;
|
||||
setflags();
|
||||
A = result&0xFF;
|
||||
break;
|
||||
//INC
|
||||
case 0xE6: case 0xF6: case 0xEE:
|
||||
case 0xFE:
|
||||
value16 = (unsigned short)read8(argument_addr);
|
||||
result = value16 + 1;
|
||||
setflags();
|
||||
write8(argument_addr, result&0xFF);
|
||||
break;
|
||||
//INX
|
||||
case 0xE8:
|
||||
result = ++X;
|
||||
setflags();
|
||||
break;
|
||||
//INY
|
||||
case 0xC8:
|
||||
result = ++Y;
|
||||
setflags();
|
||||
break;
|
||||
//JMP
|
||||
case 0x4C: case 0x6C:
|
||||
PC = argument_addr;
|
||||
break;
|
||||
//JSR
|
||||
case 0x20:
|
||||
push16(PC-1);
|
||||
PC = argument_addr;
|
||||
break;
|
||||
//LDA
|
||||
case 0xA9: case 0xA5: case 0xB5:
|
||||
case 0xAD: case 0xBD: case 0xB9:
|
||||
case 0xA1: case 0xB1:
|
||||
A = read8(argument_addr);
|
||||
result = A;
|
||||
setflags();
|
||||
break;
|
||||
//LDX
|
||||
case 0xA2: case 0xA6: case 0xB6:
|
||||
case 0xAE: case 0xBE:
|
||||
X = read8(argument_addr);
|
||||
result = X;
|
||||
setflags();
|
||||
break;
|
||||
//LDY
|
||||
case 0xA0: case 0xA4: case 0xB4:
|
||||
case 0xAC: case 0xBC:
|
||||
Y = read8(argument_addr);
|
||||
result = Y;
|
||||
setflags();
|
||||
break;
|
||||
//LSR A
|
||||
case 0x4A:
|
||||
value8 = A;
|
||||
result = value8 >> 1;
|
||||
result |= (value8&0x1)?0x8000:0;
|
||||
setflags();
|
||||
A = result&0xFF;
|
||||
break;
|
||||
//LSR
|
||||
case 0x46: case 0x56: case 0x4E:
|
||||
case 0x5E:
|
||||
value8 = read8(argument_addr);
|
||||
result = value8 >> 1;
|
||||
result |= (value8&0x1)?0x8000:0;
|
||||
setflags();
|
||||
write8(argument_addr, result&0xFF);
|
||||
break;
|
||||
//NOP
|
||||
case 0xEA:
|
||||
break;
|
||||
//ORA
|
||||
case 0x09: case 0x05: case 0x15:
|
||||
case 0x0D: case 0x1D: case 0x19:
|
||||
case 0x01: case 0x11:
|
||||
value8 = read8(argument_addr);
|
||||
result = A | value8;
|
||||
setflags();
|
||||
A = result&0xFF;
|
||||
break;
|
||||
//PHA
|
||||
case 0x48:
|
||||
push8(A);
|
||||
break;
|
||||
//PHP
|
||||
case 0x08:
|
||||
push8(SR|SR_BRK);
|
||||
break;
|
||||
//PLA
|
||||
case 0x68:
|
||||
result = pull8();
|
||||
setflags();
|
||||
A = result;
|
||||
break;
|
||||
//PLP
|
||||
case 0x28:
|
||||
SR = pull8() | SR_FIXED_BITS;
|
||||
break;
|
||||
//ROL A
|
||||
case 0x2A:
|
||||
value16 = (unsigned short)A;
|
||||
result = (value16 << 1) | (SR&SR_CARRY);
|
||||
setflags();
|
||||
A = result&0xFF;
|
||||
break;
|
||||
//ROL
|
||||
case 0x26: case 0x36: case 0x2E:
|
||||
case 0x3E:
|
||||
value16 = (unsigned short)read8(argument_addr);
|
||||
result = (value16 << 1) | (SR&SR_CARRY);
|
||||
setflags();
|
||||
write8(argument_addr, result&0xFF);
|
||||
break;
|
||||
//ROR A
|
||||
case 0x6A:
|
||||
value16 = (unsigned short)A;
|
||||
result = (value16 >> 1) | ((SR&SR_CARRY) << 7);
|
||||
result |= (value16&0x1)?0x8000:0;
|
||||
setflags();
|
||||
A = result&0xFF;
|
||||
break;
|
||||
//ROR
|
||||
case 0x66: case 0x76: case 0x6E:
|
||||
case 0x7E:
|
||||
value16 = (unsigned short)read8(argument_addr);
|
||||
result = (value16 >> 1) | ((SR&SR_CARRY) << 7);
|
||||
result |= (value16&0x1)?0x8000:0;
|
||||
setflags();
|
||||
write8(argument_addr, result&0xFF);
|
||||
break;
|
||||
//RTI
|
||||
case 0x40:
|
||||
SR = pull8();
|
||||
PC = pull16();
|
||||
break;
|
||||
//RTS
|
||||
case 0x60:
|
||||
PC = pull16() + 1;
|
||||
break;
|
||||
//SBC
|
||||
case 0xE9: case 0xE5: case 0xF5:
|
||||
case 0xED: case 0xFD: case 0xF9:
|
||||
case 0xE1: case 0xF1:
|
||||
value16 = ((unsigned short)read8(argument_addr)) ^ 0x00FF;
|
||||
result = (unsigned short)A + value16 + (unsigned short)(SR&SR_CARRY);
|
||||
setflags();
|
||||
A = result&0xFF;
|
||||
break;
|
||||
//SEC
|
||||
case 0x38:
|
||||
SR |= SR_CARRY;
|
||||
break;
|
||||
//SED
|
||||
case 0xF8:
|
||||
SR |= SR_DEC;
|
||||
break;
|
||||
//SEI
|
||||
case 0x78:
|
||||
SR |= SR_INT;
|
||||
break;
|
||||
//STA
|
||||
case 0x85: case 0x95: case 0x8D:
|
||||
case 0x9D: case 0x99: case 0x81:
|
||||
case 0x91:
|
||||
write8(argument_addr, A);
|
||||
break;
|
||||
//STX
|
||||
case 0x86: case 0x96: case 0x8E:
|
||||
write8(argument_addr, X);
|
||||
break;
|
||||
//STY
|
||||
case 0x84: case 0x94: case 0x8C:
|
||||
write8(argument_addr, Y);
|
||||
break;
|
||||
//TAX
|
||||
case 0xAA:
|
||||
X = A;
|
||||
result = A;
|
||||
setflags();
|
||||
break;
|
||||
//TAY
|
||||
case 0xA8:
|
||||
Y = A;
|
||||
result = A;
|
||||
setflags();
|
||||
break;
|
||||
//TSX
|
||||
case 0xBA:
|
||||
X = STP;
|
||||
result = STP;
|
||||
setflags();
|
||||
break;
|
||||
//TXA
|
||||
case 0x8A:
|
||||
A = X;
|
||||
result = X;
|
||||
setflags();
|
||||
break;
|
||||
//TXS
|
||||
case 0x9A:
|
||||
STP = X;
|
||||
result = X;
|
||||
setflags();
|
||||
break;
|
||||
//TYA
|
||||
case 0x98:
|
||||
A = Y;
|
||||
result = Y;
|
||||
setflags();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
29
APPLEII/ghettovga.ino
Normal file
29
APPLEII/ghettovga.ino
Normal file
@ -0,0 +1,29 @@
|
||||
void writeCharacter(unsigned char row, unsigned char col, unsigned char val) {
|
||||
unsigned char buf[4] = {0xFD, 0, 0, 0};
|
||||
buf[1] = col;
|
||||
buf[2] = row;
|
||||
buf[3] = val;
|
||||
Serial.write(buf, 4);
|
||||
}
|
||||
|
||||
unsigned char readCharacter(unsigned char row, unsigned char col) {
|
||||
unsigned long transaction_begin;
|
||||
unsigned char buf[4] = {0xFA, 0, 0};
|
||||
buf[1] = col;
|
||||
buf[2] = row;
|
||||
Serial.write(buf, 3);
|
||||
for(transaction_begin = millis(); !Serial.available(); millis() < (transaction_begin+50));
|
||||
return Serial.read();
|
||||
}
|
||||
|
||||
void clearScreen() {
|
||||
unsigned char cmd = 0xFC;
|
||||
Serial.write(&cmd, 1);
|
||||
delay(20);
|
||||
}
|
||||
|
||||
void screenScroll() {
|
||||
unsigned char cmd = 0xFB;
|
||||
Serial.write(&cmd, 1);
|
||||
delay(20);
|
||||
}
|
87
APPLEII/keyboard.ino
Normal file
87
APPLEII/keyboard.ino
Normal file
@ -0,0 +1,87 @@
|
||||
#include <avr/wdt.h>
|
||||
|
||||
#define KEYBD_DATA_PIN 4
|
||||
|
||||
const unsigned char scancode_to_apple[] PROGMEM = {
|
||||
//$0 $1 $2 $3 $4 $5 $6 $7 $8 $9 $A $B $C $D $E $F
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //$00
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xD1, 0xB1, 0x00, 0x00, 0x00, 0xDA, 0xD3, 0xC1, 0xD7, 0xB2, 0x00, //$10
|
||||
0x00, 0xC3, 0xD8, 0xC4, 0xC5, 0xB4, 0xB3, 0x00, 0x00, 0xA0, 0xD6, 0xC6, 0xD4, 0xD2, 0xB5, 0x00, //$20
|
||||
0x00, 0xCE, 0xC2, 0xC8, 0xC7, 0xD9, 0xB6, 0x00, 0x00, 0x00, 0xCD, 0xCA, 0xD5, 0xB7, 0xB8, 0x00, //$30
|
||||
0x00, 0xAC, 0xCB, 0xC9, 0xCF, 0xB0, 0xB9, 0x00, 0x00, 0xAE, 0xAF, 0xCC, 0xBB, 0xD0, 0xAD, 0x00, //$40
|
||||
0x00, 0x00, 0xA7, 0x00, 0x00, 0xBD, 0x00, 0x00, 0x00, 0x00, 0x8D, 0x00, 0x00, 0x00, 0x00, 0x00, //$50
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0xB1, 0x00, 0xB4, 0xB7, 0x00, 0x00, 0x00, //$60
|
||||
0xB0, 0xAE, 0xB2, 0xB5, 0xB6, 0xB8, 0x9B, 0x00, 0x00, 0xAB, 0xB3, 0xAD, 0xAA, 0xB9, 0x00, 0x00, //$70
|
||||
// High mirror, shift modified keys
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //$80 0
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xD1, 0xA1, 0x00, 0x00, 0x00, 0xDA, 0xD3, 0xC1, 0xD7, 0xC0, 0x00, //$90 1
|
||||
0x00, 0xC3, 0xD8, 0xC4, 0xC5, 0xA4, 0xA3, 0x00, 0x00, 0xA0, 0xD6, 0xC6, 0xD4, 0xD2, 0xA5, 0x00, //$A0 2
|
||||
0x00, 0xCE, 0xC2, 0xC8, 0xC7, 0xD9, 0xDE, 0x00, 0x00, 0x00, 0xCD, 0xCA, 0xD5, 0xA6, 0xAA, 0x00, //$B0 3
|
||||
0x00, 0xBC, 0xCB, 0xC9, 0xCF, 0xA9, 0xA8, 0x00, 0x00, 0xBE, 0xBF, 0xCC, 0xBA, 0xD0, 0xAD, 0x00, //$C0 4
|
||||
0x00, 0x00, 0xA2, 0x00, 0x00, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x8D, 0x00, 0x00, 0x00, 0x00, 0x00, //$D0 5
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0xB1, 0x00, 0xB4, 0xB7, 0x00, 0x00, 0x00, //$E0 6
|
||||
0xB0, 0xAE, 0xB2, 0xB5, 0xB6, 0xB8, 0x9B, 0x00, 0x00, 0xAB, 0xB3, 0xAD, 0xAA, 0xB9, 0x00, 0x00 //$F0 7
|
||||
};
|
||||
|
||||
// keyboard scan buffer
|
||||
unsigned short keyboard_data[3] = {0, 0, 0};
|
||||
unsigned char keyboard_buf_indx = 0, keyboard_mbyte = 0;
|
||||
boolean shift_enabled = false;
|
||||
|
||||
// In apple II scancode format
|
||||
volatile unsigned char keymem = 0;
|
||||
|
||||
unsigned char keyboard_read() {
|
||||
return keymem;
|
||||
}
|
||||
|
||||
void keyboard_strobe() {
|
||||
keymem&=0x7F;
|
||||
}
|
||||
|
||||
// clock must be on digital 3
|
||||
void keyboard_begin() {
|
||||
pinMode(3, INPUT_PULLUP);
|
||||
pinMode(KEYBD_DATA_PIN, INPUT_PULLUP);
|
||||
attachInterrupt(1, keyboard_bit, FALLING);
|
||||
}
|
||||
|
||||
void keyboard_bit() {
|
||||
if(digitalRead(KEYBD_DATA_PIN))keyboard_data[2] |= _BV(keyboard_buf_indx);
|
||||
else keyboard_data[2] &= ~(_BV(keyboard_buf_indx));
|
||||
if(++keyboard_buf_indx == 11) {
|
||||
// Ignore parity checks for now
|
||||
keyboard_data[2] = (keyboard_data[2]>>1)&0xFF;
|
||||
|
||||
// extended keys
|
||||
if(keyboard_data[2] == 0xF0 || keyboard_data[2] == 0xE0) keyboard_mbyte = 1;
|
||||
else {
|
||||
//decrement counter for multibyte commands
|
||||
if(keyboard_mbyte) keyboard_mbyte--;
|
||||
// multibyte command is finished / normal command, process it
|
||||
if(!keyboard_mbyte) {
|
||||
if(keyboard_data[1] != 0xF0 && keyboard_data[1] != 0xE0) {
|
||||
//Standard keys
|
||||
if(keyboard_data[2] == 0x12 || keyboard_data[2] == 0x59) shift_enabled = true; //shift modifiers
|
||||
else keymem = pgm_read_byte_near(scancode_to_apple+keyboard_data[2]+((shift_enabled)?0x80:0x00));
|
||||
} else if(keyboard_data[0] != 0xF0 && keyboard_data[1] == 0xE0) {
|
||||
//Extended keys
|
||||
if(keyboard_data[2] == 0x6B) keymem = 0x95; //back key
|
||||
if(keyboard_data[2] == 0x74) keymem = 0x88; //forward key
|
||||
// Power management keys, hardware reset
|
||||
if(keyboard_data[2] == 0x37) {
|
||||
// enable watchdog with min timeout
|
||||
// wait until reset
|
||||
wdt_enable(WDTO_15MS);
|
||||
for(;;);
|
||||
}
|
||||
} else if(keyboard_data[1] == 0xF0 && (keyboard_data[2] == 0x12 || keyboard_data[2] == 0x59)) shift_enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
//shuffle buffer
|
||||
keyboard_data[0] = keyboard_data[1];
|
||||
keyboard_data[1] = keyboard_data[2];
|
||||
keyboard_buf_indx = 0;
|
||||
}
|
||||
}
|
1077
APPLEII/memory.ino
Normal file
1077
APPLEII/memory.ino
Normal file
File diff suppressed because it is too large
Load Diff
29
APPLEII/monitor.ino
Normal file
29
APPLEII/monitor.ino
Normal file
@ -0,0 +1,29 @@
|
||||
// Hook routines for the apple II monitor program
|
||||
// Used to trick the apple code into working on this hardware
|
||||
// Ideally should patch the ROM itself, will do in future.
|
||||
void program_hooks(unsigned short addr) {
|
||||
// hook screen scroll, monitor command
|
||||
if(addr == 0xFC70) {
|
||||
screenScroll();
|
||||
PC = 0xFC95;
|
||||
}
|
||||
// hook cassette write commnand
|
||||
else if (addr == 0xFECD || addr == 0xFECF) {
|
||||
// Header length
|
||||
cassette_header((addr==0xFECD)?64:A);
|
||||
// Write Data Block
|
||||
cassette_write_block(read16(0x3C), read16(0x3E));
|
||||
// Emulate counter behaviour
|
||||
write16(0x003C, read16(0x3E));
|
||||
PC = 0xFEF5;
|
||||
}
|
||||
// hook cassette read command
|
||||
else if (addr == 0xFEFD) {
|
||||
// Read Data Block
|
||||
boolean success = cassette_read_block(read16(0x3C), read16(0x3E));
|
||||
// Emulate counter behaviour
|
||||
write16(0x003C, read16(0x3E));
|
||||
if(success) PC = 0xFF3A;
|
||||
else PC = 0xFF2D;
|
||||
}
|
||||
}
|
41
APPLEII/screen.ino
Normal file
41
APPLEII/screen.ino
Normal file
@ -0,0 +1,41 @@
|
||||
// squash all the modes for this demo
|
||||
unsigned char appleToGhettoVGA(unsigned char apple) {
|
||||
if(apple >= 0xC0) return apple-0x40;
|
||||
else return apple&0x7F;
|
||||
}
|
||||
|
||||
// Squash into normal mode
|
||||
unsigned char ghettoVGAToApple(unsigned char ghettoVga) {
|
||||
if(ghettoVga >= 0x40 && ghettoVga <= 0x7f) return ghettoVga;
|
||||
else return ghettoVga|0x80;
|
||||
}
|
||||
|
||||
// Extract row, column addressing from woz's interlacing mode
|
||||
static unsigned char g_row = 0, g_col = 0;
|
||||
void decodeScreenAddress(unsigned short address) {
|
||||
unsigned char block_of_lines = (address>>7) - 0x08;
|
||||
unsigned char block_offset = (address&0x00FF) - ((block_of_lines&0x01) ? 0x80 : 0x00);
|
||||
if(block_offset < 0x28) {
|
||||
g_row = block_of_lines;
|
||||
g_col = block_offset;
|
||||
} else if(block_offset < 0x50) {
|
||||
g_row = block_of_lines + 8;
|
||||
g_col = block_offset-0x28;
|
||||
} else {
|
||||
g_row = block_of_lines + 16;
|
||||
g_col = block_offset-0x50;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char screenRead(unsigned short address) {
|
||||
//Find our row/column
|
||||
decodeScreenAddress(address);
|
||||
return ghettoVGAToApple(readCharacter(g_row, g_col));
|
||||
}
|
||||
|
||||
void screenWrite(unsigned short address, unsigned char value) {
|
||||
//Find our row/column
|
||||
decodeScreenAddress(address);
|
||||
// If not bell character
|
||||
if(value != 0x87) writeCharacter(g_row, g_col, appleToGhettoVGA(value));
|
||||
}
|
12
APPLEII/speaker.ino
Normal file
12
APPLEII/speaker.ino
Normal file
@ -0,0 +1,12 @@
|
||||
#define SPEAKER_PIN 5
|
||||
|
||||
void speaker_begin() {
|
||||
pinMode(SPEAKER_PIN, OUTPUT);
|
||||
digitalWrite(SPEAKER_PIN, LOW);
|
||||
}
|
||||
|
||||
void speaker_toggle() {
|
||||
static boolean state = false;
|
||||
state = (state)?false:true;
|
||||
digitalWrite(SPEAKER_PIN, state);
|
||||
}
|
10
README.md
10
README.md
@ -1,2 +1,10 @@
|
||||
# arduino-appleii
|
||||
Emulating the original Apple II microcomputer on an Arduino Uno microcontroller.
|
||||
|
||||
Emulate the Apple II Microcomputer / 6502 on an Arduino Uno.
|
||||
To be used in conjuction with video generation code in my arduino-vga repository.
|
||||
|
||||
Currently somewhere between 5 and 8 times slower than real hardware, however the
|
||||
arduino is maybe 16-32x the speed of the original mos6502 CPU. Should be possible
|
||||
to tighten things up and reach realtime.
|
||||
|
||||
Feel free to play arround!
|
Loading…
Reference in New Issue
Block a user