forked from Apple-2-HW/arduino-appleii
Building a proper 6502 vm
This commit is contained in:
parent
2798ae6d16
commit
8e82eb6705
BIN
6502tests/.DS_Store
vendored
Normal file
BIN
6502tests/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
6502tests/test/.DS_Store
vendored
Normal file
BIN
6502tests/test/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
APPLEII/.DS_Store
vendored
Normal file
BIN
APPLEII/.DS_Store
vendored
Normal file
Binary file not shown.
54
APPLEII/addressing.ino
Normal file
54
APPLEII/addressing.ino
Normal file
@ -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;
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
// μ6502 - Barebones 6502 Emulator By Damian Peckett
|
// μ6502 - Barebones 6502 Emulator By Damian Peckett
|
||||||
// dpeckett.com, <damian.peckett@gmail.com>
|
// dpeckett.com, <damian.peckett@gmail.com>
|
||||||
|
/*
|
||||||
// Address Modes
|
// Address Modes
|
||||||
#define AD_IMP 0x01
|
#define AD_IMP 0x01
|
||||||
#define AD_A 0x02
|
#define AD_A 0x02
|
||||||
@ -60,6 +60,10 @@ const unsigned char flags[] PROGMEM = {
|
|||||||
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_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
|
// CPU registers
|
||||||
unsigned short PC;
|
unsigned short PC;
|
||||||
unsigned char STP = 0xFD, A = 0x00, X = 0x00, Y = 0x00, SR = SR_FIXED_BITS;
|
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;
|
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() {
|
void run() {
|
||||||
// Load the reset vector
|
// Load the reset vector
|
||||||
PC = read16(0xFFFC);
|
PC = read16(0xFFFC);
|
||||||
@ -171,6 +156,8 @@ void run() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//opcodes
|
//opcodes
|
||||||
switch(opcode) {
|
switch(opcode) {
|
||||||
//ADC
|
//ADC
|
||||||
@ -525,4 +512,4 @@ void run() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
209
APPLEII/fastcpu.ino
Normal file
209
APPLEII/fastcpu.ino
Normal file
@ -0,0 +1,209 @@
|
|||||||
|
// μ6502 v2.0 - Barebones 6502 Emulator By Damian Peckett
|
||||||
|
// dpeckett.com, <damian.peckett@gmail.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++)];
|
||||||
|
}
|
16
APPLEII/flags.ino
Normal file
16
APPLEII/flags.ino
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -1026,52 +1026,82 @@ const unsigned char rom[] PROGMEM = { //$E000 - FFFF
|
|||||||
};
|
};
|
||||||
|
|
||||||
unsigned char ram[1024];
|
unsigned char ram[1024];
|
||||||
// Free memory for storing BASIC programs
|
|
||||||
unsigned char basic[512];
|
|
||||||
|
|
||||||
unsigned char read8(unsigned short address) {
|
unsigned char inline read8(unsigned short address) {
|
||||||
unsigned char page = address>>8;
|
switch(address>>8) {
|
||||||
if(page < 0x04) {
|
case 0x00: case 0x01:
|
||||||
|
case 0x02: case 0x03:
|
||||||
return ram[address];
|
return ram[address];
|
||||||
} else if (page >= 0x04 && page < 0x08) {
|
case 0x04: case 0x05:
|
||||||
|
case 0x06: case 0x07:
|
||||||
return screenRead(address);
|
return screenRead(address);
|
||||||
} else if (page >= 0x08 && page < 0x10) {
|
case 0xC0:
|
||||||
return basic[address-0x800];
|
return softSwitch(address);
|
||||||
} else if (page >= 0xE0) {
|
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);
|
return pgm_read_byte_near(rom+address-0xE000);
|
||||||
} else {
|
default:
|
||||||
// Keyboard Data
|
return 0xFF;
|
||||||
if(address == 0xC000) return keyboard_read();
|
|
||||||
// Keyboard Strobe
|
|
||||||
if(address == 0xC010) keyboard_strobe();
|
|
||||||
// Speaker toggle
|
|
||||||
if(address == 0xC030) speaker_toggle();
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned short read16(unsigned short address) {
|
unsigned short inline read16(unsigned short address) {
|
||||||
return (unsigned short)read8(address) | (((unsigned short)read8(address+1))<<8);
|
return (unsigned short)read8(address) | (((unsigned short)read8(address+1))<<8);
|
||||||
}
|
}
|
||||||
|
|
||||||
void write8(unsigned short address, unsigned char value) {
|
void inline write8(unsigned short address, unsigned char value) {
|
||||||
unsigned char page = address>>8;
|
switch(address>>8) {
|
||||||
if(page < 0x04) {
|
case 0x00: case 0x01:
|
||||||
|
case 0x02: case 0x03:
|
||||||
ram[address] = value;
|
ram[address] = value;
|
||||||
} else if(page >= 0x04 && page < 0x08) {
|
break;
|
||||||
|
case 0x04: case 0x05:
|
||||||
|
case 0x06: case 0x07:
|
||||||
screenWrite(address, value);
|
screenWrite(address, value);
|
||||||
} else if (page >= 0x08 && page < 0x10) {
|
break;
|
||||||
basic[address-0x800] = value;
|
case 0xC0:
|
||||||
} else {
|
softSwitch(address);
|
||||||
// Keyboard Strobe
|
break;
|
||||||
if(address == 0xC010) keyboard_strobe();
|
default:
|
||||||
// Speaker toggle
|
return;
|
||||||
if(address == 0xC030) speaker_toggle();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void write16(unsigned short address, unsigned short value) {
|
void inline write16(unsigned short address, unsigned short value) {
|
||||||
write8(address, value&0x00FF);
|
write8(address, value&0x00FF);
|
||||||
write8(address+1, (value>>8)&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));
|
||||||
|
}
|
||||||
|
|
||||||
|
14
APPLEII/softswitch.ino
Normal file
14
APPLEII/softswitch.ino
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user