Annotation of previous/src/sysReg.c, revision 1.1.1.3

1.1       root        1: /* NeXT system registers emulation */
                      2: 
                      3: #include <stdlib.h>
                      4: #include "main.h"
                      5: #include "ioMem.h"
                      6: #include "ioMemTables.h"
                      7: #include "video.h"
                      8: #include "configuration.h"
                      9: #include "sysdeps.h"
                     10: #include "m68000.h"
1.1.1.3 ! root       11: #include "dsp.h"
1.1       root       12: #include "sysReg.h"
1.1.1.3 ! root       13: #include "rtcnvram.h"
1.1       root       14: #include "statusbar.h"
                     15: 
                     16: 
1.1.1.3 ! root       17: #define LOG_HARDCLOCK_LEVEL LOG_DEBUG
        !            18: #define LOG_SOFTINT_LEVEL   LOG_DEBUG
        !            19: 
1.1       root       20: #define IO_SEG_MASK    0x1FFFF
                     21: 
1.1.1.3 ! root       22: int SCR_ROM_overlay=0;
        !            23: 
1.1       root       24: static Uint32 scr1=0x00000000;
                     25: 
                     26: static Uint8 scr2_0=0x00;
                     27: static Uint8 scr2_1=0x00;
1.1.1.3 ! root       28: static Uint8 scr2_2=0x00;
1.1       root       29: static Uint8 scr2_3=0x00;
                     30: 
                     31: static Uint32 intStat=0x00000000;
                     32: static Uint32 intMask=0x00000000;
                     33: 
                     34: 
                     35: 
                     36: void SID_Read(void) {
                     37:        Log_Printf(LOG_WARN,"SID read at $%08x PC=$%08x\n", IoAccessCurrentAddress,m68k_getpc());
                     38:        IoMem[IoAccessCurrentAddress & 0x1FFFF]=0x00; // slot ID 0
                     39: }
                     40: 
                     41: /* System Control Register 1
                     42:  *
                     43:  * These values are valid for all non-Turbo systems:
                     44:  * -------- -------- -------- ------xx  bits 0:1   --> cpu speed
                     45:  * -------- -------- -------- ----xx--  bits 2:3   --> reserved
                     46:  * -------- -------- -------- --xx----  bits 4:5   --> main memory speed
                     47:  * -------- -------- -------- xx------  bits 6:7   --> video memory speed
                     48:  * -------- -------- ----xxxx --------  bits 8:11  --> board revision
                     49:  * -------- -------- xxxx---- --------  bits 12:15 --> cpu type
                     50:  * -------- xxxxxxxx -------- --------  bits 16:23 --> dma revision
                     51:  * ----xxxx -------- -------- --------  bits 24:27 --> reserved
                     52:  * xxxx---- -------- -------- --------  bits 28:31 --> slot id
                     53:  *
                     54:  * cpu speed:       0 = 40MHz, 1 = 20MHz, 2 = 25MHz, 3 = 33MHz
                     55:  * main mem speed:  0 = 120ns, 1 = 100ns, 2 = 80ns, 3 = 60ns
                     56:  * video mem speed: 0 = 120ns, 1 = 100ns, 2 = 80ns, 3 = 60ns
                     57:  * board revision:  for 030 Cube:
                     58:  *                  0 = DCD input inverted
                     59:  *                  1 = DCD polarity fixed
                     60:  *                  2 = must disable DSP mem before reset
                     61:  * cpu type:        0 = NeXT Computer (68030)
                     62:  *                  1 = NeXTstation monochrome
                     63:  *                  2 = NeXTcube
                     64:  *                  3 = NeXTstation color
                     65:  *                  4 = all Turbo systems
                     66:  * dma revision:    1 on all systems ?
                     67:  * slot id:         f on Turbo systems (cube too?), 0 on other systems
                     68:  *
                     69:  *
                     70:  * These bits are always 0 on all Turbo systems:
                     71:  * ----xxxx xxxxxxxx ----xxxx xxxxxxxx
                     72:  */
                     73: 
                     74: /* for Slab 040:
                     75:  * 0000 0000 0000 0001 0001 0000 0101 0010
                     76:  * 00 01 10 52
                     77:  *
                     78:  * for Cube 030:
                     79:  * 0000 0000 0000 0001 0000 0001 0101 0010
                     80:  * 00 01 01 52
                     81:  */
                     82: #define SCR1_NEXT_COMPUTER  0x00010152
                     83: #define SCR1_SLAB_MONO      0x00011052
                     84: #define SCR1_SLAB_COLOR     0x00013052
                     85: #define SCR1_CUBE           0x00012052
