|
|
1.1 root 1: //
2: // nono
3: // Copyright (C) 2017 [email protected]
4: //
5:
1.1.1.3 ! root 6: #include "mainapp.h"
1.1 root 7: #include "sram.h"
8: #include <sys/fcntl.h>
9: #include <sys/mman.h>
1.1.1.2 root 10: #include <sys/stat.h>
1.1 root 11:
12: //
13: // SRAM
14: //
15: // SRAM はビッグエンディアンのままメモリに置かれるので、
16: // 必要ならアクセス時に都度変換すること。
17: //
18:
1.1.1.3 ! root 19: std::unique_ptr<SRAMDevice> gSRAM;
1.1 root 20:
21: SRAMDevice::SRAMDevice()
22: {
23: logname = "sram";
24: devname = "SRAM";
25: devaddr = baseaddr;
26: devlen = 0x10000; // 通常実際は16KBだが64KB分占有しておく
27:
28: fd = -1;
29: }
30:
31: SRAMDevice::~SRAMDevice()
32: {
33: if (mem) {
34: munmap(mem, memlen);
35: mem = NULL;
36: memlen = 0;
37: }
38: if (fd >= 0) {
39: close(fd);
40: fd = -1;
41: }
42: }
43:
44: bool
45: SRAMDevice::Init()
46: {
1.1.1.2 root 47: struct stat st;
48:
1.1.1.3 ! root 49: filename = gMainApp.GetVMDir() + "SRAM030.DAT";
1.1.1.2 root 50: memlen = 16 * 1024;
1.1 root 51:
52: fd = open(filename.c_str(), O_RDWR);
53: if (fd == -1) {
1.1.1.2 root 54: warn("SRAM \"%s\" open failed", filename.c_str());
1.1 root 55: return false;
56: }
57:
1.1.1.2 root 58: // ファイルサイズをチェック。
59: // ファイルが短くても mmap はしれっと成功してしまうようだ。
60: if (fstat(fd, &st) == -1) {
61: warn("SRAM \"%s\" fstat failed", filename.c_str());
62: close(fd);
63: return false;
64: }
65: if (st.st_size < memlen) {
66: warnx("SRAM \"%s\" is too short (filesize is expected %d but %d)",
67: filename.c_str(), memlen, (int)st.st_size);
68: close(fd);
69: return false;
70: }
71: if (st.st_size > memlen) {
72: // 大きすぎるほうはワーニングだけでいいか
73: warnx("SRAM \"%s\" is too large (ignore %d bytes)",
74: filename.c_str(), (int)st.st_size - memlen);
75: }
76:
1.1 root 77: mem = (uint8 *)mmap(NULL, memlen, PROT_READ | PROT_WRITE,
78: MAP_SHARED, fd, 0);
79: if (mem == MAP_FAILED) {
1.1.1.2 root 80: warn("SRAM \"%s\" mmap failed", filename.c_str());
1.1 root 81: close(fd);
82: return false;
83: }
84:
85: return true;
86: }
87:
1.1.1.3 ! root 88: // アドレスデコーダ
! 89: inline uint64
! 90: SRAMDevice::Decoder(uint32 addr) const
! 91: {
! 92: return addr - baseaddr;
! 93: }
! 94:
1.1 root 95: uint64
96: SRAMDevice::Read8(uint32 addr)
97: {
1.1.1.3 ! root 98: uint32 offset = Decoder(addr);
! 99: return mem[offset];
1.1 root 100: }
101:
102: uint64
103: SRAMDevice::Read16(uint32 addr)
104: {
1.1.1.3 ! root 105: uint32 offset = Decoder(addr);
! 106: return be16toh(*(uint16 *)&mem[offset]);
1.1 root 107: }
108:
109: uint64
110: SRAMDevice::Write8(uint32 addr, uint32 data)
111: {
1.1.1.3 ! root 112: uint32 offset = Decoder(addr);
! 113:
1.1 root 114: if (writeable) {
1.1.1.3 ! root 115: if (offset < 0x100) {
1.1 root 116: putlog(1, "更新 $%06x <- $%02x", addr, data);
117: }
1.1.1.3 ! root 118: mem[offset] = data;
1.1 root 119: } else {
120: putlog(1, "書き込み禁止 $%06x <- $%02x", addr, data);
121: }
122: return 0;
123: }
124:
125: uint64
126: SRAMDevice::Write16(uint32 addr, uint32 data)
127: {
1.1.1.3 ! root 128: uint32 offset = Decoder(addr);
! 129:
1.1 root 130: if (writeable) {
1.1.1.3 ! root 131: if (offset < 0x100) {
1.1 root 132: putlog(1, "更新 $%06x <- $%04x", addr, data);
133: }
1.1.1.3 ! root 134: *(uint16 *)&mem[offset] = htobe16(data);
1.1 root 135: } else {
136: putlog(1, "書き込み禁止 $%06x <- $%04x", addr, data);
137: }
138: return 0;
139: }
140:
141: uint64
142: SRAMDevice::Peek8(uint32 addr)
143: {
1.1.1.3 ! root 144: uint32 offset = Decoder(addr);
! 145: return mem[offset];
1.1 root 146: }
147:
148: void
149: SRAMDevice::write_enable(bool value)
150: {
151: if (writeable == false && value == true) {
152: putlog(1, "書き込み許可");
153: } else if (writeable == true && value == false) {
154: putlog(1, "書き込み禁止");
155: }
156:
157: writeable = value;
158: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.