Annotation of nono/vm/sysport.cpp, revision 1.1.1.12

1.1       root        1: //
                      2: // nono
1.1.1.3   root        3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
1.1       root        5: //
                      6: 
1.1.1.8   root        7: //
                      8: // システムポート
                      9: //
                     10: 
1.1       root       11: #include "sysport.h"
1.1.1.8   root       12: #include "keyboard.h"
1.1.1.10  root       13: #include "mainram.h"
1.1.1.8   root       14: #include "mpu.h"
                     15: #include "nmi.h"
1.1.1.9   root       16: #include "power.h"
1.1.1.4   root       17: #include "romimg_x68k.h"
1.1       root       18: #include "sram.h"
1.1.1.12! root       19: #include "videoctlr.h"
1.1.1.9   root       20: #include <array>
1.1       root       21: 
1.1.1.8   root       22: // コンストラクタ
1.1       root       23: SysportDevice::SysportDevice()
1.1.1.10  root       24:        : inherited(OBJ_SYSPORT)
1.1       root       25: {
1.1.1.12! root       26:        monitor.func = ToMonitorCallback(&SysportDevice::MonitorUpdate);
        !            27:        monitor.SetSize(56, 8);
        !            28:        monitor.Regist(ID_MONITOR_SYSPORT);
1.1       root       29: }
                     30: 
1.1.1.8   root       31: // デストラクタ
1.1       root       32: SysportDevice::~SysportDevice()
                     33: {
1.1.1.10  root       34: }
                     35: 
                     36: // 初期化
                     37: bool
                     38: SysportDevice::Init()
                     39: {
                     40:        if (inherited::Init() == false) {
                     41:                return false;
                     42:        }
                     43: 
                     44:        cgrom = GetCGROMDevice();
                     45:        iplrom1 = GetIPLROM1Device();
                     46:        iplrom2 = GetIPLROM2Device();
                     47:        keyboard = GetKeyboard();
                     48:        mainram = GetMainRAMDevice();
                     49:        nmi = GetNMIDevice();
                     50:        sram = GetSRAMDevice();
1.1.1.12! root       51:        videoctlr = GetVideoCtlrDevice();
1.1.1.10  root       52: 
                     53:        return true;
1.1       root       54: }
                     55: 
1.1.1.8   root       56: // リセット
1.1.1.4   root       57: void
1.1.1.8   root       58: SysportDevice::ResetHard(bool poweron)
1.1.1.4   root       59: {
                     60:        sysport.ram_wait = 0;
                     61:        sysport.rom_wait = 0;
1.1.1.6   root       62:        sysport.key_ctrl = false;
1.1.1.9   root       63:        sysport.pwoff_count = 0;
1.1.1.10  root       64:        GetPowerDevice()->SetSystemPowerOn(true);
1.1.1.4   root       65: }
                     66: 
1.1.1.12! root       67: busdata
1.1.1.5   root       68: SysportDevice::Read(uint32 offset)
1.1       root       69: {
                     70:        uint32 data;
                     71: 
1.1.1.5   root       72:        switch (offset) {
1.1       root       73:         case SYSPORT::CONTRAST:
1.1.1.12! root       74:                data = 0xf0 | videoctlr->GetContrast();
1.1       root       75:                break;
                     76:         case SYSPORT::SCOPE3D:
                     77:                data = 0xff;
                     78:                break;
                     79:         case SYSPORT::IMAGEUNIT:
                     80:                data = 0xff;
                     81:                break;
                     82:         case SYSPORT::KEY:
1.1.1.8   root       83:                // XXX bit3 以外は要実機確認
                     84:                data = 0xf7;
1.1.1.10  root       85:                if (keyboard->IsConnected()) {
1.1.1.8   root       86:                        data |= 0x08;
                     87:                }
1.1       root       88:                break;
                     89:         case SYSPORT::WAIT:
                     90:                data = 0xff;
                     91:                break;
                     92:         case SYSPORT::MPU:
                     93:                data = 0xdc;
                     94:                break;
                     95:         case SYSPORT::SRAMWP:
                     96:                data = 0xff;
                     97:                break;
1.1.1.3   root       98:         case SYSPORT::POWEROFF:
                     99:                data = 0xff;
                    100:                break;
                    101:         default:
1.1.1.10  root      102:                VMPANIC("corrupted offset=%d", offset);
                    103:                return 0xff;
1.1       root      104:        }
1.1.1.10  root      105:        putlog(2, "$%06x -> $%02x", mpu->GetPaddr(), data);
1.1       root      106:        return data;
                    107: }
                    108: 
