mirror of
https://github.com/dmolony/DiskBrowser.git
synced 2024-09-29 07:55:13 +00:00
433 lines
14 KiB
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);
|
|
}
|
|
} |