|
|
nono 1.3.0
//
// nono
// Copyright (C) 2022 nono project
// Licensed under nono-license.txt
//
#include "m680x0bitfield.h"
#include "bitops.h"
// コンストラクタ
// 呼び出し側でここまでに ir2 へのフェッチはしておくこと。
acc_bf::acc_bf(MPU680x0Device *cpu_)
{
cpu = cpu_;
// F E D C B A 9 8 7 6 5 4 3 2 1 0
// 0 0 0 0 DO <-- offset --> DW <-- width --->
offset = (cpu->GetIR2() >> 6) & 0x1f;
if ((cpu->GetIR2() & 0x0800)) {
offset = (int32)cpu->reg.D[offset & 7];
local_offset = offset & 0x1f;
} else {
local_offset = offset;
}
width = cpu->GetIR2();
if ((cpu->GetIR2() & 0x0020)) {
width = cpu->reg.D[width & 7];
}
// モジュロ 32 を取り、0 なら 32 を表す
width = ((width - 1) & 31) + 1;
// mask は32ビットの上位から width ビット 1 が並んだもの
mask = 0xffffffff << (32 - width);
}
// データレジスタから値を読み込む。n はデータレジスタの番号。
void
acc_bf::LoadReg(uint n)
{
data = cpu->reg.D[n];
data = ROL32(data, local_offset);
data &= mask;
}
// メモリから値を読み込む。
// 命令サイクル数のため、4バイト以内なら true を返す。
bool
acc_bf::LoadMem(uint32 addr)
{
// EA の計算
ea = addr + offset / 8;
local_offset = offset % 8;
if (local_offset < 0) {
local_offset += 8;
ea--;
}
// アクセスするバイト数
bytes = (local_offset + width + 7) / 8;
// 40ビットバッファに読み込む
if (bytes <= 4) {
buf = ((uint64)cpu->read_n(ea, bytes)) << ((5 - bytes) * 8);
} else {
// 実際どういうアクセスになるのか分からないが。
if ((ea & 1) == 0) {
// 偶数アドレスから5バイト
buf = ((uint64)cpu->read_4(ea)) << 8;
buf |= ((uint64)cpu->read_1(ea + 4));
} else {
// 奇数アドレスから5バイト
buf = ((uint64)cpu->read_1(ea)) << 32;
buf |= ((uint64)cpu->read_4(ea + 1));
}
}
// 32ビット左詰めにする
data = (buf >> (8 - local_offset)) & mask;
return (bytes <= 4);
}
// データレジスタに値を書き出す。
void
acc_bf::StoreReg(uint n)
{
uint32 m = ROR32(mask, local_offset);
uint32 d = ROR32(data, local_offset);
cpu->reg.D[n] = (cpu->reg.D[n] & ~m) | (d & m);
}
// メモリに値を書き出す
void
acc_bf::StoreMem()
{
// 32ビット左詰めデータを 40ビットバッファにマージ
uint64 m = (uint64)mask << (8 - local_offset);
uint64 d = (uint64)data << (8 - local_offset);
buf = (buf & ~m) | (d & m);
// 40ビットバッファを書き戻す
if (bytes <= 4) {
cpu->write_n(ea, bytes, buf >> ((5 - bytes) * 8));
} else {
// 実際どういうアクセスになるのか分からないが。
if ((ea & 1) == 0) {
// 偶数アドレスから5バイト
cpu->write_4(ea, buf >> 8);
cpu->write_1(ea + 4, buf & 0xff);
} else {
// 奇数アドレスから5バイト
cpu->write_1(ea, buf >> 32);
cpu->write_4(ea + 1, buf);
}
}
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.