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