|
|
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: // スプライトコントローラ
! 9: //
! 10:
1.1 root 11: #include "sprite.h"
1.1.1.4 root 12: #include "mpu.h"
1.1 root 13:
1.1.1.8 ! root 14: // グローバル参照用
! 15: SpriteDevice *gSprite;
1.1.1.5 root 16:
1.1.1.8 ! root 17: // コンストラクタ
1.1 root 18: SpriteDevice::SpriteDevice()
1.1.1.7 root 19: : inherited("Sprite")
1.1 root 20: {
21: devaddr = baseaddr;
22: devlen = 0x010000;
23:
1.1.1.2 root 24: mem.reset(new uint8[4 * 8192]);
1.1 root 25: }
26:
1.1.1.8 ! root 27: // デストラクタ
1.1 root 28: SpriteDevice::~SpriteDevice()
29: {
1.1.1.8 ! root 30: gSprite = NULL;
1.1 root 31: }
32:
1.1.1.8 ! root 33: // XXX ResetHard() 未調査
1.1.1.6 root 34:
1.1 root 35: uint64
36: SpriteDevice::Read8(uint32 addr)
37: {
38: if (addr >= 0xeb8000) {
39: return mem[HB(addr - 0xeb8000)];
40: }
1.1.1.8 ! root 41: VMPANIC("not impl");
1.1 root 42: }
43:
44: uint64
45: SpriteDevice::Read16(uint32 addr)
46: {
1.1.1.4 root 47: // スプライトの Read はレジスタ、VRAM とも 17 ウェイト。
48: // InsideOut p.135
49: gMPU->AddCycle(17);
50:
1.1 root 51: if (addr >= 0xeb8000) {
52: return *(uint16 *)&mem[addr - 0xeb8000];
53: }
54: if (addr < 0xeb0400) {
55: int n = (addr - 0xeb0000) / 8;
56: switch (addr % 8) {
57: case 0:
58: return reg.sprite[n].xpos;
59: case 2:
60: return reg.sprite[n].ypos;
61: case 4:
62: return reg.sprite[n].col;
63: case 6:
64: return reg.sprite[n].prw;
65: }
66: }
67: if (0xeb0800 <= addr && addr < 0xeb0812) {
68: switch (addr) {
69: case 0xeb0800:
70: return reg.bg0x;
71: case 0xeb0802:
72: return reg.bg0y;
73: case 0xeb0804:
74: return reg.bg1x;
75: case 0xeb0806:
76: return reg.bg1y;
77: case 0xeb0808:
78: return reg.bgctrl;
79: case 0xeb080a:
80: return reg.htotal;
81: case 0xeb080c:
82: return reg.hdisp;
83: case 0xeb080e:
84: return reg.vdisp;
85: case 0xeb0810:
86: return reg.res;
87: }
88: }
89:
90: return (uint64)-1;
91: }
92:
93: uint64
94: SpriteDevice::Write8(uint32 addr, uint32 data)
95: {
96: if (addr >= 0xeb8000) {
1.1.1.4 root 97: // スプライト VRAM への書き込み (InsideOut p.135)
98: gMPU->AddCycle(18);
1.1 root 99: mem[HB(addr - 0xeb8000)] = data;
100: return 0;
101: }
1.1.1.4 root 102:
103: // スプライトレジスタへの書き込み (InsideOut p.135)
104: gMPU->AddCycle(20);
105:
1.1.1.8 ! root 106: VMPANIC("not impl");
1.1 root 107: }
108:
109: uint64
110: SpriteDevice::Write16(uint32 addr, uint32 data)
111: {
112: putlog(2, "Write16 $%06x <- $%04x", addr, data);
113: if (addr >= 0xeb8000) {
114: *(uint16 *)&mem[addr - 0xeb8000] = data;
115: return 0;
116: }
117: if (addr < 0xeb0400) {
118: int n = (addr - 0xeb0000) / 8;
119: switch (addr % 8) {
120: case 0:
121: reg.sprite[n].xpos = data & 0x3ff;
122: break;
123: case 2:
124: reg.sprite[n].ypos = data & 0x3ff;
125: break;
126: case 4:
127: reg.sprite[n].col = data & 0xcfff;
128: break;
129: case 6:
130: reg.sprite[n].prw = data & 0x3;
131: break;
132: }
133: return 0;
134: }
135: if (0xeb0800 <= addr && addr < 0xeb0812) {
136: switch (addr) {
137: case 0xeb0800:
138: reg.bg0x = data & 0x3ff;
139: break;
140: case 0xeb0802:
141: reg.bg0y = data & 0x3ff;
142: break;
143: case 0xeb0804:
144: reg.bg1x = data & 0x3ff;
145: break;
146: case 0xeb0806:
147: reg.bg1y = data & 0x3ff;
148: break;
149: case 0xeb0808:
150: reg.bgctrl = data & 0x23f;
151: break;
152: case 0xeb080a:
153: reg.htotal = data & 0xff;
154: break;
155: case 0xeb080c:
156: reg.hdisp = data & 0x3f;
157: break;
158: case 0xeb080e:
159: reg.vdisp = data & 0xff;
160: break;
161: case 0xeb0810:
162: reg.res = data & 0x1f;
163: break;
164: }
165: return 0;
166: }
167:
168: return (uint64)-1;
169: }
170:
171: uint64
172: SpriteDevice::Peek8(uint32 addr)
173: {
174: if (addr >= 0xeb8000) {
175: return mem[HB(addr - 0xeb8000)];
176: }
177: if (addr < 0xeb0400) {
178: int n = (addr - 0xeb0000) / 8;
179: switch (addr % 8) {
180: case 0:
181: return reg.sprite[n].xpos;
182: case 2:
183: return reg.sprite[n].ypos;
184: case 4:
185: return reg.sprite[n].col;
186: case 6:
187: return reg.sprite[n].prw;
188: }
189: }
190: if (0xeb0800 <= addr && addr < 0xeb0812) {
191: switch (addr) {
192: case 0xeb0800:
193: return reg.bg0x;
194: case 0xeb0802:
195: return reg.bg0y;
196: case 0xeb0804:
197: return reg.bg1x;
198: case 0xeb0806:
199: return reg.bg1y;
200: case 0xeb0808:
201: return reg.bgctrl;
202: case 0xeb080a:
203: return reg.htotal;
204: case 0xeb080c:
205: return reg.hdisp;
206: case 0xeb080e:
207: return reg.vdisp;
208: case 0xeb0810:
209: return reg.res;
210: }
211: }
212:
213: return (uint64)-1;
214: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.