|
|
1.1 root 1: //
2: // nono
1.1.1.3 root 3: // Copyright (C) 2020 nono project
4: // Licensed under nono-license.txt
1.1 root 5: //
6:
1.1.1.8 root 7: //
8: // Pluto-X (独自の仮想ボード)
9: //
10:
1.1 root 11: #include "pluto.h"
1.1.1.2 root 12: #include "mainapp.h"
1.1.1.9 root 13: #include "mainbus.h"
14: #include "mainram.h"
1.1.1.3 root 15: #include "mpu680x0.h"
1.1.1.9 root 16: #include "sram.h"
1.1.1.5 root 17:
1.1.1.8 root 18: // コンストラクタ
1.1 root 19: PlutoDevice::PlutoDevice()
1.1.1.9 root 20: : inherited(OBJ_PLUTO)
1.1 root 21: {
22: }
23:
1.1.1.8 root 24: // デストラクタ
1.1 root 25: PlutoDevice::~PlutoDevice()
26: {
27: }
28:
1.1.1.3 root 29: // ROM
30: /*static*/ const uint16
31: PlutoDevice::rom[] = {
32: // ホストファイル起動
33: 0x00ea, 0xc004, // .dc.l _start ; 起動アドレス
34: //_start:
1.1.1.9 root 35: 0x46fc, 0x2700, // move.w #0x2700,%sr
1.1.1.3 root 36: 0x2039, 0x00ea, 0xc450, // move.l (ROMIO_LOAD),%d0
1.1.1.9 root 37: 0x6b04, // bmi.s _err
38: 0x2040, // move.l %d0,%a0
1.1.1.10 root 39: 0x46fc, 0x2000, // move.w #0x2000,%sr
1.1.1.9 root 40: 0x4e90, // jsr (%a0)
1.1.1.3 root 41: //_err:
42: 0x43fa, 0x000c, // lea.l (_errmsg),%a1
43: 0x7021, 0x4e4f, // IOCS B_PRINT
44: //_loop:
45: 0x4e72, 0x2600, // stop #0x2600
46: 0x60fa, // bra.s _loop
47: //_errmsg:
48: 0x2a2a, 0x2043, 0x616e, // .dc.b "** Can"
49: 0x6e6f, 0x7420, 0x6c6f, // .dc.b "not lo"
50: 0x6164, 0x2068, 0x6f73, // .dc.b "ad hos"
51: 0x7420, 0x6669, 0x6c65, // .dc.b "t file"
52: 0x2e00, // .dc.b ".",0
53: };
54:
1.1.1.11 root 55: busdata
1.1.1.12 root 56: PlutoDevice::Read(busaddr addr)
1.1.1.3 root 57: {
1.1.1.12 root 58: uint32 paddr = addr.Addr();
59: uint32 offset = paddr - baseaddr;
60: busdata data;
1.1.1.3 root 61:
62: if (offset < sizeof(rom)) {
1.1.1.12 root 63: // ROM 部はワードデバイスっぽく応答するほうが都合がいい。
1.1.1.3 root 64: data = rom[offset / 2];
1.1.1.12 root 65: data |= BusData::Size2;
1.1.1.3 root 66:
1.1.1.12 root 67: } else if (offset == 0x450 && addr.GetSize() == 4) {
68: // ここはロングワード応答するほうが都合がいい。
69: // 自 ROM からのアクセスなので細かいことは考えない。
70: data = ROM_Load();
71: data |= BusData::Size4;
1.1.1.3 root 72:
1.1.1.12 root 73: } else {
74: data.SetBusErr();
1.1.1.3 root 75: }
76:
1.1.1.12 root 77: return data;
1.1.1.3 root 78: }
79:
1.1.1.11 root 80: busdata
1.1.1.12 root 81: PlutoDevice::Write(busaddr addr, uint32 data)
1.1.1.3 root 82: {
1.1.1.12 root 83: uint32 paddr = addr.Addr();
84: uint32 reqsize = addr.GetSize();
1.1.1.3 root 85:
1.1.1.12 root 86: putlog(0, "Write $%06x.%u (NOT IMPLEMENTED)", paddr, reqsize);
87: return BusData::BusErr;
1.1.1.3 root 88: }
89:
1.1.1.11 root 90: busdata
1.1.1.12 root 91: PlutoDevice::Peek1(uint32 addr)
1.1.1.3 root 92: {
1.1.1.9 root 93: uint32 offset = addr - baseaddr;
1.1.1.3 root 94: uint32 data;
95:
96: if (offset < sizeof(rom)) {
97: data = rom[offset / 2];
98: if ((offset & 1) == 0) {
99: return data >> 8;
100: } else {
101: return data & 0xff;
102: }
103: }
104:
1.1.1.12 root 105: return BusData::BusErr;
1.1.1.3 root 106: }
107:
108: //
109: // ホストファイル起動
110: //
111:
1.1.1.7 root 112: // -X オプションで指定されたホストファイルをロードする。
1.1.1.3 root 113: // ロードできればエントリポイントを返す。
1.1.1.7 root 114: // exec_file が指定されている時に呼ぶこと。
1.1.1.3 root 115: uint32
116: PlutoDevice::ROM_Load()
117: {
1.1.1.7 root 118: assert(gMainApp.exec_file);
1.1.1.3 root 119:
1.1.1.9 root 120: auto mainbus = GetMainbusDevice();
121: auto mainram = GetMainRAMDevice();
1.1.1.11 root 122: auto mpu680x0 = GetMPU680x0Device(mpu);
1.1.1.9 root 123: auto sram = GetSRAMDevice();
124:
1.1.1.3 root 125: // ホストファイルをロード
1.1.1.9 root 126: LoadInfo info(gMainApp.exec_file);
1.1.1.13! root 127: if (BootLoader::LoadExec(mainram, &info) == false) {
1.1.1.9 root 128: return -1;
129: }
130:
131: // NetBSD/x68k のプライマリブートローダが /boot を読み込む時、および
132: // /boot がカーネルを読み込む時には、レジスタ渡しのパラメータがあるので、
133: // ここで用意する。
134: // 本当はターゲットが NetBSD/x68k の /boot とカーネルの時に限定すべきの
135: // ような気もするけど、とりあえず。必要なパラメータは
136: //
137: // %d6 に bootdev、NetBSD/x68k の場合は
138: // bootdev = $MACULPTT
139: // ||||||++- major type
140: // |||||+--- パーティション番号
141: // ||||+---- SCSI なら LUN、それ以外なら 0
142: // |||+----- unit (SCSI なら SCSI ID、FD ならドライブ番号)
143: // ||+------ ctlr (spc0 なら 0 のやつ)
144: // |+------- adaptor (spc = 1、mha = 2)
145: // +-------- magic ($a)
146: // major type は fd=2、MemoryDisk=8、sd=4、(st=5、)、cd=7、ne=255。
147: //
148: // %d7 に howto だが今の所使ってないようだ。
149: //
150: // 一方、/boot がカーネルを読み込む時はこれに加えてスタック渡しの
151: // パラメータもある。これは (取り出す順に)
152: // firstpa.L .. 読み込んだカーネル先頭の物理アドレス?
153: // physsize.L .. RAM 容量 (SRAM の $ed0008.L の値)
154: // esym.L .. シンボルの後ろ、なので実質読み込んだ全体のサイズ
155: //
156: // これも本当はターゲットが NetBSD/x68k のカーネルの時に限定すべきの
157: // ような気もするけど、とりあえず。
158:
159: mpu680x0->reg.D[6] = 0xa1000004;
160: mpu680x0->reg.D[7] = 0;
161:
1.1.1.11 root 162: uint32 a7 = sram->GetRAMSize();
163: a7 -= 4;
1.1.1.12 root 164: mainbus->HVWrite4(a7, info.end - info.start); // esym
1.1.1.11 root 165: a7 -= 4;
1.1.1.12 root 166: mainbus->HVWrite4(a7, sram->GetRAMSize()); // physsize
1.1.1.11 root 167: a7 -= 4;
1.1.1.12 root 168: mainbus->HVWrite4(a7, 0x00000000); // firstpa
1.1.1.3 root 169:
1.1.1.11 root 170: mpu680x0->reg.A[7] = a7;
1.1.1.3 root 171:
1.1.1.9 root 172: return info.entry;
1.1.1.3 root 173: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.