Beispiel #1
0
/*      We simply find the first function in this .obj data, and execute it. */
static uae_u32 REGPARAM2 emulib_ExecuteNativeCode (struct regstruct *regs)
{
#if 0
    uaecptr object_AAM = m68k_areg (regs, 0);
    uae_u32 d1 = m68k_dreg (regs, 1);
    uae_u32 d2 = m68k_dreg (regs, 2);
    uae_u32 d3 = m68k_dreg (regs, 3);
    uae_u32 d4 = m68k_dreg (regs, 4);
    uae_u32 d5 = m68k_dreg (regs, 5);
    uae_u32 d6 = m68k_dreg (regs, 6);
    uae_u32 d7 = m68k_dreg (regs, 7);
    uae_u32 a1 = m68k_areg (regs, 1);
    uae_u32 a2 = m68k_areg (regs, 2);
    uae_u32 a3 = m68k_areg (regs, 3);
    uae_u32 a4 = m68k_areg (regs, 4);
    uae_u32 a5 = m68k_areg (regs, 5);
    uae_u32 a6 = m68k_areg (regs, 6);

    uae_u8* object_UAM = NULL;
    CREATE_NATIVE_FUNC_PTR;

    if( get_mem_bank( object_AAM ).check( object_AAM, 1 ) )
	object_UAM = get_mem_bank( object_AAM).xlateaddr( object_AAM );

    if( object_UAM )
    {
	SET_NATIVE_FUNC( FindFunctionInObject( object_UAM ) );
	CALL_NATIVE_FUNC( d1, d2, d3, d4, d5, d6, d7, a1, a2, a3, a4, a5, a6);
    }
    return 1;
#endif
    return 0;
}
Beispiel #2
0
/**
 * Write long/word/byte into memory.
 * NOTE - value will be converted to 68000 endian
 */
void	STMemory_Write ( Uint32 addr , Uint32 val , int size )
{
	addrbank	*pBank;
	Uint8		*p;

//printf ( "mem direct write %x %x %d\n" , addr , val , size );
	pBank = &get_mem_bank ( addr );

	if ( pBank->baseaddr == NULL )
		return;					/* No real memory, do nothing */

	addr -= pBank->start & pBank->mask;
	addr &= pBank->mask;
	p = pBank->baseaddr + addr;

	/* We modify the memory, so we flush the instr/data caches if needed */
	M68000_Flush_All_Caches ( addr , size );
	
	if ( size == 4 )
		do_put_mem_long ( p , val );
	else if ( size == 2 )
		do_put_mem_word ( p , (Uint16)val );
	else
		*p = (Uint8)val;
}
Beispiel #3
0
static uint8_t *memmap(uint32_t addr, uint32_t len)
{
	addrbank *bank_data = &get_mem_bank (addr);
	if (!bank_data->check (addr, len))
		return NULL;
	return bank_data->xlateaddr (addr);
}
Beispiel #4
0
static uae_u8 *memmap(uae_u32 addr, uae_u32 len)
{
	addrbank *bank_data = &get_mem_bank (addr);
	if (!bank_data->check (addr, len))
		return NULL;
	return bank_data->xlateaddr (addr);
}
Beispiel #5
0
STATIC_INLINE bool spinlock_pre(uaecptr addr)
{
	addrbank *ab = &get_mem_bank(addr);
	if ((ab->flags & ABFLAG_THREADSAFE) == 0) {
		uae_ppc_spinlock_get();
		return true;
	}
	return false;
}
Beispiel #6
0
/*************************************************************
Converts an amiga address to a native one or NULL if this
is not possible, Size specified the number of bytes you
want to access
*************************************************************/
static uae_u8 *amiga2native (uae_u32 aptr, int size)
{
	addrbank bank = get_mem_bank (aptr);

	/* Check if the address can be translated to native */
	if (bank.check (aptr, size)) {
		return bank.xlateaddr (aptr);
	}
	return NULL;
}
Beispiel #7
0
/**
 * Check that the region of 'size' starting at 'addr' is entirely inside
 * a memory bank of the same memory type
 */
