Annotation of nono/m680x0/m68030bus.cpp, revision 1.1.1.5

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: //
1.1.1.3   root        6: 
1.1.1.4   root        7: #include "mpu680x0.h"
1.1       root        8: 
1.1.1.5 ! root        9: // 現在の FC での通常アクセス (MPU 内部から使用する)
        !            10: // ミスアライン可。
        !            11: // バスエラーが起きると例外 M68K::EXCEP_BUSERR をスローする。
        !            12: //     uint32 fetch_{16,32}()
        !            13: //     uint32 read_{8,16,32}(laddr)
        !            14: //     void   write_{8,16,32}(laddr, data)
1.1       root       15: 
1.1.1.5 ! root       16: // reg.pc からワードをフェッチし reg.pc を進める。
        !            17: uint32
        !            18: MPU680x0Device::fetch_16()
1.1       root       19: {
1.1.1.5 ! root       20:        uint32 data;
        !            21: 
        !            22:        if (__predict_true(icache_enable)) {
        !            23:                data = fetch_16_cache(reg.pc);
1.1       root       24:        } else {
1.1.1.5 ! root       25:                data = fetch_16_bus(reg.pc);
1.1       root       26:        }
1.1.1.5 ! root       27:        reg.pc += 2;
        !            28: 
        !            29:        return data;
1.1       root       30: }
                     31: 
1.1.1.5 ! root       32: // reg.pc からロングワード(ミスアライン可)をフェッチし reg.pc を進める。
        !            33: uint32
        !            34: MPU680x0Device::fetch_32()
1.1       root       35: {
1.1.1.5 ! root       36:        uint32 data;
        !            37: 
        !            38:        if (__predict_true(icache_enable)) {
        !            39:                data = fetch_32_cache(reg.pc);
1.1       root       40:        } else {
1.1.1.5 ! root       41:                if ((reg.pc & 2) == 0) {
        !            42:                        data = fetch_32_bus(reg.pc);
        !            43:                } else {
        !            44:                        data  = fetch_16_bus(reg.pc) << 16;
        !            45:                        data |= fetch_16_bus(reg.pc + 2);
        !            46:                }
1.1       root       47:        }
1.1.1.5 ! root       48:        reg.pc += 4;
        !            49: 
        !            50:        return data;
1.1       root       51: }
                     52: 
1.1.1.5 ! root       53: uint32
        !            54: MPU680x0Device::read_8(uint32 addr)
1.1       root       55: {
1.1.1.5 ! root       56:        busaddr laddr(addr, fc_data | busaddr::R);
        !            57:        return read_8_fc(laddr);
1.1       root       58: }
                     59: 
1.1.1.5 ! root       60: uint32
        !            61: MPU680x0Device::read_16(uint32 addr)
1.1       root       62: {
1.1.1.5 ! root       63:        busaddr laddr(addr, fc_data | busaddr::R);
        !            64:        return read_16_fc(laddr);
1.1       root       65: }
                     66: 
1.1.1.5 ! root       67: uint32
        !            68: MPU680x0Device::read_32(uint32 addr)
1.1       root       69: {
1.1.1.5 ! root       70:        busaddr laddr(addr, fc_data | busaddr::R);
        !            71:        return read_32_fc(laddr);
1.1       root       72: }
                     73: 
1.1.1.5 ! root       74: void
        !            75: MPU680x0Device::write_8(uint32 addr, uint32 data)
1.1       root       76: {
1.1.1.5 ! root       77:        busaddr laddr(addr, fc_data | busaddr::W);
        !            78:        write_8_fc(laddr, data);
1.1       root       79: }
                     80: 
1.1.1.5 ! root       81: void
        !            82: MPU680x0Device::write_16(uint32 addr, uint32 data)
1.1       root       83: {
1.1.1.5 ! root       84:        busaddr laddr(addr, fc_data | busaddr::W);
        !            85:        write_16_fc(laddr, data);
1.1       root       86: }
                     87: 
1.1.1.5 ! root       88: void
        !            89: MPU680x0Device::write_32(uint32 addr, uint32 data)
