|
|
nono 0.1.6
//
// nono
// Copyright (C) 2020 nono project
// Licensed under nono-license.txt
//
#pragma once
#include "device.h"
#include <atomic>
class BitmapDevice
: public IODevice
{
using inherited = IODevice;
static const uint32 plane0base = 0xb10c0000;
static const uint32 plane7end = 0xb12c0000;
static const uint32 fcset0base = 0xb1300000;
static const uint32 fcset7end = 0xb1500000;
public:
BitmapDevice();
virtual ~BitmapDevice() override;
bool Init() override;
bool PowerOn() override;
void ResetHard() override;
uint64 Read8(uint32 addr) override;
uint64 Read16(uint32 addr) override;
uint64 Read32(uint32 addr) override;
uint64 Write8(uint32 addr, uint32 data) override;
uint64 Write16(uint32 addr, uint32 data) override;
uint64 Write32(uint32 addr, uint32 data) override;
uint64 Peek8(uint32 addr) override;
void MonitorUpdate(TextScreen&) override;
// プレーン数を取得
int GetPlaneCount() const { return nplane; }
// RFCNT によるオフセットを取得 (レンダラ用)
void GetRFCNT(int *h, int *v) const {
*h = hscroll;
*v = vscroll;
}
// ビットマップのアドレスを取得
const uint8 *GetBuf() const { return mem.get(); }
// 更新フラグのアドレスを取得
std::atomic<uint8> *GetDirty() { return atomic_dirty; }
// エミュレータによる出力
void EmuConsoleOpen(TextScreen *t);
void EmuConsoleUpdate();
void EmuConsoleClose();
private:
void Invalidate();
void WriteRFCNT(uint32);
void WriteCommonBitmap8(uint32, uint32);
void WriteCommonBitmap16(uint32, uint32);
void WriteCommonBitmap32(uint32, uint32);
void WritePlane8(uint, uint32, uint32);
void WritePlane16(uint, uint32, uint32);
void WritePlane32(uint, uint32, uint32);
// ROP 文字列を返す
static const char *RopStr(uint rop);
// プレーン数の上限
static const int MAX_PLANES = 8;
// プレーン数 (設定による)
int nplane {};
// RFCNT
// b31..b24 b23..b16 b15..b10 b09..b00
// 無効 水平カウンタ 無効 ラスタカウンタ
uint32 rfcnt {};
int hscroll {};
int vscroll {};
// プレーンセレクタ
// b31...b4 b3 b2 b1 b0
// <-無効-> | | | +-- プレーン0 (%1=同時設定/書き込み有効、%0=無効)
// | | +----- プレーン1
// | +-------- プレーン2
// +----------- プレーン3
uint32 bmsel {};
// ビットマッププレーン。
// ロングワードでホストバイトオーダー。
// 1枚が 256KB。1 or 4枚
std::unique_ptr<uint8[]> mem {};
// 更新フラグ。
// 更新があったラインは 1、なければ 0。
// 1ラインごとなので 1プレーンにつき 1024 エントリ。
// XXX 水平の非描画区間は今の所検出していないので描画側で多少無駄足。
std::atomic<uint8> atomic_dirty[1024] {};
// ファンクションセットとアクセスマスク
u_int fcs[MAX_PLANES] {};
uint32 mask[MAX_PLANES] {};
// エミュレータによるコンソール出力
TextScreen *textscr {};
std::vector<uint16> prev {};
int screen_w {}; // 桁数
int screen_h {}; // 行数
int origin_x {}; // 原点 X [dot]
int origin_y {}; // 原点 Y [dot]
};
extern std::unique_ptr<BitmapDevice> gBitmap;
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.