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

433 lines
14 KiB
Java
Raw Normal View History

2017-01-08 23:36:10 +00:00
package com.bytezone.diskbrowser.utilities;
2020-02-07 23:21:13 +00:00
// -----------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
public abstract class CPU
2020-02-07 23:21:13 +00:00
// -----------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
{
// 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;
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
protected void setDebug (boolean value)
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
{
debug = value;
}
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
protected void and (byte mask) // AND
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
{
aReg &= mask;
zero = aReg == 0;
negative = (aReg & 0x80) != 0;
debug ("AND");
}
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
protected void asl () // ASL
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
{
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
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
protected void bit (byte value) // BIT
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
{
byte b = (byte) (aReg & value);
zero = b == 0;
overflow = (value & 0x40) != 0;
negative = (value & 0x80) != 0;
debug ("BIT");
}
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
protected void clc () // CLC
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
{
carry = false;
debug ("CLC");
}
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
protected void cli () // CLI
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
{
interrupt = false;
debug ("CLI");
}
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
protected void clv () // CLV
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
{
overflow = false;
debug ("CLV");
}
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
protected void cmp (byte value) // CMP
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
{
int tmp = (aReg & 0xFF) - (value & 0xFF);
zero = tmp == 0;
negative = (tmp & 0x80) != 0;
carry = (aReg & 0xFF) >= (value & 0xFF);
debug ("CMP");
}
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
protected void cpx (byte value) // CPX
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
{
int tmp = (xReg & 0xFF) - (value & 0xFF);
zero = tmp == 0;
negative = (tmp & 0x80) != 0;
carry = (xReg & 0xFF) >= (value & 0xFF);
debug ("CPX");
}
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
protected void cpy (byte value) // CPY
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
{
int tmp = (yReg & 0xFF) - (value & 0xFF);
zero = tmp == 0;
negative = (tmp & 0x80) != 0;
carry = (yReg & 0xFF) >= (value & 0xFF);
debug ("CPY");
}
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
protected byte dec (byte value) // DEC
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
{
value = (byte) ((value & 0xFF) - 1);
zero = value == 0;
negative = (value & 0x80) != 0;
debug ("DEC");
return value;
}
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
protected byte inc (byte value) // INC
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
{
value = (byte) ((value & 0xFF) + 1);
zero = value == 0;
negative = (value & 0x80) != 0;
debug ("INC");
return value;
}
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
protected void inx () // INX
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
{
xReg = (byte) ((xReg & 0xFF) + 1);
xReg &= 0xFF;
zero = xReg == 0;
negative = (xReg & 0x80) != 0;
debug ("INX");
}
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
protected void lda (byte value) // LDA
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
{
aReg = value;
zero = aReg == 0;
negative = (aReg & 0x80) != 0;
debug ("LDA");
}
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
protected void lda (byte[] buffer, int offset) // LDA
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
{
aReg = buffer[offset];
zero = aReg == 0;
negative = (aReg & 0x80) != 0;
debug ("LDA");
}
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
protected void ldx (byte value) // LDX
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
{
xReg = value;
zero = xReg == 0;
negative = (xReg & 0x80) != 0;
debug ("LDX");
}
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
protected void ldy (byte value) // LDY
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
{
yReg = value;
zero = yReg == 0;
negative = (yReg & 0x80) != 0;
debug ("LDY");
}
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
protected void lsr () // LSR
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
{
negative = false;
carry = (aReg & 0x01) != 0;
aReg = (byte) ((aReg & 0xFF) >>> 1);
zero = aReg == 0;
debug ("LSR");
}
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
protected void ora (byte mask) // ORA
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
{
aReg |= mask;
zero = aReg == 0;
negative = (aReg & 0x80) != 0;
debug ("ORA");
}
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
protected void php () // PHP
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
{
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");
}
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
protected void plp () // PLP
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
{
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");
}
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
protected void pha () // PHA
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
{
stack[--sp] = aReg;
debug ("PHA");
}
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
protected void pla () // PLA
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
{
aReg = stack[sp++];
zero = aReg == 0;
negative = (aReg & 0x80) != 0;
debug ("PLA");
}
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
protected void rol () // ROL
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
{
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");
}
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
protected byte rol (byte value) // ROL
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
{
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;
}
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
protected byte ror (byte value) // ROR
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
{
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;
}
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
protected byte sta () // STA
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
{
debug ("STA");
return aReg;
}
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
protected void sta (byte[] buffer, int offset) // STA
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
{
buffer[offset] = aReg;
zero = aReg == 0;
negative = (aReg & 0x80) != 0;
debug ("STA");
}
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
protected byte stx () // STX
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
{
debug ("STX");
return xReg;
}
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
protected byte sty () // STY
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
{
debug ("STY");
return yReg;
}
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
protected void txa () // TXA
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
{
aReg = xReg;
zero = aReg == 0;
negative = (aReg & 0x80) != 0;
debug ("TXA");
}
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
protected void tya () // TYA
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
{
aReg = yReg;
zero = aReg == 0;
negative = (aReg & 0x80) != 0;
debug ("TYA");
}
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
protected void tax () // TAX
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
{
xReg = aReg;
zero = xReg == 0;
negative = (xReg & 0x80) != 0;
debug ("TAX");
}
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
protected void tay () // TAY
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
{
yReg = aReg;
zero = yReg == 0;
negative = (yReg & 0x80) != 0;
debug ("TAY");
}
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
protected void sei () // SEI
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
{
interrupt = true;
debug ("SEI");
}
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-09 06:24:53 +00:00
protected String debugString ()
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-09 06:24:53 +00:00
{
return "";
}
2017-01-08 23:36:10 +00:00
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
protected void debug (String cmd)
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
{
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 ());
}
}
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
protected int indirectY (int base, byte offset, byte page)
2020-02-07 23:21:13 +00:00
// ---------------------------------------------------------------------------------//
2017-01-08 23:36:10 +00:00
{
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);
}
}