Annotation of nono/util/sramedit/params.cpp, revision 1.1

1.1     ! root        1: //
        !             2: // nono
        !             3: // Copyright (C) 2021 nono project
        !             4: // Licensed under nono-license.txt
        !             5: //
        !             6: 
        !             7: #include "sramedit.h"
        !             8: #include <array>
        !             9: 
        !            10: // アクセスヘルパー
        !            11: 
        !            12: uint32 read8(uint32 offset);
        !            13: uint32 read16(uint32 offset);
        !            14: uint32 read32(uint32 offset);
        !            15: void write8(uint32 offset, uint32 val);
        !            16: void write16(uint32 offset, uint32 val);
        !            17: void write32(uint32 offset, uint32 val);
        !            18: uint32 read8(const sraminfo_t&);
        !            19: uint32 read16(const sraminfo_t&);
        !            20: uint32 read32(const sraminfo_t&);
        !            21: void write8(const sraminfo_t&, uint32 val);
        !            22: void write16(const sraminfo_t&, uint32 val);
        !            23: void write32(const sraminfo_t&, uint32 val);
        !            24: int update8(const sraminfo_t&, uint32 val);
        !            25: int update16(const sraminfo_t&, uint32 val);
        !            26: int update32(const sraminfo_t&, uint32 val);
        !            27: 
        !            28: uint32
        !            29: read8(uint32 offset)
        !            30: {
        !            31:        return sram[offset];
        !            32: }
        !            33: 
        !            34: uint32
        !            35: read16(uint32 offset)
        !            36: {
        !            37:        uint32 h = read8(offset) << 8;
        !            38:        uint32 l = read8(offset + 1);
        !            39: 
        !            40:        return (h | l);
        !            41: }
        !            42: 
        !            43: uint32
        !            44: read32(uint32 offset)
        !            45: {
        !            46:        uint32 h = read16(offset) << 16;
        !            47:        uint32 l = read16(offset + 2);
        !            48: 
        !            49:        return (h | l);
        !            50: }
        !            51: 
        !            52: void
        !            53: write8(uint32 offset, uint32 val)
        !            54: {
        !            55:        sram[offset] = (uint8)val;
        !            56: }
        !            57: 
        !            58: void
        !            59: write16(uint32 offset, uint32 val)
        !            60: {
        !            61:        write8(offset,     val >> 8);
        !            62:        write8(offset + 1, val & 0xff);
        !            63: }
        !            64: 
        !            65: void
        !            66: write32(uint32 offset, uint32 val)
        !            67: {
        !            68:        write16(offset,     val >> 16);
        !            69:        write16(offset + 2, val & 0xffff);
        !            70: }
        !            71: 
        !            72: uint32 read8(const sraminfo_t& si)  { return read8(si.offset); }
        !            73: uint32 read16(const sraminfo_t& si) { return read16(si.offset); }
        !            74: uint32 read32(const sraminfo_t& si) { return read32(si.offset); }
        !            75: void write8(const sraminfo_t& si, uint32 val) {
        !            76:        return write8(si.offset, val);
        !            77: }
        !            78: void write16(const sraminfo_t& si, uint32 val) {
        !            79:        return write16(si.offset, val);
        !            80: }
        !            81: void write32(const sraminfo_t& si, uint32 val) {
        !            82:        return write32(si.offset, val);
        !            83: }
        !            84: 
        !            85: int
        !            86: update8(const sraminfo_t& si, uint32 val)
        !            87: {
        !            88:        if (read8(si) == val) {
        !            89:                return 0;
        !            90:        }
        !            91:        write8(si, val);
        !            92:        return 1;
        !            93: }
        !            94: 
        !            95: int
        !            96: update16(const sraminfo_t& si, uint32 val)
        !            97: {
        !            98:        if (read16(si) == val) {
        !            99:                return 0;
        !           100:        }
        !           101:        write16(si, val);
        !           102:        return 1;
        !           103: }
        !           104: 
        !           105: int
        !           106: update32(const sraminfo_t& si, uint32 val)
        !           107: {
        !           108:        if (read32(si) == val) {
        !           109:                return 0;
        !           110:        }
        !           111:        write32(si, val);
        !           112:        return 1;
        !           113: }
        !           114: 
        !           115: //
        !           116: // 個別処理
        !           117: //
        !           118: 
        !           119: //----- ramsize
        !           120: 
        !           121: static std::string
        !           122: r_ramsize(const sraminfo_t& si)
        !           123: {
        !           124:        uint32 v = read32(si);
        !           125:        std::string res = string_format("$%08x", v);
        !           126:        if (v % (1024 * 1024) == 0) {
        !           127:                res += string_format(" (%dMB)", v / 1024 / 1024);
        !           128:        }
        !           129:        return res;
        !           130: }
        !           131: 
        !           132: static int
        !           133: w_ramsize(const sraminfo_t& si, const std::string& input)
        !           134: {
        !           135:        char *end;
        !           136:        uint32 newval;
        !           137: 
        !           138:        errno = 0;
        !           139:        newval = strtoul(input.c_str(), &end, 10);
        !           140:        // 後ろに M が付くのだけ許容する?
        !           141:        if (end == input.c_str() || errno == ERANGE ||
        !           142:            (*end != '\0' && *end != 'm' && *end != 'M')) {
        !           143:                warnx("%s='%s': bad parameter", si.name, input.c_str());
        !           144:                return -1;
        !           145:        }
        !           146:        newval *= 1024 * 1024;
        !           147: 
        !           148:        return update32(si, newval);
        !           149: }
        !           150: 
        !           151: static const std::string
        !           152: h_ramsize(const sraminfo_t& si)
        !           153: {
        !           154:        return string_format("%s = { 4..12 }", si.name);
        !           155: }
        !           156: 
        !           157: //----- romaddr
        !           158: 
        !           159: static std::string
        !           160: r_romaddr(const sraminfo_t& si)
        !           161: {
        !           162:        uint32 v = read32(si);
        !           163:        std::string res = string_format("$%08x", v);
        !           164:        if (0xfc0000 <= v && v < 0xfc0020) {
        !           165:                res += string_format(" (SCSI%d)", (v - 0xfc0000) / 4);
        !           166:        }
        !           167:        return res;
        !           168: }
        !           169: 
        !           170: static int
        !           171: w_romaddr(const sraminfo_t& si, const std::string& input)
        !           172: {
        !           173:        char *end;
        !           174:        uint32 newval;
        !           175: 
        !           176:        errno = 0;
        !           177:        if (starts_with_ignorecase(input, "scsi")) {
        !           178:                const char *start = input.c_str() + 4;
        !           179:                int id = strtoul(start, &end, 10);
        !           180:                if (end == start || *end != '\0' || errno == ERANGE) {
        !           181:                        warnx("%s='%s': bad SCSI ID", si.name, input.c_str());
        !           182:                        return -1;
        !           183:                }
        !           184:                newval = 0xfc0000 + id * 4;
        !           185:        } else {
        !           186:                newval = strtoul(input.c_str(), &end, 16);
        !           187:                if (end == input.c_str() || *end != '\0' || errno == ERANGE) {
        !           188:                        warnx("%s='%s': bad address", si.name, input.c_str());
        !           189:                }
        !           190:                if (newval > 0xffffff) {
        !           191:                        warnx("%s='%s': bad address", si.name, input.c_str());
        !           192:                }
        !           193:        }
        !           194: 
        !           195:        return update32(si, newval);
        !           196: }
        !           197: 
        !           198: static const std::string
        !           199: h_romaddr(const sraminfo_t& si)
        !           200: {
        !           201:        return string_format("%s = { [0x]<hexaddr> | scsi<0..7> }", si.name);
        !           202: }
        !           203: 
        !           204: //---
        !           205: 
        !           206: static std::string
        !           207: r_ramaddr(const sraminfo_t& si)
        !           208: {
        !           209:        uint32 v = read32(si);
        !           210:        return string_format("$%08x", v);
        !           211: }
        !           212: 
        !           213: //----- bootdev
        !           214: 
        !           215: static std::string
        !           216: r_bootdev(const sraminfo_t& si)
        !           217: {
        !           218:        uint32 v = read16(si);
        !           219:        std::string res = string_format("$%04x ", v);
        !           220: 
        !           221:        if (v == 0x0000) {
        !           222:                res += "STD (FD->HD->ROM->RAM)";
        !           223:        } else if ((v & 0xf0ff) == 0x8000) {
        !           224:                res += string_format("SASI%d", (v >> 8) & 0x0f);
        !           225:        } else if ((v & 0xf0ff) == 0x9070) {
        !           226:                res += string_format("FD%d", (v >> 8) & 0x0f);
        !           227:        } else if (v == 0xa000) {
        !           228:                res += "ROM";
        !           229:        } else if (v == 0xb000) {
        !           230:                res += "RAM";
        !           231:        } else {
        !           232:                res += "?";
        !           233:        }
        !           234: 
        !           235:        return res;
        !           236: }
        !           237: 
        !           238: static int
        !           239: w_bootdev(const sraminfo_t& si, const std::string& input)
        !           240: {
        !           241:        const char *start;
        !           242:        char *end;
        !           243:        int32 newval;
        !           244: 
        !           245:        if (strcasecmp(input.c_str(), "std") == 0) {
        !           246:                newval = 0x0000;
        !           247:        } else if (starts_with_ignorecase(input, "sasi")) {
        !           248:                errno = 0;
        !           249:                start = input.c_str() + 4;
        !           250:                int id = strtoul(start, &end, 10);
        !           251:                if (end == start || *end != '\0' || errno == ERANGE) {
        !           252:                        warnx("%s='%s': bad SASI ID", si.name, input.c_str());
        !           253:                        return -1;
        !           254:                }
        !           255:                newval = 0x8000 + (id << 8);
        !           256:        } else if (starts_with_ignorecase(input, "fd")) {
        !           257:                errno = 0;
        !           258:                start = input.c_str() + 4;
        !           259:                int id = strtoul(start, &end, 10);
        !           260:                if (end == start || *end != '\0' || errno == ERANGE) {
        !           261:                        warnx("%s='%s': bad SASI ID", si.name, input.c_str());
        !           262:                        return -1;
        !           263:                }
        !           264:                newval = 0x9070 + (id << 8);
        !           265:        } else if (strcasecmp(input.c_str(), "rom") == 0) {
        !           266:                newval = 0xa000;
        !           267:        } else if (strcasecmp(input.c_str(), "ram") == 0) {
        !           268:                newval = 0xb000;
        !           269:        } else {
        !           270:                warnx("%s='%s': bad parameter", si.name, input.c_str());
        !           271:                return -1;
        !           272:        }
        !           273: 
        !           274:        return update16(si, newval);
        !           275: }
        !           276: 
        !           277: static const std::string
        !           278: h_bootdev(const sraminfo_t& si)
        !           279: {
        !           280:        return string_format("%s = { std | sasi<0..15> | fd<0..3> | rom | ram }",
        !           281:                si.name);
        !           282: }
        !           283: 
        !           284: 
        !           285: static std::string
        !           286: r_rs232c(const sraminfo_t& si)
        !           287: {
        !           288:        uint32 v = read16(si);
        !           289:        std::string res = string_format("$%04x (", v);
        !           290: 
        !           291:        std::array<std::string, 4> stopbit {
        !           292:                "2",
        !           293:                "1",
        !           294:                "1.5",
        !           295:                "2",
        !           296:        };
        !           297:        res += "stop=";
        !           298:        res += stopbit[(v >> 14)];
        !           299:        res += ',';
        !           300: 
        !           301:        std::array<std::string, 4> parity {
        !           302:                "none",
        !           303:                "odd",
        !           304:                "even",
        !           305:                "none",
        !           306:        };
        !           307:        res += "parity=";
        !           308:        res += parity[(v >> 12) & 3];
        !           309:        res += ',';
        !           310: 
        !           311:        res += string_format("%dbit,", ((v >> 10) & 3) + 5);
        !           312: 
        !           313:        std::array<int, 9> speed {
        !           314:                75,
        !           315:                150,
        !           316:                300,
        !           317:                600,
        !           318:                1200,
        !           319:                2400,
        !           320:                4800,
        !           321:                9600,
        !           322:                17361,  // X68030 only
        !           323:        };
        !           324:        uint32 vs = (v & 0x0f);
        !           325:        if (vs < speed.size()) {
        !           326:                res += string_format("%dbps", speed[vs]);
        !           327:        } else {
        !           328:                res += "?bps";
        !           329:        }
        !           330: 
        !           331:        res += ')';
        !           332:        return res;
        !           333: }
        !           334: 
        !           335: static std::string
        !           336: r_led(const sraminfo_t& si)
        !           337: {
        !           338:        uint8 v = read8(si);
        !           339:        std::string res = string_format("$%02x", v);
        !           340: 
        !           341:        std::array<std::string, 8> names {
        !           342:                "",                     // b7
        !           343:                "Zenkaku",      // b6
        !           344:                "Hiragana",     // b5
        !           345:                "INS",          // b4
        !           346:                "CAPS",         // b3
        !           347:                "Code",         // b2
        !           348:                "Roma",         // b1
        !           349:                "Kana",         // b0
        !           350:        };
        !           351:        std::string map;
        !           352:        uint8 b = 0x40;
        !           353:        for (int i = 0; b; i++, b >>= 1) {
        !           354:                if ((v & b) != 0) {
        !           355:                        if (map.empty() == false) {
        !           356:                                map += ',';
        !           357:                        }
        !           358:                        map += names[i];
        !           359:                }
        !           360:        }
        !           361: 
        !           362:        if (map.empty() == false) {
        !           363:                res += ' ';
        !           364:                res += map;
        !           365:        }
        !           366:        return res;
        !           367: }
        !           368: 
        !           369: static std::string
        !           370: r_crtmod(const sraminfo_t& si)
        !           371: {
        !           372:        uint8 v = read8(si);
        !           373:        return string_format("$%02x", v);
        !           374: }
        !           375: 
        !           376: static std::string
        !           377: r_contrast(const sraminfo_t& si)
        !           378: {
        !           379:        uint8 v = read8(si);
        !           380:        return string_format("$%02x", v);
        !           381: }
        !           382: 
        !           383: static std::string
        !           384: r_sram_use(const sraminfo_t& si)
        !           385: {
        !           386:        uint8 v = read8(si);
        !           387:        std::string res;
        !           388: 
        !           389:        if (v == 0) {
        !           390:                res = "NotUsed";
        !           391:        } else if (v == 1) {
        !           392:                res = "SRAMDISK";
        !           393:        } else if (v == 2) {
        !           394:                res = "Program";
        !           395:        } else {
        !           396:                res = string_format("$%02x ?", v);
        !           397:        }
        !           398:        return res;
        !           399: }
        !           400: 
        !           401: //----- key_delay, key_repeat
        !           402: 
        !           403: static std::string
        !           404: r_key_repeat(const sraminfo_t& si)
        !           405: {
        !           406:        uint8 v = read8(si);
        !           407:        std::string res = string_format("$%02x ", v);
        !           408: 
        !           409:        if (v < 16) {
        !           410:                int msec;
        !           411:                if (si.offset == 0x3a) {
        !           412:                        msec = 200 + 100 * v;
        !           413:                } else {
        !           414:                        msec = 30 + 5 * v * v;
        !           415:                }
        !           416:                res += string_format("(%dmsec)", msec);
        !           417:        } else {
        !           418:                res += "(??msec)";
        !           419:        }
        !           420:        return res;
        !           421: }
        !           422: 
        !           423: static int
        !           424: w_key_repeat(const sraminfo_t& si, const std::string& input)
        !           425: {
        !           426:        char *end;
        !           427:        int newval;
        !           428: 
        !           429:        errno = 0;
        !           430:        newval = strtoul(input.c_str(), &end, 10);
        !           431:        if (end == input.c_str() || *end != '\0' || errno == ERANGE) {
        !           432:                warnx("%s='%s': bad parameter", si.name, input.c_str());
        !           433:                return 0;
        !           434:        }
        !           435: 
        !           436:        // 値は10進数、直接指定
        !           437:        if (newval < 0 || newval > 255) {
        !           438:                warnx("%s='%d': invalid range", si.name, newval);
        !           439:                return -1;
        !           440:        }
        !           441: 
        !           442:        return update8(si, newval);
        !           443: }
        !           444: 
        !           445: static const std::string
        !           446: h_key_repeat(const sraminfo_t& si)
        !           447: {
        !           448:        return string_format("%s = { 0..15 }", si.name);
        !           449: }
        !           450: 
        !           451: //-----
        !           452: 
        !           453: static std::string
        !           454: r_boottime(const sraminfo_t& si)
        !           455: {
        !           456:        uint32 v = read32(si);
        !           457:        return string_format("%u (%u:%u)", v, (v / 60), (v % 60));
        !           458: }
        !           459: 
        !           460: static std::string
        !           461: r_bootcount(const sraminfo_t& si)
        !           462: {
        !           463:        uint32 v = read32(si);
        !           464:        return string_format("%d", v);
        !           465: }
        !           466: 
        !           467: 
        !           468: static std::string
        !           469: r_debugger(const sraminfo_t& si)
        !           470: {
        !           471:        uint8 v = read8(si);
        !           472:        std::string res;
        !           473: 
        !           474:        if (v == 0x00) {
        !           475:                res = "off";
        !           476:        } else if (v == 0xff) {
        !           477:                res = "on";
        !           478:        } else {
        !           479:                res = string_format("on? (0x%02x)", v);
        !           480:        }
        !           481:        return res;
        !           482: }
        !           483: 
        !           484: static int
        !           485: w_debugger(const sraminfo_t& si, const std::string& input)
        !           486: {
        !           487:        uint8 newval;
        !           488: 
        !           489:        if (strcasecmp(input.c_str(), "off") == 0) {
        !           490:                newval = 0;
        !           491:        } else if (strcasecmp(input.c_str(), "on") == 0) {
        !           492:                newval = 0xff;
        !           493:        } else {
        !           494:                warnx("%s='%s': bad parameter", si.name, input.c_str());
        !           495:                return -1;
        !           496:        }
        !           497: 
        !           498:        return update8(si, newval);
        !           499: }
        !           500: 
        !           501: static const std::string
        !           502: h_debugger(const sraminfo_t& si)
        !           503: {
        !           504:        return string_format("%s = { on | off }", si.name);
        !           505: }
        !           506: 
        !           507: // パラメータ一覧
        !           508: #define RWH(name)      r_##name, w_##name, h_##name
        !           509: std::vector<sraminfo_t> sraminfo = {
        !           510:        // offset       name            reader          writer  help
        !           511:        { 0x08,         "ramsize",      RWH(ramsize) },
        !           512:        { 0x0c,         "romaddr",      RWH(romaddr) },
        !           513:        { 0x10,         "ramaddr",      r_ramaddr, NULL },
        !           514:        { 0x14,         "alarm_until?" },
        !           515:        { 0x18,         "bootdev",      RWH(bootdev) },
        !           516:        { 0x1a,         "rs232c",       r_rs232c,       NULL },
        !           517:        { 0x1c,         "led",          r_led,          NULL },
        !           518:        { 0x1d,         "crtmod",       r_crtmod,       NULL },
        !           519:        { 0x1e,         "alarm_op?" },
        !           520:        { 0x22,         "alarm_time?" },
        !           521:        { 0x26,         "alarm_en?" },
        !           522:        { 0x27,         "tvctrl_en?" },
        !           523:        { 0x28,         "contrast",     r_contrast,     NULL },
        !           524:        { 0x29,         "fd_eject?" },
        !           525:        { 0x2a,         "tvctrl_code?" },
        !           526:        { 0x2b,         "keyboard?" },
        !           527:        { 0x2c,         "calc_font" },
        !           528:        { 0x2d,         "sram_use",     r_sram_use, NULL },
        !           529:        { 0x2e,         "textpal0" },
        !           530:        { 0x30,         "textpal1" },
        !           531:        { 0x32,         "textpal2" },
        !           532:        { 0x34,         "textpal3" },
        !           533:        { 0x36,         "textpal4" },
        !           534:        { 0x38,         "textpal8" },
        !           535:        { 0x3a,         "key_delay",    RWH(key_repeat) },
        !           536:        { 0x3b,         "key_repeat",   RWH(key_repeat) },
        !           537:        { 0x3c,         "prn_timeout?" },
        !           538:        { 0x40,         "boottime",     r_boottime,     NULL },
        !           539:        { 0x44,         "bootcount",r_bootcount,        NULL },
        !           540:        { 0x48,         "romdisk_fat?" },
        !           541:        { 0x58,         "debugger",     RWH(debugger) },
        !           542:        { 0x59,         "charmode" },
        !           543: };

unix.superglobalmegacorp.com

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