Annotation of previous/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: void TurboSCR1_Reset(void) {
        !            52:        Uint8 memory_speed;
        !            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: Uint8 tmc_ill_read(void) {
        !            88:        Log_Printf(LOG_WARN, "[TMC] Illegal read!\n");
        !            89:        return 0;
        !            90: }
        !            91: 
        !            92: void tmc_ill_write(Uint8 val) {
        !            93:        Log_Printf(LOG_WARN, "[TMC] Illegal write!\n");
        !            94: }
        !            95: 
        !            96: Uint8 tmc_unimpl_read(void) {
        !            97:        Log_Printf(LOG_WARN, "[TMC] Unimplemented read!\n");
        !            98:        return 0;
        !            99: }
        !           100: 
        !           101: void tmc_unimpl_write(Uint8 val) {
        !           102:        Log_Printf(LOG_WARN, "[TMC] Unimplemented write!\n");
        !           103: }
        !           104: 
        !           105: Uint8 tmc_void_read(void) {
        !           106:        return 0;
        !           107: }
        !           108: 
        !           109: void tmc_void_write(Uint8 val) {
        !           110: }
        !           111: 
        !           112: /* SCR1 */
        !           113: Uint8 tmc_scr1_read0(void) {
        !           114:        Log_Printf(LOG_WARN,"[TMC] SCR1 read at $0x2200000 PC=$%08x\n",m68k_getpc());
        !           115:        return (tmc.scr1>>24);
        !           116: }
        !           117: Uint8 tmc_scr1_read1(void) {
        !           118:        Log_Printf(LOG_WARN,"[TMC] SCR1 read at $0x2200001 PC=$%08x\n",m68k_getpc());
        !           119:        return (tmc.scr1>>16);
        !           120: }
        !           121: Uint8 tmc_scr1_read2(void) {
        !           122:        Log_Printf(LOG_WARN,"[TMC] SCR1 read at $0x2200002 PC=$%08x\n",m68k_getpc());
        !           123:        return (tmc.scr1>>8);
        !           124: }
        !           125: Uint8 tmc_scr1_read3(void) {
        !           126:        Log_Printf(LOG_WARN,"[TMC] SCR1 read at $0x2200003 PC=$%08x\n",m68k_getpc());
        !           127:        return tmc.scr1;
        !           128: }
        !           129: 
        !           130: /* TMC Control Register */
        !           131: 
        !           132: Uint8 tmc_ctrl_read0(void) {
        !           133:        return (tmc.control>>24);
        !           134: }
        !           135: Uint8 tmc_ctrl_read1(void) {
        !           136:        return (tmc.control>>16);
        !           137: }
        !           138: Uint8 tmc_ctrl_read2(void) {
        !           139:        return (tmc.control>>8);
        !           140: }
        !           141: Uint8 tmc_ctrl_read3(void) {
        !           142:        return tmc.control;
        !           143: }
        !           144: 
        !           145: void tmc_ctrl_write0(Uint8 val) {
        !           146:        tmc.control &= 0x00FFFFFF;
        !           147:        tmc.control |= (val&0xFF)<<24;
        !           148: }
        !           149: void tmc_ctrl_write1(Uint8 val) {
        !           150:        tmc.control &= 0xFF00FFFF;
        !           151:        tmc.control |= (val&0xFF)<<16;
        !           152: }
        !           153: void tmc_ctrl_write2(Uint8 val) {
        !           154:        val &= ~0x04; /* no parity memory */
        !           155:        
        !           156:        tmc.control &= 0xFFFF00FF;
        !           157:        tmc.control |= (val&0xFF)<<8;
        !           158: }
        !           159: void tmc_ctrl_write3(Uint8 val) {
        !           160:        tmc.control &= 0xFFFFFF00;
        !           161:        tmc.control |= val&0xFF;
        !           162: }
        !           163: 
        !           164: 
        !           165: /* Video Interrupt Register */
        !           166: #define TMC_VI_INTERRUPT       0x01
        !           167: #define TMC_VI_INT_MASK                0x02
        !           168: 
        !           169: /* Horizontal and Vertical Configruation Registers */
        !           170: #define HFPORCH  0x18
        !           171: #define HSYNC   0x20
        !           172: #define HBPORCH  0x48
        !           173: #define HDISCNT         0x118
        !           174: 
        !           175: #define VFPORCH  0x08
        !           176: #define VSYNC   0x08
        !           177: #define VBPORCH         0x30
        !           178: #define VDISCNT         0x340
        !           179: 
        !           180: void tmc_video_reg_reset(void) {
        !           181:        tmc.video_intr = 0x00;
        !           182:        tmc.horizontal = (HFPORCH<<25)|(HSYNC<<19)|(HBPORCH<<12)|HDISCNT;
        !           183:        tmc.vertical = (VFPORCH<<25)|(VSYNC<<19)|(VBPORCH<<12)|VDISCNT;
        !           184: }
        !           185: 
        !           186: void tmc_video_interrupt(void) {
        !           187:        if (tmc.video_intr&TMC_VI_INT_MASK) {
        !           188:                set_interrupt(INT_DISK, SET_INT);
        !           189:                tmc.video_intr |= TMC_VI_INTERRUPT;
        !           190:        }
        !           191: }
        !           192: 
        !           193: Uint8 tmc_vir_read0(void) {
        !           194:        return tmc.video_intr;
        !           195: }
        !           196: 
        !           197: void tmc_vir_write0(Uint8 val) {
        !           198:        tmc.video_intr = val;
        !           199:        if (tmc.video_intr&TMC_VI_INTERRUPT) {
        !           200:                tmc.video_intr &= ~TMC_VI_INTERRUPT;
        !           201:                set_interrupt(INT_DISK, RELEASE_INT);
        !           202:        }
        !           203: }
        !           204: 
        !           205: Uint8 tmc_hcr_read0(void) {
        !           206:        return (tmc.horizontal>>24);
        !           207: }
        !           208: Uint8 tmc_hcr_read1(void) {
        !           209:        return (tmc.horizontal>>16);
        !           210: }
        !           211: Uint8 tmc_hcr_read2(void) {
        !           212:        return (tmc.horizontal>>8);
        !           213: }
        !           214: Uint8 tmc_hcr_read3(void) {
        !           215:        return tmc.horizontal;
        !           216: }
        !           217: 
        !           218: void tmc_hcr_write0(Uint8 val) {
        !           219:        tmc.horizontal &= 0x00FFFFFF;
        !           220:        tmc.horizontal |= (val&0xFF)<<24;
        !           221: }
        !           222: void tmc_hcr_write1(Uint8 val) {
        !           223:        tmc.horizontal &= 0xFF00FFFF;
        !           224:        tmc.horizontal |= (val&0xFF)<<16;
        !           225: }
        !           226: void tmc_hcr_write2(Uint8 val) {
        !           227:        tmc.horizontal &= 0xFFFF00FF;
        !           228:        tmc.horizontal |= (val&0xFF)<<8;
        !           229: }
        !           230: void tmc_hcr_write3(Uint8 val) {
        !           231:        tmc.horizontal &= 0xFFFFFF00;
        !           232:        tmc.horizontal |= val&0xFF;
        !           233: }
        !           234: 
        !           235: Uint8 tmc_vcr_read0(void) {
        !           236:        return (tmc.vertical>>24);
        !           237: }
        !           238: Uint8 tmc_vcr_read1(void) {
        !           239:        return (tmc.vertical>>16);
        !           240: }
        !           241: Uint8 tmc_vcr_read2(void) {
        !           242:        return (tmc.vertical>>8);
        !           243: }
        !           244: Uint8 tmc_vcr_read3(void) {
        !           245:        return tmc.vertical;
        !           246: }
        !           247: 
        !           248: void tmc_vcr_write0(Uint8 val) {
        !           249:        tmc.vertical &= 0x00FFFFFF;
        !           250:        tmc.vertical |= (val&0xFF)<<24;
        !           251: }
        !           252: void tmc_vcr_write1(Uint8 val) {
        !           253:        tmc.vertical &= 0xFF00FFFF;
        !           254:        tmc.vertical |= (val&0xFF)<<16;
        !           255: }
        !           256: void tmc_vcr_write2(Uint8 val) {
        !           257:        tmc.vertical &= 0xFFFF00FF;
        !           258:        tmc.vertical |= (val&0xFF)<<8;
        !           259: }
        !           260: void tmc_vcr_write3(Uint8 val) {
        !           261:        tmc.vertical &= 0xFFFFFF00;
        !           262:        tmc.vertical |= val&0xFF;
        !           263: }
        !           264: 
        !           265: 
        !           266: /* Read register functions */
        !           267: static Uint8 (*tmc_read_reg[36])(void) = {
        !           268:        tmc_scr1_read0, tmc_scr1_read1, tmc_scr1_read2, tmc_scr1_read3,
        !           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:        tmc_ctrl_read0, tmc_ctrl_read1, tmc_ctrl_read2, tmc_ctrl_read3,
        !           273:        tmc_unimpl_read, tmc_unimpl_read, tmc_unimpl_read, tmc_unimpl_read,
        !           274:        tmc_unimpl_read, tmc_unimpl_read, tmc_unimpl_read, tmc_unimpl_read,
        !           275:        tmc_unimpl_read, tmc_unimpl_read, tmc_unimpl_read, tmc_unimpl_read,
        !           276:        tmc_unimpl_read, tmc_unimpl_read, tmc_unimpl_read, tmc_unimpl_read
        !           277: };
        !           278: 
        !           279: static Uint8 (*tmc_read_vid_reg[16])(void) = {
        !           280:        tmc_vir_read0, tmc_void_read, tmc_void_read, tmc_void_read,
        !           281:        tmc_unimpl_read, tmc_unimpl_read, tmc_unimpl_read, tmc_unimpl_read,
        !           282:        tmc_hcr_read0, tmc_hcr_read1, tmc_hcr_read2, tmc_hcr_read3,
        !           283:        tmc_vcr_read0, tmc_vcr_read1, tmc_vcr_read2, tmc_vcr_read3
        !           284: };
        !           285: 
        !           286: /* Write register functions */
        !           287: static void (*tmc_write_reg[36])(Uint8) = {
        !           288:        tmc_ill_write, tmc_ill_write, tmc_ill_write, tmc_ill_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:        tmc_ctrl_write0, tmc_ctrl_write1, tmc_ctrl_write2, tmc_ctrl_write3,
        !           293:        tmc_unimpl_write, tmc_unimpl_write, tmc_unimpl_write, tmc_unimpl_write,
        !           294:        tmc_unimpl_write, tmc_unimpl_write, tmc_unimpl_write, tmc_unimpl_write,
        !           295:        tmc_unimpl_write, tmc_unimpl_write, tmc_unimpl_write, tmc_unimpl_write,
        !           296:        tmc_unimpl_write, tmc_unimpl_write, tmc_unimpl_write, tmc_unimpl_write
        !           297: };
        !           298: 
        !           299: static void (*tmc_write_vid_reg[16])(Uint8) = {
        !           300:        tmc_vir_write0, tmc_void_write, tmc_void_write, tmc_void_write,
        !           301:        tmc_unimpl_write, tmc_unimpl_write, tmc_unimpl_write, tmc_unimpl_write,
        !           302:        tmc_hcr_write0, tmc_hcr_write1, tmc_hcr_write2, tmc_hcr_write3,
        !           303:        tmc_vcr_write0, tmc_vcr_write1, tmc_vcr_write2, tmc_vcr_write3
        !           304: };
        !           305: 
        !           306: 
        !           307: Uint32 tmc_lget(uaecptr addr) {
        !           308:        Uint32 val = 0;
        !           309:        
        !           310:     if (addr%4) {
        !           311:         Log_Printf(LOG_WARN, "[TMC] Unaligned access.");
        !           312:         abort();
        !           313:     }
        !           314:        
        !           315:        if (addr==0x02210000) {
        !           316:                Log_Printf(LOG_WARN, "[TMC] Nitro register lget from $%08X",addr);
        !           317:                if (ConfigureParams.System.nCpuFreq==40) {
        !           318:                        val = tmc.nitro;
        !           319:                } else {
        !           320:                        Log_Printf(LOG_WARN, "[TMC] No nitro --> bus error!");
        !           321:                        M68000_BusError(addr, 1);
        !           322:                }
        !           323:                return val;
        !           324:        }
        !           325: 
        !           326:        if ((addr&0xFFFFF00)==TMC_ADB_ADDR_MASK) {
        !           327:                return adb_lget(addr);
        !           328:        }
        !           329:        
        !           330:        Log_Printf(LOG_TMC_LEVEL, "[TMC] lget from %08X",addr);
        !           331:        
        !           332:        addr &= TMC_REGS_MASK;
        !           333: 
        !           334:        if (addr<36) {
        !           335:                val = tmc_read_reg[addr]()<<24;
        !           336:                val |= tmc_read_reg[addr+1]()<<16;
        !           337:                val |= tmc_read_reg[addr+2]()<<8;
        !           338:                val |= tmc_read_reg[addr+3]();
        !           339:        } else if (addr>=128 && addr<144) {
        !           340:                val = tmc_read_vid_reg[addr&0xF]()<<24;
        !           341:                val |= tmc_read_vid_reg[(addr+1)&0xF]()<<16;
        !           342:                val |= tmc_read_vid_reg[(addr+2)&0xF]()<<8;
        !           343:                val |= tmc_read_vid_reg[(addr+3)&0xF]();
        !           344:        }
        !           345: 
        !           346:        return val;
        !           347: }
        !           348: 
        !           349: Uint32 tmc_wget(uaecptr addr) {
        !           350:     Uint32 val = 0;
        !           351:     
        !           352:        if (addr%2) {
        !           353:                Log_Printf(LOG_WARN, "[TMC] Unaligned access.");
        !           354:                abort();
        !           355:        }
        !           356:        
        !           357:        if ((addr&0xFFFFF00)==TMC_ADB_ADDR_MASK) {
        !           358:                return adb_wget(addr);
        !           359:        }
        !           360:        
        !           361:        Log_Printf(LOG_TMC_LEVEL, "[TMC] wget from %08X",addr);
        !           362: 
        !           363:        addr &= TMC_REGS_MASK;
        !           364:        
        !           365:        if (addr<36) {
        !           366:                val = tmc_read_reg[addr]()<<8;
        !           367:                val |= tmc_read_reg[addr+1]();
        !           368:        } else if (addr>=128 && addr<144) {
        !           369:                val = tmc_read_vid_reg[addr&0xF]()<<8;
        !           370:                val |= tmc_read_vid_reg[(addr+1)&0xF]();
        !           371:        }
        !           372:        
        !           373:        return val;
        !           374: }
        !           375: 
        !           376: Uint32 tmc_bget(uaecptr addr) {
        !           377:        if ((addr&0xFFFFF00)==TMC_ADB_ADDR_MASK) {
        !           378:                return adb_bget(addr);
        !           379:        }
        !           380:        
        !           381:        Log_Printf(LOG_TMC_LEVEL, "[TMC] bget from %08X",addr);
        !           382: 
        !           383:        addr &= TMC_REGS_MASK;
        !           384: 
        !           385:        if (addr<36) {
        !           386:                return tmc_read_reg[addr]();
        !           387:        } else if (addr>=128 && addr<144) {
        !           388:                return tmc_read_vid_reg[addr&0xF]();
        !           389:        }
        !           390: 
        !           391:     return 0;
        !           392: }
        !           393: 
        !           394: void tmc_lput(uaecptr addr, Uint32 l) {
        !           395:        if (addr%4) {
        !           396:                Log_Printf(LOG_WARN, "[TMC] Unaligned access.");
        !           397:                abort();
        !           398:        }
        !           399:        
        !           400:        if (addr==0x02210000) {
        !           401:                Log_Printf(LOG_WARN, "[TMC] Nitro register lput %08X at $%08X",l,addr);
        !           402:                if (ConfigureParams.System.nCpuFreq==40) {
        !           403:                        tmc.nitro = l&0x0000011F;
        !           404:                } else {
        !           405:                        Log_Printf(LOG_WARN, "[TMC] No nitro --> bus error!");
        !           406:                        M68000_BusError(addr, 0);
        !           407:                }
        !           408:                return;
        !           409:        }
        !           410:        
        !           411:        if ((addr&0xFFFFF00)==TMC_ADB_ADDR_MASK) {
        !           412:                adb_lput(addr, l);
        !           413:                return;
        !           414:        }
        !           415:        
        !           416:        Log_Printf(LOG_TMC_LEVEL, "[TMC] lput %08X to %08X",l,addr);
        !           417: 
        !           418:        addr &= TMC_REGS_MASK;
        !           419:        
        !           420:        if (addr<36) {
        !           421:                tmc_write_reg[addr](l>>24);
        !           422:                tmc_write_reg[addr+1](l>>16);
        !           423:                tmc_write_reg[addr+2](l>>8);
        !           424:                tmc_write_reg[addr+3](l);
        !           425:        } else if (addr>=128 && addr<144) {
        !           426:                tmc_write_vid_reg[addr&0xF](l>>24);
        !           427:                tmc_write_vid_reg[(addr+1)&0xF](l>>16);
        !           428:                tmc_write_vid_reg[(addr+2)&0xF](l>>8);
        !           429:                tmc_write_vid_reg[(addr+3)&0xF](l);
        !           430:        }
        !           431: }
        !           432: 
        !           433: void tmc_wput(uaecptr addr, Uint32 w) {
        !           434:        if (addr%2) {
        !           435:                Log_Printf(LOG_WARN, "[TMC] Unaligned access.");
        !           436:                abort();
        !           437:        }
        !           438:        
        !           439:        if ((addr&0xFFFFF00)==TMC_ADB_ADDR_MASK) {
        !           440:                adb_wput(addr, w);
        !           441:                return;
        !           442:        }
        !           443:        
        !           444:        Log_Printf(LOG_TMC_LEVEL, "[TMC] wput %04X to %08X",w,addr);
        !           445: 
        !           446:        addr &= TMC_REGS_MASK;
        !           447:        
        !           448:        if (addr<36) {
        !           449:                tmc_write_reg[addr](w>>8);
        !           450:                tmc_write_reg[addr+1](w);
        !           451:        } else if (addr>=128 && addr<144) {
        !           452:                tmc_write_vid_reg[addr&0xF](w>>8);
        !           453:                tmc_write_vid_reg[(addr+1)&0xF](w);
        !           454:        }
        !           455: }
        !           456: 
        !           457: void tmc_bput(uaecptr addr, Uint32 b) {
        !           458:        if ((addr&0xFFFFF00)==TMC_ADB_ADDR_MASK) {
        !           459:                adb_bput(addr, b);
        !           460:                return;
        !           461:        }
        !           462:        
        !           463:        Log_Printf(LOG_TMC_LEVEL, "[TMC] bput %02X to %08X",b,addr);
        !           464: 
        !           465:        addr &= TMC_REGS_MASK;
        !           466:        
        !           467:        if (addr<36) {
        !           468:                tmc_write_reg[addr](b);
        !           469:        } else if (addr>=128 && addr<144) {
        !           470:                tmc_write_vid_reg[addr&0xF](b);
        !           471:        }
        !           472: }
        !           473: 
        !           474: 
        !           475: /* TMC Reset */
        !           476: 
        !           477: void TMC_Reset(void) {
        !           478:        TurboSCR1_Reset();
        !           479:        
        !           480:        tmc_video_reg_reset();
        !           481:        tmc.control = 0x0D17038F;
        !           482:        tmc.nitro = 0x00000000;
        !           483:        ADB_Reset();
        !           484: }

unix.superglobalmegacorp.com

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