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

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: 
1.1.1.3 ! root       12: uint32 read1(uint32 offset);
        !            13: uint32 read2(uint32 offset);
        !            14: uint32 read4(uint32 offset);
        !            15: void write1(uint32 offset, uint32 val);
        !            16: void write2(uint32 offset, uint32 val);
        !            17: void write4(uint32 offset, uint32 val);
        !            18: uint32 read1(const sraminfo_t&);
        !            19: uint32 read2(const sraminfo_t&);
        !            20: uint32 read4(const sraminfo_t&);
        !            21: void write1(const sraminfo_t&, uint32 val);
        !            22: void write2(const sraminfo_t&, uint32 val);
        !            23: void write4(const sraminfo_t&, uint32 val);
        !            24: int update1(const sraminfo_t&, uint32 val);
        !            25: int update2(const sraminfo_t&, uint32 val);
        !            26: int update4(const sraminfo_t&, uint32 val);
1.1       root       27: 
                     28: uint32
1.1.1.3 ! root       29: read1(uint32 offset)
1.1       root       30: {
                     31:        return sram[offset];
                     32: }
                     33: 
                     34: uint32
1.1.1.3 ! root       35: read2(uint32 offset)
1.1       root       36: {
1.1.1.3 ! root       37:        uint32 h = read1(offset) << 8;
        !            38:        uint32 l = read1(offset + 1);
1.1       root       39: 
                     40:        return (h | l);
                     41: }
                     42: 
                     43: uint32
1.1.1.3 ! root       44: read4(uint32 offset)
1.1       root       45: {
1.1.1.3 ! root       46:        uint32 h = read2(offset) << 16;
        !            47:        uint32 l = read2(offset + 2);
1.1       root       48: 
                     49:        return (h | l);
                     50: }
                     51: 
                     52: void
1.1.1.3 ! root       53: write1(uint32 offset, uint32 val)
1.1       root       54: {
                     55:        sram[offset] = (uint8)val;
                     56: }
                     57: 
                     58: void
1.1.1.3 ! root       59: write2(uint32 offset, uint32 val)
1.1       root       60: {
1.1.1.3 ! root       61:        write1(offset,     val >> 8);
        !            62:        write1(offset + 1, val & 0xff);
1.1       root       63: }
                     64: 
                     65: void
1.1.1.3 ! root       66: write4(uint32 offset, uint32 val)
1.1       root       67: {
1.1.1.3 ! root       68:        write2(offset,     val >> 16);
        !            69:        write2(offset + 2, val & 0xffff);
1.1       root       70: }
                     71: 
1.1.1.3 ! root       72: uint32 read1(const sraminfo_t& si) { return read1(si.offset); }
        !            73: uint32 read2(const sraminfo_t& si) { return read2(si.offset); }
        !            74: uint32 read4(const sraminfo_t& si) { return read4(si.offset); }
        !            75: void write1(const sraminfo_t& si, uint32 val) {
        !            76:        return write1(si.offset, val);
1.1       root       77: }
1.1.1.3 ! root       78: void write2(const sraminfo_t& si, uint32 val) {
        !            79:        return write2(si.offset, val);
1.1       root       80: }
1.1.1.3 ! root       81: void write4(const sraminfo_t& si, uint32 val) {
        !            82:        return write4(si.offset, val);
1.1       root       83: }
                     84: 
                     85: int
1.1.1.3 ! root       86: update1(const sraminfo_t& si, uint32 val)
1.1       root       87: {
1.1.1.3 ! root       88:        if (read1(si) == val) {
1.1       root       89:                return 0;
                     90:        }
1.1.1.3 ! root       91:        write1(si, val);
1.1       root       92:        return 1;
                     93: }
                     94: 
                     95: int
1.1.1.3 ! root       96: update2(const sraminfo_t& si, uint32 val)
1.1       root       97: {
1.1.1.3 ! root       98:        if (read2(si) == val) {
1.1       root       99:                return 0;
                    100:        }
1.1.1.3 ! root      101:        write2(si, val);
1.1       root      102:        return 1;
                    103: }
                    104: 
                    105: int