1.1.1.3 ! root       86: #define SCR1_TURBO          0x00004000
1.1       root       87: 
                     88: #define SCR1_CONST_MASK     0xFFFFFF00
                     89: 
                     90: void SCR_Reset(void) {
1.1.1.3 ! root       91:     SCR_ROM_overlay = 0;
        !            92:     
1.1       root       93:     scr2_0=0x00;
                     94:     scr2_1=0x00;
1.1.1.3 ! root       95:        if (ConfigureParams.System.bTurbo) {
        !            96:                scr2_2=0x10;
        !            97:                scr2_3=0x80;
        !            98:        } else {
        !            99:                scr2_2=0x00;
        !           100:                scr2_3=0x00;
        !           101:        }
        !           102:        
1.1       root      103:     intStat=0x00000000;
                    104:     intMask=0x00000000;
                    105: 
                    106:     if (ConfigureParams.System.bTurbo) {
                    107:         scr1 = SCR1_TURBO;
1.1.1.3 ! root      108:         scr1 |= (ConfigureParams.System.nMachineType==NEXT_CUBE040)?0:0xF0000000;
1.1       root      109:         return;
                    110:     } else {
                    111:         switch (ConfigureParams.System.nMachineType) {
                    112:             case NEXT_CUBE030:
                    113:                 scr1 = SCR1_NEXT_COMPUTER & SCR1_CONST_MASK;
                    114:                 break;
                    115:             case NEXT_CUBE040:
                    116:                 scr1 = SCR1_CUBE & SCR1_CONST_MASK;
                    117:                 break;
                    118:             case NEXT_STATION:
                    119:                 if (ConfigureParams.System.bColor)
                    120:                     scr1 = SCR1_SLAB_COLOR & SCR1_CONST_MASK;
                    121:                 else
                    122:                     scr1 = SCR1_SLAB_MONO & SCR1_CONST_MASK;
                    123:                 break;
                    124:             default:
                    125:                 break;
                    126:         }
                    127:     }
                    128:     
1.1.1.3 ! root      129:     Uint8 cpu_speed;
1.1       root      130:     Uint8 memory_speed;
1.1.1.3 ! root      131:     
        !           132:     if (ConfigureParams.System.nCpuFreq<20) {
        !           133:         cpu_speed = 0;
        !           134:     } else if (ConfigureParams.System.nCpuFreq<25) {
        !           135:         cpu_speed = 1;
        !           136:     } else if (ConfigureParams.System.nCpuFreq<33) {
        !           137:         cpu_speed = 2;
        !           138:     } else {
        !           139:         cpu_speed = 3;
        !           140:     }
        !           141:     
1.1       root      142:     switch (ConfigureParams.Memory.nMemorySpeed) {
                    143:         case MEMORY_120NS: memory_speed = 0x00; break;
                    144:         case MEMORY_100NS: memory_speed = 0x50; break;
                    145:         case MEMORY_80NS: memory_speed = 0xA0; break;
                    146:         case MEMORY_60NS: memory_speed = 0xF0; break;
                    147:         default: Log_Printf(LOG_WARN, "SCR1 error: unknown memory speed\n"); break;
                    148:     }
                    149:     scr1 |= ((memory_speed&0xF0)|(cpu_speed&0x03));
                    150: }
                    151: 
                    152: void SCR1_Read0(void)
                    153: {
                    154:        Log_Printf(LOG_WARN,"SCR1 read at $%08x PC=$%08x\n", IoAccessCurrentAddress,m68k_getpc());
                    155:     IoMem[IoAccessCurrentAddress&IO_SEG_MASK] = (scr1&0xFF000000)>>24;
                    156: }
                    157: void SCR1_Read1(void)
                    158: {
                    159:        Log_Printf(LOG_WARN,"SCR1 read at $%08x PC=$%08x\n", IoAccessCurrentAddress,m68k_getpc());
                    160:     IoMem[IoAccessCurrentAddress&IO_SEG_MASK] = (scr1&0x00FF0000)>>16;
                    161: }
                    162: void SCR1_Read2(void)
                    163: {
                    164:        Log_Printf(LOG_WARN,"SCR1 read at $%08x PC=$%08x\n", IoAccessCurrentAddress,m68k_getpc());
                    165:     IoMem[IoAccessCurrentAddress&IO_SEG_MASK] = (scr1&0x0000FF00)>>8;
                    166: }
                    167: void SCR1_Read3(void)
                    168: {
                    169:        Log_Printf(LOG_WARN,"SCR1 read at $%08x PC=$%08x\n", IoAccessCurrentAddress,m68k_getpc());
                    170:     IoMem[IoAccessCurrentAddress&IO_SEG_MASK] = scr1&0x000000FF;
                    171: }
                    172: 
                    173: 
                    174: /* System Control Register 2 
                    175:  
                    176:  s_dsp_reset : 1,
                    177:  s_dsp_block_end : 1,
                    178:  s_dsp_unpacked : 1,
                    179:  s_dsp_mode_B : 1,
                    180:  s_dsp_mode_A : 1,
                    181:  s_remote_int : 1,
                    182:  s_local_int : 2,
                    183:  s_dram_256K : 4,
                    184:  s_dram_1M : 4,
                    185:  s_timer_on_ipl7 : 1,
                    186:  s_rom_wait_states : 3,
                    187:  s_rom_1M : 1,
                    188:  s_rtdata : 1,
                    189:  s_rtclk : 1,
                    190:  s_rtce : 1,
                    191:  s_rom_overlay : 1,
                    192:  s_dsp_int_en : 1,
                    193:  s_dsp_mem_en : 1,
                    194:  s_reserved : 4,
                    195:  s_led : 1;
                    196:  
                    197:  */
                    198: 
