|
|
nono 1.7.0
//
// nono
// Copyright (C) 2022 nono project
// Licensed under nono-license.txt
//
//
// HD64180 CPU コア
//
#pragma once
#include "header.h"
// 定数定義など
struct HD64180
{
// 動作モード
enum OpMode {
Reset = 0,
Normal,
Halt,
Sleep,
// I/O ストップモードは IOSTP ビットを立てたもの。
// 特にモードとして持たなくてもいいかも。
//IOStop,
// システムストップモードは Sleep + IOStop の状態。
// スリープモードでいい。
//SystemStop,
};
// フラグレジスタ
static const uint8 FlagS = 0x80;
static const uint8 FlagZ = 0x40;
static const uint8 FlagH = 0x10;
static const uint8 FlagPV = 0x04;
static const uint8 FlagN = 0x02;
static const uint8 FlagC = 0x01;
};
enum ixiy_t {
USE_HL = 0,
USE_IX = 1,
USE_IY = 2,
};
// フラグレジスタ。
//
// 7 6 5 4 3 2 1 0
// +---+---+---+---+---+---+---+---+
// | S | Z | - | H | - |P/V| N | C |
// +---+---+---+---+---+---+---+---+
//
// '-' のところも値は保持できる
struct hd64180flag
{
protected:
// S フラグは S の S_BIT が立っていれば 1
// Z フラグは Z == 0 なら 1
// H フラグは H の H_BIT が立っていれば 1
// N フラグは N が true なら 1
// C フラグは C の C_BIT が立っていれば 1
//
// P/V フラグは PV の PV_BIT が立っていれば 1 で、
// PVisP が true なら P、false なら V とする。
static const uint32 S_BIT = 0x00000080;
static const uint32 H_BIT = 0x00000010;
static const uint32 PV_BIT = 0x00000080;
static const uint32 C_BIT = 0x00000001;
union {
uint16 CZ;
struct {
#if BYTE_ORDER == LITTLE_ENDIAN
uint8 Z;
uint8 C;
#else
uint8 C;
uint8 Z;
#endif
} __packed;
};
uint8 S {}; // b7: Sign
uint8 H {}; // b4: Half Carry
bool N {}; // b1: Add/Sub
bool b5 {};
bool b3 {};
uint8 PV {}; // b2: Parity/Overflow
bool PVisP {}; // true なら P/V は P
public:
// フラグをセットする
void SetS(bool value) { S = (value) ? S_BIT : 0; }
void SetZ(bool value) { Z = (value) ? 0 : 1; }
void SetH(bool value) { H = (value) ? H_BIT : 0; }
void SetN(bool value) { N = value; }
void SetC(bool value) { C = (value) ? C_BIT : 0; }
// P/V フラグを今のモードのまま値だけ変える
void SetPV(bool value) { PV = (value) ? PV_BIT : 0; }
// P か V フラグをセットする
void SetP(bool value) { SetPV(value); PVisP = true; }
void SetV(bool value) { SetPV(value); PVisP = false; }
// フラグを取得する
bool IsS() const { return (S & S_BIT); }
bool IsZ() const { return (Z == 0); }
bool IsH() const { return (H & H_BIT); }
bool IsPV() const { return (PV & PV_BIT); }
bool IsN() const { return N; }
bool IsC() const { return (C & C_BIT); }
// P か V 指定のほうが立っているか (モニタ用)
bool IsP() const { return (IsPV() && PVisP == true); }
bool IsV() const { return (IsPV() && PVisP == false); }
// F レジスタの値として取得する
uint8 Get() const;
// F レジスタに代入する
void Set(uint8 val);
// fff (0..7) の条件が成立すれば true を返す
bool IsCond(uint fff) const;
protected:
// パリティを計算し P フラグを更新する。
// P フラグは結果のビット数が偶数ならセット (合計で奇数になるパリティ)。
void LetP(uint8 src) {
SetPV((__builtin_popcount(src) & 1) == 0);
PVisP = true;
}
// V フラグを更新する。引数は bool ではないので注意。
void LetV(uint32 data) {
PV = data;
PVisP = false;
}
};
// レジスタ。
// I レジスタと R レジスタは MPU64180Device クラス内で管理している。
struct hd64180reg
{
uint16 pc {};
uint16 sp {};
union {
uint8 r[8] {};
struct {
uint8 b;
uint8 c;
uint8 d;
uint8 e;
uint8 h;
uint8 l;
uint8 padding;
uint8 a;
};
};
hd64180flag f {};
uint16 GetBC() const {
return (b << 8) | c;
}
uint16 GetDE() const {
return (d << 8) | e;
}
uint16 GetHL() const {
return (h << 8) | l;
}
void SetBC(uint16 src) {
b = src >> 8;
c = src & 0xff;
}
void SetDE(uint16 src) {
d = src >> 8;
e = src & 0xff;
}
void SetHL(uint16 src) {
h = src >> 8;
l = src & 0xff;
}
// 裏レジスタ
struct {
uint8 b;
uint8 c;
uint8 d;
uint8 e;
uint8 h;
uint8 l;
hd64180flag f;
uint8 a;
} ex {};
uint16 ix {};
uint16 iy {};
};
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.