|
|
1.1 root 1: //
2: // nono
3: // Copyright (C) 2022 nono project
4: // Licensed under nono-license.txt
5: //
6:
7: //
8: // NEWS の ROM エミュレーション (-X のみ対応)
9: //
10:
11: #include "romemu_news.h"
12: #include "mainram.h"
13: #include "memorystream.h"
14: #include "mpu680x0.h"
15: #include "newsfb.h"
16:
17: // コンストラクタ
18: NewsROMEmuDevice::NewsROMEmuDevice()
19: : inherited(OBJ_PROM)
20: {
21: // 適当
22: uint devlen = 4096;
23: imagebuf.reset(new uint8 [devlen]);
24: memset(&imagebuf[0], 0, devlen);
25: mem = &imagebuf[0];
26:
27: mask = devlen - 1;
28: }
29:
30: // デストラクタ
31: NewsROMEmuDevice::~NewsROMEmuDevice()
32: {
33: }
34:
35: // 初期化
36: bool
37: NewsROMEmuDevice::Init()
38: {
39: if (inherited::Init() == false) {
40: return false;
41: }
42:
43: mainram = GetMainRAMDevice();
44:
45: MemoryStreamBE ms(imagebuf.get());
46: ms.Write32(0x00000400); // +00: リセットベクタ SP
47: ms.Write32(0xf8000400); // +04: リセットベクタ PC
48: // ベクタ
49: for (int i = 2; i < 256; i++) {
50: ms.Write32(0);
51: }
52: ms.SetOffset(32 * 4);
53: ms.Write32(0xf8000500); // Trap#0 で ROM のサービスコール
54:
55: // リセット時に実行する命令
56: ms.SetOffset(0x400);
57: ms.Write16(0x2039); // move.l (ROMIO_INIT),d0
58: ms.Write32(ROMIO_INIT);
59: ms.Write16(0x2040); // move.l d0,a0 ; ジャンプ先を a0 にセット
60: ms.Write16(0x4ed0); // jmp (a0) ; ジャンプ
61:
62: // ROM サービスコール
63: ms.SetOffset(0x500);
64: ms.Write16(0x0c80); // cmpi.l #3,d0
65: ms.Write32(0x00000003); //
66: ms.Write16(0x6708); // beq @f
67: ms.Write16(0x2039); // move.l (ROMIO_SYS),d0
68: ms.Write32(ROMIO_SYS); //
69: ms.Write16(0x4e73); // rte
70: //@@: ; Read は対応してないので
71: ms.Write32(0x4e722500); // stop #0x2500 ; STOP しつつ
72: ms.Write16(0x60fa); // bra @b ; 無限ループ。
73: ms.Write16(0x4e73); // rte
74:
75: return true;
76: }
77:
78: void
79: NewsROMEmuDevice::ResetHard(bool poweron)
80: {
81: // 起動時に RAM にリセットベクタを書き込んでおく。(手抜き)
82: for (int i = 0; i < 8; i++) {
83: mainram->Write8(i, imagebuf[i]);
84: }
85: }
86:
87: uint64
88: NewsROMEmuDevice::Read32(uint32 addr)
89: {
90: switch (addr) {
91: case ROMIO_INIT:
92: return ROM_Init();
93:
94: case ROMIO_SYS:
95: return ROM_Sys();
96:
97: default:
98: break;
99: }
100:
101: return inherited::Read32(addr);
102: }
103:
104: uint32
105: NewsROMEmuDevice::ROM_Init()
106: {
107: LoadInfo info;
108:
109: // -X file
110: if (gMainApp.exec_file) {
111: // ホストのファイルを読み込んでエントリポイントアドレスを
112: // この Read アクセスの読み出し値として返す。
113: // エラーがあればエラーメッセージは呼び出し先側で表示してある。
114: info.path = gMainApp.exec_file;
115: if (mainram->LoadFromFile(&info) == false) {
116: // XXX どうすべ
117: PANIC("** Couldn't load specified host program.\n");
118: return -1;
119: }
120: putmsg(1, "Host program loaded. Entry point = $%08x\n", info.entry);
121: }
122:
123: // ROMCONS のために VBR を設定
124: m68kreg& reg = GetMPU680x0Device()->reg;
125: reg.vbr = 0xf8000000;
126:
127: // %d2 には MARK_END (たぶん最後の番地)
128: // %d4 にメモリサイズ。
129: // %d5 には読み込んだファイル名の先頭番地?
130: // %d6 に bootdev、NetBSD/news68k の場合は
131: // bootdev = $MCxUHPTT
132: // || |||++ Type? (SD=0)
133: // || ||+-- Partition?
134: // || |+--- Host: 機種? (NEWS1700 は 0)
135: // || +---- Unit?
136: // |+------ Controller?
137: // +------- magic ($5)
138: // 下位28ビット(7桁) は ROM から渡されるようだ。
139: // %d7 は boothowto。
140: reg.D[2] = info.sym;
141: reg.D[4] = mainram->GetSize();
142: reg.D[6] = 0x50000000;
143: reg.D[7] = 0;
144:
145: return info.entry;
146: }
147:
148: uint32
149: NewsROMEmuDevice::ROM_Sys()
150: {
151: auto mpu680x0 = GetMPU680x0Device();
152: m68kreg& reg = mpu680x0->reg;
153: auto newsfb = GetNewsfbDevice();
154:
155: if (reg.D[0] == SYS_write) {
156: uint32 a6 = reg.A[6];
157: uint32 fd = mpu680x0->Read32(a6 + 8);
158: uint32 buf = mpu680x0->Read32(a6 + 12);
159: uint32 len = mpu680x0->Read32(a6 + 16);
160:
161: for (int i = 0; i < len; i++) {
162: uint64 ch = mpu680x0->Read8(buf++);
163: if ((int64)ch < 0) {
164: // XXX ?
165: return 0;
166: }
167: if (ch == '\r') {
168: continue;
169: }
170: newsfb->Putc(ch);
171: }
172: (void)fd;
173: return len;
174: }
175:
176: VMPANIC("Unknown service call $%02x", reg.D[0]);
177: return 0;
178: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.