bool	STMemory_CheckAreaType ( Uint32 addr , int size , int mem_type )
{
	addrbank	*pBank;

	pBank = &get_mem_bank ( addr );

	if ( ( pBank->flags & mem_type ) == 0 )
	{
		fprintf(stderr, "pBank flags mismatch: 0x%x & 0x%x (RAM = 0x%x)\n", pBank->flags, mem_type, ABFLAG_RAM);
		return false;
	}

	return pBank->check ( addr , size );
}
Beispiel #8
0
/**
 * Read long/word/byte from memory.
 * NOTE - value will be converted to 68000 endian
 */
Uint32	STMemory_Read ( Uint32 addr , int size )
{
	addrbank	*pBank;
	Uint8		*p;

//printf ( "mem direct read %x %d\n" , addr , size );
	pBank = &get_mem_bank ( addr );

	if ( pBank->baseaddr == NULL )
		return 0;				/* No real memory, return 0 */

	addr -= pBank->start & pBank->mask;
	addr &= pBank->mask;
	p = pBank->baseaddr + addr;
	
	if ( size == 4 )
		return do_get_mem_long ( p );
	else if ( size == 2 )
		return (Uint32)do_get_mem_word ( p );
	else
		return (Uint32)*p;
}
Beispiel #9
0
static __inline__ void byteput (uaecptr addr, uae_u32 b)
{
    call_mem_put_func (get_mem_bank (addr).bput, addr, b);
}
Beispiel #10
0
__inline__ uae_u32 longget (uaecptr addr)
{
    return call_mem_get_func (get_mem_bank (addr).lget, addr);
}
Beispiel #11
0
static int execscsicmd_direct (int unitnum, uaecptr acmd)
{
    int sactual = 0;
    struct scsidevdata *sdd = &drives[unitnum];
    SCSI *scgp              = sdd->scgp;
    struct scg_cmd *scmd    = scgp->scmd;

    uaecptr scsi_data      = get_long (acmd + 0);
    uae_u32 scsi_len       = get_long (acmd + 4);
    uaecptr scsi_cmd       = get_long (acmd + 12);
    int scsi_cmd_len       = get_word (acmd + 16);
    int scsi_cmd_len_orig  = scsi_cmd_len;
    uae_u8  scsi_flags     = get_byte (acmd + 20);
    uaecptr scsi_sense     = get_long (acmd + 22);
    uae_u16 scsi_sense_len = get_word (acmd + 26);
    int io_error           = 0;
    int parm;
    addrbank *bank_data    = &get_mem_bank (scsi_data);
    addrbank *bank_cmd	   = &get_mem_bank (scsi_cmd);
    uae_u8   *scsi_datap;
    uae_u8   *scsi_datap_org;

    DEBUG_LOG ("SCSIDEV: unit=%d: execscsicmd_direct\n", unitnum);

    /* do transfer directly to and from Amiga memory */
    if (!bank_data || !bank_data->check (scsi_data, scsi_len))
	return -5; /* IOERR_BADADDRESS */

    uae_sem_wait (&scgp_sem);

    memset (scmd, 0, sizeof (*scmd));
    /* the Amiga does not tell us how long the timeout shall be, so make it
     * _very_ long (specified in seconds) */
    scmd->timeout   = 80 * 60;
    scsi_datap      = scsi_datap_org = scsi_len
		      ? bank_data->xlateaddr (scsi_data) : 0;
    scmd->size      = scsi_len;
    scmd->flags     = (scsi_flags & 1) ? SCG_RECV_DATA : SCG_DISRE_ENA;
    memcpy (&scmd->cdb, bank_cmd->xlateaddr (scsi_cmd), scsi_cmd_len);
    scmd->target    = sdd->target;
    scmd->sense_len = (scsi_flags & 4) ? 4 : /* SCSIF_OLDAUTOSENSE */
		      (scsi_flags & 2) ? scsi_sense_len : /* SCSIF_AUTOSENSE */
		      -1;
    scmd->sense_count = 0;
    *(uae_u8 *)&scmd->scb = 0;
    if (sdd->isatapi)
	scsi_atapi_fixup_pre (scmd->cdb.cmd_cdb, &scsi_cmd_len, &scsi_datap,
			      &scsi_len, &parm);
    scmd->addr      = (caddr_t)scsi_datap;
    scmd->cdb_len   = scsi_cmd_len;

    scg_settarget (scgp, sdd->bus, sdd->target, sdd->lun);
    scgp->cmdname    = "???";
    scgp->curcmdname = "???";

    DEBUG_LOG ("SCSIDEV: sending command: 0x%2x\n", scmd->cdb.g0_cdb.cmd);

    scg_cmd (scgp);

    DEBUG_LOG ("SCSIDEV: result: %d %d %s\n", scmd->error, scmd->ux_errno,\
	       scgp->errstr);

	gui_flicker_led (LED_CD, 0, 1);

    put_word (acmd + 18, scmd->error == SCG_FATAL
					? 0 : scsi_cmd_len); /* fake scsi_CmdActual */
    put_byte (acmd + 21, *(uae_u8 *)&scmd->scb);	     /* scsi_Status */

    if (*(uae_u8 *)&scmd->scb) {
	io_error = 45; /* HFERR_BadStatus */
	/* copy sense? */
	for (sactual = 0;
	     scsi_sense && sactual < scsi_sense_len && sactual < scmd->sense_count;
	     sactual++) {
	     put_byte (scsi_sense + sactual, scmd->u_sense.cmd_sense[sactual]);
	}
	put_long (acmd + 8, 0); /* scsi_Actual */
    } else {
	int i;
	for (i = 0; i < scsi_sense_len; i++)
	    put_byte (scsi_sense + i, 0);
	sactual = 0;
	if (scmd->error != SCG_NO_ERROR || scmd->ux_errno != 0) {
	    /* We might have been limited by the hosts DMA limits,
	       which is usually indicated by ENOMEM */
	    if (scsi_len > (unsigned int)sdd->max_dma && scmd->ux_errno == ENOMEM)
		io_error = (uae_u8)-4; /* IOERR_BADLENGTH */
	    else {
		io_error = 20; /* io_Error, but not specified */
		put_long (acmd + 8, 0); /* scsi_Actual */
	    }
	} else {
	    scsi_len = scmd->size;
	    if (sdd->isatapi)
		scsi_atapi_fixup_post (scmd->cdb.cmd_cdb, scsi_cmd_len,
				       scsi_datap_org, scsi_datap,
				       &scsi_len, parm);
	    io_error = 0;
	    put_long (acmd + 8, scsi_len); /* scsi_Actual */
	}
    }
    put_word (acmd + 28, sactual);

    uae_sem_post (&scgp_sem);

    if (scsi_datap != scsi_datap_org)
	free (scsi_datap);

    return io_error;
}
Beispiel #12
0
static int execscsicmd_direct_ioctl (int unitnum, struct amigascsi* ascsi)
{
    struct scsidevdata *sdd;
    struct cdrom_generic_command cmd;
    struct request_sense sense;
    uaecptr acmd = VALUE_TO_PTR(ascsi);

    uaecptr scsi_data         = get_long (acmd + 0);
    uae_u32 scsi_len          = get_long (acmd + 4);
    uaecptr scsi_cmd          = get_long (acmd + 12);
    int     scsi_cmd_len      = get_word (acmd + 16);
    uae_u8  scsi_flags        = get_byte (acmd + 20);
    uae_u8  scsi_status       = get_byte (acmd + 21);
    uaecptr scsi_sense        = get_long (acmd + 22);
    uae_u16 scsi_sense_len    = get_word (acmd + 26);

    int io_error;
    unsigned int senselen;
    int parm, i;

    addrbank *bank_data    = &get_mem_bank (scsi_data);
    addrbank *bank_cmd	   = &get_mem_bank (scsi_cmd);
    addrbank *bank_sense   = &get_mem_bank (scsi_sense);

    uae_u8   *scsi_datap;
    uae_u8   *scsi_datap_org;

    DEBUG_LOG ("SCSIDEV: unit = %d: execscsicmd_direct_ioctl\n", unitnum);
    DEBUG_LOG ("SCSIDEV: scsi_len = %d, scsi_cmd_len = %d, scsi_sense_len = %d, scsi_flags = %x\n",
	       scsi_len, scsi_cmd_len, scsi_sense_len, scsi_flags);

    if (unitnum >= total_drives) {
	DEBUG_LOG ("SCSIDEV: illegal unit %d >= total_drives %d.\n", unitnum, total_drives);
	return -1; /* TODO: better error code */
    }
    sdd = &drives[unitnum];

    /* do transfer directly to and from Amiga memory */
    if (!bank_data || !bank_data->check (scsi_data, scsi_len)) {
	DEBUG_LOG ("SCSIDEV: illegal Amiga memory buffer\n");
	return -5; /* IOERR_BADADDRESS */
    }

    if (scsi_cmd_len > CDROM_PACKET_SIZE) {
	DEBUG_LOG ("SCSIDEV: scsi_cmd_len too large (%d)\n", scsi_cmd_len);
	return -5; /* TODO: better code */
    }

    scsi_datap = scsi_datap_org = (scsi_len ? bank_data->xlateaddr (scsi_data) : 0);

    memcpy (cmd.cmd, bank_cmd->xlateaddr (scsi_cmd), scsi_cmd_len);
    cmd.buffer = scsi_datap;
    cmd.buflen = scsi_len;
    cmd.stat = scsi_status;
    if (sdd->isatapi) {
	scsi_atapi_fixup_pre (cmd.cmd, &scsi_cmd_len, &scsi_datap,
			      &scsi_len, &parm);
    }
    senselen = (scsi_flags & 4) ? 4 : /* SCSIF_OLDAUTOSENSE */
		      (scsi_flags & 2) ? scsi_sense_len : /* SCSIF_AUTOSENSE */
		      0;
    cmd.sense = senselen > 0 ? &sense : 0;
    cmd.data_direction = (scsi_flags & 1) ? CGC_DATA_READ : CGC_DATA_WRITE;
    cmd.quiet = 0;
    cmd.timeout = 80*60;

        gui_flicker_led (LED_CD, 0, 1);

    io_error = ioctl (sdd->fd, CDROM_SEND_PACKET, &cmd);

    DEBUG_LOG ("SCSIDEV: error: %d, stat: %d\n", io_error, cmd.stat);

    if (cmd.stat != 0) {
	unsigned int n;

	io_error = 45;  /* HFERR_BadStatus */
	put_byte (acmd + 8, 0);
	put_byte (acmd + 18, 0 /*scsi_cmd_len */);
	put_byte (acmd + 21, cmd.stat);
	DEBUG_LOG ("SCSIDEV: bad status\n");
	n = cmd.sense ? cmd.sense->add_sense_len + 7 : 0;
	if (senselen > n) {
	    if (scsi_sense)
		memset (bank_sense->xlateaddr (scsi_sense), 0, senselen);
	    senselen = n;
	}
	DEBUG_LOG ("SCSIDEV: senselen = %d\n", senselen);
	if (scsi_sense && cmd.sense && senselen > 0) {
	    memcpy (bank_sense->xlateaddr (scsi_sense), cmd.sense, senselen);
	}
	put_byte (acmd + 28, senselen);
    } else {
	put_byte (acmd + 28, 0);
	if (scsi_sense && senselen > 0) {
	    memset (bank_sense->xlateaddr (scsi_sense), 0, senselen);
	}
	if (io_error == 0) {
	    if (sdd->isatapi) {
		scsi_atapi_fixup_post (cmd.cmd, scsi_cmd_len,
				       scsi_datap_org, scsi_datap,
				       &scsi_len, parm);
	    }
	    put_long (acmd + 8,  scsi_len);
	    put_word (acmd + 18, scsi_cmd_len);
	    put_byte (acmd + 21, cmd.stat);
	    io_error = 0;
	} else {
	    DEBUG_LOG ("SCSIDEV: errno: %d, %s\n", errno, strerror (errno));
	    put_long (acmd + 8,  0);
	    put_word (acmd + 18, 0);
	    put_byte (acmd + 21, cmd.stat);
	    io_error = 20; /* TODO: Map errors */
	}
    }
    if (scsi_datap != scsi_datap_org)
	xfree (scsi_datap);
    return io_error;
}
Beispiel #13
0
static void scsidev_do_scsi (struct scsidevdata *sdd, uaecptr request)
{
    SCSI *scgp = sdd->scgp;
    struct scg_cmd *scmd = scgp->scmd;
    uaecptr acmd = get_long (request + 40);
    uaecptr scsi_data = get_long (acmd + 0);
    uae_u32 scsi_len = get_long (acmd + 4);
    uaecptr scsi_cmd = get_long (acmd + 12);
    uae_u16 scsi_cmd_len = get_word (acmd + 16);
    uae_u8 scsi_flags = get_byte (acmd + 20);
    uaecptr scsi_sense = get_long (acmd + 22);
    uae_u16 scsi_sense_len = get_word (acmd + 26);
    int sactual = 0;
    addrbank *bank_data = &get_mem_bank (scsi_data);
    addrbank *bank_cmd  = &get_mem_bank (scsi_cmd);

    /* do transfer directly to and from Amiga memory */
    if (!bank_data || !bank_data->check (scsi_data, scsi_len) ||
	!bank_cmd  || !bank_cmd->check (scsi_cmd, scsi_cmd_len)) {
	put_byte (request + 31, (uae_u8)-5); /* IOERR_BADADDRESS */
	return;
    }

#ifdef SCSI_IS_NOT_THREAD_SAFE
    uae_sem_wait (&scgp_sem);
#endif

	 scmd->timeout = 80 * 60; /* the Amiga does not tell us how long the timeout shall be, so make it _very_ long (specified in seconds) */
    scmd->addr = bank_data->xlateaddr (scsi_data);
    scmd->size = scsi_len;
    scmd->flags = ((scsi_flags & 1) ? SCG_RECV_DATA : 0) | SCG_DISRE_ENA;
    scmd->cdb_len = scsi_cmd_len;
    memcpy(&scmd->cdb, bank_cmd->xlateaddr (scsi_cmd), scsi_cmd_len);
    scmd->target = sdd->target;
    scmd->sense_len = (scsi_flags & 4) ? 4 : /* SCSIF_OLDAUTOSENSE */
	(scsi_flags & 2) ? scsi_sense_len : /* SCSIF_AUTOSENSE */
	-1;
    scmd->sense_count = 0;
    *(uae_u8 *)&scmd->scb = 0;

    #ifdef DEBUG_CDR
    /* please ignore this code - it can be used to debug raw CD-R writing... */
    if (!(scsi_len % 2368)) {
	/* Structure for generating bytes 2353...2368 if writing in ultra raw mode */
	typedef struct QDATAtag {
	    BYTE ControlAdr;
	    BCD Tno;
	    BCD Point;
	    BCD Min;
	    BCD Sec;
	    BCD Frame;
	    BYTE Zero;
	    BCD PMin;
	    BCD PSec;
	    BCD PFrame;
	    WORD Crc;
	    BYTE Reserved[3];
	    BYTE PChannel;
	} QDATA;

	int i = scsi_len / 2368;
	QDATA *data = (QDATA *)&((unsigned char *)scmd->addr)[2352];
	for (; i > 0; i--, data = (QDATA *)&((unsigned char *)data)[2368]) {
	    printf ("$%02x: $%02x $%02x | $%02x:$%02x:$%02x = %6ld | $%02x | $%02x:$%02x:$%02x = %6ld\n",
		    (int)data->ControlAdr, (int)*(UBYTE *)&data->Tno, (int)*(UBYTE *)&data->Point,
		    (int)*(UBYTE *)&data->Min, (int)*(UBYTE *)&data->Sec, (int)*(UBYTE *)&data->Frame,
		    BCDTime2Block_Pointer (&data->Min) + 150,
		    *(UBYTE *)&data->Zero,
		    *(UBYTE *)&data->PMin, *(UBYTE *)&data->PSec, *(UBYTE *)&data->PFrame,
		    BCDTime2Block_Pointer (&data->PMin));
	}
	fflush (stdout);
    }
    #endif

    scgp->scsibus = sdd->bus;
    scgp->target  = sdd->target;
    scgp->lun     = sdd->lun;
    scgp->cmdname = "???";
    scgp->curcmdname = "???";

    /* replace MODE_SELECT/SENSE_6 if we access a ATAPI drive,
       otherwise send it now */
    if (sdd->isatapi &&
	(scmd->cdb.g0_cdb.cmd == MODE_SELECT_6 ||
	 scmd->cdb.g0_cdb.cmd == MODE_SENSE_6)) {
	uae_u8 buffer[256 + 2], *data = scmd->addr, *tmp;
	int len = 0, page_len, i;
	int do_it = 1;
	uae_u8 sp = scmd->cdb.g0_cdb.high_addr & 1;
	uae_u8 alloc_len = scmd->cdb.g0_cdb.count;
	uae_u8 pcf_page_code = scmd->cdb.g0_cdb.mid_addr;
	uae_u8 cmd = scmd->cdb.g0_cdb.cmd;

	memset (&scmd->cdb.g1_cdb, 0, sizeof(scmd->cdb.g1_cdb));
	if (cmd == MODE_SELECT_6) {
	    /* expand parameter list */
	    tmp = data;
	    buffer[len++] = *tmp++;      /* first byte, should be 0 */
	    buffer[len++] = 0;           /* reserved */
	    buffer[len++] = *tmp++;      /* medium type */
	    buffer[len++] = 0; *tmp++;   /* ignore host application code */
	    for (i = 0; i < 4; i++) {
		buffer[len++] = 0;
	    }
	    if (*tmp) {
		/* skip block descriptor */
		tmp += 8;
	    }
	    tmp++;
	    page_len = scsi_len - (tmp - data);
	    if (page_len > 0) {
		memcpy (&buffer[len], tmp, page_len);
		len += page_len;

		scmd->cdb.g1_cdb.cmd = MODE_SELECT_10;
		scmd->cdb.g1_cdb.lun = sdd->lun;
		scmd->cdb.g1_cdb.res = 1 << 3; /* PF bit */
		scmd->cdb.g1_cdb.reladr = sp;
		scmd->cdb.g1_cdb.count[0] = len >> 8;
		scmd->cdb.g1_cdb.count[1] = len;
	    } else {
Beispiel #14
0
__inline__ uae_u32 wordget (uaecptr addr)
{
    return call_mem_get_func (get_mem_bank (addr).wget, addr);
}
Beispiel #15
0
static __inline__ uae_u32 byteget (uaecptr addr)
{
    return call_mem_get_func (get_mem_bank (addr).bget, addr);
}
Beispiel #16
0
static __inline__ void wordput (uaecptr addr, uae_u32 w)
{
    call_mem_put_func (get_mem_bank (addr).wput, addr, w);
}
Beispiel #17
0
static __inline__ void longput (uaecptr addr, uae_u32 l)
{
    call_mem_put_func (get_mem_bank (addr).lput, addr, l);
}