Annotation of hatari/src/cpu/hatari-glue.c, revision 1.1.1.9

1.1       root        1: /*
                      2:   Hatari - hatari-glue.c
                      3: 
1.1.1.4   root        4:   This file is distributed under the GNU General Public License, version 2
                      5:   or at your option any later version. Read the file gpl.txt for details.
1.1       root        6: 
                      7:   This file contains some code to glue the UAE CPU core to the rest of the
                      8:   emulator and Hatari's "illegal" opcodes.
                      9: */
                     10: const char HatariGlue_fileid[] = "Hatari hatari-glue.c : " __DATE__ " " __TIME__;
                     11: 
                     12: 
                     13: #include <stdio.h>
                     14: 
                     15: #include "main.h"
                     16: #include "configuration.h"
                     17: #include "cycInt.h"
                     18: #include "tos.h"
                     19: #include "gemdos.h"
1.1.1.4   root       20: #include "natfeats.h"
1.1       root       21: #include "cart.h"
                     22: #include "vdi.h"
                     23: #include "stMemory.h"
                     24: #include "ikbd.h"
                     25: #include "screen.h"
                     26: #include "video.h"
1.1.1.2   root       27: #include "psg.h"
1.1.1.4   root       28: #include "mfp.h"
                     29: #include "fdc.h"
1.1.1.9 ! root       30: #include "memorySnapShot.h"
1.1       root       31: 
                     32: #include "sysdeps.h"
1.1.1.6   root       33: #include "options_cpu.h"
1.1       root       34: #include "maccess.h"
                     35: #include "memory.h"
1.1.1.4   root       36: #include "m68000.h"
1.1       root       37: #include "newcpu.h"
1.1.1.3   root       38: #include "cpu_prefetch.h"
1.1.1.9 ! root       39: #include "savestate.h"
1.1       root       40: #include "hatari-glue.h"
                     41: 
                     42: 
                     43: struct uae_prefs currprefs, changed_prefs;
                     44: 
                     45: int pendingInterrupts = 0;
                     46: 
                     47: 
                     48: /**
                     49:  * Reset custom chips
1.1.1.4   root       50:  * In case the RESET instruction is called, we must reset all the peripherals
                     51:  * connected to the CPU's reset pin.
1.1       root       52:  */
                     53: void customreset(void)
                     54: {
                     55:        pendingInterrupts = 0;
                     56: 
1.1.1.4   root       57:        /* Reset the IKBD */
                     58:        IKBD_Reset ( false );
1.1       root       59: 
                     60:        /* Reseting the GLUE video chip should also set freq/res register to 0 */
                     61:        Video_Reset_Glue ();
1.1.1.2   root       62: 
1.1.1.7   root       63:        /* Reset the YM2149 (stop any sound) */
                     64:        PSG_Reset ();
1.1.1.4   root       65: 
                     66:        /* Reset the MFP */
                     67:        MFP_Reset ();
                     68: 
                     69:        /* Reset the FDC */
1.1.1.5   root       70:        FDC_Reset ( false );
1.1       root       71: }
                     72: 
                     73: 
                     74: /**
                     75:  * Return interrupt number (1 - 7), -1 means no interrupt.
                     76:  * Note that the interrupt stays pending if it can't be executed yet
                     77:  * due to the interrupt level field in the SR.
                     78:  */
                     79: int intlev(void)
                     80: {
1.1.1.6   root       81:        if ( pendingInterrupts & (1 << 6) )             /* MFP/DSP interrupt ? */
                     82:                return 6;
                     83:        else if ( pendingInterrupts & (1 << 4) )        /* VBL interrupt ? */
1.1.1.4   root       84:                return 4;
                     85:        else if ( pendingInterrupts & (1 << 2) )        /* HBL interrupt ? */
                     86:                return 2;
1.1       root       87: 
                     88:        return -1;
                     89: }
                     90: 