1.1.1.3 ! root      199: /* byte 0 */
        !           200: #define SCR2_DSP_RESET      0x80
        !           201: #define SCR2_DSP_BLK_END    0x40
        !           202: #define SCR2_DSP_UNPKD      0x20
        !           203: #define SCR2_DSP_MODE_B     0x10
        !           204: #define SCR2_DSP_MODE_A     0x08
1.1       root      205: #define SCR2_SOFTINT2          0x02
                    206: #define SCR2_SOFTINT1          0x01
                    207: 
1.1.1.3 ! root      208: /* byte 2 */
1.1       root      209: #define SCR2_TIMERIPL7         0x80
                    210: #define SCR2_RTDATA            0x04
                    211: #define SCR2_RTCLK             0x02
                    212: #define SCR2_RTCE              0x01
                    213: 
1.1.1.3 ! root      214: /* byte 3 */
1.1       root      215: #define SCR2_ROM               0x80
1.1.1.3 ! root      216: #define SCR2_DSP_INT_EN 0x40
        !           217: #define SCR2_DSP_MEM_EN 0x20
        !           218: #define SCR2_LED               0x01
1.1       root      219: 
                    220: 
                    221: void SCR2_Write0(void)
                    222: {      
                    223:        Uint8 old_scr2_0=scr2_0;
                    224:     // Log_Printf(LOG_WARN,"SCR2 write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress,IoMem[IoAccessCurrentAddress & IO_SEG_MASK],m68k_getpc());
                    225:        scr2_0=IoMem[IoAccessCurrentAddress & 0x1FFFF];
                    226: 
                    227:        if ((old_scr2_0&SCR2_SOFTINT1)!=(scr2_0&SCR2_SOFTINT1)) {
1.1.1.3 ! root      228:                Log_Printf(LOG_SOFTINT_LEVEL,"SCR2 SCR2_SOFTINT1 change at $%08x val=%x PC=$%08x\n",
1.1       root      229:                            IoAccessCurrentAddress,scr2_0&SCR2_SOFTINT1,m68k_getpc());
                    230:                if (scr2_0&SCR2_SOFTINT1) 
                    231:                        set_interrupt(INT_SOFT1,SET_INT);
                    232:                else
                    233:                        set_interrupt(INT_SOFT1,RELEASE_INT);
                    234:        }
                    235: 
                    236:        if ((old_scr2_0&SCR2_SOFTINT2)!=(scr2_0&SCR2_SOFTINT2)) {
1.1.1.3 ! root      237:                Log_Printf(LOG_SOFTINT_LEVEL,"SCR2 SCR2_SOFTINT2 change at $%08x val=%x PC=$%08x\n",
1.1       root      238:                            IoAccessCurrentAddress,scr2_0&SCR2_SOFTINT2,m68k_getpc());
                    239:                if (scr2_0&SCR2_SOFTINT2) 
                    240:                        set_interrupt(INT_SOFT2,SET_INT);
                    241:                else
                    242:                        set_interrupt(INT_SOFT2,RELEASE_INT);
                    243:        }
1.1.1.3 ! root      244:     
        !           245:     /* DSP bits */
        !           246:     if (scr2_0&SCR2_DSP_MODE_A) {
        !           247:         Log_Printf(LOG_WARN,"[SCR2] DSP Mode A");
        !           248:     }
        !           249:     if (scr2_0&SCR2_DSP_MODE_B) {
        !           250:         Log_Printf(LOG_WARN,"[SCR2] DSP Mode B");
        !           251:     }
        !           252:     if (!(scr2_0&SCR2_DSP_RESET) && (old_scr2_0&SCR2_DSP_RESET)) {
        !           253:         Log_Printf(LOG_WARN,"[SCR2] DSP Reset");
        !           254:         DSP_Reset();
        !           255:     } else if ((scr2_0&SCR2_DSP_RESET) && !(old_scr2_0&SCR2_DSP_RESET)) {
        !           256:         Log_Printf(LOG_WARN,"[SCR2] DSP Start (mode %i)",(~(scr2_0>>3))&3);
        !           257:         DSP_Start((~(scr2_0>>3))&3);
        !           258:     }
        !           259:        dsp_intr_at_block_end = scr2_0&SCR2_DSP_BLK_END;
        !           260:     if ((old_scr2_0&SCR2_DSP_BLK_END) != (scr2_0&SCR2_DSP_BLK_END)) {
        !           261:         Log_Printf(LOG_WARN,"[SCR2] %s DSP interrupt from DMA at block end",dsp_intr_at_block_end?"Enable":"Disable");
        !           262:     }
        !           263:        dsp_dma_unpacked = scr2_0&SCR2_DSP_UNPKD;
        !           264:     if ((old_scr2_0&SCR2_DSP_UNPKD) != (scr2_0&SCR2_DSP_UNPKD)) {
        !           265:         Log_Printf(LOG_WARN,"[SCR2] %s DSP DMA unpacked mode",dsp_dma_unpacked?"Enable":"Disable");
        !           266:     }
1.1       root      267: }
                    268: 
                    269: void SCR2_Read0(void)
                    270: {
                    271:     // Log_Printf(LOG_WARN,"SCR2 read at $%08x PC=$%08x\n", IoAccessCurrentAddress,m68k_getpc());
                    272:        IoMem[IoAccessCurrentAddress & 0x1FFFF]=scr2_0;
                    273: }
                    274: 
                    275: void SCR2_Write1(void)
                    276: {      
                    277:     // Log_Printf(LOG_WARN,"SCR2 write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress,IoMem[IoAccessCurrentAddress & IO_SEG_MASK],m68k_getpc());
                    278:        scr2_1=IoMem[IoAccessCurrentAddress & 0x1FFFF];
                    279: }
                    280: 
                    281: void SCR2_Read1(void)
                    282: {
                    283:     // Log_Printf(LOG_WARN,"SCR2 read at $%08x PC=$%08x\n", IoAccessCurrentAddress,m68k_getpc());
                    284:        IoMem[IoAccessCurrentAddress & 0x1FFFF]=scr2_1;
                    285: }
                    286: 
                    287: void SCR2_Write2(void)
