Annotation of nono/util/sramedit/params.cpp, revision 1.1.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.