1.1.1.9 ! root       91: 
        !            92: void UAE_Set_Quit_Reset ( bool hard )
        !            93: {
        !            94: //fprintf ( stderr , "UAE_Set_Quit_Reset %d\n" , hard );
        !            95:        if ( hard )
        !            96:                quit_program = UAE_RESET_HARD;
        !            97:        else
        !            98:                quit_program = UAE_RESET;
        !            99: }
        !           100: 
        !           101: 
        !           102: void UAE_Set_State_Save ( void )
        !           103: {
        !           104: //fprintf ( stderr , "UAE_Set_State_Save\n" );
        !           105:        savestate_state = STATE_SAVE;
        !           106: }
        !           107: 
        !           108: 
        !           109: void UAE_Set_State_Restore ( void )
        !           110: {
        !           111: //fprintf ( stderr , "UAE_Set_State_Restore\n" );
        !           112:        savestate_state = STATE_RESTORE;
        !           113: }
        !           114: 
        !           115: 
        !           116: 
1.1       root      117: /**
1.1.1.9 ! root      118:  * Replace WinUAE's save_state / restore_state functions with Hatari's specific ones
1.1       root      119:  */
1.1.1.9 ! root      120: int save_state (const TCHAR *filename, const TCHAR *description)
1.1       root      121: {
1.1.1.9 ! root      122: //fprintf ( stderr , "save_state in\n" );
        !           123:        MemorySnapShot_Capture_Do ();
        !           124: //fprintf ( stderr , "save_state out\n" );
        !           125:        savestate_state = 0;
        !           126:        return 0;                                       /* return value is not used */
        !           127: }
1.1       root      128: 
                    129: 
1.1.1.9 ! root      130: void restore_state (const TCHAR *filename)
        !           131: {
        !           132:        MemorySnapShot_Restore_Do ();
        !           133: }
        !           134: 
        !           135: 
        !           136: void savestate_restore_finish (void)
        !           137: {
        !           138: //fprintf ( stderr , "savestate_restore_finish in %d\n" , quit_program );
        !           139:        if (!isrestore ())
        !           140:                return;
        !           141:        restore_cpu_finish ();
        !           142:        savestate_state = 0;
        !           143:        quit_program = 0;                               /* at this point, quit_program was already processed, we must reset it */
        !           144: //fprintf ( stderr , "savestate_restore_finish out %d\n" , quit_program );
        !           145: }
1.1       root      146: 
1.1.1.9 ! root      147: 
        !           148: 
        !           149: 
        !           150: /**
        !           151:  * Initialize 680x0 emulation
        !           152:  */
        !           153: int Init680x0(void)
        !           154: {
        !           155: //fprintf ( stderr , "Init680x0 in\n" );
        !           156:        init_m68k();
        !           157: //fprintf ( stderr , "Init680x0 out\n" );
1.1       root      158:        return true;
                    159: }
                    160: 
                    161: 
                    162: /**
                    163:  * Deinitialize 680x0 emulation
                    164:  */
                    165: void Exit680x0(void)
                    166: {
                    167:        memory_uninit();
                    168: 
                    169:        free(table68k);
                    170:        table68k = NULL;
                    171: }
                    172: 
1.1.1.6   root      173: 
                    174: /**
                    175:  * Execute a 'NOP' opcode (increment PC by 2 bytes and take care
                    176:  * of prefetch at the CPU level depending on the current CPU mode)
                    177:  * This is used to return from Gemdos / Natfeats interception, by ignoring
                    178:  * the intercepted opcode and executing a NOP instead once the work has been done.
                    179:  */
                    180: static void    CpuDoNOP ( void )
                    181: {
                    182:        (*cpufunctbl[0X4E71])(0x4E71);
                    183: }
                    184: 
                    185: 