1.1.1.3 ! root      288: {    
1.1       root      289:        Uint8 old_scr2_2=scr2_2;
                    290: 
                    291:        scr2_2=IoMem[IoAccessCurrentAddress & 0x1FFFF];
                    292: 
                    293:        if ((old_scr2_2&SCR2_TIMERIPL7)!=(scr2_2&SCR2_TIMERIPL7)) {
                    294:                Log_Printf(LOG_WARN,"SCR2 TIMER IPL7 change at $%08x val=%x PC=$%08x\n",
                    295:                            IoAccessCurrentAddress,scr2_2&SCR2_TIMERIPL7,m68k_getpc());
                    296:        }
                    297: 
1.1.1.3 ! root      298:     /* RTC enabled */
1.1       root      299:        if (scr2_2&SCR2_RTCE) {
                    300:         if (((old_scr2_2&SCR2_RTCLK)!=(scr2_2&SCR2_RTCLK)) && ((scr2_2&SCR2_RTCLK)==0) ) {
1.1.1.3 ! root      301:             Uint8 rtdata = scr2_2&SCR2_RTDATA;
        !           302:             scr2_2 &= ~SCR2_RTDATA;
        !           303:             scr2_2 |= rtc_interface_io(rtdata)?SCR2_RTDATA:0;
        !           304:         }
        !           305:        } else {
        !           306:         rtc_interface_reset();
        !           307:     }
1.1       root      308: }
                    309: 
                    310: void SCR2_Read2(void)
                    311: {
                    312:     // Log_Printf(LOG_WARN,"SCR2 read at $%08x PC=$%08x\n", IoAccessCurrentAddress,m68k_getpc());
                    313:     // IoMem[IoAccessCurrentAddress & 0x1FFFF]=scr2_2 & (SCR2_RTDATA|SCR2_RTCLK|SCR2_RTCE)); // + data
                    314:        IoMem[IoAccessCurrentAddress & 0x1FFFF]=scr2_2;
                    315: }
                    316: 
                    317: void SCR2_Write3(void)
                    318: {      
                    319:        Uint8 old_scr2_3=scr2_3;
                    320:     // Log_Printf(LOG_WARN,"SCR2 write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress,IoMem[IoAccessCurrentAddress & IO_SEG_MASK],m68k_getpc());
                    321:        scr2_3=IoMem[IoAccessCurrentAddress & 0x1FFFF];
                    322:        if ((old_scr2_3&SCR2_ROM)!=(scr2_3&SCR2_ROM)) {
                    323:                Log_Printf(LOG_WARN,"SCR2 ROM change at $%08x val=%x PC=$%08x\n",
                    324:                    IoAccessCurrentAddress,scr2_3&SCR2_ROM,m68k_getpc());
                    325:                   SCR_ROM_overlay=scr2_3&SCR2_ROM;
                    326:                }
                    327:        if ((old_scr2_3&SCR2_LED)!=(scr2_3&SCR2_LED)) {
1.1.1.3 ! root      328:                Log_Printf(LOG_DEBUG,"SCR2 LED change at $%08x val=%x PC=$%08x\n",
1.1       root      329:                    IoAccessCurrentAddress,scr2_3&SCR2_LED,m68k_getpc());
1.1.1.3 ! root      330:         Statusbar_SetSystemLed(scr2_3&SCR2_LED);
        !           331:     }
        !           332:     
        !           333:     if ((old_scr2_3&SCR2_DSP_INT_EN) != (scr2_3&SCR2_DSP_INT_EN)) {
        !           334:         Log_Printf(LOG_WARN,"[SCR2] DSP interrupt at level %i",(scr2_3&SCR2_DSP_INT_EN)?4:3);
        !           335:                if (intStat&(INT_DSP_L3|INT_DSP_L4)) {
        !           336:                        Log_Printf(LOG_WARN,"[SCR2] Switching DSP interrupt to level %i",(scr2_3&SCR2_DSP_INT_EN)?4:3);
        !           337:                        set_interrupt(INT_DSP_L3|INT_DSP_L4, RELEASE_INT);
        !           338:                        set_dsp_interrupt(SET_INT);
        !           339:                }
        !           340:     }
        !           341:     if ((old_scr2_3&SCR2_DSP_MEM_EN) != (scr2_3&SCR2_DSP_MEM_EN)) {
        !           342:         Log_Printf(LOG_WARN,"[SCR2] %s DSP memory",(scr2_3&SCR2_DSP_MEM_EN)?"Enable":"Disable");
1.1       root      343:     }
                    344: }
                    345: 
                    346: 
                    347: void SCR2_Read3(void)
                    348: {
                    349:     // Log_Printf(LOG_WARN,"SCR2 read at $%08x PC=$%08x\n", IoAccessCurrentAddress,m68k_getpc());
                    350:        IoMem[IoAccessCurrentAddress & 0x1FFFF]=scr2_3;
                    351: }
                    352: 
                    353: 
                    354: 
                    355: /* Interrupt Status Register */
                    356: 
                    357: void IntRegStatRead(void) {
                    358:     IoMem_WriteLong(IoAccessCurrentAddress & IO_SEG_MASK, intStat);
                    359: }
                    360: 
                    361: void IntRegStatWrite(void) {
                    362:     intStat = IoMem_ReadLong(IoAccessCurrentAddress & IO_SEG_MASK);
                    363: }
                    364: 
