Annotation of previous_trunk/src/tmc.c, revision 1.1

1.1     ! root        1: #include "main.h"
        !             2: #include "configuration.h"
        !             3: #include "m68000.h"
        !             4: #include "sysdeps.h"
        !             5: #include "sysReg.h"
        !             6: #include "adb.h"
        !             7: #include "tmc.h"
        !             8: 
        !             9: #define LOG_TMC_LEVEL LOG_DEBUG
        !            10: 
        !            11: /* NeXT TMC emulation */
        !            12: 
        !            13: #define TMC_ADB_ADDR_MASK      0x02208000
        !            14: 
        !            15: #define TMC_REGS_MASK          0x0000FFFF
        !            16: 
        !            17: /* TMC registers */
        !            18: 
        !            19: struct {
        !            20:        Uint32 scr1;
        !            21:        Uint32 control;
        !            22:        Uint32 horizontal;
        !            23:        Uint32 vertical;
        !            24:        Uint8 video_intr;
        !            25:        Uint32 nitro;
        !            26: } tmc;
        !            27: 
        !            28: /* Additional System Control Register for Turbo systems:
        !            29:  * -------- -------- -------- -----xxx  bits 0:2   --> cpu speed
        !            30:  * -------- -------- -------- --xx----  bits 4:5   --> main memory speed
        !            31:  * -------- -------- -------- xx------  bits 6:7   --> video memory speed
        !            32:  * -------- -------- ----xxxx --------  bits 8:11  --> cpu revision
        !            33:  * -------- -------- xxxx---- --------  bits 12:15 --> cpu type
        !            34:  * xxxx---- -------- -------- --------  bits 28:31 --> slot id
        !            35:  * ----xxxx xxxxxxxx -------- ----x---  all other bits: 1
        !            36:  *
        !            37:  * cpu speed:       7 = 33MHz?
        !            38:  * main mem speed:  0 = 60ns, 1 = 70ns, 2 = 80ns, 3 = 100ns
        !            39:  * video mem speed: 3 on all Turbo systems (100ns)?
        !            40:  * cpu revision:    0xF = rev 0
        !            41:  *                  0xE = rev 1
        !            42:  *                  0xD = rev 2
        !            43:  *                  0xC - 0x0: rev 3 - 15
        !            44:  * cpu type:        4 = NeXTstation turbo monochrome
        !            45:  *                  5 = NeXTstation turbo color
        !            46:  *                  8 = NeXTcube turbo
        !            47:  */
        !            48: 
        !            49: #define TURBOSCR_FMASK   0x0FFF0F08
        !            50: 
        !            51: static void TurboSCR1_Reset(void) {
        !            52:        Uint8 memory_speed = 0;
        !            53:        Uint8 cpu_speed = 0x07; // 33 MHz
        !            54:        
        !            55:        if (ConfigureParams.System.nCpuFreq<20) {
        !            56:                cpu_speed = 4;
        !            57:        } else if (ConfigureParams.System.nCpuFreq<25) {
        !            58:                cpu_speed = 5;
        !            59:        } else if (ConfigureParams.System.nCpuFreq<33) {
        !            60:                cpu_speed = 6;
        !            61:        } else {
        !            62:                cpu_speed = 7;
        !            63:        }
        !            64:        
        !            65:        switch (ConfigureParams.Memory.nMemorySpeed) {
        !            66:                case MEMORY_120NS: memory_speed = 0x00; break;
        !            67:                case MEMORY_100NS: memory_speed = 0x50; break;
        !            68:                case MEMORY_80NS: memory_speed = 0xA0; break;
        !            69:                case MEMORY_60NS: memory_speed = 0xF0; break;
        !            70:                default: Log_Printf(LOG_WARN, "Turbo SCR1 error: unknown memory speed\n"); break;
        !            71:        }
        !            72:        tmc.scr1 = ((memory_speed&0xF0)|(cpu_speed&0x07));
        !            73:        if (ConfigureParams.System.nMachineType == NEXT_CUBE040)
        !            74:                tmc.scr1 |= 0x8000;
        !            75:        else if (ConfigureParams.System.bColor) {
        !            76:                tmc.scr1 |= 0x5000;
        !            77:        } else {
        !            78:                tmc.scr1 |= 0x4000;
        !            79:        }
        !            80:        tmc.scr1 |= TURBOSCR_FMASK;
        !            81: }
        !            82: 
        !            83: 
        !            84: 
        !            85: /* Register read/write functions */
        !            86: 
        !            87: static void tmc_ill_write(Uint8 val) {
        !            88:        Log_Printf(LOG_WARN, "[TMC] Illegal write!\n");
        !            89: }
        !            90: 
        !            91: static Uint8 tmc_unimpl_read(void) {
        !            92:        Log_Printf(LOG_WARN, "[TMC] Unimplemented read!\n");
        !            93:        return 0;
        !            94: }
        !            95: 
        !            96: static void tmc_unimpl_write(Uint8 val) {
        !            97:        Log_Printf(LOG_WARN, "[TMC] Unimplemented write!\n");
        !            98: }
        !            99: 
        !           100: static Uint8 tmc_void_read(void) {
        !           101:        return 0;
        !           102: }
        !           103: 
        !           104: static void tmc_void_write(Uint8 val) {
        !           105: }
        !           106: 
        !           107: /* SCR1 */
        !           108: static Uint8 tmc_scr1_read0(void) {
        !           109:        Log_Printf(LOG_WARN,"[TMC] SCR1 read at $0x2200000 PC=$%08x\n",m68k_getpc());
        !           110:        return (tmc.scr1>>24);
        !           111: }
        !           112: static Uint8 tmc_scr1_read1(void) {
        !           113:        Log_Printf(LOG_WARN,"[TMC] SCR1 read at $0x2200001 PC=$%08x\n",m68k_getpc());
        !           114:        return (tmc.scr1>>16);
        !           115: }
        !           116: static Uint8 tmc_scr1_read2(void) {
        !           117:        Log_Printf(LOG_WARN,"[TMC] SCR1 read at $0x2200002 PC=$%08x\n",m68k_getpc());
        !           118:        return (tmc.scr1>>8);
        !           119: }
        !           120: static Uint8 tmc_scr1_read3(void) {
        !           121:        Log_Printf(LOG_WARN,"[TMC] SCR1 read at $0x2200003 PC=$%08x\n",m68k_getpc());
        !           122:        return tmc.scr1;
        !           123: }
        !           124: 
        !           125: /* TMC Control Register */
        !           126: 
        !           127: static Uint8 tmc_ctrl_read0(void) {
        !           128:        return (tmc.control>>24);
        !           129: }
        !           130: static Uint8 tmc_ctrl_read1(void) {
        !           131:        return (tmc.control>>16);
        !           132: }
        !           133: static Uint8 tmc_ctrl_read2(void) {
        !           134:        return (tmc.control>>8);
        !           135: }
        !           136: static Uint8 tmc_ctrl_read3(void) {
        !           137:        return tmc.control;
        !           138: }
        !           139: 
        !           140: static void tmc_ctrl_write0(Uint8 val) {
        !           141:        tmc.control &= 0x00FFFFFF;
        !           142:        tmc.control |= (val&0xFF)<<24;
        !           143: }
        !           144: static void tmc_ctrl_write1(Uint8 val) {
        !           145:        tmc.control &= 0xFF00FFFF;
        !           146:        tmc.control |= (val&0xFF)<<16;
        !           147: }
        !           148: static void tmc_ctrl_write2(Uint8 val) {
        !           149:        val &= ~0x04; /* no parity memory */
        !           150:        
        !           151:        tmc.control &= 0xFFFF00FF;
        !           152:        tmc.control |= (val&0xFF)<<8;
        !           153: }
        !           154: static void tmc_ctrl_write3(Uint8 val) {
        !           155:        tmc.control &= 0xFFFFFF00;
        !           156:        tmc.control |= val&0xFF;
        !           157: }
        !           158: 
        !           159: 
        !           160: /* Video Interrupt Register */
        !           161: #define TMC_VI_INTERRUPT       0x01
        !           162: #define TMC_VI_INT_MASK                0x02
        !           163: 
        !           164: /* Horizontal and Vertical Configruation Registers */
        !           165: #define HFPORCH  0x18
        !           166: #define HSYNC   0x20
        !           167: #define HBPORCH  0x48
        !           168: #define HDISCNT         0x118
        !           169: 
        !           170: #define VFPORCH  0x08
        !           171: #define VSYNC   0x08
        !           172: #define VBPORCH         0x30
        !           173: #define VDISCNT         0x340
        !           174: 
        !           175: static void tmc_video_reg_reset(void) {
        !           176:        tmc.video_intr = 0x00;
        !           177:        tmc.horizontal = (HFPORCH<<25)|(HSYNC<<19)|(HBPORCH<<12)|HDISCNT;
        !           178:        tmc.vertical = (VFPORCH<<25)|(VSYNC<<19)|(VBPORCH<<12)|VDISCNT;
        !           179: }
        !           180: 
        !           181: void tmc_video_interrupt(void) {
        !           182:        if (tmc.video_intr&TMC_VI_INT_MASK) {
        !           183:                set_interrupt(INT_DISK, SET_INT);
        !           184:                tmc.video_intr |= TMC_VI_INTERRUPT;
        !           185:        }
        !           186: }
        !           187: 
        !           188: static Uint8 tmc_vir_read0(void) {
        !           189:        return tmc.video_intr;
        !           190: }
        !           191: 
        !           192: static void tmc_vir_write0(Uint8 val) {
        !           193:        tmc.video_intr = val;
        !           194:        if (tmc.video_intr&TMC_VI_INTERRUPT) {
        !           195:                tmc.video_intr &= ~TMC_VI_INTERRUPT;
        !           196:                set_interrupt(INT_DISK, RELEASE_INT);
        !           197:        }
        !           198: }
        !           199: 
        !           200: static Uint8 tmc_hcr_read0(void) {
        !           201:        return (tmc.horizontal>>24);
        !           202: }
        !           203: static Uint8 tmc_hcr_read1(void) {
        !           204:        return (tmc.horizontal>>16);
        !           205: }
        !           206: static Uint8 tmc_hcr_read2(void) {
        !           207:        return (tmc.horizontal>>8);
        !           208: }
        !           209: static Uint8 tmc_hcr_read3(void) {
        !           210:        return tmc.horizontal;
        !           211: }
        !           212: 
        !           213: static void tmc_hcr_write0(Uint8 val) {
        !           214:        tmc.horizontal &= 0x00FFFFFF;
        !           215:        tmc.horizontal |= (val&0xFF)<<24;
        !           216: }
        !           217: static void tmc_hcr_write1(Uint8 val) {
        !           218:        tmc.horizontal &= 0xFF00FFFF;
        !           219:        tmc.horizontal |= (val&0xFF)<<16;
        !           220: }
        !           221: static void tmc_hcr_write2(Uint8 val) {
        !           222:        tmc.horizontal &= 0xFFFF00FF;
        !           223:        tmc.horizontal |= (val&0xFF)<<8;
        !           224: }
        !           225: static void tmc_hcr_write3(Uint8 val) {
        !           226:        tmc.horizontal &= 0xFFFFFF00;
        !           227:        tmc.horizontal |= val&0xFF;
        !           228: }
        !           229: 
        !           230: static Uint8 tmc_vcr_read0(void) {
        !           231:        return (tmc.vertical>>24);
        !           232: }
        !           233: static Uint8 tmc_vcr_read1(void) {
        !           234:        return (tmc.vertical>>16);
        !           235: }
        !           236: static Uint8 tmc_vcr_read2(void) {
        !           237:        return (tmc.vertical>>8);
        !           238: }
        !           239: static Uint8 tmc_vcr_read3(void) {
        !           240:        return tmc.vertical;
        !           241: }
        !           242: 
        !           243: static void tmc_vcr_write0(Uint8 val) {
        !           244:        tmc.vertical &= 0x00FFFFFF;
        !           245:        tmc.vertical |= (val&0xFF)<<24;
        !           246: }
        !           247: static void tmc_vcr_write1(Uint8 val) {
        !           248:        tmc.vertical &= 0xFF00FFFF;
        !           249:        tmc.vertical |= (val&0xFF)<<16;
        !           250: }
        !           251: static void tmc_vcr_write2(Uint8 val) {
        !           252:        tmc.vertical &= 0xFFFF00FF;
        !           253:        tmc.vertical |= (val&0xFF)<<8;
        !           254: }
        !           255: static void tmc_vcr_write3(Uint8 val) {
        !           256:        tmc.vertical &= 0xFFFFFF00;
        !           257:        tmc.vertical |= val&0xFF;
        !           258: }
        !           259: 
        !           260: 
        !           261: /* Read register functions */
        !           262: static Uint8 (*tmc_read_reg[36])(void) = {
        !           263:        tmc_scr1_read0, tmc_scr1_read1, tmc_scr1_read2, tmc_scr1_read3,
        !           264:        tmc_unimpl_read, tmc_unimpl_read, tmc_unimpl_read, tmc_unimpl_read,
        !           265:        tmc_unimpl_read, tmc_unimpl_read, tmc_unimpl_read, tmc_unimpl_read,
        !           266:        tmc_unimpl_read, tmc_unimpl_read, tmc_unimpl_read, tmc_unimpl_read,
        !           267:        tmc_ctrl_read0, tmc_ctrl_read1, tmc_ctrl_read2, tmc_ctrl_read3,
        !           268:        tmc_unimpl_read, tmc_unimpl_read, tmc_unimpl_read, tmc_unimpl_read,
        !           269:        tmc_unimpl_read, tmc_unimpl_read, tmc_unimpl_read, tmc_unimpl_read,
        !           270:        tmc_unimpl_read, tmc_unimpl_read, tmc_unimpl_read, tmc_unimpl_read,
        !           271:        tmc_unimpl_read, tmc_unimpl_read, tmc_unimpl_read, tmc_unimpl_read
        !           272: };
        !           273: 
        !           274: static Uint8 (*tmc_read_vid_reg[16])(void) = {
        !           275:        tmc_vir_read0, tmc_void_read, tmc_void_read, tmc_void_read,
        !           276:        tmc_unimpl_read, tmc_unimpl_read, tmc_unimpl_read, tmc_unimpl_read,
        !           277:        tmc_hcr_read0, tmc_hcr_read1, tmc_hcr_read2, tmc_hcr_read3,
        !           278:        tmc_vcr_read0, tmc_vcr_read1, tmc_vcr_read2, tmc_vcr_read3
        !           279: };
        !           280: 
        !           281: /* Write register functions */
        !           282: static void (*tmc_write_reg[36])(Uint8) = {
        !           283:        tmc_ill_write, tmc_ill_write, tmc_ill_write, tmc_ill_write,
        !           284:        tmc_unimpl_write, tmc_unimpl_write, tmc_unimpl_write, tmc_unimpl_write,
        !           285:        tmc_unimpl_write, tmc_unimpl_write, tmc_unimpl_write, tmc_unimpl_write,
        !           286:        tmc_unimpl_write, tmc_unimpl_write, tmc_unimpl_write, tmc_unimpl_write,
        !           287:        tmc_ctrl_write0, tmc_ctrl_write1, tmc_ctrl_write2, tmc_ctrl_write3,
        !           288:        tmc_unimpl_write, tmc_unimpl_write, tmc_unimpl_write, tmc_unimpl_write,
        !           289:        tmc_unimpl_write, tmc_unimpl_write, tmc_unimpl_write, tmc_unimpl_write,
        !           290:        tmc_unimpl_write, tmc_unimpl_write, tmc_unimpl_write, tmc_unimpl_write,
        !           291:        tmc_unimpl_write, tmc_unimpl_write, tmc_unimpl_write, tmc_unimpl_write
        !           292: };
        !           293: 
        !           294: static void (*tmc_write_vid_reg[16])(Uint8) = {
        !           295:        tmc_vir_write0, tmc_void_write, tmc_void_write, tmc_void_write,
        !           296:        tmc_unimpl_write, tmc_unimpl_write, tmc_unimpl_write, tmc_unimpl_write,
        !           297:        tmc_hcr_write0, tmc_hcr_write1, tmc_hcr_write2, tmc_hcr_write3,
        !           298:        tmc_vcr_write0, tmc_vcr_write1, tmc_vcr_write2, tmc_vcr_write3
        !           299: };
        !           300: 
        !           301: 
        !           302: Uint32 tmc_lget(uaecptr addr) {
        !           303:        Uint32 val = 0;
        !           304:        
        !           305:     if (addr%4) {
        !           306:         Log_Printf(LOG_WARN, "[TMC] Unaligned access.");
        !           307:         abort();
        !           308:     }
        !           309:        
        !           310:        if (addr==0x02210000) {
        !           311:                Log_Printf(LOG_WARN, "[TMC] Nitro register lget from $%08X",addr);
        !           312:                if (ConfigureParams.System.nCpuFreq==40) {
        !           313:                        val = tmc.nitro;
        !           314:                } else {
        !           315:                        Log_Printf(LOG_WARN, "[TMC] No nitro --> bus error!");
        !           316:                        M68000_BusError(addr, 1);
        !           317:                }
        !           318:                return val;
        !           319:        }
        !           320: 
        !           321:        if ((addr&0xFFFFF00)==TMC_ADB_ADDR_MASK) {
        !           322:                return adb_lget(addr);
        !           323:        }
        !           324:        
        !           325:        Log_Printf(LOG_TMC_LEVEL, "[TMC] lget from %08X",addr);
        !           326:        
        !           327:        addr &= TMC_REGS_MASK;
        !           328: 
        !           329:        if (addr<36) {
        !           330:                val = tmc_read_reg[addr]()<<24;
        !           331:                val |= tmc_read_reg[addr+1]()<<16;
        !           332:                val |= tmc_read_reg[addr+2]()<<8;
        !           333:                val |= tmc_read_reg[addr+3]();
        !           334:        } else if (addr>=128 && addr<144) {
        !           335:                val = tmc_read_vid_reg[addr&0xF]()<<24;
        !           336:                val |= tmc_read_vid_reg[(addr+1)&0xF]()<<16;
        !           337:                val |= tmc_read_vid_reg[(addr+2)&0xF]()<<8;
        !           338:                val |= tmc_read_vid_reg[(addr+3)&0xF]();
        !           339:        }
        !           340: 
        !           341:        return val;
        !           342: }
        !           343: 
        !           344: Uint32 tmc_wget(uaecptr addr) {
        !           345:     Uint32 val = 0;
        !           346:     
        !           347:        if (addr%2) {
        !           348:                Log_Printf(LOG_WARN, "[TMC] Unaligned access.");
        !           349:                abort();
        !           350:        }
        !           351:        
        !           352:        if ((addr&0xFFFFF00)==TMC_ADB_ADDR_MASK) {
        !           353:                return adb_wget(addr);
        !           354:        }
        !           355:        
        !           356:        Log_Printf(LOG_TMC_LEVEL, "[TMC] wget from %08X",addr);
        !           357: 
        !           358:        addr &= TMC_REGS_MASK;
        !           359:        
        !           360:        if (addr<36) {
        !           361:                val = tmc_read_reg[addr]()<<8;
        !           362:                val |= tmc_read_reg[addr+1]();
        !           363:        } else if (addr>=128 && addr<144) {
        !           364:                val = tmc_read_vid_reg[addr&0xF]()<<8;
        !           365:                val |= tmc_read_vid_reg[(addr+1)&0xF]();
        !           366:        }
        !           367:        
        !           368:        return val;
        !           369: }
        !           370: 
        !           371: Uint32 tmc_bget(uaecptr addr) {
        !           372:        if ((addr&0xFFFFF00)==TMC_ADB_ADDR_MASK) {
        !           373:                return adb_bget(addr);
        !           374:        }
        !           375:        
        !           376:        Log_Printf(LOG_TMC_LEVEL, "[TMC] bget from %08X",addr);
        !           377: 
        !           378:        addr &= TMC_REGS_MASK;
        !           379: 
        !           380:        if (addr<36) {
        !           381:                return tmc_read_reg[addr]();
        !           382:        } else if (addr>=128 && addr<144) {
        !           383:                return tmc_read_vid_reg[addr&0xF]();
        !           384:        }
        !           385: 
        !           386:     return 0;
        !           387: }
        !           388: 
        !           389: void tmc_lput(uaecptr addr, Uint32 l) {
        !           390:        if (addr%4) {
        !           391:                Log_Printf(LOG_WARN, "[TMC] Unaligned access.");
        !           392:                abort();
        !           393:        }
        !           394:        
        !           395:        if (addr==0x02210000) {
        !           396:                Log_Printf(LOG_WARN, "[TMC] Nitro register lput %08X at $%08X",l,addr);
        !           397:                if (ConfigureParams.System.nCpuFreq==40) {
        !           398:                        tmc.nitro = l&0x0000011F;
        !           399:                } else {
        !           400:                        Log_Printf(LOG_WARN, "[TMC] No nitro --> bus error!");
        !           401:                        M68000_BusError(addr, 0);
        !           402:                }
        !           403:                return;
        !           404:        }
        !           405:        
        !           406:        if ((addr&0xFFFFF00)==TMC_ADB_ADDR_MASK) {
        !           407:                adb_lput(addr, l);
        !           408:                return;
        !           409:        }
        !           410:        
        !           411:        Log_Printf(LOG_TMC_LEVEL, "[TMC] lput %08X to %08X",l,addr);
        !           412: 
        !           413:        addr &= TMC_REGS_MASK;
        !           414:        
        !           415:        if (addr<36) {
        !           416:                tmc_write_reg[addr](l>>24);
        !           417:                tmc_write_reg[addr+1](l>>16);
        !           418:                tmc_write_reg[addr+2](l>>8);
        !           419:                tmc_write_reg[addr+3](l);
        !           420:        } else if (addr>=128 && addr<144) {
        !           421:                tmc_write_vid_reg[addr&0xF](l>>24);
        !           422:                tmc_write_vid_reg[(addr+1)&0xF](l>>16);
        !           423:                tmc_write_vid_reg[(addr+2)&0xF](l>>8);
        !           424:                tmc_write_vid_reg[(addr+3)&0xF](l);
        !           425:        }
        !           426: }
        !           427: 
        !           428: void tmc_wput(uaecptr addr, Uint32 w) {
        !           429:        if (addr%2) {
        !           430:                Log_Printf(LOG_WARN, "[TMC] Unaligned access.");
        !           431:                abort();
        !           432:        }
        !           433:        
        !           434:        if ((addr&0xFFFFF00)==TMC_ADB_ADDR_MASK) {
        !           435:                adb_wput(addr, w);
        !           436:                return;
        !           437:        }
        !           438:        
        !           439:        Log_Printf(LOG_TMC_LEVEL, "[TMC] wput %04X to %08X",w,addr);
        !           440: 
        !           441:        addr &= TMC_REGS_MASK;
        !           442:        
        !           443:        if (addr<36) {
        !           444:                tmc_write_reg[addr](w>>8);
        !           445:                tmc_write_reg[addr+1](w);
        !           446:        } else if (addr>=128 && addr<144) {
        !           447:                tmc_write_vid_reg[addr&0xF](w>>8);
        !           448:                tmc_write_vid_reg[(addr+1)&0xF](w);
        !           449:        }
        !           450: }
        !           451: 
        !           452: void tmc_bput(uaecptr addr, Uint32 b) {
        !           453:        if ((addr&0xFFFFF00)==TMC_ADB_ADDR_MASK) {
        !           454:                adb_bput(addr, b);
        !           455:                return;
        !           456:        }
        !           457:        
        !           458:        Log_Printf(LOG_TMC_LEVEL, "[TMC] bput %02X to %08X",b,addr);
        !           459: 
        !           460:        addr &= TMC_REGS_MASK;
        !           461:        
        !           462:        if (addr<36) {
        !           463:                tmc_write_reg[addr](b);
        !           464:        } else if (addr>=128 && addr<144) {
        !           465:                tmc_write_vid_reg[addr&0xF](b);
        !           466:        }
        !           467: }
        !           468: 
        !           469: 
        !           470: /* TMC Reset */
        !           471: 
        !           472: void TMC_Reset(void) {
        !           473:        TurboSCR1_Reset();
        !           474:        
        !           475:        tmc_video_reg_reset();
        !           476:        tmc.control = 0x0D17038F;
        !           477:        tmc.nitro = 0x00000000;
        !           478:        ADB_Reset();
        !           479: }

unix.superglobalmegacorp.com

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