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

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

unix.superglobalmegacorp.com

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