1.1.1.3 ! root      365: void set_dsp_interrupt(Uint8 state) {
        !           366:     if (scr2_3&SCR2_DSP_INT_EN || ConfigureParams.System.bTurbo) {
        !           367:                set_interrupt(INT_DSP_L4, state);
1.1       root      368:     } else {
1.1.1.3 ! root      369:                set_interrupt(INT_DSP_L3, state);
1.1       root      370:     }
1.1.1.3 ! root      371: }
        !           372: 
        !           373: void set_interrupt(Uint32 intr, Uint8 state) {
        !           374:     /* The interrupt gets polled by the cpu via intlev()
        !           375:      * --> see previous-glue.c
        !           376:      */
        !           377:     if (state==SET_INT) {
        !           378:         intStat |= intr;
        !           379:     } else {
        !           380:         intStat &= ~intr;
1.1       root      381:     }
1.1.1.3 ! root      382: }
        !           383: 
        !           384: int get_interrupt_level(void) {
        !           385:     Uint32 interrupt = intStat&intMask;
        !           386:     
        !           387:     if (!interrupt) {
        !           388:         return 0;
        !           389:     } else if (interrupt&INT_L7_MASK) {
        !           390:         return 7;
        !           391:     } else if ((interrupt&INT_TIMER) && (scr2_2&SCR2_TIMERIPL7)) {
        !           392:         return 7;
        !           393:     } else if (interrupt&INT_L6_MASK) {
        !           394:         return 6;
        !           395:     } else if (interrupt&INT_L5_MASK) {
        !           396:         return 5;
        !           397:     } else if (interrupt&INT_L4_MASK) {
        !           398:         return 4;
        !           399:     } else if (interrupt&INT_L3_MASK) {
        !           400:         return 3;
        !           401:     } else if (interrupt&INT_L2_MASK) {
        !           402:         return 2;
        !           403:     } else if (interrupt&INT_L1_MASK) {
        !           404:         return 1;
1.1       root      405:     } else {
1.1.1.3 ! root      406:         abort();
1.1       root      407:     }
                    408: }
                    409: 
                    410: /* Interrupt Mask Register */
                    411: 
                    412: void IntRegMaskRead(void) {
                    413:        IoMem_WriteLong(IoAccessCurrentAddress & IO_SEG_MASK,intMask);
                    414: }
                    415: 
                    416: void IntRegMaskWrite(void) {
                    417:        intMask = IoMem_ReadLong(IoAccessCurrentAddress & IO_SEG_MASK);
                    418:         Log_Printf(LOG_WARN,"Interrupt mask: %08x", intMask);
                    419: }
                    420: 