1.1       root       90: {
1.1.1.5 ! root       91:        busaddr laddr(addr, fc_data | busaddr::W);
        !            92:        write_32_fc(laddr, data);
1.1       root       93: }
                     94: 
1.1.1.5 ! root       95: // FC 指定アクセス (MPU コアから使用する)
        !            96: // ミスアライン可。
        !            97: // バスエラーが起きると例外 M68K::EXCEP_BUSERR をスローする。
        !            98: //     uint32 read_{8,16,32}_fc(busaddr)
        !            99: //     void   write_{8,16,32}_fc(busaddr, data)
        !           100: // (fetch は常に現在の FC でアクセスするので FC 指定版は不要)
1.1       root      101: 
                    102: uint32
1.1.1.5 ! root      103: MPU680x0Device::read_8_fc(busaddr addr)
1.1       root      104: {
1.1.1.5 ! root      105:        uint32 data;
1.1       root      106: 
1.1.1.5 ! root      107:        if (1) {
        !           108:                data = read_8_bus(addr);
        !           109:        }
        !           110: 
        !           111:        return data;
1.1       root      112: }
                    113: 
                    114: uint32
1.1.1.5 ! root      115: MPU680x0Device::read_16_fc(busaddr addr)
1.1       root      116: {
1.1.1.5 ! root      117:        uint32 data;
        !           118: 
        !           119:        if (1) {
        !           120:                // バスアクセスは要整列。
        !           121:                if (__predict_true((addr & 1) == 0)) {
        !           122:                        data = read_16_bus(addr);
        !           123:                } else {
        !           124:                        data  = read_8_bus(addr) << 8;
        !           125:                        addr += 1;
        !           126:                        data |= read_8_bus(addr);
        !           127:                }
        !           128:        }
        !           129: 
        !           130:        return data;
1.1       root      131: }
                    132: 
                    133: uint32
1.1.1.5 ! root      134: MPU680x0Device::read_32_fc(busaddr addr)
1.1       root      135: {
1.1.1.5 ! root      136:        uint32 data;
        !           137: 
        !           138:        if (1) {
        !           139:                // バスアクセスは要整列。
        !           140:                if (__predict_true((addr & 3) == 0)) {
        !           141:                        data = read_32_bus(addr);
        !           142:                } else if (__predict_true((addr & 1) == 0)) {
        !           143:                        data  = read_16_bus(addr) << 16;
        !           144:                        addr += 2;
        !           145:                        data |= read_16_bus(addr);
        !           146:                } else {
        !           147:                        data  = read_8_bus(addr) << 24;
        !           148:                        addr += 1;
        !           149:                        data |= read_16_bus(addr) << 8;
        !           150:                        addr += 2;
        !           151:                        data |= read_8_bus(addr);
        !           152:                }
        !           153:        }
        !           154: 
        !           155:        return data;
1.1       root      156: }
                    157: 
1.1.1.5 ! root      158: void
        !           159: MPU680x0Device::write_8_fc(busaddr addr, uint32 data)
1.1       root      160: {
1.1.1.5 ! root      161:        if (1) {
        !           162:                write_8_bus(addr, data);
        !           163:        }
1.1       root      164: }
                    165: 
                    166: void
1.1.1.5 ! root      167: MPU680x0Device::write_16_fc(busaddr addr, uint32 data)
1.1       root      168: {
1.1.1.5 ! root      169:        if (1) {
        !           170:                // バスアクセスは要整列。
        !           171:                if (__predict_true((addr & 1) == 0)) {
        !           172:                        write_16_bus(addr, data);
        !           173:                } else {
        !           174:                        write_8_bus(addr, data >> 8);
        !           175:                        addr += 1;
        !           176:                        write_8_bus(addr, data & 0xff);
        !           177:                }
        !           178:        }
1.1       root      179: }
                    180: 
                    181: void