1.1       root      186: /**
1.1.1.7   root      187:  * Check whether PC is currently in ROM cartridge space - used
                    188:  * to test whether our "illegal" Hatari opcodes should be handled
                    189:  * or whether they are just "normal" illegal opcodes.
                    190:  */
                    191: static bool is_cart_pc(void)
                    192: {
                    193:        Uint32 pc = M68000_GetPC();
                    194: 
                    195:        if (ConfigureParams.System.bAddressSpace24 || (pc >> 24) == 0xff)
                    196:        {
                    197:                pc &= 0x00ffffff;       /* Mask to 24-bit address */
                    198:        }
                    199: 
                    200:        return pc >= 0xfa0000 && pc < 0xfc0000;
                    201: }
                    202: 
                    203: 
                    204: /**
1.1       root      205:  * This function will be called at system init by the cartridge routine
                    206:  * (after gemdos init, before booting floppies).
                    207:  * The GEMDOS vector (#$84) is setup and we also initialize the connected
1.1.1.9 ! root      208:  * drive mask and Line-A variables (for an extended VDI resolution) from here.
1.1       root      209:  */
1.1.1.7   root      210: uae_u32 REGPARAM3 OpCode_SysInit(uae_u32 opcode)
1.1       root      211: {
1.1.1.7   root      212:        if (is_cart_pc())
1.1       root      213:        {
1.1.1.7   root      214:                /* Add any drives mapped by TOS in the interim */
                    215:                ConnectedDriveMask |= STMemory_ReadLong(0x4c2);
                    216:                /* Initialize the connected drive mask */
                    217:                STMemory_WriteLong(0x4c2, ConnectedDriveMask);
                    218: 
1.1       root      219:                /* Init on boot - see cart.c */
                    220:                GemDOS_Boot();
                    221: 
                    222:                /* Update LineA for extended VDI res
                    223:                 * D0: LineA base, A1: Font base
                    224:                 */
                    225:                VDI_LineA(regs.regs[0], regs.regs[9]);
1.1.1.7   root      226: 
1.1.1.9 ! root      227:                CpuDoNOP();
        !           228:        }
        !           229:        else if (!bUseTos)
        !           230:        {
        !           231:                GemDOS_Boot();
        !           232:                CpuDoNOP();
1.1.1.7   root      233:        }
                    234:        else
                    235:        {
                    236:                LOG_TRACE(TRACE_OS_GEMDOS | TRACE_OS_BASE | TRACE_OS_VDI | TRACE_OS_AES,
                    237:                          "SYSINIT opcode invoked outside of cartridge space\n");
                    238:                /* illegal instruction */
                    239:                op_illg(opcode);
                    240:                fill_prefetch();
1.1       root      241:        }
                    242: 
1.1.1.3   root      243:        return 4 * CYCLE_UNIT / 2;
1.1       root      244: }
                    245: 
                    246: 
                    247: /**
                    248:  * Intercept GEMDOS calls.
                    249:  * Used for GEMDOS HD emulation (see gemdos.c).
                    250:  */
1.1.1.7   root      251: uae_u32 REGPARAM3 OpCode_GemDos(uae_u32 opcode)
1.1       root      252: {
1.1.1.7   root      253:        if (is_cart_pc())
                    254:        {
                    255:                GemDOS_OpCode();    /* handler code in gemdos.c */
                    256:                CpuDoNOP();
                    257:        }
                    258:        else
                    259:        {
                    260:                LOG_TRACE(TRACE_OS_GEMDOS, "GEMDOS opcode invoked outside of cartridge space\n");
                    261:                /* illegal instruction */
                    262:                op_illg(opcode);
                    263:                fill_prefetch();
                    264:        }
1.1       root      265: 
1.1.1.3   root      266:        return 4 * CYCLE_UNIT / 2;
1.1       root      267: }
                    268: 
                    269: 
                    270: /**
                    271:  * This is called after completion of each VDI call
                    272:  */
