diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..96aeeed Binary files /dev/null and b/.DS_Store differ diff --git a/6502tests/.DS_Store b/6502tests/.DS_Store new file mode 100644 index 0000000..1d70cf8 Binary files /dev/null and b/6502tests/.DS_Store differ diff --git a/6502tests/test/.DS_Store b/6502tests/test/.DS_Store new file mode 100644 index 0000000..fa63f08 Binary files /dev/null and b/6502tests/test/.DS_Store differ diff --git a/APPLEII/.DS_Store b/APPLEII/.DS_Store new file mode 100644 index 0000000..04bc5b6 Binary files /dev/null and b/APPLEII/.DS_Store differ diff --git a/APPLEII/addressing.ino b/APPLEII/addressing.ino new file mode 100644 index 0000000..d70908e --- /dev/null +++ b/APPLEII/addressing.ino @@ -0,0 +1,54 @@ +// In fastcpu ino +extern unsigned short PC; +extern unsigned char X, Y; + +// Addressing Modes +unsigned short inline a_abs() { + PC += 2; + return read16(PC-2); +} + +unsigned short inline a_absx() { + PC += 2; + return (read16(PC-2) + (unsigned short)X); +} + +unsigned short inline a_absy() { + PC += 2; + return (read16(PC-2) + (unsigned short)Y); +} + +unsigned short inline a_imm() { + return PC++; +} + +//ignore page wrap bug +unsigned short inline a_ind() { + PC += 2; + return read16(read16(PC-2)); +} + +unsigned short inline a_indx() { + return read16(((unsigned short)read8(PC++) + (unsigned short)X)&0xFF); +} + +unsigned short inline a_indy() { + return read16(((unsigned short)read8(PC++) + (unsigned short)Y)&0xFF); +} + +unsigned short inline a_rel() { + unsigned short addr = (unsigned short)read8(PC++); + return addr | ((addr&0x80)?0xFF00:0x0000); +} + +unsigned short inline a_zpg() { + return (unsigned short)read8(PC++); +} + +unsigned short inline a_zpgx() { + return ((unsigned short)read8(PC++) + (unsigned short)X)&0xFF; +} + +unsigned short inline a_zpgy() { + return ((unsigned short)read8(PC++) + (unsigned short)Y)&0xFF; +} diff --git a/APPLEII/cpu.ino b/APPLEII/cpu.ino index 561a4e8..9fc8e6c 100644 --- a/APPLEII/cpu.ino +++ b/APPLEII/cpu.ino @@ -1,6 +1,6 @@ // μ6502 - Barebones 6502 Emulator By Damian Peckett // dpeckett.com, - +/* // Address Modes #define AD_IMP 0x01 #define AD_A 0x02 @@ -42,24 +42,28 @@ //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 + 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 }; +const void *opcode[] PROGMEM = { + +} + // CPU registers unsigned short PC; unsigned char STP = 0xFD, A = 0x00, X = 0x00, Y = 0x00, SR = SR_FIXED_BITS; @@ -89,25 +93,6 @@ void setflags() { 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); @@ -171,6 +156,8 @@ void run() { break; } + + //opcodes switch(opcode) { //ADC @@ -525,4 +512,4 @@ void run() { break; } } -} +}*/ diff --git a/APPLEII/fastcpu.ino b/APPLEII/fastcpu.ino new file mode 100644 index 0000000..49ffea4 --- /dev/null +++ b/APPLEII/fastcpu.ino @@ -0,0 +1,209 @@ +// μ6502 v2.0 - Barebones 6502 Emulator By Damian Peckett +// dpeckett.com, + +//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 + +// CPU registers +unsigned short PC; +unsigned char STP = 0xFD, A = 0x00, X = 0x00, Y = 0x00, SR = SR_FIXED_BITS; + +void run() { + // Opcode Addresses, Labels As Values + static const void* opcodes[] = { + &&BRK, &&ORA_INDX, &&UNDF, &&UNDF, &&UNDF, &&ORA_ZPG, &&ASL_ZPG, &&UNDF, &&PHP, &&ORA_IMM, &&ASL_A, &&UNDF, &&UNDF, &&ORA_ABS, &&ASL_ABS, &&UNDF, + &&BPL_REL, &&ORA_INDY, &&UNDF, &&UNDF, &&UNDF, &&ORA_ZPGX, &&ASL_ZPGX, &&UNDF, &&CLC, &&ORA_ABSY, &&UNDF, &&UNDF, &&UNDF, &&ORA_ABSX, &&ASL_ABSX, &&UNDF, + &&JSR_ABS, &&AND_INDX, &&UNDF, &&UNDF, &&BIT_ZPG, &&AND_ZPG, &&ROL_ZPG, &&UNDF, &&PLP, &&AND_IMM, &&ROL_A, &&UNDF, &&BIT_ABS, &&AND_ABS, &&ROL_ABS, &&UNDF + }; + + unsigned char value8, result8; + unsigned short value16, result16; + unsigned short ptr; + + // Load the reset vector + PC = read16(0xFFFC); + + // Begin Execution + goto *opcodes[read8(PC++)]; + + // Instruction interpreter + BRK: + push16(PC+1); + push8(SR|SR_BRK); + SR |= SR_INT; + PC = read16(0xFFFE); + goto *opcodes[read8(PC++)]; + ORA_INDX: + A |= read8(a_indx()); + flagZero(A); + flagNegative(A); + goto *opcodes[read8(PC++)]; + ORA_ZPG: + A |= read8(a_zpg()); + flagZero(A); + flagNegative(A); + goto *opcodes[read8(PC++)]; + ASL_ZPG: + ptr = a_zpg(); + value16 = read8(ptr); + result16 = value16<<1; + flagZero(result16&0x00FF); + flagNegative(result16&0x00FF); + flagCarry(result16); + write8(ptr, result16&0x00FF); + goto *opcodes[read8(PC++)]; + PHP: + push8(SR|SR_BRK); + goto *opcodes[read8(PC++)]; + ORA_IMM: + A |= read8(a_imm()); + flagZero(A); + flagNegative(A); + goto *opcodes[read8(PC++)]; + ASL_A: + value16 = A; + result16 = value16<<1; + flagZero(result16&0x00FF); + flagNegative(result16&0x00FF); + flagCarry(result16); + A = result16&0x00FF; + goto *opcodes[read8(PC++)]; + ORA_ABS: + A |= read8(a_abs()); + flagZero(A); + flagNegative(A); + goto *opcodes[read8(PC++)]; + ASL_ABS: + ptr = a_abs(); + value16 = read8(ptr); + result16 = value16<<1; + flagZero(result16&0x00FF); + flagNegative(result16&0x00FF); + flagCarry(result16); + write8(ptr, result16&0x00FF); + goto *opcodes[read8(PC++)]; + BPL_REL: + if(!(SR&SR_NEG)) PC += a_rel(); + goto *opcodes[read8(PC++)]; + ORA_INDY: + A |= read8(a_indy()); + flagZero(A); + flagNegative(A); + goto *opcodes[read8(PC++)]; + ORA_ZPGX: + A |= read8(a_zpgx()); + flagZero(A); + flagNegative(A); + goto *opcodes[read8(PC++)]; + ASL_ZPGX: + ptr = a_zpgx(); + value16 = read8(ptr); + result16 = value16<<1; + flagZero(result16&0x00FF); + flagNegative(result16&0x00FF); + flagCarry(result16); + write8(ptr, result16&0x00FF); + goto *opcodes[read8(PC++)]; + CLC: + SR &= ~SR_CARRY; + goto *opcodes[read8(PC++)]; + ORA_ABSY: + A |= read8(a_absy()); + flagZero(A); + flagNegative(A); + goto *opcodes[read8(PC++)]; + ORA_ABSX: + A |= read8(a_absx()); + flagZero(A); + flagNegative(A); + goto *opcodes[read8(PC++)]; + ASL_ABSX: + ptr = a_absx(); + value16 = read8(ptr); + result16 = value16<<1; + flagZero(result16&0x00FF); + flagNegative(result16&0x00FF); + flagCarry(result16); + write8(ptr, result16&0x00FF); + goto *opcodes[read8(PC++)]; + JSR_ABS: + push16(PC-1); + PC = a_abs(); + goto *opcodes[read8(PC++)]; + AND_INDX: + A &= read8(a_indx()); + flagZero(A); + flagNegative(A); + goto *opcodes[read8(PC++)]; + BIT_ZPG: + value8 = read8(a_zpg()); + result8 = A & value8; + flagZero(result8); + SR = (SR&0x3F) | (value8&0xC0); + goto *opcodes[read8(PC++)]; + AND_ZPG: + A &= read8(a_zpg()); + flagZero(A); + flagNegative(A); + goto *opcodes[read8(PC++)]; + ROL_ZPG: + ptr = a_zpg(); + value16 = read8(ptr); + result16 = (value16 << 1) | (SR&SR_CARRY); + flagZero(result16&0x00FF); + flagNegative(result16&0x00FF); + flagCarry(result16); + write8(ptr, result16&0x00FF); + goto *opcodes[read8(PC++)]; + PLP: + SR = pull8() | SR_FIXED_BITS; + goto *opcodes[read8(PC++)]; + AND_IMM: + A &= read8(a_imm()); + flagZero(A); + flagNegative(A); + goto *opcodes[read8(PC++)]; + ROL_A: + value16 = A; + result16 = (value16 << 1) | (SR&SR_CARRY); + flagZero(result16&0x00FF); + flagNegative(result16&0x00FF); + flagCarry(result16); + A = result16&0x00FF; + goto *opcodes[read8(PC++)]; + BIT_ABS: + value8 = read8(a_abs()); + result8 = A & value8; + flagZero(result8); + SR = (SR&0x3F) | (value8&0xC0); + goto *opcodes[read8(PC++)]; + AND_ABS: + A &= read8(a_abs()); + flagZero(A); + flagNegative(A); + goto *opcodes[read8(PC++)]; + ROL_ABS: + ptr = a_abs(); + value16 = read8(ptr); + result16 = (value16 << 1) | (SR&SR_CARRY); + flagZero(result16&0x00FF); + flagNegative(result16&0x00FF); + flagCarry(result16); + write8(ptr, result16&0x00FF); + goto *opcodes[read8(PC++)]; + + // -- Undefined Opcodes + UNDF: + // Raise an error + goto *opcodes[read8(PC++)]; +} diff --git a/APPLEII/flags.ino b/APPLEII/flags.ino new file mode 100644 index 0000000..8a18704 --- /dev/null +++ b/APPLEII/flags.ino @@ -0,0 +1,16 @@ +void inline flagZero(unsigned char value) { + if(!value) SR |= SR_ZERO; + else SR &= ~SR_ZERO; +} + +void inline flagNegative(unsigned char value) { + if(value&0x80) SR |= SR_NEG; + else SR &= ~SR_NEG; +} + +void inline flagCarry(unsigned short value) { + if(value&0xFF00) SR |= SR_CARRY; + else SR &= ~SR_CARRY; +} + + diff --git a/APPLEII/memory.ino b/APPLEII/memory.ino index e41842b..48a87b6 100644 --- a/APPLEII/memory.ino +++ b/APPLEII/memory.ino @@ -1026,52 +1026,82 @@ const unsigned char rom[] PROGMEM = { //$E000 - FFFF }; unsigned char ram[1024]; -// Free memory for storing BASIC programs -unsigned char basic[512]; -unsigned char read8(unsigned short address) { - unsigned char page = address>>8; - if(page < 0x04) { +unsigned char inline read8(unsigned short address) { + switch(address>>8) { + case 0x00: case 0x01: + case 0x02: case 0x03: return ram[address]; - } else if (page >= 0x04 && page < 0x08) { + case 0x04: case 0x05: + case 0x06: case 0x07: return screenRead(address); - } else if (page >= 0x08 && page < 0x10) { - return basic[address-0x800]; - } else if (page >= 0xE0) { + case 0xC0: + return softSwitch(address); + case 0xE0: case 0xE1: + case 0xE2: case 0xE3: + case 0xE4: case 0xE5: + case 0xE6: case 0xE7: + case 0xE8: case 0xE9: + case 0xEA: case 0xEB: + case 0xEC: case 0xED: + case 0xEE: case 0xEF: + case 0xF0: case 0xF1: + case 0xF2: case 0xF3: + case 0xF4: case 0xF5: + case 0xF6: case 0xF7: + case 0xF8: case 0xF9: + case 0xFA: case 0xFB: + case 0xFC: case 0xFD: + case 0xFE: case 0xFF: return pgm_read_byte_near(rom+address-0xE000); - } else { - // Keyboard Data - if(address == 0xC000) return keyboard_read(); - // Keyboard Strobe - if(address == 0xC010) keyboard_strobe(); - // Speaker toggle - if(address == 0xC030) speaker_toggle(); - return 0; + default: + return 0xFF; } } -unsigned short read16(unsigned short address) { +unsigned short inline read16(unsigned short address) { return (unsigned short)read8(address) | (((unsigned short)read8(address+1))<<8); } -void write8(unsigned short address, unsigned char value) { - unsigned char page = address>>8; - if(page < 0x04) { +void inline write8(unsigned short address, unsigned char value) { + switch(address>>8) { + case 0x00: case 0x01: + case 0x02: case 0x03: ram[address] = value; - } else if(page >= 0x04 && page < 0x08) { + break; + case 0x04: case 0x05: + case 0x06: case 0x07: screenWrite(address, value); - } else if (page >= 0x08 && page < 0x10) { - basic[address-0x800] = value; - } else { - // Keyboard Strobe - if(address == 0xC010) keyboard_strobe(); - // Speaker toggle - if(address == 0xC030) speaker_toggle(); + break; + case 0xC0: + softSwitch(address); + break; + default: + return; } } -void write16(unsigned short address, unsigned short value) { +void inline write16(unsigned short address, unsigned short value) { write8(address, value&0x00FF); write8(address+1, (value>>8)&0x00FF); } +// Stack functions +void inline push16(unsigned short pushval) { + write8(STP_BASE + (STP--), (pushval>>8)&0xFF); + write8(STP_BASE + (STP--), pushval&0xFF); +} + +void inline push8(unsigned char pushval) { + write8(STP_BASE + (STP--), pushval); +} + +unsigned short inline pull16() { + unsigned short value16 = read8(STP_BASE + (++STP)) | ((unsigned short)read8(STP_BASE + (++STP))<< 8); + return value16; +} + +unsigned char inline pull8() { + return read8(STP_BASE + (++STP)); +} + diff --git a/APPLEII/softswitch.ino b/APPLEII/softswitch.ino new file mode 100644 index 0000000..33a45e3 --- /dev/null +++ b/APPLEII/softswitch.ino @@ -0,0 +1,14 @@ +unsigned char softSwitch(unsigned short address) { + switch(address&0x00FF) { + case 0x00: // Keyboard Data + return keyboard_read(); + case 0x10: // Keyboard Strobe + keyboard_strobe(); + return 0xFF; + case 0x30: // Speaker toggle + speaker_toggle(); + return 0xFF; + default: + return 0xFF; + } +}