Annotation of nono/m680x0/m680x0acc.cpp, revision 1.1

1.1     ! root        1: //
        !             2: // nono
        !             3: // Copyright (C) 2020 nono project
        !             4: // Licensed under nono-license.txt
        !             5: //
        !             6: 
        !             7: #include "mpu680x0.h"
        !             8: #include "m680x0acc.h"
        !             9: 
        !            10: /*static*/ inline uint32
        !            11: m680x0ACC::vflag_add_8(uint32 src, uint32 dst, uint32 res)
        !            12: {
        !            13:        return vflag_add_32(src, dst, res) << 24;
        !            14: }
        !            15: 
        !            16: /*static*/ inline uint32
        !            17: m680x0ACC::vflag_add_16(uint32 src, uint32 dst, uint32 res)
        !            18: {
        !            19:        return vflag_add_32(src, dst, res) << 16;
        !            20: }
        !            21: 
        !            22: /*static*/ inline uint32
        !            23: m680x0ACC::vflag_add_32(uint32 src, uint32 dst, uint32 res)
        !            24: {
        !            25:        return (src ^ res) & (dst ^ res);
        !            26: }
        !            27: 
        !            28: // src + dst を計算し、XNZVC フラグをセットして結果を返す。
        !            29: // src, dst の上位ビットはクリアしておくこと。
        !            30: // 戻り値の上位ビットはクリアされている。
        !            31: uint32
        !            32: m680x0ACC::add_8(uint32 src, uint32 dst)
        !            33: {
        !            34:        Z = dst + src;
        !            35:        C = Z >> 8;
        !            36:        X = C;
        !            37:        N = Z << 24;
        !            38:        Z &= 0xff;
        !            39:        V = vflag_add_8(src, dst, Z);
        !            40:        return Z;
        !            41: }
        !            42: 
        !            43: // src + dst を計算し、XNZVC フラグをセットして結果を返す。
        !            44: // src, dst の上位ビットはクリアしておくこと。
        !            45: // 戻り値の上位ビットはクリアされている。
        !            46: uint32
        !            47: m680x0ACC::add_16(uint32 src, uint32 dst)
        !            48: {
        !            49:        Z = dst + src;
        !            50:        C = Z >> 16;
        !            51:        X = C;
        !            52:        N = Z << 16;
        !            53:        Z &= 0xffff;
        !            54:        V = vflag_add_16(src, dst, Z);
        !            55:        return Z;
        !            56: }
        !            57: 
        !            58: // src + dst を計算し、XNZVC フラグをセットして結果を返す。
        !            59: uint32
        !            60: m680x0ACC::add_32(uint32 src, uint32 dst)
        !            61: {
        !            62:        CZ = (uint64)dst + (uint64)src;
        !            63:        X = C;
        !            64:        V = vflag_add_32(src, dst, Z);
        !            65:        N = Z;
        !            66:        return Z;
        !            67: }
        !            68: 
        !            69: // src + dst + X を計算し、XNZVC フラグをセットして結果を返す。
        !            70: // src, dst の上位ビットはクリアしておくこと。
        !            71: // 戻り値の上位ビットはクリアされている。
        !            72: uint32
        !            73: m680x0ACC::addx_8(uint32 src, uint32 dst)
        !            74: {
        !            75:        uint32 res = dst + src + (IsX() ? 1 : 0);
        !            76:        C = res >> 8;
        !            77:        X = C;
        !            78:        N = res << 24;
        !            79:        // 結果がゼロでなければ Z をクリア、結果がゼロなら Z は何もしない
        !            80:        if (N != 0) {
        !            81:                Z = N;
        !            82:        }
        !            83:        V = vflag_add_8(src, dst, res);
        !            84:        return res & 0xff;
        !            85: }
        !            86: 
        !            87: // src + dst + X を計算し、XNZVC フラグをセットして結果を返す。
        !            88: // src, dst の上位ビットはクリアしておくこと。
        !            89: // 戻り値の上位ビットはクリアされている。
        !            90: uint32
        !            91: m680x0ACC::addx_16(uint32 src, uint32 dst)
        !            92: {
        !            93:        uint32 res = dst + src + (IsX() ? 1 : 0);
        !            94:        C = res >> 16;
        !            95:        X = C;
        !            96:        N = res << 16;
        !            97:        // 結果がゼロでなければ Z をクリア、結果がゼロなら Z は何もしない
        !            98:        if (N != 0) {
        !            99:                Z = N;
        !           100:        }
        !           101:        V = vflag_add_16(src, dst, res);
        !           102:        return res & 0xffff;
        !           103: }
        !           104: 
        !           105: // src + dst + X を計算し、XNZVC フラグをセットして結果を返す。
        !           106: uint32
        !           107: m680x0ACC::addx_32(uint32 src, uint32 dst)
        !           108: {
        !           109:        uint64 res = (uint64)dst + (uint64)src + (IsX() ? 1 : 0);
        !           110:        C = res >> 32;
        !           111:        X = C;
        !           112:        N = res;
        !           113:        // 結果がゼロでなければ Z をクリア、結果がゼロなら Z は何もしない
        !           114:        if (N != 0) {
        !           115:                Z = N;
        !           116:        }
        !           117:        V = vflag_add_32(src, dst, res);
        !           118:        return res;
        !           119: }
        !           120: 
        !           121: 
        !           122: /*static*/ inline uint32
        !           123: m680x0ACC::vflag_sub_8(uint32 src, uint32 dst, uint32 res)
        !           124: {
        !           125:        return vflag_sub_32(src, dst, res) << 24;
        !           126: }
        !           127: 
        !           128: /*static*/ inline uint32
        !           129: m680x0ACC::vflag_sub_16(uint32 src, uint32 dst, uint32 res)
        !           130: {
        !           131:        return vflag_sub_32(src, dst, res) << 16;
        !           132: }
        !           133: 
        !           134: /*static*/ inline uint32
        !           135: m680x0ACC::vflag_sub_32(uint32 src, uint32 dst, uint32 res)
        !           136: {
        !           137:        return (src ^ dst) & (dst ^ res);
        !           138: }
        !           139: 
        !           140: // dst - src を計算し、NZVC フラグをセットして結果を返す。
        !           141: // src, dst の上位ビットはクリアしておくこと。
        !           142: // 戻り値の上位ビットはクリアされている。
        !           143: uint32
        !           144: m680x0ACC::cmp_8(uint32 src, uint32 dst)
        !           145: {
        !           146:        Z = dst - src;
        !           147:        C = Z >> 8;
        !           148:        N = Z << 24;
        !           149:        Z &= 0xff;
        !           150:        V = vflag_sub_8(src, dst, Z);
        !           151:        return Z;
        !           152: }
        !           153: 
        !           154: // dst - src を計算し、NZVC フラグをセットして結果を返す。
        !           155: // src, dst の上位ビットはクリアしておくこと。
        !           156: // 戻り値の上位ビットはクリアされている。
        !           157: uint32
        !           158: m680x0ACC::cmp_16(uint32 src, uint32 dst)
        !           159: {
        !           160:        Z = dst - src;
        !           161:        C = Z >> 16;
        !           162:        N = Z << 16;
        !           163:        Z &= 0xffff;
        !           164:        V = vflag_sub_16(src, dst, Z);
        !           165:        return Z;
        !           166: }
        !           167: 
        !           168: // dst - src を計算し、NZVC フラグをセットして結果を返す。
        !           169: uint32
        !           170: m680x0ACC::cmp_32(uint32 src, uint32 dst)
        !           171: {
        !           172:        CZ = (uint64)dst - (uint64)src;
        !           173:        N = Z;
        !           174:        V = vflag_sub_32(src, dst, Z);
        !           175:        return Z;
        !           176: }
        !           177: 
        !           178: // dst - src を計算し、XNZVC フラグをセットして結果を返す。
        !           179: // src, dst の上位ビットはクリアしておくこと。
        !           180: // 戻り値の上位ビットはクリアされている。
        !           181: uint32
        !           182: m680x0ACC::sub_8(uint32 src, uint32 dst)
        !           183: {
        !           184:        uint32 res = cmp_8(src, dst);
        !           185:        X = C;
        !           186:        return res;
        !           187: }
        !           188: 
        !           189: // dst - src を計算し、XNZVC フラグをセットして結果を返す。
        !           190: // src, dst の上位ビットはクリアしておくこと。
        !           191: // 戻り値の上位ビットはクリアされている。
        !           192: uint32
        !           193: m680x0ACC::sub_16(uint32 src, uint32 dst)
        !           194: {
        !           195:        uint32 res = cmp_16(src, dst);
        !           196:        X = C;
        !           197:        return res;
        !           198: }
        !           199: 
        !           200: // dst - src を計算し、XNZVC フラグをセットして結果を返す。
        !           201: uint32
        !           202: m680x0ACC::sub_32(uint32 src, uint32 dst)
        !           203: {
        !           204:        uint32 res = cmp_32(src, dst);
        !           205:        X = C;
        !           206:        return res;
        !           207: }
        !           208: 
        !           209: // src - dst - X を計算し、XNZVC フラグをセットして結果を返す。
        !           210: // src, dst の上位ビットはクリアしておくこと。
        !           211: // 戻り値 res の上位ビットはクリアされている。
        !           212: uint32
        !           213: m680x0ACC::subx_8(uint32 src, uint32 dst)
        !           214: {
        !           215:        uint32 res = dst - src - (IsX() ? 1 : 0);
        !           216:        C = res >> 8;
        !           217:        X = C;
        !           218:        N = res << 24;
        !           219:        // 結果がゼロでなければ Z をクリア、結果がゼロなら Z は何もしない
        !           220:        if (N != 0) {
        !           221:                Z = N;
        !           222:        }
        !           223:        V = vflag_sub_8(src, dst, res);
        !           224:        return res & 0xff;
        !           225: }
        !           226: 
        !           227: // src - dst - X を計算し、XNZVC フラグをセットして結果を返す。
        !           228: // src, dst の上位ビットはクリアしておくこと。
        !           229: // 戻り値 res の上位ビットはクリアされている。
        !           230: uint32
        !           231: m680x0ACC::subx_16(uint32 src, uint32 dst)
        !           232: {
        !           233:        uint32 res = dst - src - (IsX() ? 1 : 0);
        !           234:        C = res >> 16;
        !           235:        X = C;
        !           236:        N = res << 16;
        !           237:        // 結果がゼロでなければ Z をクリア、結果がゼロなら Z は何もしない
        !           238:        if (N != 0) {
        !           239:                Z = N;
        !           240:        }
        !           241:        V = vflag_sub_16(src, dst, res);
        !           242:        return res & 0xffff;
        !           243: }
        !           244: 
        !           245: // src - dst - X を計算し、XNZVC フラグをセットして結果を返す。
        !           246: uint32
        !           247: m680x0ACC::subx_32(uint32 src, uint32 dst)
        !           248: {
        !           249:        uint64 res = (uint64)dst - (uint64)src - (IsX() ? 1 : 0);
        !           250:        C = res >> 32;
        !           251:        X = C;
        !           252:        N = res;
        !           253:        // 結果がゼロでなければ Z をクリア、結果がゼロなら Z は何もしない
        !           254:        if (N != 0) {
        !           255:                Z = N;
        !           256:        }
        !           257:        V = vflag_sub_32(src, dst, res);
        !           258:        return res;
        !           259: }
        !           260: 
        !           261: // src(u16) * dst(u16) を計算し、NZVC フラグをセットして結果(u32)を返す。
        !           262: // src, dst の上位ビットはクリアしておくこと。
        !           263: uint32
        !           264: m680x0ACC::mulu_16(uint32 src, uint32 dst)
        !           265: {
        !           266:        uint32 res = src * dst;
        !           267:        // 16x16->32 ではオーバーフローは起きないので move でよい
        !           268:        move_32(res);
        !           269:        return res;
        !           270: }
        !           271: 
        !           272: // src(s16) * dst(s16) を計算し、NZVC フラグをセットして結果(u32)を返す。
        !           273: // src, dst の上位ビットはクリアしておくこと。
        !           274: uint32
        !           275: m680x0ACC::muls_16(uint32 src, uint32 dst)
        !           276: {
        !           277:        int32 res = (int32)(int16)src * (int32)(int16)dst;
        !           278:        // 16x16->32 ではオーバーフローは起きないので move でよい
        !           279:        move_32(res);
        !           280:        return res;
        !           281: }
        !           282: 
        !           283: // src(u32) * dst(u32) を計算し、NZVC フラグをセットして結果(32bit)を返す。
        !           284: uint32
        !           285: m680x0ACC::mulu_32(uint32 src, uint32 dst)
        !           286: {
        !           287:        uint64 res = (uint64)src * (uint64)dst;
        !           288:        Z = res;
        !           289:        N = res;
        !           290:        C = 0;
        !           291:        if (res > 0xffffffffUL) {
        !           292:                V = V_BIT;
        !           293:        } else {
        !           294:                V = 0;
        !           295:        }
        !           296:        return (uint32)res;
        !           297: }
        !           298: 
        !           299: // src(s32) * dst(s32) を計算し、NZVC フラグをセットして結果(32bit)を返す。
        !           300: uint32
        !           301: m680x0ACC::muls_32(uint32 src, uint32 dst)
        !           302: {
        !           303:        int64 res = (int64)(int32)src * (int64)(int32)dst;
        !           304:        Z = res;
        !           305:        N = res;
        !           306:        C = 0;
        !           307:        // V フラグは64ビット演算結果の上位32ビットが
        !           308:        // 下位32ビットの符号拡張になっていなかった場合に立つ。
        !           309:        // つまり符号付き整数で 32bit 表現と 64bit 表現が一致していなければ立つ。
        !           310:        int32 tmp = res;
        !           311:        if (res != tmp) {
        !           312:                V = V_BIT;
        !           313:        } else {
        !           314:                V = 0;
        !           315:        }
        !           316:        return (uint32)res;
        !           317: }
        !           318: 
        !           319: // src(u32) * dst(u32) を計算し、NZVC フラグをセットして結果(64bit)を返す。
        !           320: uint64
        !           321: m680x0ACC::mulu_64(uint32 src, uint32 dst)
        !           322: {
        !           323:        uint64 res = (uint64)src * (uint64)dst;
        !           324:        N = res >> 32;
        !           325:        Z = N | res;
        !           326:        V = 0;
        !           327:        C = 0;
        !           328:        return res;
        !           329: }
        !           330: 
        !           331: // src(s32) * dst(s32) を計算し、NZVC フラグをセットして結果(64bit)を返す。
        !           332: uint64
        !           333: m680x0ACC::muls_64(uint32 src, uint32 dst)
        !           334: {
        !           335:        int64 res = (int64)(int32)src * (int64)(int32)dst;
        !           336:        N = res >> 32;
        !           337:        Z = N | res;
        !           338:        V = 0;
        !           339:        C = 0;
        !           340:        return res;
        !           341: }
        !           342: 
        !           343: void
        !           344: m680x0ACC::btst(uint32 data, int n)
        !           345: {
        !           346:        Z = data & (1 << n);
        !           347: }
        !           348: 
        !           349: uint32
        !           350: m680x0ACC::bchg(uint32 data, int n)
        !           351: {
        !           352:        Z = data & (1 << n);
        !           353:        data ^= (1 << n);
        !           354:        return data;
        !           355: }
        !           356: 
        !           357: uint32
        !           358: m680x0ACC::bclr(uint32 data, int n)
        !           359: {
        !           360:        Z = data & (1 << n);
        !           361:        data &= ~(1 << n);
        !           362:        return data;
        !           363: }
        !           364: 
        !           365: uint32
        !           366: m680x0ACC::bset(uint32 data, int n)
        !           367: {
        !           368:        Z = data & (1 << n);
        !           369:        data |= (1 << n);
        !           370:        return data;
        !           371: }
        !           372: 
        !           373: 
        !           374: // data を count ビット算術左シフトし、XNZVC フラグを反映して結果を返す。
        !           375: // count は 0..63。data の上位はクリアしておくこと。
        !           376: uint32
        !           377: m680x0ACC::asl_8(uint32 data, int count)
        !           378: {
        !           379:        if (count == 0) {
        !           380:                move_8(data);
        !           381:                return data;
        !           382:        }
        !           383:        int64 tmps = (int64)(int8)data;
        !           384:        if (count > 8) count = 9;
        !           385:        uint64 tmp = (uint64)tmps << count;
        !           386:        X = C = tmp >> 8;
        !           387:        N = tmp << 24;
        !           388:        Z = N;
        !           389:        // 送り出された全てのビットが元の MSB と一致すれば V=0
        !           390:        SetV(((int64)tmp >> 7) != (tmps >> 8));
        !           391:        return tmp & 0xff;
        !           392: }
        !           393: 
        !           394: // data を count ビット算術左シフトし、XNZVC フラグを反映して結果を返す。
        !           395: // count は 0..63。data の上位はクリアしておくこと。
        !           396: uint32
        !           397: m680x0ACC::asl_16(uint32 data, int count)
        !           398: {
        !           399:        if (count == 0) {
        !           400:                move_16(data);
        !           401:                return data;
        !           402:        }
        !           403:        int64 tmps = (int64)(int16)data;
        !           404:        if (count > 16) count = 17;
        !           405:        uint64 tmp = (uint64)tmps << count;
        !           406:        X = C = tmp >> 16;
        !           407:        N = tmp << 16;
        !           408:        Z = N;
        !           409:        // 送り出された全てのビットが元の MSB と一致すれば V=0
        !           410:        SetV(((int64)tmp >> 15) != (tmps >> 16));
        !           411:        return tmp & 0xffff;
        !           412: }
        !           413: 
        !           414: // data を count ビット算術左シフトし、XNZVC フラグを反映して結果を返す。
        !           415: // count は 0..63
        !           416: uint32
        !           417: m680x0ACC::asl_32(uint32 data, int count)
        !           418: {
        !           419:        if (count == 0) {
        !           420:                move_32(data);
        !           421:                return data;
        !           422:        }
        !           423:        int64 tmps = (int64)(int32)data;
        !           424:        if (count > 32) count = 33;
        !           425:        uint64 tmp = (uint64)tmps << count;
        !           426:        X = C = tmp >> 32;
        !           427:        N = Z = tmp;
        !           428:        // 送り出された全てのビットが元の MSB と一致すれば V=0
        !           429:        SetV(((int64)tmp >> 31) != (tmps >> 32));
        !           430:        return tmp;
        !           431: }
        !           432: 
        !           433: // data を count ビット左シフトし、NZVC フラグを反映して結果を返す。
        !           434: // count は 0..63。data の上位はクリアしておくこと。
        !           435: uint32
        !           436: m680x0ACC::lsl_8(uint32 data, int count)
        !           437: {
        !           438:        if (count == 0) {
        !           439:                move_8(data);
        !           440:                return data;
        !           441:        }
        !           442:        uint64 tmp = (uint64)data << count;
        !           443:        X = C = tmp >> 8;
        !           444:        N = tmp << 24;
        !           445:        Z = tmp & 0xff;
        !           446:        V = 0;
        !           447:        return Z;
        !           448: }
        !           449: 
        !           450: // data を count ビット左シフトし、NZVC フラグを反映して結果を返す。
        !           451: // count は 0..63。data の上位はクリアしておくこと。
        !           452: uint32
        !           453: m680x0ACC::lsl_16(uint32 data, int count)
        !           454: {
        !           455:        if (count == 0) {
        !           456:                move_16(data);
        !           457:                return data;
        !           458:        }
        !           459:        uint64 tmp = (uint64)data << count;
        !           460:        X = C = tmp >> 16;
        !           461:        N = tmp << 16;
        !           462:        Z = tmp & 0xffff;
        !           463:        V = 0;
        !           464:        return Z;
        !           465: }
        !           466: 
        !           467: // data を count ビット左シフトし、NZVC フラグを反映して結果を返す。
        !           468: // count は 0..63
        !           469: uint32
        !           470: m680x0ACC::lsl_32(uint32 data, int count)
        !           471: {
        !           472:        if (count == 0) {
        !           473:                move_32(data);
        !           474:                return data;
        !           475:        }
        !           476:        uint64 tmp = (uint64)data << count;
        !           477:        X = C = tmp >> 32;
        !           478:        N = tmp;
        !           479:        Z = tmp;
        !           480:        V = 0;
        !           481:        return Z;
        !           482: }
        !           483: 
        !           484: // data:X を count ビット左ローテートし、XNZVC フラグを反映して結果を返す。
        !           485: // count は 0..63
        !           486: uint32
        !           487: m680x0ACC::roxl_8(uint32 data, int count)
        !           488: {
        !           489:        count %= 9;
        !           490:        if (count == 0) {
        !           491:                Z = data;
        !           492:                N = data << 24;
        !           493:                V = 0;
        !           494:                C = X;
        !           495:                return Z;
        !           496:        }
        !           497:        uint32 xbit = X & 1;
        !           498:        Z = (data << count) | (data >> (9 - count)) | (xbit << (count - 1));
        !           499:        C = X = Z >> 8;
        !           500:        Z &= 0xff;
        !           501:        N = Z << 24;
        !           502:        V = 0;
        !           503:        return Z;
        !           504: }
        !           505: 
        !           506: // data:X を count ビット左ローテートし、XNZVC フラグを反映して結果を返す。
        !           507: // count は 0..63
        !           508: uint32
        !           509: m680x0ACC::roxl_16(uint32 data, int count)
        !           510: {
        !           511:        count %= 17;
        !           512:        if (count == 0) {
        !           513:                Z = data;
        !           514:                N = data << 16;
        !           515:                V = 0;
        !           516:                C = X;
        !           517:                return Z;
        !           518:        }
        !           519:        uint32 xbit = X & 1;
        !           520:        Z = (data << count) | (data >> (17 - count)) | (xbit << (count - 1));
        !           521:        C = X = Z >> 16;
        !           522:        Z &= 0xffff;
        !           523:        N = Z << 16;
        !           524:        V = 0;
        !           525:        return Z;
        !           526: }
        !           527: 
        !           528: // data:X を count ビット左ローテートし、XNZVC フラグを反映して結果を返す。
        !           529: // count は 0..63
        !           530: uint32
        !           531: m680x0ACC::roxl_32(uint32 data, int count)
        !           532: {
        !           533:        count %= 33;
        !           534:        if (count == 0) {
        !           535:                Z = data;
        !           536:                N = data;
        !           537:                V = 0;
        !           538:                C = X;
        !           539:                return Z;
        !           540:        }
        !           541:        // 32bit値の 32ビットシフトは未定義動作なので 64bit値を使用
        !           542:        uint64 data64 = data;
        !           543:        uint32 xbit = X & 1;
        !           544:        Z = (data64 << count) | (data64 >> (33 - count)) | (xbit << (count - 1));
        !           545:        C = X = data64 >> (32 - count);
        !           546:        N = Z;
        !           547:        V = 0;
        !           548:        return Z;
        !           549: }
        !           550: 
        !           551: // data を count ビット左ローテートし、NZVC フラグを反映して結果を返す。
        !           552: // count は 0..63。data の上位はクリアしておくこと
        !           553: uint32
        !           554: m680x0ACC::rol_8(uint32 data, int count)
        !           555: {
        !           556:        if (count == 0) {
        !           557:                move_8(data);
        !           558:                return data;
        !           559:        }
        !           560: 
        !           561:        count %= 8;
        !           562:        int count2 = (8 - count) % 8;
        !           563:        uint8 tmp = (data << count) | (data >> count2);
        !           564:        Z = tmp;
        !           565:        N = (uint32)tmp << 24;
        !           566:        C = data >> count2;
        !           567:        V = 0;
        !           568:        return Z;
        !           569: }
        !           570: 
        !           571: // data を count ビット左ローテートし、NZVC フラグを反映して結果を返す。
        !           572: // count は 0..63。data の上位はクリアしておくこと
        !           573: uint32
        !           574: m680x0ACC::rol_16(uint32 data, int count)
        !           575: {
        !           576:        if (count == 0) {
        !           577:                move_16(data);
        !           578:                return data;
        !           579:        }
        !           580: 
        !           581:        count %= 16;
        !           582:        int count2 = (16 - count) % 16;
        !           583:        uint16 tmp = (data << count) | (data >> count2);
        !           584:        Z = tmp;
        !           585:        N = (uint32)tmp << 16;
        !           586:        C = data >> count2;
        !           587:        V = 0;
        !           588:        return Z;
        !           589: }
        !           590: 
        !           591: // data を count ビット左ローテートし、NZVC フラグを反映して結果を返す。
        !           592: // count は 0..63
        !           593: uint32
        !           594: m680x0ACC::rol_32(uint32 data, int count)
        !           595: {
        !           596:        if (count == 0) {
        !           597:                move_32(data);
        !           598:                return data;
        !           599:        }
        !           600: 
        !           601:        count %= 32;
        !           602:        int count2 = (32 - count) % 32;
        !           603:        uint64 data64 = (uint64)data;
        !           604:        uint64 tmp = (data << count) | (data >> count2);
        !           605:        Z = tmp;
        !           606:        N = Z;
        !           607:        C = data64 >> count2;
        !           608:        V = 0;
        !           609:        return Z;
        !           610: }
        !           611: 
        !           612: // data を count ビット算術右シフトし、XNZVC フラグを反映して結果を返す。
        !           613: // count は 0..64。data の上位はクリアしておくこと。
        !           614: uint32
        !           615: m680x0ACC::asr_8(uint32 data, int count)
        !           616: {
        !           617:        if (count == 0) {
        !           618:                move_8(data);
        !           619:                return data;
        !           620:        }
        !           621:        if (count > 8) {
        !           622:                if ((int8)data < 0) {
        !           623:                        data = 0xff;
        !           624:                } else {
        !           625:                        data = 0;
        !           626:                }
        !           627:                X = C = Z = data;
        !           628:                N = data << 24;
        !           629:                V = 0;
        !           630:                return data;
        !           631:        }
        !           632:        // data >>> count の結果が tmp の上位32ビット中の下位8ビットに入る
        !           633:        uint64 tmp = (uint64)(int64)(int8)data << (32 - count);
        !           634:        X = C = tmp >> 31;
        !           635:        N = tmp >> 8;
        !           636:        Z = (tmp >> 32) & 0xff;
        !           637:        V = 0;
        !           638:        return Z;
        !           639: }
        !           640: 
        !           641: // data を count ビット算術右シフトし、XNZVC フラグを反映して結果を返す。
        !           642: // count は 0..64。data の上位はクリアしておくこと。
        !           643: uint32
        !           644: m680x0ACC::asr_16(uint32 data, int count)
        !           645: {
        !           646:        if (count == 0) {
        !           647:                move_16(data);
        !           648:                return data;
        !           649:        }
        !           650:        if (count > 16) {
        !           651:                if ((int16)data < 0) {
        !           652:                        data = 0xffff;
        !           653:                } else {
        !           654:                        data = 0;
        !           655:                }
        !           656:                X = C = Z = data;
        !           657:                N = data << 16;
        !           658:                V = 0;
        !           659:                return data;
        !           660:        }
        !           661:        // data >>> count の結果が tmp の上位32ビット中の下位16ビットに入る
        !           662:        uint64 tmp = (uint64)(int64)(int16)data << (32 - count);
        !           663:        X = C = tmp >> 31;
        !           664:        N = tmp >> 16;
        !           665:        Z = (tmp >> 32) & 0xffff;
        !           666:        V = 0;
        !           667:        return Z;
        !           668: }
        !           669: 
        !           670: // data を count ビット算術右シフトし、XNZVC フラグを反映して結果を返す。
        !           671: // count は 0..64
        !           672: uint32
        !           673: m680x0ACC::asr_32(uint32 data, int count)
        !           674: {
        !           675:        if (count == 0) {
        !           676:                move_32(data);
        !           677:                return data;
        !           678:        }
        !           679:        if (count > 32) {
        !           680:                if ((int32)data < 0) {
        !           681:                        data = 0xffffffff;
        !           682:                } else {
        !           683:                        data = 0;
        !           684:                }
        !           685:                X = C = Z = data;
        !           686:                N = data;
        !           687:                V = 0;
        !           688:                return data;
        !           689:        }
        !           690:        // data >>> count の結果が tmp の上位32ビットに入る
        !           691:        uint64 tmp = (uint64)(int64)(int32)data << (32 - count);
        !           692:        X = C = tmp >> 31;
        !           693:        Z = N = tmp >> 32;
        !           694:        V = 0;
        !           695:        return Z;
        !           696: }
        !           697: 
        !           698: // data を count ビット論理右シフトし、XNZVC フラグを反映して結果を返す。
        !           699: // count は 0..63
        !           700: uint32
        !           701: m680x0ACC::lsr_8(uint32 data, int count)
        !           702: {
        !           703:        if (count == 0) {
        !           704:                move_8(data);
        !           705:                return data;
        !           706:        }
        !           707:        if (count > 8) {
        !           708:                X = C = 0;
        !           709:                move_8(0);
        !           710:                return 0;
        !           711:        }
        !           712:        // data >> count の結果が tmp の上位32ビットに入る
        !           713:        uint64 tmp = (uint64)data << (32 - count);
        !           714:        X = C = tmp >> 31;
        !           715:        N = tmp >> 8;
        !           716:        Z = (tmp >> 32) & 0xff;
        !           717:        V = 0;
        !           718:        return Z;
        !           719: }
        !           720: 
        !           721: // data を count ビット論理右シフトし、XNZVC フラグを反映して結果を返す。
        !           722: // count は 0..63
        !           723: uint32
        !           724: m680x0ACC::lsr_16(uint32 data, int count)
        !           725: {
        !           726:        if (count == 0) {
        !           727:                move_16(data);
        !           728:                return data;
        !           729:        }
        !           730:        if (count > 16) {
        !           731:                X = C = 0;
        !           732:                move_16(0);
        !           733:                return 0;
        !           734:        }
        !           735:        // data >> count の結果が tmp の上位32ビットに入る
        !           736:        uint64 tmp = (uint64)data << (32 - count);
        !           737:        X = C = tmp >> 31;
        !           738:        N = tmp >> 16;
        !           739:        Z = (tmp >> 32) & 0xffff;
        !           740:        V = 0;
        !           741:        return Z;
        !           742: }
        !           743: 
        !           744: // data を count ビット論理右シフトし、XNZVC フラグを反映して結果を返す。
        !           745: // count は 0..63
        !           746: uint32
        !           747: m680x0ACC::lsr_32(uint32 data, int count)
        !           748: {
        !           749:        if (count == 0) {
        !           750:                move_32(data);
        !           751:                return data;
        !           752:        }
        !           753:        if (count > 32) {
        !           754:                X = C = 0;
        !           755:                move_32(0);
        !           756:                return 0;
        !           757:        }
        !           758:        // data >> count の結果が tmp の上位32ビットに入る
        !           759:        uint64 tmp = (uint64)data << (32 - count);
        !           760:        X = C = tmp >> 31;
        !           761:        Z = N = tmp >> 32;
        !           762:        V = 0;
        !           763:        return Z;
        !           764: }
        !           765: 
        !           766: // data:C を count ビット右ローテートし、NZVC フラグを反映して結果を返す。
        !           767: // count は 0..63
        !           768: uint32
        !           769: m680x0ACC::roxr_8(uint32 data, int count)
        !           770: {
        !           771:        count %= 9;
        !           772:        if (count == 0) {
        !           773:                Z = data;
        !           774:                N = data << 24;
        !           775:                V = 0;
        !           776:                C = X;
        !           777:                return Z;
        !           778:        }
        !           779:        uint32 rot = data & ((1 << (count - 1)) - 1);
        !           780:        uint32 xbit = X & 1;
        !           781:        Z = (data >> count) | (rot << (9 - count)) | (xbit << (8 - count));
        !           782:        C = X = data >> (count - 1);
        !           783:        N = Z << 24;
        !           784:        V = 0;
        !           785:        return Z;
        !           786: }
        !           787: 
        !           788: // data:C を count ビット右ローテートし、NZVC フラグを反映して結果を返す。
        !           789: // count は 0..63
        !           790: uint32
        !           791: m680x0ACC::roxr_16(uint32 data, int count)
        !           792: {
        !           793:        count %= 17;
        !           794:        if (count == 0) {
        !           795:                Z = data;
        !           796:                N = data << 16;
        !           797:                V = 0;
        !           798:                C = X;
        !           799:                return Z;
        !           800:        }
        !           801:        uint32 rot = data & ((1 << (count - 1)) - 1);
        !           802:        uint32 xbit = X & 1;
        !           803:        Z = (data >> count) | (rot << (17 - count)) | (xbit << (16 - count));
        !           804:        C = X = data >> (count - 1);
        !           805:        N = Z << 16;
        !           806:        V = 0;
        !           807:        return Z;
        !           808: }
        !           809: 
        !           810: // data:C を count ビット右ローテートし、NZVC フラグを反映して結果を返す。
        !           811: // count は 0..63
        !           812: uint32
        !           813: m680x0ACC::roxr_32(uint32 data, int count)
        !           814: {
        !           815:        count %= 33;
        !           816:        if (count == 0) {
        !           817:                Z = data;
        !           818:                N = data;
        !           819:                V = 0;
        !           820:                C = X;
        !           821:                return Z;
        !           822:        }
        !           823:        // 32bit値の 32ビットシフトは未定義動作なので 64bit値を使用
        !           824:        uint64 data64 = data;
        !           825:        uint64 rot = data64 & ((1 << (count - 1)) - 1);
        !           826:        uint32 xbit = X & 1;
        !           827:        Z = (data64 >> count) | (rot << (33 - count)) | (xbit << (32 - count));
        !           828:        C = X = data64 >> (count - 1);
        !           829:        N = Z;
        !           830:        V = 0;
        !           831:        return Z;
        !           832: }
        !           833: 
        !           834: // data を count ビット右ローテートし、NZVC フラグを反映して結果を返す。
        !           835: // count は 0..63
        !           836: uint32
        !           837: m680x0ACC::ror_8(uint32 data, int count)
        !           838: {
        !           839:        if (count == 0) {
        !           840:                move_8(data);
        !           841:                return data;
        !           842:        }
        !           843: 
        !           844:        count %= 8;
        !           845:        uint8 tmp = (data >> count) | (data << (8 - count));
        !           846:        Z = tmp;
        !           847:        N = (uint32)tmp << 24;
        !           848:        // 7 0 1 2 3 4 5 6
        !           849:        C = data >> ((count + 7) % 8);
        !           850:        V = 0;
        !           851:        return tmp;
        !           852: }
        !           853: 
        !           854: // data を count ビット右ローテートし、NZVC フラグを反映して結果を返す。
        !           855: // count は 0..63
        !           856: uint32
        !           857: m680x0ACC::ror_16(uint32 data, int count)
        !           858: {
        !           859:        if (count == 0) {
        !           860:                move_16(data);
        !           861:                return data;
        !           862:        }
        !           863: 
        !           864:        count %= 16;
        !           865:        uint16 tmp = (data >> count) | (data << (16 - count));
        !           866:        Z = tmp;
        !           867:        N = (uint32)tmp << 16;
        !           868:        C = data >> ((count + 15) % 16);
        !           869:        V = 0;
        !           870:        return tmp;
        !           871: }
        !           872: 
        !           873: // data を count ビット右ローテートし、NZVC フラグを反映して結果を返す。
        !           874: // count は 0..63
        !           875: uint32
        !           876: m680x0ACC::ror_32(uint32 data, int count)
        !           877: {
        !           878:        if (count == 0) {
        !           879:                move_32(data);
        !           880:                return data;
        !           881:        }
        !           882: 
        !           883:        count %= 32;
        !           884:        uint64 data64 = (uint64)data;
        !           885:        uint64 tmp = (data >> count) | (data << (32 - count));
        !           886:        Z = tmp;
        !           887:        N = tmp;
        !           888:        C = data64 >> ((count + 31) % 32);
        !           889:        V = 0;
        !           890:        return tmp;
        !           891: }
        !           892: 
        !           893: void
        !           894: m680x0ACC::chk2cmp2_32(uint32 compare, uint32 lower, uint32 upper)
        !           895: {
        !           896:        // 実機の実行結果をじっと睨んだ結果、このロジックで
        !           897:        // cmp2 は実行していると考えられる。
        !           898:        // オペランド順はフラグに影響する。
        !           899:        // なぜ 68k のデザイナが順序を入れ替えたのかは不明。
        !           900:        // なんかの都合があったんだろうな...
        !           901: 
        !           902:        // この cmp は通常の if で代替できるけど、
        !           903:        // あえて MPU 内部の動作をエミュレート。
        !           904:        cmp_32(lower, upper);
        !           905: 
        !           906:        if (CondCS()) {
        !           907:                cmp_32(compare, upper);
        !           908:                if (CondEQ()) {
        !           909:                        // break
        !           910:                } else if (CondCS()) {
        !           911:                        cmp_32(lower, compare);
        !           912:                } else {
        !           913:                        cmp_32(compare, lower);
        !           914:                }
        !           915:        } else {
        !           916:                cmp_32(lower, compare);
        !           917:                if (CondEQ()) {
        !           918:                        // break
        !           919:                } else if (CondCS()) {
        !           920:                        // break
        !           921:                } else {
        !           922:                        cmp_32(compare, upper);
        !           923:                }
        !           924:        }
        !           925: }
        !           926: 
        !           927: // src_10 + dst_10 + X を計算し、XNZVC フラグをセットして結果を返す。
        !           928: // src, dst の上位ビットはクリアしておくこと。
        !           929: // 戻り値の上位ビットはクリアされている。
        !           930: uint32
        !           931: m680x0ACC::abcd_8(uint32 src, uint32 dst)
        !           932: {
        !           933:        uint32 res;
        !           934:        uint32 tmp;
        !           935:        uint32 adj;
        !           936:        uint32 low;
        !           937:        uint32 cbit;
        !           938: 
        !           939:        adj = 0;
        !           940:        cbit = 0;
        !           941: 
        !           942:        // X フラグは LSB なので直接足してよい
        !           943:        tmp = src + dst + (X & X_BIT);
        !           944: 
        !           945:        low = (src & 0x0f) + (dst & 0x0f) + (X & X_BIT);
        !           946:        if (low > 0x09) {
        !           947:                adj = 0x06;
        !           948:        }
        !           949: 
        !           950:        if (tmp > 0x99) {
        !           951:                adj += 0x60;
        !           952:                cbit = C_BIT;
        !           953:        }
        !           954: 
        !           955:        res = tmp + adj;
        !           956:        cbit |= res >> 8;
        !           957:        X = C = cbit;
        !           958: 
        !           959:        res &= 0xff;
        !           960:        Z |= res;
        !           961: 
        !           962:        // V フラグは不定だが 68030 では常にクリア
        !           963:        V = 0;
        !           964:        // N フラグは不定だが 68030 実機合わせ
        !           965:        N = res << 24;
        !           966: 
        !           967:        return res;
        !           968: }
        !           969: 
        !           970: // src_10 - dst_10 - X を計算し、XNZVC フラグをセットして結果を返す。
        !           971: // src, dst の上位ビットはクリアしておくこと。
        !           972: // 戻り値の上位ビットはクリアされている。
        !           973: uint32
        !           974: m680x0ACC::sbcd_8(uint32 src, uint32 dst)
        !           975: {
        !           976:        uint32 res;
        !           977:        int32 tmp;
        !           978:        int32 adj;
        !           979:        int32 low;
        !           980:        uint32 cbit;
        !           981: 
        !           982:        adj = 0;
        !           983:        cbit = 0;
        !           984: 
        !           985:        // X フラグは LSB なので直接引いてよい
        !           986:        tmp = dst - src - (X & X_BIT);
        !           987: 
        !           988:        low = (dst & 0x0f) - (src & 0x0f) - (X & X_BIT);
        !           989:        if (low < 0) {
        !           990:                adj = 0x06;
        !           991:        }
        !           992: 
        !           993:        if (tmp < 0) {
        !           994:                adj += 0x60;
        !           995:                cbit = C_BIT;
        !           996:        }
        !           997: 
        !           998:        res = tmp - adj;
        !           999:        cbit |= res >> 8;
        !          1000:        X = C = cbit;
        !          1001: 
        !          1002:        res &= 0xff;
        !          1003:        Z |= res;
        !          1004: 
        !          1005:        // V フラグは不定だが 68030 では常にクリア
        !          1006:        V = 0;
        !          1007:        // N フラグは不定だが 68030 実機合わせ
        !          1008:        N = res << 24;
        !          1009: 
        !          1010:        return res;
        !          1011: }

unix.superglobalmegacorp.com

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