Annotation of previous_trunk/src/tmc.c, revision 1.1.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.