1.1.1.7   root      273: uae_u32 REGPARAM3 OpCode_VDI(uae_u32 opcode)
1.1       root      274: {
1.1.1.4   root      275:        /* this is valid only after VDI trap, called from cartridge code */
1.1.1.7   root      276:        if (VDI_OldPC && is_cart_pc())
1.1.1.4   root      277:        {
                    278:                VDI_Complete();
                    279: 
                    280:                /* Set PC back to where originated from to continue instruction decoding */
                    281:                m68k_setpc(VDI_OldPC);
                    282:                VDI_OldPC = 0;
                    283:        }
                    284:        else
                    285:        {
1.1.1.7   root      286:                LOG_TRACE(TRACE_OS_VDI, "VDI opcode invoked outside of cartridge space\n");
1.1.1.4   root      287:                /* illegal instruction */
                    288:                op_illg(opcode);
                    289:        }
1.1       root      290: 
1.1.1.6   root      291:        fill_prefetch();
1.1.1.3   root      292:        return 4 * CYCLE_UNIT / 2;
1.1       root      293: }
1.1.1.4   root      294: 
                    295: 
                    296: /**
                    297:  * Emulator Native Features ID opcode interception.
                    298:  */
1.1.1.7   root      299: uae_u32 REGPARAM3 OpCode_NatFeat_ID(uae_u32 opcode)
1.1.1.4   root      300: {
                    301:        Uint32 stack = Regs[REG_A7] + SIZE_LONG;        /* skip return address */
                    302: 
1.1.1.7   root      303:        if (NatFeat_ID(stack, &(Regs[REG_D0])))
                    304:        {
1.1.1.6   root      305:                CpuDoNOP ();
1.1.1.4   root      306:        }
                    307:        return 4 * CYCLE_UNIT / 2;
                    308: }
                    309: 
                    310: /**
                    311:  * Emulator Native Features call opcode interception.
                    312:  */
1.1.1.7   root      313: uae_u32 REGPARAM3 OpCode_NatFeat_Call(uae_u32 opcode)
1.1.1.4   root      314: {
                    315:        Uint32 stack = Regs[REG_A7] + SIZE_LONG;        /* skip return address */
                    316:        Uint16 SR = M68000_GetSR();
                    317:        bool super;
                    318: 
                    319:        super = ((SR & SR_SUPERMODE) == SR_SUPERMODE);
1.1.1.7   root      320:        if (NatFeat_Call(stack, super, &(Regs[REG_D0])))
                    321:        {
1.1.1.6   root      322:                CpuDoNOP ();
1.1.1.4   root      323:        }
                    324:        return 4 * CYCLE_UNIT / 2;
                    325: }
1.1.1.6   root      326: 
                    327: 
1.1.1.7   root      328: TCHAR* buf_out (TCHAR *buffer, int *bufsize, const TCHAR *format, ...)
                    329: {
                    330:        va_list parms;
                    331: 
                    332:        if (buffer == NULL)
                    333:        {
                    334:                return NULL;
                    335:        }
                    336: 
                    337:        va_start (parms, format);
                    338:        vsnprintf (buffer, (*bufsize) - 1, format, parms);
                    339:        va_end (parms);
                    340:        *bufsize -= _tcslen (buffer);
1.1.1.6   root      341: 
1.1.1.7   root      342:        return buffer + _tcslen (buffer);
                    343: }
                    344: 
                    345: void error_log(const TCHAR *format, ...)
                    346: {
                    347:        va_list parms;
1.1.1.6   root      348: 
1.1.1.7   root      349:        va_start(parms, format);
                    350:        vfprintf(stderr, format, parms);
                    351:        va_end(parms);
1.1.1.6   root      352: 
1.1.1.7   root      353:        if (format[strlen(format) - 1] != '\n')
                    354:        {
                    355:                fputc('\n', stderr);
                    356:        }
1.1.1.6   root      357: }

unix.superglobalmegacorp.com

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