Annotation of nono/m680x0/m68030bus.h, revision 1.1.1.3

1.1       root        1: //
                      2: // nono
1.1.1.2   root        3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
1.1       root        5: //
                      6: 
                      7: #pragma once
                      8: 
1.1.1.3 ! root        9: //
        !            10: // 1回の(アラインド)物理アクセスを担当するマクロ。
        !            11: // これらは続く _mmu テンプレートで使用する。
        !            12: // goto を含むことに注意。gcc 拡張式(?)に注意。
        !            13: // Translate* は Fetch, Read, Write の3種だが、Mainbus には
        !            14: // Read, Write しかないことに注意。物理バスに FC0 と FC1、つまりプログラム
        !            15: // 空間かどうかの情報は出していないため。
        !            16: //
1.1       root       17: 
1.1.1.3 ! root       18: #define FETCH(size) ({ \
        !            19:        bus.paddr = bus.laddr;  \
        !            20:        if (use_mmu && TranslateFetch() == false)       \
        !            21:                goto buserr;    \
        !            22:        uint64 data_ = mainbus->__CONCAT(Read,size)(bus.paddr); \
        !            23:        if ((int64)data_ < 0)   \
        !            24:                goto buserr;    \
        !            25:        data_;  /* これが戻り値 */        \
        !            26: })
        !            27: 
        !            28: #define READ(size) ({  \
        !            29:        bus.paddr = bus.laddr;  \
        !            30:        if (use_mmu && TranslateRead() == false)        \
        !            31:                goto buserr;    \
        !            32:        uint64 data_ = mainbus->__CONCAT(Read,size)(bus.paddr); \
        !            33:        if ((int64)data_ < 0)   \
        !            34:                goto buserr;    \
        !            35:        data_;  /* これが戻り値 */        \
        !            36: })
        !            37: 
        !            38: #define WRITE(size, data)      ({      \
        !            39:        bus.paddr = bus.laddr;  \
        !            40:        if (use_mmu && TranslateWrite() == false)       \
        !            41:                goto buserr;    \
        !            42:        int64 berr_ = mainbus->__CONCAT(Write,size)(bus.paddr, (data)); \
        !            43:        if (berr_ < 0)  \
        !            44:                goto buserr;    \
        !            45:        0;      /* 戻り値不要だけど一応 */    \
        !            46: })
        !            47: 
        !            48: //
        !            49: // MMU を考慮した下請けテンプレート。
        !            50: // 1回分のミスアラインドありのアクセスを担当。
        !            51: //
        !            52: 
        !            53: template<bool use_mmu> uint32
        !            54: fetch_16_mmu()
        !            55: {
        !            56:        uint64 data;
        !            57: 
        !            58:        data = FETCH(16);
        !            59:        // XXX バスエラー時に PC をインクリメントするタイミングは?
        !            60:        reg.pc += 2;
        !            61: 
        !            62:        return data;
        !            63: 
        !            64:  buserr:
        !            65:        bus.SET_SSW(use_mmu, M68K::SSW_SIZE_WORD);
        !            66:        throw M68K::EXCEP_BUSERR;
        !            67: }
        !            68: 
        !            69: template<bool use_mmu> uint32
        !            70: fetch_32_mmu()
        !            71: {
        !            72:        uint64 data;
        !            73: 
        !            74:        if ((bus.laddr & 3) == 0) {
        !            75:                data = FETCH(32);
        !            76:        } else {
        !            77:                uint64 h, l;
        !            78: 
        !            79:                h = FETCH(16);
        !            80:                bus.laddr += 2;
        !            81: 
        !            82:                l = FETCH(16);
        !            83:                data = (h << 16) | l;
        !            84:        }
        !            85:        // XXX バスエラー時に PC をインクリメントするタイミングは?
        !            86:        reg.pc += 4;
        !            87:        return data;
        !            88: 
        !            89:  buserr:
        !            90:        bus.SET_SSW(use_mmu, M68K::SSW_SIZE_LONG);
        !            91:        throw M68K::EXCEP_BUSERR;
1.1       root       92: }
                     93: 
1.1.1.3 ! root       94: template<bool use_mmu> uint32
        !            95: read_8_mmu()
1.1       root       96: {
1.1.1.3 ! root       97:        uint64 data;
        !            98: 
        !            99:        data = READ(8);
        !           100: 
        !           101:        if (1)
        !           102:                putlog(2, "read_8   %08X -> %02X", bus.laddr, (uint32)data);
1.1       root      103:        return data;
1.1.1.3 ! root      104: 
        !           105:  buserr:
        !           106:        bus.SET_SSW(use_mmu, M68K::SSW_SIZE_BYTE);
        !           107:        throw M68K::EXCEP_BUSERR;
1.1       root      108: }
                    109: 
1.1.1.3 ! root      110: template<bool use_mmu> uint32
        !           111: read_16_mmu()
