Annotation of previous/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: 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.