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

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

unix.superglobalmegacorp.com

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