dmolony-DiskBrowser/src/com/bytezone/diskbrowser/utilities/CPU.java

433 lines
14 KiB
Java

package com.bytezone.diskbrowser.utilities;
// -----------------------------------------------------------------------------------//
public abstract class CPU
// -----------------------------------------------------------------------------------//
{
// registers
private byte xReg;
private byte yReg;
private byte aReg;
// status register
protected boolean carry;
protected boolean zero;
protected boolean interrupt;
protected boolean decimal;
protected boolean breakFlag;
protected boolean overflow; // Clancy
protected boolean negative;
// stack
private final byte[] stack = new byte[0x100];
private int sp = stack.length;
private boolean debug = false;
// ---------------------------------------------------------------------------------//
protected void setDebug (boolean value)
// ---------------------------------------------------------------------------------//
{
debug = value;
}
// ---------------------------------------------------------------------------------//
protected void and (byte mask) // AND
// ---------------------------------------------------------------------------------//
{
aReg &= mask;
zero = aReg == 0;
negative = (aReg & 0x80) != 0;
debug ("AND");
}
// ---------------------------------------------------------------------------------//
protected void asl () // ASL
// ---------------------------------------------------------------------------------//
{
carry = (aReg & 0x80) != 0; // move bit 7 into the carry flag
aReg = (byte) (aReg << 1); // shift left
zero = aReg == 0;
negative = (aReg & 0x80) != 0;
debug ("ASL");
}
// unfinished
// ---------------------------------------------------------------------------------//
protected void bit (byte value) // BIT
// ---------------------------------------------------------------------------------//
{
byte b = (byte) (aReg & value);
zero = b == 0;
overflow = (value & 0x40) != 0;
negative = (value & 0x80) != 0;
debug ("BIT");
}
// ---------------------------------------------------------------------------------//
protected void clc () // CLC
// ---------------------------------------------------------------------------------//
{
carry = false;
debug ("CLC");
}
// ---------------------------------------------------------------------------------//
protected void cli () // CLI
// ---------------------------------------------------------------------------------//
{
interrupt = false;
debug ("CLI");
}
// ---------------------------------------------------------------------------------//
protected void clv () // CLV
// ---------------------------------------------------------------------------------//
{
overflow = false;
debug ("CLV");
}
// ---------------------------------------------------------------------------------//
protected void cmp (byte value) // CMP
// ---------------------------------------------------------------------------------//
{
int tmp = (aReg & 0xFF) - (value & 0xFF);
zero = tmp == 0;
negative = (tmp & 0x80) != 0;
carry = (aReg & 0xFF) >= (value & 0xFF);
debug ("CMP");
}
// ---------------------------------------------------------------------------------//
protected void cpx (byte value) // CPX
// ---------------------------------------------------------------------------------//
{
int tmp = (xReg & 0xFF) - (value & 0xFF);
zero = tmp == 0;
negative = (tmp & 0x80) != 0;
carry = (xReg & 0xFF) >= (value & 0xFF);
debug ("CPX");
}
// ---------------------------------------------------------------------------------//
protected void cpy (byte value) // CPY
// ---------------------------------------------------------------------------------//
{
int tmp = (yReg & 0xFF) - (value & 0xFF);
zero = tmp == 0;
negative = (tmp & 0x80) != 0;
carry = (yReg & 0xFF) >= (value & 0xFF);
debug ("CPY");
}
// ---------------------------------------------------------------------------------//
protected byte dec (byte value) // DEC
// ---------------------------------------------------------------------------------//
{
value = (byte) ((value & 0xFF) - 1);
zero = value == 0;
negative = (value & 0x80) != 0;
debug ("DEC");
return value;
}
// ---------------------------------------------------------------------------------//
protected byte inc (byte value) // INC
// ---------------------------------------------------------------------------------//
{
value = (byte) ((value & 0xFF) + 1);
zero = value == 0;
negative = (value & 0x80) != 0;
debug ("INC");
return value;
}
// ---------------------------------------------------------------------------------//
protected void inx () // INX
// ---------------------------------------------------------------------------------//
{
xReg = (byte) ((xReg & 0xFF) + 1);
xReg &= 0xFF;
zero = xReg == 0;
negative = (xReg & 0x80) != 0;
debug ("INX");
}
// ---------------------------------------------------------------------------------//
protected void lda (byte value) // LDA
// ---------------------------------------------------------------------------------//
{
aReg = value;
zero = aReg == 0;
negative = (aReg & 0x80) != 0;
debug ("LDA");
}
// ---------------------------------------------------------------------------------//
protected void lda (byte[] buffer, int offset) // LDA
// ---------------------------------------------------------------------------------//
{
aReg = buffer[offset];
zero = aReg == 0;
negative = (aReg & 0x80) != 0;
debug ("LDA");
}
// ---------------------------------------------------------------------------------//
protected void ldx (byte value) // LDX
// ---------------------------------------------------------------------------------//
{
xReg = value;
zero = xReg == 0;
negative = (xReg & 0x80) != 0;
debug ("LDX");
}
// ---------------------------------------------------------------------------------//
protected void ldy (byte value) // LDY
// ---------------------------------------------------------------------------------//
{
yReg = value;
zero = yReg == 0;
negative = (yReg & 0x80) != 0;
debug ("LDY");
}
// ---------------------------------------------------------------------------------//
protected void lsr () // LSR
// ---------------------------------------------------------------------------------//
{
negative = false;
carry = (aReg & 0x01) != 0;
aReg = (byte) ((aReg & 0xFF) >>> 1);
zero = aReg == 0;
debug ("LSR");
}
// ---------------------------------------------------------------------------------//
protected void ora (byte mask) // ORA
// ---------------------------------------------------------------------------------//
{
aReg |= mask;
zero = aReg == 0;
negative = (aReg & 0x80) != 0;
debug ("ORA");
}
// ---------------------------------------------------------------------------------//
protected void php () // PHP
// ---------------------------------------------------------------------------------//
{
byte flags = 0;
if (negative)
flags |= 0x80;
if (overflow)
flags |= 0x40;
if (breakFlag)
flags |= 0x10;
if (decimal)
flags |= 0x08;
if (interrupt)
flags |= 0x04;
if (zero)
flags |= 0x02;
if (carry)
flags |= 0x01;
stack[--sp] = flags;
debug ("PHP");
}
// ---------------------------------------------------------------------------------//
protected void plp () // PLP
// ---------------------------------------------------------------------------------//
{
byte flags = stack[sp++];
negative = (flags & 0x80) != 0;
overflow = (flags & 0x40) != 0;
breakFlag = (flags & 0x10) != 0;
decimal = (flags & 0x08) != 0;
interrupt = (flags & 0x04) != 0;
zero = (flags & 0x02) != 0;
carry = (flags & 0x01) != 0;
debug ("PLP");
}
// ---------------------------------------------------------------------------------//
protected void pha () // PHA
// ---------------------------------------------------------------------------------//
{
stack[--sp] = aReg;
debug ("PHA");
}
// ---------------------------------------------------------------------------------//
protected void pla () // PLA
// ---------------------------------------------------------------------------------//
{
aReg = stack[sp++];
zero = aReg == 0;
negative = (aReg & 0x80) != 0;
debug ("PLA");
}
// ---------------------------------------------------------------------------------//
protected void rol () // ROL
// ---------------------------------------------------------------------------------//
{
boolean tempCarry = carry;
carry = (aReg & 0x80) != 0; // move bit 7 into the carry flag
aReg = (byte) (aReg << 1); // shift left
if (tempCarry)
aReg |= 0x01; // move old carry into bit 0
zero = aReg == 0;
negative = (aReg & 0x80) != 0;
debug ("ROL");
}
// ---------------------------------------------------------------------------------//
protected byte rol (byte value) // ROL
// ---------------------------------------------------------------------------------//
{
boolean tempCarry = carry;
carry = (value & 0x80) != 0; // move bit 7 into the carry flag
value = (byte) (value << 1);
if (tempCarry)
value |= 0x01; // move old carry into bit 0
zero = value == 0;
negative = (value & 0x80) != 0;
debug ("ROL");
return value;
}
// ---------------------------------------------------------------------------------//
protected byte ror (byte value) // ROR
// ---------------------------------------------------------------------------------//
{
boolean tempCarry = carry;
carry = (value & 0x01) != 0; // move bit 0 into the carry flag
value = (byte) ((value & 0xFF) >>> 1);
if (tempCarry)
value |= 0x80; // move old carry into bit 7
zero = value == 0;
negative = (value & 0x80) != 0;
debug ("ROR");
return value;
}
// ---------------------------------------------------------------------------------//
protected byte sta () // STA
// ---------------------------------------------------------------------------------//
{
debug ("STA");
return aReg;
}
// ---------------------------------------------------------------------------------//
protected void sta (byte[] buffer, int offset) // STA
// ---------------------------------------------------------------------------------//
{
buffer[offset] = aReg;
zero = aReg == 0;
negative = (aReg & 0x80) != 0;
debug ("STA");
}
// ---------------------------------------------------------------------------------//
protected byte stx () // STX
// ---------------------------------------------------------------------------------//
{
debug ("STX");
return xReg;
}
// ---------------------------------------------------------------------------------//
protected byte sty () // STY
// ---------------------------------------------------------------------------------//
{
debug ("STY");
return yReg;
}
// ---------------------------------------------------------------------------------//
protected void txa () // TXA
// ---------------------------------------------------------------------------------//
{
aReg = xReg;
zero = aReg == 0;
negative = (aReg & 0x80) != 0;
debug ("TXA");
}
// ---------------------------------------------------------------------------------//
protected void tya () // TYA
// ---------------------------------------------------------------------------------//
{
aReg = yReg;
zero = aReg == 0;
negative = (aReg & 0x80) != 0;
debug ("TYA");
}
// ---------------------------------------------------------------------------------//
protected void tax () // TAX
// ---------------------------------------------------------------------------------//
{
xReg = aReg;
zero = xReg == 0;
negative = (xReg & 0x80) != 0;
debug ("TAX");
}
// ---------------------------------------------------------------------------------//
protected void tay () // TAY
// ---------------------------------------------------------------------------------//
{
yReg = aReg;
zero = yReg == 0;
negative = (yReg & 0x80) != 0;
debug ("TAY");
}
// ---------------------------------------------------------------------------------//
protected void sei () // SEI
// ---------------------------------------------------------------------------------//
{
interrupt = true;
debug ("SEI");
}
// ---------------------------------------------------------------------------------//
protected String debugString ()
// ---------------------------------------------------------------------------------//
{
return "";
}
// ---------------------------------------------------------------------------------//
protected void debug (String cmd)
// ---------------------------------------------------------------------------------//
{
if (debug)
{
String flags = String.format ("%s %s - %s %s %s %s %s", negative ? "1" : ".",
overflow ? "1" : ".", breakFlag ? "1" : ".", decimal ? "1" : ".",
interrupt ? "1" : ".", zero ? "1" : ".", carry ? "1" : ".");
System.out.printf ("%3s A: %02X X: %02X Y: %02X %s %s%n", cmd, aReg, xReg,
yReg, flags, debugString ());
}
}
// ---------------------------------------------------------------------------------//
protected int indirectY (int base, byte offset, byte page)
// ---------------------------------------------------------------------------------//
{
if (debug)
System.out.printf ("base: %,6d, page: %02X, offset: %02X, yReg: %02X%n", base, page,
offset, yReg);
return ((page & 0xFF) * 256 + (offset & 0xFF)) - base + (yReg & 0xFF);
}
}