Annotation of previous_trunk/src/sysReg.c, revision 1.1.1.1

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"
                     11: #include "dsp.h"
                     12: #include "sysReg.h"
                     13: #include "rtcnvram.h"
                     14: #include "statusbar.h"
                     15: #include "host.h"
                     16: 
                     17: #define LOG_HARDCLOCK_LEVEL LOG_DEBUG
                     18: #define LOG_SOFTINT_LEVEL   LOG_DEBUG
                     19: #define LOG_DSP_LEVEL       LOG_DEBUG
                     20: 
                     21: #define IO_SEG_MASK    0x1FFFF
                     22: 
                     23: int SCR_ROM_overlay=0;
                     24: 
                     25: static Uint32 scr1=0x00000000;
                     26: 
                     27: static Uint8 scr2_0=0x00;
                     28: static Uint8 scr2_1=0x00;
                     29: static Uint8 scr2_2=0x00;
                     30: static Uint8 scr2_3=0x00;
                     31: 
                     32: static Uint32 intStat=0x00000000;
                     33: static Uint32 intMask=0x00000000;
                     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
                     87: #define SCR1_TURBO          0x00004000
                     88: 
                     89: #define SCR1_CONST_MASK     0xFFFFFF00
                     90: 
                     91: void SCR_Reset(void) {
                     92:     SCR_ROM_overlay = 0;
                     93:     
                     94:     scr2_0=0x00;
                     95:     scr2_1=0x00;
                     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:        
                    104:     intStat=0x00000000;
                    105:     intMask=0x00000000;
                    106: 
                    107:     if (ConfigureParams.System.bTurbo) {
                    108:         scr1 = SCR1_TURBO;
                    109:         scr1 |= (ConfigureParams.System.nMachineType==NEXT_CUBE040)?0:0xF0000000;
                    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:     
                    130:     Uint8 cpu_speed;
                    131:     Uint8 memory_speed = 0;
                    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:     
                    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: 
                    153: void SCR1_Read0(void)
                    154: {
                    155:        Log_Printf(LOG_WARN,"SCR1 read at $%08x PC=$%08x\n", IoAccessCurrentAddress,m68k_getpc());
                    156:     IoMem[IoAccessCurrentAddress&IO_SEG_MASK] = (scr1&0xFF000000)>>24;
                    157: }
                    158: void SCR1_Read1(void)
                    159: {
                    160:        Log_Printf(LOG_WARN,"SCR1 read at $%08x PC=$%08x\n", IoAccessCurrentAddress,m68k_getpc());
                    161:     IoMem[IoAccessCurrentAddress&IO_SEG_MASK] = (scr1&0x00FF0000)>>16;
                    162: }
                    163: void SCR1_Read2(void)
                    164: {
                    165:        Log_Printf(LOG_WARN,"SCR1 read at $%08x PC=$%08x\n", IoAccessCurrentAddress,m68k_getpc());
                    166:     IoMem[IoAccessCurrentAddress&IO_SEG_MASK] = (scr1&0x0000FF00)>>8;
                    167: }
                    168: void SCR1_Read3(void)
                    169: {
                    170:        Log_Printf(LOG_WARN,"SCR1 read at $%08x PC=$%08x\n", IoAccessCurrentAddress,m68k_getpc());
                    171:     IoMem[IoAccessCurrentAddress&IO_SEG_MASK] = scr1&0x000000FF;
                    172: }
                    173: 
                    174: 
                    175: /* System Control Register 2 
                    176:  
                    177:  s_dsp_reset : 1,
                    178:  s_dsp_block_end : 1,
                    179:  s_dsp_unpacked : 1,
                    180:  s_dsp_mode_B : 1,
                    181:  s_dsp_mode_A : 1,
                    182:  s_remote_int : 1,
                    183:  s_local_int : 2,
                    184:  s_dram_256K : 4,
                    185:  s_dram_1M : 4,
                    186:  s_timer_on_ipl7 : 1,
                    187:  s_rom_wait_states : 3,
                    188:  s_rom_1M : 1,
                    189:  s_rtdata : 1,
                    190:  s_rtclk : 1,
                    191:  s_rtce : 1,
                    192:  s_rom_overlay : 1,
                    193:  s_dsp_int_en : 1,
                    194:  s_dsp_mem_en : 1,
                    195:  s_reserved : 4,
                    196:  s_led : 1;
                    197:  
                    198:  */
                    199: 
                    200: /* byte 0 */
                    201: #define SCR2_DSP_RESET      0x80
                    202: #define SCR2_DSP_BLK_END    0x40
                    203: #define SCR2_DSP_UNPKD      0x20
                    204: #define SCR2_DSP_MODE_B     0x10
                    205: #define SCR2_DSP_MODE_A     0x08
                    206: #define SCR2_SOFTINT2          0x02
                    207: #define SCR2_SOFTINT1          0x01
                    208: 
                    209: /* byte 2 */
                    210: #define SCR2_TIMERIPL7         0x80
                    211: #define SCR2_RTDATA            0x04
                    212: #define SCR2_RTCLK             0x02
                    213: #define SCR2_RTCE              0x01
                    214: 
                    215: /* byte 3 */
                    216: #define SCR2_ROM               0x80
                    217: #define SCR2_DSP_INT_EN 0x40
                    218: #define SCR2_DSP_MEM_EN 0x20
                    219: #define SCR2_LED               0x01
                    220: 
                    221: 
                    222: void SCR2_Write0(void)
                    223: {      
                    224:        Uint8 old_scr2_0=scr2_0;
                    225:     // Log_Printf(LOG_WARN,"SCR2 write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress,IoMem[IoAccessCurrentAddress & IO_SEG_MASK],m68k_getpc());
                    226:        scr2_0=IoMem[IoAccessCurrentAddress & 0x1FFFF];
                    227: 
                    228:        if ((old_scr2_0&SCR2_SOFTINT1)!=(scr2_0&SCR2_SOFTINT1)) {
                    229:                Log_Printf(LOG_SOFTINT_LEVEL,"SCR2 SCR2_SOFTINT1 change at $%08x val=%x PC=$%08x\n",
                    230:                            IoAccessCurrentAddress,scr2_0&SCR2_SOFTINT1,m68k_getpc());
                    231:                if (scr2_0&SCR2_SOFTINT1) 
                    232:                        set_interrupt(INT_SOFT1,SET_INT);
                    233:                else
                    234:                        set_interrupt(INT_SOFT1,RELEASE_INT);
                    235:        }
                    236: 
                    237:        if ((old_scr2_0&SCR2_SOFTINT2)!=(scr2_0&SCR2_SOFTINT2)) {
                    238:                Log_Printf(LOG_SOFTINT_LEVEL,"SCR2 SCR2_SOFTINT2 change at $%08x val=%x PC=$%08x\n",
                    239:                            IoAccessCurrentAddress,scr2_0&SCR2_SOFTINT2,m68k_getpc());
                    240:                if (scr2_0&SCR2_SOFTINT2) 
                    241:                        set_interrupt(INT_SOFT2,SET_INT);
                    242:                else
                    243:                        set_interrupt(INT_SOFT2,RELEASE_INT);
                    244:        }
                    245:     
                    246:     /* DSP bits */
                    247:     if (scr2_0&SCR2_DSP_MODE_A) {
                    248:         Log_Printf(LOG_DSP_LEVEL,"[SCR2] DSP Mode A");
                    249:     }
                    250:     if (scr2_0&SCR2_DSP_MODE_B) {
                    251:         Log_Printf(LOG_DSP_LEVEL,"[SCR2] DSP Mode B");
                    252:     }
                    253:     if (!(scr2_0&SCR2_DSP_RESET) && (old_scr2_0&SCR2_DSP_RESET)) {
                    254:         Log_Printf(LOG_DSP_LEVEL,"[SCR2] DSP Reset");
                    255:         DSP_Reset();
                    256:     } else if ((scr2_0&SCR2_DSP_RESET) && !(old_scr2_0&SCR2_DSP_RESET)) {
                    257:         Log_Printf(LOG_DSP_LEVEL,"[SCR2] DSP Start (mode %i)",(~(scr2_0>>3))&3);
                    258:         DSP_Start((~(scr2_0>>3))&3);
                    259:     }
                    260:        dsp_intr_at_block_end = scr2_0&SCR2_DSP_BLK_END;
                    261:     if ((old_scr2_0&SCR2_DSP_BLK_END) != (scr2_0&SCR2_DSP_BLK_END)) {
                    262:         Log_Printf(LOG_DSP_LEVEL,"[SCR2] %s DSP interrupt from DMA at block end",dsp_intr_at_block_end?"Enable":"Disable");
                    263:     }
                    264:        dsp_dma_unpacked = scr2_0&SCR2_DSP_UNPKD;
                    265:     if ((old_scr2_0&SCR2_DSP_UNPKD) != (scr2_0&SCR2_DSP_UNPKD)) {
                    266:         Log_Printf(LOG_DSP_LEVEL,"[SCR2] %s DSP DMA unpacked mode",dsp_dma_unpacked?"Enable":"Disable");
                    267:     }
                    268: }
                    269: 
                    270: void SCR2_Read0(void)
                    271: {
                    272:     // Log_Printf(LOG_WARN,"SCR2 read at $%08x PC=$%08x\n", IoAccessCurrentAddress,m68k_getpc());
                    273:        IoMem[IoAccessCurrentAddress & 0x1FFFF]=scr2_0;
                    274: }
                    275: 
                    276: void SCR2_Write1(void)
                    277: {      
                    278:     // Log_Printf(LOG_WARN,"SCR2 write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress,IoMem[IoAccessCurrentAddress & IO_SEG_MASK],m68k_getpc());
                    279:        scr2_1=IoMem[IoAccessCurrentAddress & 0x1FFFF];
                    280: }
                    281: 
                    282: void SCR2_Read1(void)
                    283: {
                    284:     // Log_Printf(LOG_WARN,"SCR2 read at $%08x PC=$%08x\n", IoAccessCurrentAddress,m68k_getpc());
                    285:        IoMem[IoAccessCurrentAddress & 0x1FFFF]=scr2_1;
                    286: }
                    287: 
                    288: void SCR2_Write2(void)
                    289: {    
                    290:        Uint8 old_scr2_2=scr2_2;
                    291: 
                    292:        scr2_2=IoMem[IoAccessCurrentAddress & 0x1FFFF];
                    293: 
                    294:        if ((old_scr2_2&SCR2_TIMERIPL7)!=(scr2_2&SCR2_TIMERIPL7)) {
                    295:                Log_Printf(LOG_WARN,"SCR2 TIMER IPL7 change at $%08x val=%x PC=$%08x\n",
                    296:                            IoAccessCurrentAddress,scr2_2&SCR2_TIMERIPL7,m68k_getpc());
                    297:        }
                    298: 
                    299:     /* RTC enabled */
                    300:        if (scr2_2&SCR2_RTCE) {
                    301:         if (((old_scr2_2&SCR2_RTCLK)!=(scr2_2&SCR2_RTCLK)) && ((scr2_2&SCR2_RTCLK)==0) ) {
                    302:             Uint8 rtdata = scr2_2&SCR2_RTDATA;
                    303:             scr2_2 &= ~SCR2_RTDATA;
                    304:             scr2_2 |= rtc_interface_io(rtdata)?SCR2_RTDATA:0;
                    305:         }
                    306:        } else {
                    307:         rtc_interface_reset();
                    308:     }
                    309: }
                    310: 
                    311: void SCR2_Read2(void)
                    312: {
                    313:     // Log_Printf(LOG_WARN,"SCR2 read at $%08x PC=$%08x\n", IoAccessCurrentAddress,m68k_getpc());
                    314:     // IoMem[IoAccessCurrentAddress & 0x1FFFF]=scr2_2 & (SCR2_RTDATA|SCR2_RTCLK|SCR2_RTCE)); // + data
                    315:        IoMem[IoAccessCurrentAddress & 0x1FFFF]=scr2_2;
                    316: }
                    317: 
                    318: void SCR2_Write3(void)
                    319: {      
                    320:        Uint8 old_scr2_3=scr2_3;
                    321:     // Log_Printf(LOG_WARN,"SCR2 write at $%08x val=$%02x PC=$%08x\n", IoAccessCurrentAddress,IoMem[IoAccessCurrentAddress & IO_SEG_MASK],m68k_getpc());
                    322:        scr2_3=IoMem[IoAccessCurrentAddress & 0x1FFFF];
                    323:        if ((old_scr2_3&SCR2_ROM)!=(scr2_3&SCR2_ROM)) {
                    324:                Log_Printf(LOG_WARN,"SCR2 ROM change at $%08x val=%x PC=$%08x\n",
                    325:                    IoAccessCurrentAddress,scr2_3&SCR2_ROM,m68k_getpc());
                    326:                   SCR_ROM_overlay=scr2_3&SCR2_ROM;
                    327:                }
                    328:        if ((old_scr2_3&SCR2_LED)!=(scr2_3&SCR2_LED)) {
                    329:                Log_Printf(LOG_DEBUG,"SCR2 LED change at $%08x val=%x PC=$%08x\n",
                    330:                    IoAccessCurrentAddress,scr2_3&SCR2_LED,m68k_getpc());
                    331:         Statusbar_SetSystemLed(scr2_3&SCR2_LED);
                    332:     }
                    333:     
                    334:     if ((old_scr2_3&SCR2_DSP_INT_EN) != (scr2_3&SCR2_DSP_INT_EN)) {
                    335:         Log_Printf(LOG_DSP_LEVEL,"[SCR2] DSP interrupt at level %i",(scr2_3&SCR2_DSP_INT_EN)?4:3);
                    336:                if (intStat&(INT_DSP_L3|INT_DSP_L4)) {
                    337:                        Log_Printf(LOG_DSP_LEVEL,"[SCR2] Switching DSP interrupt to level %i",(scr2_3&SCR2_DSP_INT_EN)?4:3);
                    338:                        set_interrupt(INT_DSP_L3|INT_DSP_L4, RELEASE_INT);
                    339:                        set_dsp_interrupt(SET_INT);
                    340:                }
                    341:     }
                    342:     if ((old_scr2_3&SCR2_DSP_MEM_EN) != (scr2_3&SCR2_DSP_MEM_EN)) {
                    343:         Log_Printf(LOG_DSP_LEVEL,"[SCR2] %s DSP memory",(scr2_3&SCR2_DSP_MEM_EN)?"Enable":"Disable");
                    344:     }
                    345: }
                    346: 
                    347: 
                    348: void SCR2_Read3(void)
                    349: {
                    350:     // Log_Printf(LOG_WARN,"SCR2 read at $%08x PC=$%08x\n", IoAccessCurrentAddress,m68k_getpc());
                    351:        IoMem[IoAccessCurrentAddress & 0x1FFFF]=scr2_3;
                    352: }
                    353: 
                    354: 
                    355: 
                    356: /* Interrupt Status Register */
                    357: 
                    358: void IntRegStatRead(void) {
                    359:     IoMem_WriteLong(IoAccessCurrentAddress & IO_SEG_MASK, intStat);
                    360: }
                    361: 
                    362: void IntRegStatWrite(void) {
                    363:     intStat = IoMem_ReadLong(IoAccessCurrentAddress & IO_SEG_MASK);
                    364: }
                    365: 
                    366: void set_dsp_interrupt(Uint8 state) {
                    367:     if (scr2_3&SCR2_DSP_INT_EN || ConfigureParams.System.bTurbo) {
                    368:                set_interrupt(INT_DSP_L4, state);
                    369:     } else {
                    370:                set_interrupt(INT_DSP_L3, state);
                    371:     }
                    372: }
                    373: 
                    374: void set_interrupt(Uint32 intr, Uint8 state) {
                    375:     /* The interrupt gets polled by the cpu via intlev()
                    376:      * --> see previous-glue.c
                    377:      */
                    378:     if (state==SET_INT) {
                    379:         intStat |= intr;
                    380:     } else {
                    381:         intStat &= ~intr;
                    382:     }
                    383: }
                    384: 
                    385: int get_interrupt_level(void) {
                    386:     Uint32 interrupt = intStat&intMask;
                    387:     
                    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;
                    406:     } else {
                    407:         abort();
                    408:     }
                    409: }
                    410: 
                    411: /* Interrupt Mask Register */
                    412: 
                    413: void IntRegMaskRead(void) {
                    414:        IoMem_WriteLong(IoAccessCurrentAddress & IO_SEG_MASK,intMask);
                    415: }
                    416: 
                    417: void IntRegMaskWrite(void) {
                    418:        intMask = IoMem_ReadLong(IoAccessCurrentAddress & IO_SEG_MASK);
                    419:         Log_Printf(LOG_DEBUG,"Interrupt mask: %08x", intMask);
                    420: }
                    421: 
                    422: 
                    423: /* Hardclock internal interrupt */
                    424: 
                    425: #define HARDCLOCK_ENABLE 0x80
                    426: #define HARDCLOCK_LATCH  0x40
                    427: #define HARDCLOCK_ZERO   0x3F
                    428: 
                    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;
                    435: 
                    436: void Hardclock_InterruptHandler ( void )
                    437: {
                    438:        CycInt_AcknowledgeInterrupt();
                    439:        if ((hardclock_csr&HARDCLOCK_ENABLE) && (latch_hardclock>0)) {
                    440: //             Log_Printf(LOG_WARN,"[INT] throwing hardclock %lld", host_time_us());
                    441:         set_interrupt(INT_TIMER,SET_INT);
                    442:         Uint64 now = host_time_us();
                    443:         host_hardclock(latch_hardclock, now - hardClockLastLatch);
                    444:         hardClockLastLatch = now;
                    445:         CycInt_AddRelativeInterruptUs(latch_hardclock, 0, INTERRUPT_HARDCLOCK);
                    446:        }
                    447: }
                    448: 
                    449: 
                    450: void HardclockRead0(void){
                    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());
                    453: }
                    454: void HardclockRead1(void){
                    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());
                    457: }
                    458: 
                    459: void HardclockWrite0(void){
                    460:        Log_Printf(LOG_HARDCLOCK_LEVEL,"[hardclock] write at $%08x val=%02x PC=$%08x", IoAccessCurrentAddress,IoMem[IoAccessCurrentAddress & 0x1FFFF],m68k_getpc());
                    461:        hardclock0=IoMem[IoAccessCurrentAddress & 0x1FFFF];
                    462: }
                    463: void HardclockWrite1(void){
                    464:        Log_Printf(LOG_HARDCLOCK_LEVEL,"[hardclock] write at $%08x val=%02x PC=$%08x",IoAccessCurrentAddress,IoMem[IoAccessCurrentAddress & 0x1FFFF],m68k_getpc());
                    465:        hardclock1=IoMem[IoAccessCurrentAddress & 0x1FFFF];
                    466: }
                    467: 
                    468: void HardclockWriteCSR(void) {
                    469:        Log_Printf(LOG_HARDCLOCK_LEVEL,"[hardclock] write at $%08x val=%02x PC=$%08x", IoAccessCurrentAddress,IoMem[IoAccessCurrentAddress & 0x1FFFF],m68k_getpc());
                    470:        hardclock_csr=IoMem[IoAccessCurrentAddress & 0x1FFFF];
                    471:        if (hardclock_csr&HARDCLOCK_LATCH) {
                    472:         hardclock_csr&= ~HARDCLOCK_LATCH;
                    473:                latch_hardclock=(hardclock0<<8)|hardclock1;
                    474:         hardClockLastLatch = host_time_us();
                    475:        }
                    476:        if ((hardclock_csr&HARDCLOCK_ENABLE) && (latch_hardclock>0)) {
                    477:         Log_Printf(LOG_HARDCLOCK_LEVEL,"[hardclock] enable periodic interrupt (%i microseconds).", latch_hardclock);
                    478:         CycInt_AddRelativeInterruptUs(latch_hardclock, 0, INTERRUPT_HARDCLOCK);
                    479:        } else {
                    480:         Log_Printf(LOG_HARDCLOCK_LEVEL,"[hardclock] disable periodic interrupt.");
                    481:     }
                    482:     set_interrupt(INT_TIMER,RELEASE_INT);
                    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: 
                    491: /* Event counter register */
                    492: 
                    493: static Uint64 sysTimerOffset = 0;
                    494: static bool   resetTimer;
                    495: 
                    496: void System_Timer_Read(void) {
                    497:     Uint64 now = host_time_us();
                    498:     if(resetTimer) {
                    499:         sysTimerOffset = now;
                    500:         resetTimer = false;
                    501:     }
                    502:     now -= sysTimerOffset;
                    503:     IoMem_WriteLong(IoAccessCurrentAddress&IO_SEG_MASK, now & 0xFFFFF);
                    504: }
                    505: 
                    506: void System_Timer_Write(void) {
                    507:     resetTimer = true;
                    508: }
                    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.