1.1.1.12! root      109: busdata
1.1.1.5   root      110: SysportDevice::Write(uint32 offset, uint32 data)
1.1       root      111: {
1.1.1.5   root      112:        switch (offset) {
1.1       root      113:         case SYSPORT::CONTRAST:
1.1.1.12! root      114:                putlog(1, "$e8e001 <- $%02x", data);
        !           115:                videoctlr->SetContrast(data & 15);
1.1       root      116:                break;
                    117: 
                    118:         case SYSPORT::SCOPE3D:
                    119:         case SYSPORT::IMAGEUNIT:
                    120:                break;
                    121: 
                    122:         case SYSPORT::KEY:
1.1.1.3   root      123:                data &= 0x0e;
1.1.1.8   root      124:                // bit1
                    125:                if ((data & 0x02)) {
1.1.1.9   root      126:                        putlog(0, "$e8e007 <- $%02x (HRL NOT IMPLEMENTED)", data);
1.1.1.3   root      127:                }
1.1.1.8   root      128:                // bit2: NMI リセット
                    129:                if ((data & 0x04)) {
1.1.1.10  root      130:                        nmi->NegateNMI();
1.1.1.8   root      131:                }
1.1.1.6   root      132:                sysport.key_ctrl = (data & 0x08);
1.1       root      133:                break;
                    134: 
                    135:         case SYSPORT::WAIT:
1.1.1.4   root      136:         {
1.1.1.12! root      137:                uint32 rom_wait = data >> 4;
        !           138:                uint32 ram_wait = data & 0xf;
        !           139: 
        !           140:                // InsideOut p.124
        !           141:                rom_wait += 2;
        !           142:                if (ram_wait > 0) {
        !           143:                        ram_wait += 2;
        !           144:                }
        !           145: 
        !           146:                // ROM/RAM に指示。
        !           147:                iplrom1->SetWait(rom_wait);
        !           148:                iplrom2->SetWait(rom_wait);
        !           149:                cgrom->SetWait(rom_wait);
        !           150:                mainram->SetWait(ram_wait);
        !           151: 
        !           152:                // ROM/RAM への指定値で保持する。
        !           153:                sysport.rom_wait = rom_wait;
        !           154:                sysport.ram_wait = ram_wait;
1.1       root      155:                break;
1.1.1.4   root      156:         }
1.1       root      157: 
                    158:         case SYSPORT::MPU:
                    159:                break;
                    160: 
                    161:         case SYSPORT::SRAMWP:
                    162:                if (data == 0x31) {
1.1.1.10  root      163:                        sram->WriteEnable(true);
1.1       root      164:                } else {
1.1.1.10  root      165:                        sram->WriteEnable(false);
1.1       root      166:                }
                    167:                break;
                    168: 
                    169:         case SYSPORT::POWEROFF:
1.1.1.9   root      170:         {
                    171:                static const std::array<uint8, 3> sig { 0x00, 0x0f, 0x0f };
                    172: 
1.1.1.10  root      173:                if (sysport.pwoff_count >= sig.size()) {
                    174:                        // すでにカウントオーバーしている場合何もしない?
                    175:                        putlog(2, "$e8e00f (POWEROFF) <- %02x", data);
                    176:                        break;
                    177:                }
                    178: 
1.1.1.9   root      179:                if (data == sig[sysport.pwoff_count]) {
                    180:                        sysport.pwoff_count++;
                    181:                } else {
                    182:                        sysport.pwoff_count = 0;
                    183:                }
                    184:                putlog(2, "$e8e00f (POWEROFF) <- %02x (count=%d)",
                    185:                        data, sysport.pwoff_count);
                    186:                if (sysport.pwoff_count == sig.size()) {
                    187:                        // pwoff_count はここではクリアせず、電源オン時に再初期化する。
                    188:                        putlog(1, "$e8e00f (POWEROFF) Power Off");
1.1.1.10  root      189:                        GetPowerDevice()->SetSystemPowerOn(false);
1.1.1.9   root      190:                }
1.1       root      191:                break;
1.1.1.9   root      192:         }
1.1.1.3   root      193: 
                    194:         default:
1.1.1.10  root      195:                VMPANIC("corrupted offset=%d", offset);
                    196:                break;
1.1       root      197:        }
                    198:        return 0;
                    199: }
                    200: 
