mirror of
https://github.com/kanjitalk755/macemu.git
synced 2024-12-23 19:29:18 +00:00
- implemented direct SCSI transfers (bypassing the buffer)
- minor fixes
This commit is contained in:
parent
3d2bac9f15
commit
4f8d06b671
@ -18,6 +18,8 @@
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
|
||||
DEBUG_DETAIL SET 1
|
||||
|
||||
INCLUDE "exec/types.i"
|
||||
INCLUDE "exec/macros.i"
|
||||
INCLUDE "exec/memory.i"
|
||||
@ -25,7 +27,7 @@
|
||||
INCLUDE "dos/dos.i"
|
||||
INCLUDE "devices/timer.i"
|
||||
|
||||
INCLUDE "asmsupp.i"
|
||||
; INCLUDE "asmsupp.i"
|
||||
|
||||
XDEF _AtomicAnd
|
||||
XDEF _AtomicOr
|
||||
@ -199,7 +201,7 @@ _Execute68kTrap
|
||||
rts
|
||||
|
||||
*
|
||||
* Exception handler of main task (for 60Hz interrupts)
|
||||
* Exception handler of main task (for interrupts)
|
||||
*
|
||||
|
||||
_ExceptionHandlerAsm
|
||||
@ -392,7 +394,7 @@ doaline move.l a0,(sp) ;Save a0
|
||||
addq.l #8,sp ;Remove exception frame from supervisor stack
|
||||
andi #$d8ff,sr ;Switch to user mode, enable interrupts
|
||||
|
||||
and.w #$f8ff,_EmulatedSR ;enable interrupts in EmulatedSR
|
||||
; and.w #$f8ff,_EmulatedSR ;enable interrupts in EmulatedSR
|
||||
|
||||
move.l $28.w,-(sp) ;Jump to MacOS exception handler
|
||||
rts
|
||||
|
@ -192,11 +192,10 @@ int main(int argc, char **argv)
|
||||
QuitEmulator();
|
||||
}
|
||||
|
||||
if (FindTask((UBYTE *) "« Enforcer »"))
|
||||
{
|
||||
if (FindTask((UBYTE *) "« Enforcer »")) {
|
||||
ErrorAlert(STR_ENFORCER_RUNNING_ERR);
|
||||
QuitEmulator();
|
||||
}
|
||||
}
|
||||
|
||||
// These two can fail (the respective gfx support won't be available, then)
|
||||
P96Base = OpenLibrary((UBYTE *) "Picasso96API.library", 2);
|
||||
|
@ -53,6 +53,8 @@ static UBYTE cmd_buffer[12]; // Buffer for SCSI command
|
||||
const int SENSE_LENGTH = 256;
|
||||
static UBYTE *sense_buffer = NULL; // Buffer for autosense data
|
||||
|
||||
static bool direct_transfers_supported = false; // Direct data transfers (bypassing the buffer) are supported
|
||||
|
||||
|
||||
/*
|
||||
* Initialization
|
||||
@ -69,6 +71,7 @@ void SCSIInit(void)
|
||||
break;
|
||||
case 2:
|
||||
buffer_memf = MEMF_ANY | MEMF_PUBLIC;
|
||||
direct_transfers_supported = true;
|
||||
break;
|
||||
default:
|
||||
buffer_memf = MEMF_CHIP | MEMF_PUBLIC;
|
||||
@ -212,23 +215,29 @@ bool scsi_set_target(int id, int lun)
|
||||
|
||||
bool scsi_send_cmd(size_t data_length, bool reading, int sg_size, uint8 **sg_ptr, uint32 *sg_len, uint16 *stat, uint32 timeout)
|
||||
{
|
||||
// Check if buffer is large enough, allocate new buffer if needed
|
||||
if (!try_buffer(data_length)) {
|
||||
char str[256];
|
||||
sprintf(str, GetString(STR_SCSI_BUFFER_ERR), data_length);
|
||||
ErrorAlert(str);
|
||||
return false;
|
||||
}
|
||||
// Bypass the buffer if there's only one S/G table entry
|
||||
bool do_direct_transfer = (sg_size == 1 && ((uint32)sg_ptr[0] & 1) == 0 && direct_transfers_supported);
|
||||
|
||||
// Process S/G table when writing
|
||||
if (!reading) {
|
||||
D(bug(" writing to buffer\n"));
|
||||
uint8 *buffer_ptr = buffer;
|
||||
for (int i=0; i<sg_size; i++) {
|
||||
uint32 len = sg_len[i];
|
||||
D(bug(" %d bytes from %08lx\n", len, sg_ptr[i]));
|
||||
memcpy(buffer_ptr, sg_ptr[i], len);
|
||||
buffer_ptr += len;
|
||||
if (!do_direct_transfer) {
|
||||
|
||||
// Check if buffer is large enough, allocate new buffer if needed
|
||||
if (!try_buffer(data_length)) {
|
||||
char str[256];
|
||||
sprintf(str, GetString(STR_SCSI_BUFFER_ERR), data_length);
|
||||
ErrorAlert(str);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Process S/G table when writing
|
||||
if (!reading) {
|
||||
D(bug(" writing to buffer\n"));
|
||||
uint8 *buffer_ptr = buffer;
|
||||
for (int i=0; i<sg_size; i++) {
|
||||
uint32 len = sg_len[i];
|
||||
D(bug(" %d bytes from %08lx\n", len, sg_ptr[i]));
|
||||
memcpy(buffer_ptr, sg_ptr[i], len);
|
||||
buffer_ptr += len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -240,13 +249,19 @@ bool scsi_send_cmd(size_t data_length, bool reading, int sg_size, uint8 **sg_ptr
|
||||
D(bug(" autosense\n"));
|
||||
memcpy(buffer, sense_buffer, scsi.scsi_SenseActual);
|
||||
scsi.scsi_Status = 0;
|
||||
do_direct_transfer = false;
|
||||
|
||||
} else {
|
||||
|
||||
// No, send regular command
|
||||
D(bug(" sending command, length %ld\n", data_length));
|
||||
scsi.scsi_Data = (UWORD *)buffer;
|
||||
scsi.scsi_Length = data_length;
|
||||
if (do_direct_transfer) {
|
||||
scsi.scsi_Data = (UWORD *)sg_ptr[0];
|
||||
scsi.scsi_Length = sg_len[0];
|
||||
} else {
|
||||
scsi.scsi_Data = (UWORD *)buffer;
|
||||
scsi.scsi_Length = data_length;
|
||||
}
|
||||
scsi.scsi_Actual = 0;
|
||||
scsi.scsi_Flags = (reading ? SCSIF_READ : SCSIF_WRITE) | SCSIF_AUTOSENSE;
|
||||
scsi.scsi_SenseActual = 0;
|
||||
@ -256,15 +271,18 @@ bool scsi_send_cmd(size_t data_length, bool reading, int sg_size, uint8 **sg_ptr
|
||||
*stat = scsi.scsi_Status;
|
||||
}
|
||||
|
||||
// Process S/G table when reading
|
||||
if (reading && res == 0) {
|
||||
D(bug(" reading from buffer\n"));
|
||||
uint8 *buffer_ptr = buffer;
|
||||
for (int i=0; i<sg_size; i++) {
|
||||
uint32 len = sg_len[i];
|
||||
D(bug(" %d bytes to %08lx\n", len, sg_ptr[i]));
|
||||
memcpy(sg_ptr[i], buffer_ptr, len);
|
||||
buffer_ptr += len;
|
||||
if (!do_direct_transfer) {
|
||||
|
||||
// Process S/G table when reading
|
||||
if (reading && res == 0) {
|
||||
D(bug(" reading from buffer\n"));
|
||||
uint8 *buffer_ptr = buffer;
|
||||
for (int i=0; i<sg_size; i++) {
|
||||
uint32 len = sg_len[i];
|
||||
D(bug(" %d bytes to %08lx\n", len, sg_ptr[i]));
|
||||
memcpy(sg_ptr[i], buffer_ptr, len);
|
||||
buffer_ptr += len;
|
||||
}
|
||||
}
|
||||
}
|
||||
return res == 0;
|
||||
|
@ -251,9 +251,9 @@ bool VideoInit(bool classic)
|
||||
break;
|
||||
|
||||
case DISPLAY_PIP:
|
||||
default_depth = VDEPTH_16BIT;
|
||||
default_width = window_width;
|
||||
default_height = window_height;
|
||||
default_depth = VDEPTH_16BIT;
|
||||
add_modes(window_width, window_height, VDEPTH_16BIT);
|
||||
break;
|
||||
|
||||
@ -271,23 +271,22 @@ bool VideoInit(bool classic)
|
||||
default_width = 1 + dimInfo.Nominal.MaxX - dimInfo.Nominal.MinX;
|
||||
default_height = 1 + dimInfo.Nominal.MaxY - dimInfo.Nominal.MinY;
|
||||
|
||||
switch (dimInfo.MaxDepth)
|
||||
{
|
||||
case 1:
|
||||
default_depth = VDEPTH_1BIT;
|
||||
break;
|
||||
case 8:
|
||||
default_depth = VDEPTH_8BIT;
|
||||
break;
|
||||
case 15:
|
||||
case 16:
|
||||
default_depth = VDEPTH_16BIT;
|
||||
break;
|
||||
case 24:
|
||||
case 32:
|
||||
default_depth = VDEPTH_32BIT;
|
||||
break;
|
||||
}
|
||||
switch (dimInfo.MaxDepth) {
|
||||
case 1:
|
||||
default_depth = VDEPTH_1BIT;
|
||||
break;
|
||||
case 8:
|
||||
default_depth = VDEPTH_8BIT;
|
||||
break;
|
||||
case 15:
|
||||
case 16:
|
||||
default_depth = VDEPTH_16BIT;
|
||||
break;
|
||||
case 24:
|
||||
case 32:
|
||||
default_depth = VDEPTH_32BIT;
|
||||
break;
|
||||
}
|
||||
|
||||
for (unsigned d=VDEPTH_8BIT; d<=VDEPTH_32BIT; d++) {
|
||||
ULONG mode_id = find_mode_for_depth(default_width, default_height, bits_from_depth(video_depth(d)));
|
||||
@ -298,8 +297,6 @@ bool VideoInit(bool classic)
|
||||
break;
|
||||
}
|
||||
|
||||
// video_init_depth_list();
|
||||
|
||||
#if DEBUG
|
||||
bug("Available video modes:\n");
|
||||
vector<video_mode>::const_iterator i = VideoModes.begin(), end = VideoModes.end();
|
||||
@ -313,8 +310,7 @@ bool VideoInit(bool classic)
|
||||
__LINE__, default_width, default_height, default_depth));
|
||||
|
||||
// Find requested default mode and open display
|
||||
if (VideoModes.size() == 1)
|
||||
{
|
||||
if (VideoModes.size() == 1) {
|
||||
uint32 default_id ;
|
||||
|
||||
// Create Amiga_monitor_desc for this (the only) display
|
||||
@ -325,14 +321,14 @@ bool VideoInit(bool classic)
|
||||
|
||||
// Open display
|
||||
return monitor->video_open();
|
||||
}
|
||||
else {
|
||||
|
||||
} else {
|
||||
|
||||
// Find mode with specified dimensions
|
||||
std::vector<video_mode>::const_iterator i, end = VideoModes.end();
|
||||
for (i = VideoModes.begin(); i != end; ++i) {
|
||||
D(bug("VideoInit/%ld: w=%ld h=%ld d=%ld\n", __LINE__, i->x, i->y, bits_from_depth(i->depth)));
|
||||
if (i->x == default_width && i->y == default_height && i->depth == default_depth)
|
||||
{
|
||||
if (i->x == default_width && i->y == default_height && i->depth == default_depth) {
|
||||
// Create Amiga_monitor_desc for this (the only) display
|
||||
uint32 default_id = i->resolution_id;
|
||||
D(bug("VideoInit/%ld: default_id=%ld\n", __LINE__, default_id));
|
||||
@ -341,7 +337,7 @@ bool VideoInit(bool classic)
|
||||
|
||||
// Open display
|
||||
return monitor->video_open();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create Amiga_monitor_desc for this (the only) display
|
||||
@ -371,8 +367,6 @@ bool Amiga_monitor_desc::video_open()
|
||||
return false;
|
||||
}
|
||||
|
||||
// VideoMonitor.mode = mode;
|
||||
|
||||
D(bug("video_open/%ld: display_type=%ld\n", __LINE__, display_type));
|
||||
|
||||
// Open display
|
||||
@ -435,6 +429,7 @@ void Amiga_monitor_desc::video_close()
|
||||
}
|
||||
|
||||
delete drv;
|
||||
drv = NULL;
|
||||
|
||||
// Free mouse pointer
|
||||
if (null_pointer) {
|
||||
@ -556,14 +551,13 @@ static __saveds void periodic_func(void)
|
||||
// D(bug("periodic_func/%ld: display_type=%ld the_win=%08lx\n", __LINE__, drv->monitor.display_type, drv->the_win));
|
||||
|
||||
if (sig & timer_mask) {
|
||||
if (drv->get_bitmap())
|
||||
{
|
||||
if (drv->get_bitmap()) {
|
||||
// Timer tick, update display
|
||||
BltTemplate(drv->get_bitmap()->Planes[0], 0,
|
||||
drv->get_bitmap()->BytesPerRow, drv->the_win->RPort,
|
||||
drv->the_win->BorderLeft, drv->the_win->BorderTop,
|
||||
mode.x, mode.y);
|
||||
}
|
||||
}
|
||||
|
||||
// Restart timer
|
||||
timer_io->tr_node.io_Command = TR_ADDREQUEST;
|
||||
@ -588,33 +582,32 @@ static __saveds void periodic_func(void)
|
||||
// Handle message according to class
|
||||
switch (cl) {
|
||||
case IDCMP_MOUSEMOVE:
|
||||
switch (drv->monitor.display_type)
|
||||
{
|
||||
case DISPLAY_SCREEN_P96:
|
||||
case DISPLAY_SCREEN_CGFX:
|
||||
// D(bug("periodic_func/%ld: IDCMP_MOUSEMOVE mx=%ld my=%ld\n", __LINE__, mx, my));
|
||||
ADBMouseMoved(mx, my);
|
||||
break;
|
||||
default:
|
||||
// D(bug("periodic_func/%ld: IDCMP_MOUSEMOVE mx=%ld my=%ld\n", __LINE__, mx - drv->the_win->BorderLeft, my - drv->the_win->BorderTop));
|
||||
ADBMouseMoved(mx - drv->the_win->BorderLeft, my - drv->the_win->BorderTop);
|
||||
if (mx < drv->the_win->BorderLeft
|
||||
|| my < drv->the_win->BorderTop
|
||||
|| mx >= drv->the_win->BorderLeft + mode.x
|
||||
|| my >= drv->the_win->BorderTop + mode.y) {
|
||||
if (current_pointer) {
|
||||
ClearPointer(drv->the_win);
|
||||
current_pointer = NULL;
|
||||
switch (drv->monitor.display_type) {
|
||||
case DISPLAY_SCREEN_P96:
|
||||
case DISPLAY_SCREEN_CGFX:
|
||||
// D(bug("periodic_func/%ld: IDCMP_MOUSEMOVE mx=%ld my=%ld\n", __LINE__, mx, my));
|
||||
ADBMouseMoved(mx, my);
|
||||
break;
|
||||
default:
|
||||
// D(bug("periodic_func/%ld: IDCMP_MOUSEMOVE mx=%ld my=%ld\n", __LINE__, mx - drv->the_win->BorderLeft, my - drv->the_win->BorderTop));
|
||||
ADBMouseMoved(mx - drv->the_win->BorderLeft, my - drv->the_win->BorderTop);
|
||||
if (mx < drv->the_win->BorderLeft
|
||||
|| my < drv->the_win->BorderTop
|
||||
|| mx >= drv->the_win->BorderLeft + mode.x
|
||||
|| my >= drv->the_win->BorderTop + mode.y) {
|
||||
if (current_pointer) {
|
||||
ClearPointer(drv->the_win);
|
||||
current_pointer = NULL;
|
||||
}
|
||||
} else {
|
||||
if (current_pointer != null_pointer) {
|
||||
// Hide mouse pointer inside window
|
||||
SetPointer(drv->the_win, null_pointer, 1, 16, 0, 0);
|
||||
current_pointer = null_pointer;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (current_pointer != null_pointer) {
|
||||
// Hide mouse pointer inside window
|
||||
SetPointer(drv->the_win, null_pointer, 1, 16, 0, 0);
|
||||
current_pointer = null_pointer;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case IDCMP_MOUSEBUTTONS:
|
||||
@ -844,7 +837,7 @@ driver_base::~driver_base()
|
||||
driver_window::driver_window(Amiga_monitor_desc &m, int width, int height)
|
||||
: black_pen(-1), white_pen(-1), driver_base(m)
|
||||
{
|
||||
// Set relative mouse mode
|
||||
// Set absolute mouse mode
|
||||
ADBSetRelMouseMode(false);
|
||||
|
||||
// Open window
|
||||
@ -913,9 +906,11 @@ driver_window::~driver_window()
|
||||
driver_pip::driver_pip(Amiga_monitor_desc &m, int width, int height)
|
||||
: driver_base(m)
|
||||
{
|
||||
// Set relative mouse mode
|
||||
// Set absolute mouse mode
|
||||
ADBSetRelMouseMode(false);
|
||||
|
||||
D(bug("driver_pip(%d,%d)\n", width, height));
|
||||
|
||||
// Open window
|
||||
ULONG error = 0;
|
||||
the_win = p96PIP_OpenTags(
|
||||
@ -923,6 +918,7 @@ driver_pip::driver_pip(Amiga_monitor_desc &m, int width, int height)
|
||||
P96PIP_SourceWidth, width,
|
||||
P96PIP_SourceHeight, height,
|
||||
P96PIP_ErrorCode, (ULONG)&error,
|
||||
P96PIP_AllowCropping, true,
|
||||
WA_Left, 0, WA_Top, 0,
|
||||
WA_InnerWidth, width, WA_InnerHeight, height,
|
||||
WA_SimpleRefresh, true,
|
||||
@ -964,7 +960,7 @@ driver_pip::~driver_pip()
|
||||
driver_screen_p96::driver_screen_p96(Amiga_monitor_desc &m, ULONG mode_id)
|
||||
: driver_base(m)
|
||||
{
|
||||
// Set absolute mouse mode
|
||||
// Set relative mouse mode
|
||||
ADBSetRelMouseMode(true);
|
||||
|
||||
// Check if the mode is one we can handle
|
||||
@ -1167,4 +1163,3 @@ void driver_screen_cgfx::set_palette(uint8 *pal, int num)
|
||||
// And load it
|
||||
LoadRGB32(&the_screen->ViewPort, table);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user