Annotation of nono/vm/sprite.cpp, revision 1.1.1.14

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.12  root       12: #include "event.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: {
                     25: }
                     26: 
1.1.1.8   root       27: // デストラクタ
1.1       root       28: SpriteDevice::~SpriteDevice()
                     29: {
                     30: }
                     31: 
1.1.1.13  root       32: // 初期化
                     33: bool
                     34: SpriteDevice::Init()
                     35: {
1.1.1.14! root       36:        constexpr size_t devlen = 4 * 8192;
1.1.1.13  root       37:        mem.reset(new(std::nothrow) uint8[devlen]);
                     38:        if ((bool)mem == false) {
1.1.1.14! root       39:                warnx("Could not allocate %zu bytes at %s", devlen, __method__);
1.1.1.13  root       40:                return false;
                     41:        }
                     42: 
                     43:        return true;
                     44: }
                     45: 
1.1.1.8   root       46: // XXX ResetHard() 未調査
1.1.1.6   root       47: 
1.1.1.11  root       48: busdata
1.1.1.12  root       49: SpriteDevice::Read(busaddr addr)
1.1       root       50: {
1.1.1.11  root       51:        busdata data;
                     52: 
1.1.1.12  root       53:        uint32 paddr2 = addr.Addr() & ~1U;
                     54:        data = Get16(paddr2);
                     55:        putlog(3, "$%06x -> $%04x", paddr2, data.Data());
                     56:        data |= read_wait;
                     57:        data |= BusData::Size2;
                     58:        return data;
                     59: }
                     60: 
                     61: busdata
                     62: SpriteDevice::Write(busaddr addr, uint32 data)
                     63: {
                     64:        uint32 paddr = addr.Addr();
                     65:        uint32 reqsize = addr.GetSize();
                     66:        uint32 datasize = std::min(2 - (paddr & 1U), reqsize);
                     67:        data >>= (reqsize - datasize) * 8;
                     68: 
                     69:        uint32 paddr2 = paddr & ~1U;
                     70:        if (datasize == 1) {
                     71:                putlog(2, "$%06x <- $%02x", paddr, data);
                     72:                uint32 tmp = Get16(paddr2);
                     73:                if ((paddr & 1U) == 0) {
                     74:                        data = (data << 8) | (tmp & 0xff);
                     75:                } else {
                     76:                        data = (tmp & 0xff00) | (data & 0xff);
                     77:                }
1.1.1.11  root       78:        } else {
1.1.1.12  root       79:                putlog(2, "$%06x <- $%04x", paddr, data);
1.1       root       80:        }
1.1.1.11  root       81: 
1.1.1.12  root       82:        busdata r = Set16(paddr2, data);
                     83:        r |= busdata::Size(datasize);
                     84:        return r;
                     85: }
                     86: 
                     87: busdata
                     88: SpriteDevice::Peek1(uint32 addr)
                     89: {
                     90:        busdata data = Get16(addr & ~1U);
                     91:        if ((addr & 1U) == 0) {
                     92:                return data >> 8;
                     93:        } else {
                     94:                return data & 0xff;
                     95:        }
1.1.1.11  root       96:        return data;
1.1       root       97: }
                     98: 
1.1.1.12  root       99: // 指定のアドレスの16ビット値を返す。
                    100: // addr は偶数アドレスを指定すること。
