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