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

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

unix.superglobalmegacorp.com

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