1.1.1.11  root      101: busdata
1.1.1.12  root      102: SpriteDevice::Get16(uint32 addr) const
1.1       root      103: {
1.1.1.12  root      104:        assert((addr & 1U) == 0);
1.1.1.4   root      105: 
1.1       root      106:        if (addr >= 0xeb8000) {
1.1.1.12  root      107:                return *(uint16 *)&mem[addr - 0xeb8000];
                    108:        }
                    109:        if (addr < 0xeb0400) {
                    110:                uint n = (addr - 0xeb0000) / 8;
1.1       root      111:                switch (addr % 8) {
                    112:                 case 0:
1.1.1.12  root      113:                        return reg.sprite[n].xpos;
1.1       root      114:                 case 2:
1.1.1.12  root      115:                        return reg.sprite[n].ypos;
1.1       root      116:                 case 4:
1.1.1.12  root      117:                        return reg.sprite[n].col;
1.1       root      118:                 case 6:
1.1.1.12  root      119:                        return reg.sprite[n].prw;
1.1.1.11  root      120:                 default:
                    121:                        __unreachable();
1.1       root      122:                }
                    123:        }
                    124: 
1.1.1.12  root      125:        switch (addr) {
                    126:         case 0xeb0800:
                    127:                return reg.bg0x;
                    128:         case 0xeb0802:
                    129:                return reg.bg0y;
                    130:         case 0xeb0804:
                    131:                return reg.bg1x;
                    132:         case 0xeb0806:
                    133:                return reg.bg1y;
                    134:         case 0xeb0808:
                    135:                return reg.bgctrl;
                    136:         case 0xeb080a:
                    137:                return reg.htotal;
                    138:         case 0xeb080c:
                    139:                return reg.hdisp;
                    140:         case 0xeb080e:
                    141:                return reg.vdisp;
                    142:         case 0xeb0810:
                    143:                return reg.res;
                    144:         default:
                    145:                break;
1.1       root      146:        }
1.1.1.12  root      147: 
                    148:        return BusData::BusErr;
1.1       root      149: }
                    150: 
1.1.1.12  root      151: // addr は偶数アドレスを指定すること。
                    152: // ウェイト値もしくは BusData::BusErr を返す。
1.1.1.11  root      153: busdata
1.1.1.12  root      154: SpriteDevice::Set16(uint32 addr, uint32 data)
1.1       root      155: {
1.1.1.12  root      156:        assert((addr & 1U) == 0);
                    157: 
1.1       root      158:        if (addr >= 0xeb8000) {
                    159:                *(uint16 *)&mem[addr - 0xeb8000] = data;
1.1.1.11  root      160:                return vram_wait;
1.1       root      161:        }
                    162:        if (addr < 0xeb0400) {
1.1.1.12  root      163:                uint n = (addr - 0xeb0000) / 8;
1.1       root      164:                switch (addr % 8) {
                    165:                 case 0:
                    166:                        reg.sprite[n].xpos = data & 0x3ff;
                    167:                        break;
                    168:                 case 2:
                    169:                        reg.sprite[n].ypos = data & 0x3ff;
                    170:                        break;
                    171:                 case 4:
                    172:                        reg.sprite[n].col = data & 0xcfff;
                    173:                        break;
                    174:                 case 6:
                    175:                        reg.sprite[n].prw = data & 0x3;
                    176:                        break;
1.1.1.12  root      177:                 default:
                    178:                        __unreachable();
1.1       root      179:                }
1.1.1.11  root      180:                return reg_wait;
1.1       root      181:        }
                    182:        if (0xeb0800 <= addr && addr < 0xeb0812) {
                    183:                switch (addr) {
                    184:                 case 0xeb0800:
                    185:                        reg.bg0x = data & 0x3ff;
                    186:                        break;
                    187:                 case 0xeb0802:
                    188:                        reg.bg0y = data & 0x3ff;
                    189:                        break;
                    190:                 case 0xeb0804:
                    191:                        reg.bg1x = data & 0x3ff;
                    192:                        break;
                    193:                 case 0xeb0806:
                    194:                        reg.bg1y = data & 0x3ff;
                    195:                        break;
                    196:                 case 0xeb0808:
                    197:                        reg.bgctrl = data & 0x23f;
                    198:                        break;
                    199:                 case 0xeb080a:
                    200:                        reg.htotal = data & 0xff;
                    201:                        break;
                    202:                 case 0xeb080c:
                    203:                        reg.hdisp = data & 0x3f;
                    204:                        break;
                    205:                 case 0xeb080e:
                    206:                        reg.vdisp = data & 0xff;
                    207:                        break;
                    208:                 case 0xeb0810:
                    209:                        reg.res = data & 0x1f;
                    210:                        break;
1.1.1.12  root      211:                 default:
                    212:                        __unreachable();
1.1       root      213:                }
1.1.1.11  root      214:                return reg_wait;
1.1       root      215:        }
                    216: 
1.1.1.11  root      217:        busdata r = reg_wait;   // ?
                    218:        r.SetBusErr();
                    219:        return r;
1.1       root      220: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.