Annotation of nono/hd64180/hd64180acc.cpp, revision 1.1

1.1     ! root        1: //
        !             2: // nono
        !             3: // Copyright (C) 2022 nono project
        !             4: // Licensed under nono-license.txt
        !             5: //
        !             6: 
        !             7: //
        !             8: // HD64180 演算部分
        !             9: //
        !            10: 
        !            11: #include "hd64180acc.h"
        !            12: 
        !            13: /*static*/ inline uint32
        !            14: hd64180acc::vflag_add(uint32 dst, uint32 src, uint32 res)
        !            15: {
        !            16:        return (src ^ res) & (dst ^ res);
        !            17: }
        !            18: 
        !            19: /*static*/ inline uint32
        !            20: hd64180acc::vflag_sub(uint32 dst, uint32 src, uint32 res)
        !            21: {
        !            22:        return (src ^ dst) & (dst ^ res);
        !            23: }
        !            24: 
        !            25: /*static*/ inline uint32
        !            26: hd64180acc::hflag_add(uint32 dst, uint32 src)
        !            27: {
        !            28:        return (dst & 0x0f) + (src & 0x0f);
        !            29: }
        !            30: 
        !            31: /*static*/ inline uint32
        !            32: hd64180acc::hflag_sub(uint32 dst, uint32 src)
        !            33: {
        !            34:        return (dst & 0x0f) - (src & 0x0f);
        !            35: }
        !            36: 
        !            37: // LD A,I、LD A,R 命令のフラグ変化。
        !            38: // S:* Z:* H:0 P/V:IEF2 N:0 C:-
        !            39: uint32
        !            40: hd64180acc::ld_ir8(uint32 src)
        !            41: {
        !            42:        // P/V (IEF2) は呼び出し側で行う。
        !            43: 
        !            44:        S = Z = src;
        !            45:        SetH(false);
        !            46:        SetN(false);
        !            47:        return Z;
        !            48: }
        !            49: 
        !            50: // save_c が true なら C を変更しない。
        !            51: // S:* Z:* H:* V:* N:0 C:*/-
        !            52: uint32
        !            53: hd64180acc::add_8(uint32 dst, uint32 src, bool save_c)
        !            54: {
        !            55:        if (save_c) {
        !            56:                Z = dst + src;
        !            57:        } else {
        !            58:                CZ = dst + src;
        !            59:        }
        !            60:        S = Z;
        !            61:        H = hflag_add(dst, src);
        !            62:        LetV(vflag_add(dst, src, Z));
        !            63:        SetN(false);
        !            64: 
        !            65:        return (uint8)Z;
        !            66: }
        !            67: 
        !            68: // save_c が true なら C を変更しない。
        !            69: // S:* Z:* H:* V:* N:0 C:*/-
        !            70: uint32
        !            71: hd64180acc::sub_8(uint32 dst, uint32 src, bool save_c)
        !            72: {
        !            73:        if (save_c) {
        !            74:                Z = dst - src;
        !            75:        } else {
        !            76:                CZ = dst - src;
        !            77:        }
        !            78:        S = Z;
        !            79:        H = hflag_sub(dst, src);
        !            80:        LetV(vflag_sub(dst, src, Z));
        !            81:        SetN(true);
        !            82: 
        !            83:        return (uint8)Z;
        !            84: }
        !            85: 
        !            86: // S:* Z:* H:* V:* N:0 C:*
        !            87: uint32
        !            88: hd64180acc::adc_8(uint32 dst, uint32 src)
        !            89: {
        !            90:        uint32 cin = IsC() ? 1 : 0;
        !            91:        uint32 res = dst + src + cin;
        !            92: 
        !            93:        CZ = res;
        !            94:        S = res;
        !            95:        LetV(vflag_add(dst, src, res));
        !            96:        H  = hflag_add(dst, src);
        !            97:        H |= hflag_add(H, cin);
        !            98:        SetN(false);
        !            99: 
        !           100:        return Z;
        !           101: }
        !           102: 
        !           103: // S:* Z:* H:* V:* N:0 C:*
        !           104: uint32
        !           105: hd64180acc::sbc_8(uint32 dst, uint32 src)
        !           106: {
        !           107:        uint32 cin = IsC() ? 1 : 0;
        !           108:        uint32 res = dst - src - cin;
        !           109: 
        !           110:        CZ = res;
        !           111:        S = res;
        !           112:        LetV(vflag_sub(dst, src, res));
        !           113:        H  = hflag_sub(dst, src);
        !           114:        H |= hflag_sub(H, cin);
        !           115:        SetN(true);
        !           116: 
        !           117:        return Z;
        !           118: }
        !           119: 
        !           120: // S:- Z:- H:X PV:- N:0 C:*
        !           121: uint32
        !           122: hd64180acc::add_16(uint32 dst, uint32 src)
        !           123: {
        !           124:        uint32 res = dst + src;
        !           125:        C = res >> 16;
        !           126:        SetN(false);
        !           127:        // XXX H は不定
        !           128: 
        !           129:        return res;
        !           130: }
        !           131: 
        !           132: // S:* Z:* H:X V:* N:0 C:*
        !           133: uint32
        !           134: hd64180acc::adc_16(uint32 dst, uint32 src)
        !           135: {
        !           136:        // V のために2回に分けて計算しないといけない?
        !           137:        uint32 res = dst + src;
        !           138:        uint32 v = vflag_add(dst, src, res);
        !           139: 
        !           140:        dst = res;
        !           141:        src = IsC() ? 1 : 0;
        !           142:        res = dst + src;
        !           143:        v |= vflag_add(dst, src, res);
        !           144: 
        !           145:        LetV((uint32)(v >> 8));
        !           146: 
        !           147:        // C, S, Z は 16bit が対象でいい?
        !           148:        C = res >> 16;
        !           149:        S = res >> 8;
        !           150:        Z = res | S;
        !           151: 
        !           152:        SetN(false);
        !           153: 
        !           154:        // XXX H は本当は不定
        !           155: 
        !           156:        return res;
        !           157: }
        !           158: 
        !           159: // S:* Z:* H:X V:* N:1 C:*
        !           160: uint32
        !           161: hd64180acc::sbc_16(uint32 dst, uint32 src)
        !           162: {
        !           163:        // V のために2回に分けて計算しないといけない?
        !           164:        uint32 res = dst - src;
        !           165:        uint32 v = vflag_sub(dst, src, res);
        !           166: 
        !           167:        dst = res;
        !           168:        src = IsC() ? 1 : 0;
        !           169:        res = dst - src;
        !           170:        v |= vflag_sub(dst, src, res);
        !           171: 
        !           172:        LetV((uint32)(v >> 8));
        !           173: 
        !           174:        // C, S, Z は 16bit が対象でいい?
        !           175:        C = res >> 16;
        !           176:        S = res >> 8;
        !           177:        Z = res | S;
        !           178: 
        !           179:        SetN(true);
        !           180: 
        !           181:        // XXX H は本当は不定
        !           182: 
        !           183:        return res;
        !           184: }
        !           185: 
        !           186: // BIT 命令
        !           187: // S:X Z:* H:1 PV:X N:0 C:-
        !           188: void
        !           189: hd64180acc::bit_8(uint b, uint32 src)
        !           190: {
        !           191:        Z = src & (1U << b);
        !           192:        SetH(true);
        !           193:        SetN(false);
        !           194:        // XXX S, P(V) は本当は不定
        !           195: }
        !           196: 
        !           197: // IN A,(n) 命令のフラグ変化。他からも色々呼ばれる。
        !           198: // S:* Z:* H:0 P:* N:0 C:-
        !           199: uint32
        !           200: hd64180acc::in_8(uint32 src)
        !           201: {
        !           202:        S = Z = src;
        !           203:        SetN(false);
        !           204:        SetH(false);
        !           205:        LetP(Z);
        !           206:        return Z;
        !           207: }
        !           208: 
        !           209: // OTIM/OTDM 命令のフラグ変化。
        !           210: // 戻り値は演算後の B レジスタの値。
        !           211: // HD64180.pdf p.110
        !           212: // S:* Z:* H:* P:* N:* C:*
        !           213: uint32
        !           214: hd64180acc::outm_8(uint32 src, uint32 breg)
        !           215: {
        !           216:        CZ = breg - 1;
        !           217:        S = Z;
        !           218:        H = hflag_sub(breg, 1);
        !           219:        LetP(Z);                        // 減算後の B のパリティ
        !           220:        N = (src & 0x80);       // (HL) の MSB
        !           221: 
        !           222:        return Z;
        !           223: }
        !           224: 
        !           225: // S:* Z:* H:1 P:* N:0 C:0
        !           226: uint32
        !           227: hd64180acc::and_8(uint32 dst, uint32 src)
        !           228: {
        !           229:        uint32 res;
        !           230:        SetC(false);
        !           231:        res = in_8(dst & src);
        !           232:        SetH(true);                     // これだけ H はセット
        !           233:        return res;
        !           234: }
        !           235: 
        !           236: // S:* Z:* H:0 P:* N:0 C:0
        !           237: uint32
        !           238: hd64180acc::or_8(uint32 dst, uint32 src)
        !           239: {
        !           240:        SetC(false);
        !           241:        return in_8(dst | src);
        !           242: }
        !           243: 
        !           244: // S:* Z:* H:0 P:* N:0 C:0
        !           245: uint32
        !           246: hd64180acc::xor_8(uint32 dst, uint32 src)
        !           247: {
        !           248:        SetC(false);
        !           249:        return in_8(dst ^ src);
        !           250: }
        !           251: 
        !           252: // S:* Z:* H:1 P:* N:0 C:0
        !           253: void
        !           254: hd64180acc::tst_8(uint32 dst, uint32 src)
        !           255: {
        !           256:        in_8(dst & src);
        !           257:        SetH(true);
        !           258:        SetC(false);
        !           259: }
        !           260: 
        !           261: // S:* Z:* H:0 P:* N:0 C:*
        !           262: uint32
        !           263: hd64180acc::sla_8(uint32 src)
        !           264: {
        !           265:        CZ = src << 1;
        !           266:        return in_8(Z);
        !           267: }
        !           268: 
        !           269: // S:* Z:* H:0 P:* N:0 C:*
        !           270: uint32
        !           271: hd64180acc::sra_8(uint32 src)
        !           272: {
        !           273:        C = src;
        !           274:        Z = (src >> 1);
        !           275:        Z |= src & 0x80;
        !           276:        return in_8(Z);
        !           277: }
        !           278: 
        !           279: // S:* Z:* H:0 P:* N:0 C:*
        !           280: uint32
        !           281: hd64180acc::srl_8(uint32 src)
        !           282: {
        !           283:        C = src;
        !           284:        Z = src >> 1;
        !           285:        return in_8(Z);
        !           286: }
        !           287: 
        !           288: //       S Z H P N C
        !           289: // RLA   - - 0 - 0 * : rl_8()
        !           290: // RL r  * * 0 P 0 * : in_8(rl_8())
        !           291: // RLD   * * 0 P 0 - : in_8()
        !           292: 
        !           293: uint32
        !           294: hd64180acc::rl_8(uint32 src)
        !           295: {
        !           296:        src <<= 1;
        !           297:        if (IsC()) {
        !           298:                src |= 0x01;
        !           299:        }
        !           300:        C = src >> 8;
        !           301: 
        !           302:        SetN(false);
        !           303:        SetH(false);
        !           304: 
        !           305:        return (uint8)src;
        !           306: }
        !           307: 
        !           308: uint32
        !           309: hd64180acc::rlc_8(uint32 src)
        !           310: {
        !           311:        src <<= 1;
        !           312:        if ((src & 0x100)) {
        !           313:                src |= 0x01;
        !           314:        }
        !           315:        C = src >> 8;
        !           316: 
        !           317:        SetN(false);
        !           318:        SetH(false);
        !           319: 
        !           320:        return (uint8)src;
        !           321: }
        !           322: 
        !           323: uint32
        !           324: hd64180acc::rr_8(uint32 src)
        !           325: {
        !           326:        src = (uint8)src;
        !           327:        if (IsC()) {
        !           328:                src |= 0x100;
        !           329:        }
        !           330:        C = src;
        !           331:        src >>= 1;
        !           332: 
        !           333:        SetN(false);
        !           334:        SetH(false);
        !           335: 
        !           336:        return (uint8)src;
        !           337: }
        !           338: 
        !           339: uint32
        !           340: hd64180acc::rrc_8(uint32 src)
        !           341: {
        !           342:        C = src;
        !           343:        src = (uint8)src;
        !           344:        src |= (C << 8);
        !           345:        src >>= 1;
        !           346: 
        !           347:        SetN(false);
        !           348:        SetH(false);
        !           349: 
        !           350:        return (uint8)src;
        !           351: }

unix.superglobalmegacorp.com

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