1.1.1.3 ! root      421: 
        !           422: /* Hardclock internal interrupt */
1.1       root      423: 
                    424: #define HARDCLOCK_ENABLE 0x80
                    425: #define HARDCLOCK_LATCH  0x40
1.1.1.3 ! root      426: #define HARDCLOCK_ZERO   0x3F
1.1       root      427: 
                    428: Uint8 hardclock_csr=0;
                    429: Uint8 hardclock1=0;
                    430: Uint8 hardclock0=0;
1.1.1.3 ! root      431: int hardclock_delay=0;
1.1       root      432: int latch_hardclock=0;
                    433: 
                    434: void Hardclock_InterruptHandler ( void )
                    435: {
                    436:        CycInt_AcknowledgeInterrupt();
                    437:        if ((hardclock_csr&HARDCLOCK_ENABLE) && (latch_hardclock>0)) {
                    438:                // Log_Printf(LOG_WARN,"[INT] throwing hardclock");
1.1.1.3 ! root      439:         set_interrupt(INT_TIMER,SET_INT);
        !           440:         CycInt_AddRelativeInterrupt(hardclock_delay, INT_CPU_CYCLE, INTERRUPT_HARDCLOCK);
1.1       root      441:        }
                    442: }
                    443: 
                    444: 
                    445: void HardclockRead0(void){
1.1.1.3 ! root      446:        IoMem[IoAccessCurrentAddress & 0x1FFFF]=(latch_hardclock>>8);
        !           447:        Log_Printf(LOG_HARDCLOCK_LEVEL,"[hardclock] read at $%08x val=%02x PC=$%08x", IoAccessCurrentAddress,IoMem[IoAccessCurrentAddress & 0x1FFFF],m68k_getpc());
1.1       root      448: }
                    449: void HardclockRead1(void){
1.1.1.3 ! root      450:        IoMem[IoAccessCurrentAddress & 0x1FFFF]=latch_hardclock&0xff;
        !           451:        Log_Printf(LOG_HARDCLOCK_LEVEL,"[hardclock] read at $%08x val=%02x PC=$%08x", IoAccessCurrentAddress,IoMem[IoAccessCurrentAddress & 0x1FFFF],m68k_getpc());
1.1       root      452: }
                    453: 
                    454: void HardclockWrite0(void){
1.1.1.3 ! root      455:        Log_Printf(LOG_HARDCLOCK_LEVEL,"[hardclock] write at $%08x val=%02x PC=$%08x", IoAccessCurrentAddress,IoMem[IoAccessCurrentAddress & 0x1FFFF],m68k_getpc());
1.1       root      456:        hardclock0=IoMem[IoAccessCurrentAddress & 0x1FFFF];
                    457: }
                    458: void HardclockWrite1(void){
1.1.1.3 ! root      459:        Log_Printf(LOG_HARDCLOCK_LEVEL,"[hardclock] write at $%08x val=%02x PC=$%08x",IoAccessCurrentAddress,IoMem[IoAccessCurrentAddress & 0x1FFFF],m68k_getpc());
1.1       root      460:        hardclock1=IoMem[IoAccessCurrentAddress & 0x1FFFF];
                    461: }
                    462: 
                    463: void HardclockWriteCSR(void) {
1.1.1.3 ! root      464:        Log_Printf(LOG_HARDCLOCK_LEVEL,"[hardclock] write at $%08x val=%02x PC=$%08x", IoAccessCurrentAddress,IoMem[IoAccessCurrentAddress & 0x1FFFF],m68k_getpc());
1.1       root      465:        hardclock_csr=IoMem[IoAccessCurrentAddress & 0x1FFFF];
1.1.1.3 ! root      466:        if (hardclock_csr&HARDCLOCK_LATCH) {
        !           467:         hardclock_csr&= ~HARDCLOCK_LATCH;
1.1       root      468:                latch_hardclock=(hardclock0<<8)|hardclock1;
1.1.1.3 ! root      469:                hardclock_delay=latch_hardclock*11;
1.1       root      470:        }
                    471:        if ((hardclock_csr&HARDCLOCK_ENABLE) && (latch_hardclock>0)) {
1.1.1.3 ! root      472:         Log_Printf(LOG_HARDCLOCK_LEVEL,"[hardclock] enable periodic interrupt (%i microseconds).", latch_hardclock);
        !           473:         CycInt_AddRelativeInterrupt(hardclock_delay, INT_CPU_CYCLE, INTERRUPT_HARDCLOCK);
        !           474:        } else {
        !           475:         Log_Printf(LOG_HARDCLOCK_LEVEL,"[hardclock] disable periodic interrupt.");
        !           476:     }
        !           477:     set_interrupt(INT_TIMER,RELEASE_INT);
1.1       root      478: }
                    479: void HardclockReadCSR(void) {
                    480:        IoMem[IoAccessCurrentAddress & 0x1FFFF]=hardclock_csr;
                    481:        // Log_Printf(LOG_WARN,"[hardclock] read at $%08x val=%02x PC=$%08x", IoAccessCurrentAddress,IoMem[IoAccessCurrentAddress & 0x1FFFF],m68k_getpc());
                    482:        set_interrupt(INT_TIMER,RELEASE_INT);
                    483: }
                    484: 
                    485: 