1.1.1.5 ! root      182: MPU680x0Device::write_32_fc(busaddr addr, uint32 data)
1.1       root      183: {
1.1.1.5 ! root      184:        if (1) {
        !           185:                // バスアクセスは要整列。
        !           186:                if (__predict_true((addr & 3) == 0)) {
        !           187:                        write_32_bus(addr, data);
        !           188:                } else if (__predict_true((addr & 1) == 0)) {
        !           189:                        write_16_bus(addr, data >> 16);
        !           190:                        addr += 2;
        !           191:                        write_16_bus(addr, data & 0xffff);
        !           192:                } else {
        !           193:                        write_8_bus(addr, data >> 24);
        !           194:                        addr += 1;
        !           195:                        write_16_bus(addr, (data >> 8) & 0xffff);
        !           196:                        addr += 2;
        !           197:                        write_8_bus(addr, data & 0xff);
        !           198:                }
        !           199:        }
1.1       root      200: }
                    201: 
1.1.1.5 ! root      202: // 外部バスアクセス (MMU を含む)
        !           203: // ミスアライン不可。
        !           204: // バスエラーが起きると例外 M68K::EXCEP_BUSERR をスローする。
        !           205: //     uint32 fetch_{16,32}_bus()
        !           206: //     uint32 read_{8,16,32}_bus(busaddr)
        !           207: //     void   write_{8,16,32}_bus(busaddr, data)
        !           208: 
        !           209: // goto を含むことに注意。gcc 拡張式(?) に注意。
        !           210: #define FETCH(size)    ({      \
        !           211:        bus.laddr.Set(addr, fc_inst);   \
        !           212:        bus.paddr = bus.laddr;  \
        !           213:        bus.ci = false; \
        !           214:        if (__predict_true(mmu_enable)) {       \
        !           215:                if (__predict_false(TranslateFetch() == false)) \
        !           216:                        goto buserr;    \
        !           217:        }       \
        !           218:        busdata bd_ = mainbus->__CONCAT(Read,size)(bus.paddr);  \
        !           219:        if (bd_.IsBusErr()) \
        !           220:                goto buserr;    \
        !           221:        bd_;    /* これが戻り値 */        \
        !           222: })
        !           223: #define READ(size)     ({      \
        !           224:        bus.laddr = addr;       \
        !           225:        bus.paddr = addr;       \
        !           226:        bus.ci = false; \
        !           227:        if (__predict_true(mmu_enable)) {       \
        !           228:                if (__predict_false(TranslateRead() == false))  \
        !           229:                        goto buserr;    \
        !           230:        }       \
        !           231:        busdata bd_ = mainbus->__CONCAT(Read,size)(bus.paddr);  \
        !           232:        if (bd_.IsBusErr()) \
        !           233:                goto buserr;    \
        !           234:        bd_;    /* これが戻り値 */        \
        !           235: })
        !           236: #define WRITE(size, data_)     ({      \
        !           237:        bus.laddr = addr;       \
        !           238:        bus.paddr = addr;       \
        !           239:        bus.ci = false; \
        !           240:        if (__predict_true(mmu_enable)) {       \
        !           241:                if (__predict_false(TranslateWrite() == false)) \
        !           242:                        goto buserr;    \
        !           243:        }       \
        !           244:        busdata bd_ = mainbus->__CONCAT(Write,size)(bus.paddr, data_); \
        !           245:        if (bd_.IsBusErr()) \
        !           246:                goto buserr;    \
        !           247:        bd_;    /* これが戻り値 */        \
        !           248: })
        !           249: 
        !           250: uint32
        !           251: MPU680x0Device::fetch_16_bus(uint32 addr)
1.1       root      252: {
1.1.1.5 ! root      253:        busdata bd;
        !           254: 
        !           255:        bd = FETCH(16);
        !           256:        buswait += bd.GetWait();
        !           257:        return bd.Data();
        !           258: 
        !           259:  buserr:
        !           260:        bus.size = M68K::SSW_SIZE_WORD;
        !           261:        throw M68K::EXCEP_BUSERR;
1.1       root      262: }
                    263: 
1.1.1.5 ! root      264: uint32
        !           265: MPU680x0Device::fetch_32_bus(uint32 addr)
        !           266: {
        !           267:        busdata bd;
        !           268: 
        !           269:        bd = FETCH(32);
        !           270:        buswait += bd.GetWait();
        !           271:        return bd.Data();
        !           272: 
        !           273:  buserr:
        !           274:        bus.size = M68K::SSW_SIZE_LONG;
        !           275:        throw M68K::EXCEP_BUSERR;
        !           276: }