1.1       root      112: {
1.1.1.3 ! root      113:        uint64 data;
        !           114: 
        !           115:        if ((bus.laddr & 1) == 0) {
        !           116:                data = READ(16);
        !           117:        } else {
        !           118:                uint64 h, l;
        !           119: 
        !           120:                h = READ(8);
        !           121:                bus.laddr += 1;
        !           122: 
        !           123:                l = READ(8);
        !           124:                data = (h << 8) | l;
        !           125:        }
        !           126: 
        !           127:        if (1)
        !           128:                putlog(2, "read_16  %08X -> %04X", bus.laddr, (uint32)data);
1.1       root      129:        return data;
1.1.1.3 ! root      130: 
        !           131:  buserr:
        !           132:        bus.SET_SSW(use_mmu, M68K::SSW_SIZE_WORD);
        !           133:        throw M68K::EXCEP_BUSERR;
        !           134: }
        !           135: 
        !           136: template<bool use_mmu> uint32
        !           137: read_32_mmu()
        !           138: {
        !           139:        uint64 data;
        !           140: 
        !           141:        if ((bus.laddr & 3) == 0) {
        !           142:                data = READ(32);
        !           143:        } else if ((bus.laddr & 1) == 0) {
        !           144:                uint64 h, l;
        !           145: 
        !           146:                h = READ(16);
        !           147:                bus.laddr += 2;
        !           148: 
        !           149:                l = READ(16);
        !           150:                data = (h << 16) | l;
        !           151:        } else {
        !           152:                uint64 h, m, l;
        !           153: 
        !           154:                h = READ(8);
        !           155:                bus.laddr += 1;
        !           156: 
        !           157:                m = READ(16);
        !           158:                bus.laddr += 2;
        !           159: 
        !           160:                l = READ(8);
        !           161:                data = (h << 24) | (m << 8) | l;
        !           162:        }
        !           163: 
        !           164:        if (1)
        !           165:                putlog(2, "read_32  %08X -> %08X", bus.laddr, (uint32)data);
        !           166:        return data;
        !           167: 
        !           168:  buserr:
        !           169:        bus.SET_SSW(use_mmu, M68K::SSW_SIZE_LONG);
        !           170:        throw M68K::EXCEP_BUSERR;
        !           171: }
        !           172: 
        !           173: template<bool use_mmu> void
        !           174: write_8_mmu()
        !           175: {
        !           176:        uint32 data = bus.data;
        !           177: 
        !           178:        if (1)
        !           179:                putlog(2, "write_8  %08X <- %02X", bus.laddr, data);
        !           180: 
        !           181:        WRITE(8, data);
        !           182:        return;
        !           183: 
        !           184:  buserr:
        !           185:        bus.SET_SSW(use_mmu, M68K::SSW_SIZE_BYTE);
        !           186:        throw M68K::EXCEP_BUSERR;
        !           187: }
        !           188: 
        !           189: template<bool use_mmu> void
        !           190: write_16_mmu()
        !           191: {
        !           192:        uint32 data = bus.data;
        !           193: 
        !           194:        if (1)
        !           195:                putlog(2, "write_16 %08X <- %04X", bus.laddr, data);
        !           196: 
        !           197:        if ((bus.laddr & 1) == 0) {
        !           198:                WRITE(16, data);
        !           199:        } else {
        !           200:                WRITE(8, data >> 8);
        !           201: 
        !           202:                bus.laddr += 1;
        !           203:                WRITE(8, data & 0xff);
        !           204:        }
        !           205:        return;
        !           206: 
        !           207:  buserr:
        !           208:        bus.SET_SSW(use_mmu, M68K::SSW_SIZE_WORD);
        !           209:        throw M68K::EXCEP_BUSERR;
        !           210: }
        !           211: 
        !           212: template<bool use_mmu> void
        !           213: write_32_mmu()
        !           214: {
        !           215:        uint32 data = bus.data;
        !           216: 
        !           217:        if (1)
        !           218:                putlog(2, "write_32 %08X <- %08X", bus.laddr, data);
        !           219: 
        !           220:        if ((bus.laddr & 3) == 0) {
        !           221:                WRITE(32, data);
        !           222:        } else if ((bus.laddr & 1) == 0) {
        !           223:                WRITE(16, data >> 16);
        !           224: 
        !           225:                bus.laddr += 2;
        !           226:                WRITE(16, data & 0xffff);
        !           227:        } else {
        !           228:                WRITE(8, data >> 24);
        !           229: 
        !           230:                bus.laddr += 1;
        !           231:                WRITE(16, (data >> 8) & 0xffff);
        !           232: 
        !           233:                bus.laddr += 2;
        !           234:                WRITE(8, data & 0xff);
        !           235:        }
        !           236:        return;
        !           237: 
        !           238:  buserr:
        !           239:        bus.SET_SSW(use_mmu, M68K::SSW_SIZE_LONG);
        !           240:        throw M68K::EXCEP_BUSERR;
1.1       root      241: }

unix.superglobalmegacorp.com

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