/*
*
* achtbit.Store.java
*
* Created on: 07.08.2012
* Author: Christian Wahlmann
* This file is part of achtBit.
*
* achtBit is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* achtBit is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with achtBit. If not, see <http://www.gnu.org/licenses/>.
*
*/
package achtbit;
/**
*
* @author christian
*/
public class Storage {
static final int RegisterRegister=0; // r,r
static final int RegisterConstant=1; // r,n
static final int RegisterAdress=2; // r,(n)
static final int RegisterPointer=3; // r,(r)
static final int AdressRegister=4; // (n),r
static final int PointerRegister=5; // (r),r
static final int PointerConstant=6; // (r),n
private int storeType;
private int destination;
private int source;
private int flags;
private int offset; // used for IX Register
public Storage() {
this.storeType=0;
this.destination=0;
this.source=0;
this.flags=0;
}
public int init(int storeType, int adr) {
this.storeType=storeType;
int adress=adr;
Memory mem=Memory.instance();
switch (storeType) {
case AdressRegister:
this.source=mem.getByte(adress);
this.destination=mem.getWord(adress+1);
adress=adress+3;
break;
case RegisterRegister:
this.source=mem.getByte(adress) & 15;
this.destination=mem.getByte(adress) /16;
adress=adress+1;
break;
case PointerRegister:
this.source=mem.getByte(adress) & 15;
this.destination=mem.getByte(adress) /16;
adress=adress+1;
if (this.destination==Memory.regIX) {
this.offset=mem.getByte(adress)-128;
adress++;
}
break;
case RegisterPointer:
this.source=mem.getByte(adress) & 15;
this.destination=mem.getByte(adress) /16;
adress=adress+1;
if (this.source==Memory.regIX) {
this.offset=mem.getByte(adress)-128;
adress++;
}
break;
case PointerConstant:
this.destination=mem.getByte(adress);
adress++;
if (this.destination==Memory.regIX) {
this.offset=mem.getByte(adress)-128;
adress++;
}
this.source=mem.getByte(adress);
adress++;
break;
case RegisterConstant:
this.destination=mem.getByte(adress);
if (this.destination<Memory.regAF)
this.source=mem.getByte(adress+1);
else {
this.source=mem.getWord(adress+1);
adress=adress+1;
}
adress=adress+2;
break;
case RegisterAdress:
this.destination=mem.getByte(adress);
this.source=mem.getWord(adress+1);
adress=adress+3;
break;
default:
this.source=0;
this.destination=0;
}
flags=0;
return adress;
}
public Storage(int storeType, int destination, int source) {
this.storeType=storeType;
this.destination=destination;
this.source=source;
flags=0;
}
public Storage(int storeType, int source) {
this.storeType=storeType;
this.destination=source;
this.source=source;
flags=0;
}
public void setFlags(int flags) {
this.flags=flags;
}
public boolean tryFlags() {
return Memory.instance().hasFlag(flags);
}
public int getFlags() {
return flags;
}
public boolean isByte() {
switch (storeType) {
case AdressRegister:
case RegisterRegister:
case PointerRegister:
return source<Memory.regAF;
case RegisterPointer:
case RegisterConstant:
case RegisterAdress:
return destination<Memory.regAF;
case PointerConstant:
return true;
default:
return true;
}
}
public boolean isWord() {
return !isByte();
}
public int get() {
Memory mem=Memory.instance();
switch (storeType) {
case AdressRegister:
case RegisterRegister:
case PointerRegister:
return mem.getReg(source);
case RegisterPointer:
if (this.source==Memory.regIX)
return mem.getWord(mem.getReg(source)+this.offset);
return mem.getWord(mem.getReg(source));
case PointerConstant:
case RegisterConstant:
return source;
case RegisterAdress:
if (isByte())
return mem.getByte(source);
return mem.getWord(source);
default:
return 0;
}
}
public int getMinus() {
return minus(get());
}
public int minus(int e) {
if (isByte()) {
return 0x200-e;
}
return 0x20000-e;
}
public int dec(int value) {
if (value>0) return value-1;
return minus(-(value-1));
}
public void set(int val) {
Memory mem=Memory.instance();
int value=val;
while (value<0) {
if (isByte()) value+=0x100;
else value+=0x10000;
}
int pointer=0;
switch (storeType) {
case AdressRegister:
if (source<Memory.regAF) {
mem.setByte(destination, value);
}
else {
mem.setWord(destination, value);
}
break;
case RegisterRegister:
case RegisterPointer:
case RegisterConstant:
case RegisterAdress:
mem.setReg(destination, value);
break;
case PointerRegister:
pointer=mem.getReg(destination);
if (this.destination==Memory.regIX) {
pointer+=this.offset;
}
if (source<Memory.regAF) {
mem.setByte(pointer, value);
}
else {
mem.setWord(pointer, value);
}
break;
case PointerConstant:
if (this.destination==Memory.regIX) {
mem.setByte(mem.getReg(destination)+offset, value);
}
else {
mem.setByte(mem.getReg(destination), value);
}
break;
default:
}
return;
}
public void checkAndSetFlags(int val) {
Memory mem=Memory.instance();
if (isByte()) {
mem.setCFlag(val<0 || val>0xff);
}
else {
mem.setCFlag(val<0 || val>0xffff);
}
int value=val;
while (value<0) {
if (isByte()) value+=0x100;
else value+=0x10000;
}
mem.setPFlag((value & 1)==0);
switch (storeType) {
case AdressRegister:
if (source<Memory.regAF) {
mem.setZFlag((value & 0xff)==0);
}
else {
mem.setZFlag((value & 0xffff)==0);
}
break;
case RegisterRegister:
case RegisterPointer:
case RegisterConstant:
case RegisterAdress:
if (destination<Memory.regAF) {
mem.setZFlag((value & 0xff)==0);
}
else {
mem.setZFlag((value & 0xffff)==0);
}
break;
case PointerRegister:
if (source<Memory.regAF) {
mem.setZFlag((value & 0xff)==0);
}
else {
mem.setZFlag((value & 0xffff)==0);
}
break;
case PointerConstant:
mem.setCFlag(value>0xffff);
break;
default:
}
return;
}
public int getDestinationValue() {
Memory mem=Memory.instance();
switch (storeType) {
case AdressRegister:
if (source<Memory.regAF)
return mem.getByte(destination);
else
return mem.getWord(destination);
case RegisterRegister:
case RegisterPointer:
case RegisterConstant:
case RegisterAdress:
return mem.getReg(destination);
case PointerRegister:
if (this.destination==Memory.regIX) {
return mem.getByte(mem.getReg(destination)+offset);
}
else if (source<Memory.regAF)
return mem.getByte(destination);
else
return mem.getWord(destination);
case PointerConstant:
if (this.destination==Memory.regIX) {
return mem.getByte(mem.getReg(destination)+offset);
}
else
return mem.getWord(mem.getReg(destination));
default:
return 0;
}
}
public int getStoreType() {
return storeType;
}
public void setStoreType(int storeType) {
this.storeType = storeType;
}
public int getDestination() {
return destination;
}
public void setDestination(int destination) {
this.destination = destination;
}
public int getOffset() {
return offset;
}
public void setOffset(int offset) {
this.offset = offset;
}
public int getSource() {
return source;
}
public void setSource(int source) {
this.source = source;
}
public String toString() {
return "storetype="+Assembler.int2hex(this.storeType,2)
+" dest="+Assembler.int2hex(this.destination,4)
+" src="+Assembler.int2hex(this.source,4)
+" flags="+Assembler.int2hex(this.flags,2);
}
}