1.1.1.3 ! root      486: /* Event counter register */
        !           487: #define EVENTC_DEBUG 0
        !           488: Uint32 lasteventc; /* debugging code */
        !           489: 
        !           490: Uint32 eventcounter;
        !           491: 
        !           492: #if USE_FREQ_DIVIDER
        !           493: void System_Timer_Read(void) { /* tuned for power-on test */
        !           494: #if EVENTC_DEBUG
        !           495:     lasteventc = eventcounter; /* for debugging */
        !           496: #endif
        !           497:     if (ConfigureParams.System.nCpuLevel == 3) {
        !           498:         if (NEXTRom[0xFFAB]==0x04) { // HACK for ROM version 0.8.31 power-on test, WARNING: this causes slowdown of emulation
        !           499:             eventcounter = (nCyclesMainCounter/(240/nCpuFreqDivider))&0xFFFFF;
        !           500:         } else {
        !           501:             eventcounter = (nCyclesMainCounter/(48/nCpuFreqDivider))&0xFFFFF;
        !           502:         }
        !           503:     } else { // System has 68040 CPU
        !           504:         eventcounter = (nCyclesMainCounter/(72/nCpuFreqDivider))&0xFFFFF;
        !           505:     }
        !           506:     IoMem_WriteLong(IoAccessCurrentAddress&IO_SEG_MASK, eventcounter);
        !           507:     
        !           508: #if EVENTC_DEBUG
        !           509:     Log_Printf(LOG_WARN, "[Eventcounter] Difference = %i (Frequency = %i, Divider = %i)",
        !           510:                eventcounter-lasteventc,ConfigureParams.System.nCpuFreq,nCpuFreqDivider);
        !           511: #endif
        !           512: }
        !           513: #else
        !           514: void System_Timer_Read(void) { // tuned for power-on test
        !           515: //  lasteventc = eventcounter; // debugging code
        !           516:     if (ConfigureParams.System.nCpuLevel == 3) {
        !           517:         if (NEXTRom[0xFFAB]==0x04) { // HACK for ROM version 0.8.31 power-on test, WARNING: this causes slowdown of emulation
        !           518: //          eventcounter = (nCyclesMainCounter/((1280/ConfigureParams.System.nCpuFreq)*3))&0xFFFFF; // debugging code
        !           519:             IoMem_WriteLong(IoAccessCurrentAddress&0x1FFFF, (nCyclesMainCounter/((1280/ConfigureParams.System.nCpuFreq)*3))&0xFFFFF);
        !           520:         } else {
        !           521: //          eventcounter = (nCyclesMainCounter/((128/ConfigureParams.System.nCpuFreq)*3))&0xFFFFF; // debugging code
        !           522:             IoMem_WriteLong(IoAccessCurrentAddress&0x1FFFF, (nCyclesMainCounter/((128/ConfigureParams.System.nCpuFreq)*3))&0xFFFFF);
        !           523:         }
        !           524:     } else { // System has 68040 CPU
        !           525: //      eventcounter = (nCyclesMainCounter/((64/ConfigureParams.System.nCpuFreq)*9))&0xFFFFF; // debugging code
        !           526:         IoMem_WriteLong(IoAccessCurrentAddress&0x1FFFF, (nCyclesMainCounter/((64/ConfigureParams.System.nCpuFreq)*9))&0xFFFFF);
        !           527:     }
        !           528: //  printf("DIFFERENCE = %i PC = %08X\n",eventcounter-lasteventc,m68k_getpc());
        !           529: }
        !           530: #endif
        !           531: 
        !           532: 
        !           533: /* Color Video Interrupt Register */
        !           534: 
        !           535: #define VID_CMD_CLEAR_INT    0x01
        !           536: #define VID_CMD_ENABLE_INT   0x02
        !           537: #define VID_CMD_UNBLANK      0x04
        !           538: 
        !           539: Uint8 col_vid_intr = 0;
        !           540: 
        !           541: void ColorVideo_CMD_Write(void) {
        !           542:        col_vid_intr=IoMem[IoAccessCurrentAddress & 0x1FFFF];
        !           543:        Log_Printf(LOG_DEBUG,"[Color Video] Command write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress & IO_SEG_MASK], m68k_getpc());
        !           544:        
        !           545:        if (col_vid_intr&VID_CMD_CLEAR_INT) {
        !           546:                set_interrupt(INT_DISK, RELEASE_INT);
        !           547:        }
        !           548: }
        !           549: 
        !           550: void color_video_interrupt(void) {
        !           551:        if (col_vid_intr&VID_CMD_ENABLE_INT) {
        !           552:                set_interrupt(INT_DISK, SET_INT);
        !           553:                col_vid_intr &= ~VID_CMD_ENABLE_INT;
        !           554:        }
        !           555: }

unix.superglobalmegacorp.com

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