1.1.1.12! root      201: busdata
1.1.1.5   root      202: SysportDevice::Peek(uint32 offset)
1.1       root      203: {
                    204:        uint32 data;
                    205: 
1.1.1.5   root      206:        switch (offset) {
1.1       root      207:         case SYSPORT::CONTRAST:
1.1.1.12! root      208:                data = 0xf0 | videoctlr->GetContrast();
1.1       root      209:                break;
                    210:         case SYSPORT::SCOPE3D:
                    211:                data = 0xff;
                    212:                break;
                    213:         case SYSPORT::IMAGEUNIT:
                    214:                data = 0xff;
                    215:                break;
                    216:         case SYSPORT::KEY:
1.1.1.8   root      217:                // XXX bit3 以外は要実機確認
                    218:                data = 0xf7;
1.1.1.10  root      219:                if (keyboard->IsConnected()) {
1.1.1.8   root      220:                        data |= 0x08;
                    221:                }
1.1       root      222:                break;
                    223:         case SYSPORT::WAIT:
                    224:                data = 0xff;
                    225:                break;
                    226:         case SYSPORT::MPU:
                    227:                data = 0xdc;
                    228:                break;
                    229:         case SYSPORT::SRAMWP:
                    230:                data = 0xff;
                    231:                break;
1.1.1.3   root      232:         case SYSPORT::POWEROFF:
1.1       root      233:                data = 0xff;
                    234:                break;
1.1.1.3   root      235:         default:
1.1.1.10  root      236:                data = 0xff;
                    237:                break;
1.1       root      238:        }
                    239:        return data;
                    240: }
1.1.1.12! root      241: 
        !           242: void
        !           243: SysportDevice::MonitorUpdate(Monitor *, TextScreen& screen)
        !           244: {
        !           245:        screen.Clear();
        !           246: 
        !           247:        static const char * const name[] = {
        !           248:                "Contrast",
        !           249:                "3D Scope",
        !           250:                "Image Unit",
        !           251:                "Keyboard Control",
        !           252:                "ROM/RAM Wait",
        !           253:                "MPU/FPU Type",
        !           254:                "SRAM Protect",
        !           255:                "PowerOff Sequence",
        !           256:        };
        !           257: 
        !           258:        uint8 val[8];
        !           259:        const uint32 disphex = 0x39;
        !           260:        for (int i = 0; i < 8; i++) {
        !           261:                char hex[4];
        !           262:                if ((disphex & (1U << i)) != 0) {
        !           263:                        val[i] = Peek(i);
        !           264:                        snprintf(hex, sizeof(hex), "%02x", val[i]);
        !           265:                } else {
        !           266:                        strlcpy(hex, "--", sizeof(hex));
        !           267:                }
        !           268: 
        !           269:                screen.Print(0, i, "$%06x %s: #%d %-17s:",
        !           270:                        baseaddr + 1 + i * 2, hex, i, name[i]);
        !           271:        }
        !           272: 
        !           273:        int x = 34;
        !           274:        // #0 Contrast
        !           275:        screen.Print(x, 0, "%2d", videoctlr->GetContrast());
        !           276:        screen.Puts(x, 1, "(Not Supported)");
        !           277:        screen.Puts(x, 2, "(Not Supported)");
        !           278:        // #3 Keyboard
        !           279:        if ((val[SYSPORT::KEY] & 0x08) != 0) {
        !           280:                screen.Puts(x, 3, "Connected");
        !           281:        } else {
        !           282:                screen.Puts(x, 3, "Not connected");
        !           283:        }
        !           284:        // #4 ROM/RAM Wait
        !           285:        screen.Print(x, 4, "ROM %2u clk, RAM %2u clk",
        !           286:                sysport.rom_wait, sysport.ram_wait);
        !           287:        // #5 MPU/FPU Type
        !           288:        screen.Puts(x, 5, "MC68030 / 25MHz");
        !           289:        // #6 SRAM
        !           290:        if (sram->IsWriteable()) {
        !           291:                screen.Puts(x, 6, "Writeable");
        !           292:        } else {
        !           293:                screen.Puts(x, 6, "Protected");
        !           294:        }
        !           295:        // #7 PowerOff
        !           296:        screen.Print(x, 7, "%d/3", sysport.pwoff_count);
        !           297: }

unix.superglobalmegacorp.com

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