1.1.1.3 ! root      106: update4(const sraminfo_t& si, uint32 val)
1.1       root      107: {
1.1.1.3 ! root      108:        if (read4(si) == val) {
1.1       root      109:                return 0;
                    110:        }
1.1.1.3 ! root      111:        write4(si, val);
1.1       root      112:        return 1;
                    113: }
                    114: 
                    115: //
                    116: // 個別処理
                    117: //
                    118: 
                    119: //----- ramsize
                    120: 
                    121: static std::string
                    122: r_ramsize(const sraminfo_t& si)
                    123: {
1.1.1.3 ! root      124:        uint32 v = read4(si);
1.1       root      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: 
1.1.1.3 ! root      148:        return update4(si, newval);
1.1       root      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: {
1.1.1.3 ! root      162:        uint32 v = read4(si);
1.1       root      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: 
1.1.1.3 ! root      195:        return update4(si, newval);
1.1       root      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: {
1.1.1.3 ! root      209:        uint32 v = read4(si);
1.1       root      210:        return string_format("$%08x", v);
                    211: }
                    212: 
                    213: //----- bootdev
                    214: 
                    215: static std::string
                    216: r_bootdev(const sraminfo_t& si)
                    217: {
1.1.1.3 ! root      218:        uint32 v = read2(si);
1.1       root      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:                }
1.1.1.2   root      255:                if (id < 0 || id > 16) {
                    256:                        warnx("%s='%s': out of range", si.name, input.c_str());
                    257:                        return -1;
                    258:                }
1.1       root      259:                newval = 0x8000 + (id << 8);
                    260:        } else if (starts_with_ignorecase(input, "fd")) {
                    261:                errno = 0;
1.1.1.2   root      262:                start = input.c_str() + 2;
1.1       root      263:                int id = strtoul(start, &end, 10);
                    264:                if (end == start || *end != '\0' || errno == ERANGE) {
1.1.1.2   root      265:                        warnx("%s='%s': bad unit number", si.name, input.c_str());
                    266:                        return -1;
                    267:                }
                    268:                if (id < 0 || id > 4) {
                    269:                        warnx("%s='%s': out of range", si.name, input.c_str());
1.1       root      270:                        return -1;
                    271:                }
                    272:                newval = 0x9070 + (id << 8);
                    273:        } else if (strcasecmp(input.c_str(), "rom") == 0) {
                    274:                newval = 0xa000;
                    275:        } else if (strcasecmp(input.c_str(), "ram") == 0) {
                    276:                newval = 0xb000;
                    277:        } else {
                    278:                warnx("%s='%s': bad parameter", si.name, input.c_str());
                    279:                return -1;
                    280:        }
                    281: 
1.1.1.3 ! root      282:        return update2(si, newval);
1.1       root      283: }
                    284: 
                    285: static const std::string
                    286: h_bootdev(const sraminfo_t& si)
                    287: {
                    288:        return string_format("%s = { std | sasi<0..15> | fd<0..3> | rom | ram }",
                    289:                si.name);
                    290: }
                    291: 
                    292: 
                    293: static std::string
                    294: r_rs232c(const sraminfo_t& si)
                    295: {
1.1.1.3 ! root      296:        uint32 v = read2(si);
1.1       root      297:        std::string res = string_format("$%04x (", v);
                    298: 
                    299:        std::array<std::string, 4> stopbit {
                    300:                "2",
                    301:                "1",
                    302:                "1.5",
                    303:                "2",
                    304:        };
                    305:        res += "stop=";
                    306:        res += stopbit[(v >> 14)];
                    307:        res += ',';
                    308: 
                    309:        std::array<std::string, 4> parity {
                    310:                "none",
                    311:                "odd",
                    312:                "even",
                    313:                "none",
                    314:        };
                    315:        res += "parity=";
                    316:        res += parity[(v >> 12) & 3];
                    317:        res += ',';
                    318: 
                    319:        res += string_format("%dbit,", ((v >> 10) & 3) + 5);
                    320: 
                    321:        std::array<int, 9> speed {
                    322:                75,
                    323:                150,
                    324:                300,
                    325:                600,
                    326:                1200,
                    327:                2400,
                    328:                4800,
                    329:                9600,
                    330:                17361,  // X68030 only
                    331:        };
                    332:        uint32 vs = (v & 0x0f);
                    333:        if (vs < speed.size()) {
                    334:                res += string_format("%dbps", speed[vs]);
                    335:        } else {
                    336:                res += "?bps";
                    337:        }
                    338: 
                    339:        res += ')';
                    340:        return res;
                    341: }
                    342: 
                    343: static std::string
                    344: r_led(const sraminfo_t& si)
                    345: {
1.1.1.3 ! root      346:        uint8 v = read1(si);
1.1       root      347:        std::string res = string_format("$%02x", v);
                    348: 
                    349:        std::array<std::string, 8> names {
                    350:                "",                     // b7
                    351:                "Zenkaku",      // b6
                    352:                "Hiragana",     // b5
                    353:                "INS",          // b4
                    354:                "CAPS",         // b3
                    355:                "Code",         // b2
                    356:                "Roma",         // b1
                    357:                "Kana",         // b0
                    358:        };
                    359:        std::string map;
                    360:        uint8 b = 0x40;
                    361:        for (int i = 0; b; i++, b >>= 1) {
                    362:                if ((v & b) != 0) {
                    363:                        if (map.empty() == false) {
                    364:                                map += ',';
                    365:                        }
                    366:                        map += names[i];
                    367:                }
                    368:        }
                    369: 
                    370:        if (map.empty() == false) {
                    371:                res += ' ';
                    372:                res += map;
                    373:        }
                    374:        return res;
                    375: }
                    376: 
                    377: static std::string
                    378: r_crtmod(const sraminfo_t& si)
                    379: {
1.1.1.3 ! root      380:        uint8 v = read1(si);
1.1       root      381:        return string_format("$%02x", v);
                    382: }
                    383: 
                    384: static std::string
                    385: r_contrast(const sraminfo_t& si)
                    386: {
1.1.1.3 ! root      387:        uint8 v = read1(si);
1.1       root      388:        return string_format("$%02x", v);
                    389: }
                    390: 
                    391: static std::string
                    392: r_sram_use(const sraminfo_t& si)
                    393: {
1.1.1.3 ! root      394:        uint8 v = read1(si);
1.1       root      395:        std::string res;
                    396: 
                    397:        if (v == 0) {
                    398:                res = "NotUsed";
                    399:        } else if (v == 1) {
                    400:                res = "SRAMDISK";
                    401:        } else if (v == 2) {
                    402:                res = "Program";
                    403:        } else {
                    404:                res = string_format("$%02x ?", v);
                    405:        }
                    406:        return res;
                    407: }
                    408: 
                    409: //----- key_delay, key_repeat
                    410: 
                    411: static std::string
                    412: r_key_repeat(const sraminfo_t& si)
                    413: {
1.1.1.3 ! root      414:        uint8 v = read1(si);
1.1       root      415:        std::string res = string_format("$%02x ", v);
                    416: 
                    417:        if (v < 16) {
                    418:                int msec;
                    419:                if (si.offset == 0x3a) {
                    420:                        msec = 200 + 100 * v;
                    421:                } else {
                    422:                        msec = 30 + 5 * v * v;
                    423:                }
                    424:                res += string_format("(%dmsec)", msec);
                    425:        } else {
                    426:                res += "(??msec)";
                    427:        }
                    428:        return res;
                    429: }
                    430: 
                    431: static int
                    432: w_key_repeat(const sraminfo_t& si, const std::string& input)
                    433: {
                    434:        char *end;
                    435:        int newval;
                    436: 
                    437:        errno = 0;
                    438:        newval = strtoul(input.c_str(), &end, 10);
                    439:        if (end == input.c_str() || *end != '\0' || errno == ERANGE) {
                    440:                warnx("%s='%s': bad parameter", si.name, input.c_str());
                    441:                return 0;
                    442:        }
                    443: 
                    444:        // 値は10進数、直接指定
                    445:        if (newval < 0 || newval > 255) {
                    446:                warnx("%s='%d': invalid range", si.name, newval);
                    447:                return -1;
                    448:        }
                    449: 
1.1.1.3 ! root      450:        return update1(si, newval);
1.1       root      451: }
                    452: 
                    453: static const std::string
                    454: h_key_repeat(const sraminfo_t& si)
                    455: {
                    456:        return string_format("%s = { 0..15 }", si.name);
                    457: }
                    458: 
                    459: //-----
                    460: 
                    461: static std::string
                    462: r_boottime(const sraminfo_t& si)
                    463: {
1.1.1.3 ! root      464:        uint32 v = read4(si);
1.1       root      465:        return string_format("%u (%u:%u)", v, (v / 60), (v % 60));
                    466: }
                    467: 
                    468: static std::string
                    469: r_bootcount(const sraminfo_t& si)
                    470: {
1.1.1.3 ! root      471:        uint32 v = read4(si);
1.1       root      472:        return string_format("%d", v);
                    473: }
                    474: 
                    475: 
                    476: static std::string
                    477: r_debugger(const sraminfo_t& si)
                    478: {
1.1.1.3 ! root      479:        uint8 v = read1(si);
1.1       root      480:        std::string res;
                    481: 
                    482:        if (v == 0x00) {
                    483:                res = "off";
                    484:        } else if (v == 0xff) {
                    485:                res = "on";
                    486:        } else {
                    487:                res = string_format("on? (0x%02x)", v);
                    488:        }
                    489:        return res;
                    490: }
                    491: 
                    492: static int
                    493: w_debugger(const sraminfo_t& si, const std::string& input)
                    494: {
                    495:        uint8 newval;
                    496: 
                    497:        if (strcasecmp(input.c_str(), "off") == 0) {
                    498:                newval = 0;
                    499:        } else if (strcasecmp(input.c_str(), "on") == 0) {
                    500:                newval = 0xff;
                    501:        } else {
                    502:                warnx("%s='%s': bad parameter", si.name, input.c_str());
                    503:                return -1;
                    504:        }
                    505: 
1.1.1.3 ! root      506:        return update1(si, newval);
1.1       root      507: }
                    508: 
                    509: static const std::string
                    510: h_debugger(const sraminfo_t& si)
                    511: {
                    512:        return string_format("%s = { on | off }", si.name);
                    513: }
                    514: 
                    515: // パラメータ一覧
                    516: #define RWH(name)      r_##name, w_##name, h_##name
                    517: std::vector<sraminfo_t> sraminfo = {
                    518:        // offset       name            reader          writer  help
                    519:        { 0x08,         "ramsize",      RWH(ramsize) },
                    520:        { 0x0c,         "romaddr",      RWH(romaddr) },
                    521:        { 0x10,         "ramaddr",      r_ramaddr, NULL },
                    522:        { 0x14,         "alarm_until?" },
                    523:        { 0x18,         "bootdev",      RWH(bootdev) },
                    524:        { 0x1a,         "rs232c",       r_rs232c,       NULL },
                    525:        { 0x1c,         "led",          r_led,          NULL },
                    526:        { 0x1d,         "crtmod",       r_crtmod,       NULL },
                    527:        { 0x1e,         "alarm_op?" },
                    528:        { 0x22,         "alarm_time?" },
                    529:        { 0x26,         "alarm_en?" },
                    530:        { 0x27,         "tvctrl_en?" },
                    531:        { 0x28,         "contrast",     r_contrast,     NULL },
                    532:        { 0x29,         "fd_eject?" },
                    533:        { 0x2a,         "tvctrl_code?" },
                    534:        { 0x2b,         "keyboard?" },
                    535:        { 0x2c,         "calc_font" },
                    536:        { 0x2d,         "sram_use",     r_sram_use, NULL },
                    537:        { 0x2e,         "textpal0" },
                    538:        { 0x30,         "textpal1" },
                    539:        { 0x32,         "textpal2" },
                    540:        { 0x34,         "textpal3" },
                    541:        { 0x36,         "textpal4" },
                    542:        { 0x38,         "textpal8" },
                    543:        { 0x3a,         "key_delay",    RWH(key_repeat) },
                    544:        { 0x3b,         "key_repeat",   RWH(key_repeat) },
                    545:        { 0x3c,         "prn_timeout?" },
                    546:        { 0x40,         "boottime",     r_boottime,     NULL },
                    547:        { 0x44,         "bootcount",r_bootcount,        NULL },
                    548:        { 0x48,         "romdisk_fat?" },
                    549:        { 0x58,         "debugger",     RWH(debugger) },
                    550:        { 0x59,         "charmode" },
                    551: };

unix.superglobalmegacorp.com

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