1.1       root      277: 
                    278: uint32
1.1.1.5 ! root      279: MPU680x0Device::read_8_bus(busaddr addr)
1.1       root      280: {
1.1.1.5 ! root      281:        busdata data;
        !           282: 
        !           283:        data = READ(8);
        !           284:        putlog(2, "read_8   %08x -> %02x", bus.laddr.Addr(), data.Data());
        !           285:        buswait += data.GetWait();
        !           286:        return data.Data();
        !           287: 
        !           288:  buserr:
        !           289:        bus.size = M68K::SSW_SIZE_BYTE;
        !           290:        throw M68K::EXCEP_BUSERR;
1.1       root      291: }
                    292: 
                    293: uint32
1.1.1.5 ! root      294: MPU680x0Device::read_16_bus(busaddr addr)
1.1       root      295: {
1.1.1.5 ! root      296:        busdata data;
        !           297: 
        !           298:        data = READ(16);
        !           299:        putlog(2, "read_16  %08x -> %04x", bus.laddr.Addr(), data.Data());
        !           300:        buswait += data.GetWait();
        !           301:        return data.Data();
        !           302: 
        !           303:  buserr:
        !           304:        bus.size = M68K::SSW_SIZE_WORD;
        !           305:        throw M68K::EXCEP_BUSERR;
1.1       root      306: }
                    307: 
                    308: uint32
1.1.1.5 ! root      309: MPU680x0Device::read_32_bus(busaddr addr)
1.1       root      310: {
1.1.1.5 ! root      311:        busdata data;
        !           312: 
        !           313:        data = READ(32);
        !           314:        putlog(2, "read_32  %08x -> %08x", bus.laddr.Addr(), data.Data());
        !           315:        buswait += data.GetWait();
        !           316:        return data.Data();
        !           317: 
        !           318:  buserr:
        !           319:        bus.size = M68K::SSW_SIZE_LONG;
        !           320:        throw M68K::EXCEP_BUSERR;
1.1       root      321: }
                    322: 
                    323: void
1.1.1.5 ! root      324: MPU680x0Device::write_8_bus(busaddr addr, uint32 data)
1.1       root      325: {
1.1.1.5 ! root      326:        busdata rd;
        !           327: 
        !           328:        rd = WRITE(8, data);
        !           329:        putlog(2, "write_8  %08x <- %02x", bus.laddr.Addr(), data);
        !           330:        buswait += rd.GetWait();
        !           331:        return;
        !           332: 
        !           333:  buserr:
        !           334:        bus.size = M68K::SSW_SIZE_BYTE;
        !           335:        throw M68K::EXCEP_BUSERR;
1.1       root      336: }
                    337: 
                    338: void
1.1.1.5 ! root      339: MPU680x0Device::write_16_bus(busaddr addr, uint32 data)
1.1       root      340: {
1.1.1.5 ! root      341:        busdata rd;
        !           342: 
        !           343:        rd = WRITE(16, data);
        !           344:        putlog(2, "write_16 %08x <- %04x", bus.laddr.Addr(), data);
        !           345:        buswait += rd.GetWait();
        !           346:        return;
        !           347: 
        !           348:  buserr:
        !           349:        bus.size = M68K::SSW_SIZE_WORD;
        !           350:        throw M68K::EXCEP_BUSERR;
1.1       root      351: }
                    352: 
                    353: void
1.1.1.5 ! root      354: MPU680x0Device::write_32_bus(busaddr addr, uint32 data)
1.1       root      355: {
1.1.1.5 ! root      356:        busdata rd;
        !           357: 
        !           358:        rd = WRITE(32, data);
        !           359:        putlog(2, "write_32 %08x <- %08x", bus.laddr.Addr(), data);
        !           360:        buswait += rd.GetWait();
        !           361:        return;
        !           362: 
        !           363:  buserr:
        !           364:        bus.size = M68K::SSW_SIZE_LONG;
        !           365:        throw M68K::EXCEP_BUSERR;
1.1       root      366: }

unix.superglobalmegacorp.com

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