Search
lxdream.org :: lxdream/src/bios.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/bios.c
changeset 586:2a3ba82cf243
prev502:c4ecae2b1b5e
next736:a02d1475ccfd
author nkeynes
date Tue Jan 15 20:50:23 2008 +0000 (11 years ago)
permissions -rw-r--r--
last change Merged lxdream-mmu r570:596 to trunk
file annotate diff log raw
nkeynes@87
     1
/**
nkeynes@586
     2
 * $Id$
nkeynes@87
     3
 * 
nkeynes@87
     4
 * "Fake" BIOS functions, for operation without the actual BIOS.
nkeynes@87
     5
 *
nkeynes@87
     6
 * Copyright (c) 2005 Nathan Keynes.
nkeynes@87
     7
 *
nkeynes@87
     8
 * This program is free software; you can redistribute it and/or modify
nkeynes@87
     9
 * it under the terms of the GNU General Public License as published by
nkeynes@87
    10
 * the Free Software Foundation; either version 2 of the License, or
nkeynes@87
    11
 * (at your option) any later version.
nkeynes@87
    12
 *
nkeynes@87
    13
 * This program is distributed in the hope that it will be useful,
nkeynes@87
    14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nkeynes@87
    15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
nkeynes@87
    16
 * GNU General Public License for more details.
nkeynes@87
    17
 */
nkeynes@87
    18
nkeynes@87
    19
#include "dream.h"
nkeynes@87
    20
#include "mem.h"
nkeynes@102
    21
#include "syscall.h"
nkeynes@422
    22
#include "dreamcast.h"
nkeynes@586
    23
#include "sh4/sh4.h"
nkeynes@87
    24
nkeynes@87
    25
#define COMMAND_QUEUE_LENGTH 16
nkeynes@87
    26
nkeynes@87
    27
/* TODO: Check if these are the real ATAPI command codes or not */
nkeynes@87
    28
#define GD_CMD_PIOREAD     16
nkeynes@87
    29
#define GD_CMD_DMAREAD     17
nkeynes@87
    30
#define GD_CMD_GETTOC      18
nkeynes@87
    31
#define GD_CMD_GETTOC2     19
nkeynes@87
    32
#define GD_CMD_PLAY        20
nkeynes@87
    33
#define GD_CMD_PLAY2       21
nkeynes@87
    34
#define GD_CMD_PAUSE       22
nkeynes@87
    35
#define GD_CMD_RELEASE     23
nkeynes@87
    36
#define GD_CMD_INIT        24
nkeynes@87
    37
#define GD_CMD_SEEK        27
nkeynes@87
    38
#define GD_CMD_READ        28
nkeynes@87
    39
#define GD_CMD_STOP        33
nkeynes@87
    40
#define GD_CMD_GETSCD      34
nkeynes@87
    41
#define GD_CMD_GETSES      35
nkeynes@87
    42
nkeynes@87
    43
#define GD_CMD_STATUS_NONE 0
nkeynes@87
    44
#define GD_CMD_STATUS_ACTIVE 1
nkeynes@87
    45
#define GD_CMD_STATUS_DONE 2
nkeynes@87
    46
#define GD_CMD_STATUS_ABORT 3
nkeynes@87
    47
#define GD_CMD_STATUS_ERROR 4
nkeynes@87
    48
nkeynes@87
    49
#define GD_ERROR_OK          0
nkeynes@87
    50
#define GD_ERROR_NO_DISC     2
nkeynes@87
    51
#define GD_ERROR_DISC_CHANGE 6
nkeynes@87
    52
#define GD_ERROR_SYSTEM      1
nkeynes@87
    53
nkeynes@87
    54
nkeynes@87
    55
typedef struct gdrom_command {
nkeynes@87
    56
    int status;
nkeynes@87
    57
    uint32_t cmd_code;
nkeynes@502
    58
    sh4ptr_t data;
nkeynes@87
    59
    uint32_t result[4];
nkeynes@87
    60
} *gdrom_command_t;
nkeynes@87
    61
nkeynes@87
    62
static struct gdrom_command gdrom_cmd_queue[COMMAND_QUEUE_LENGTH];
nkeynes@87
    63
nkeynes@87
    64
static struct bios_gdrom_status {
nkeynes@87
    65
    uint32_t status;
nkeynes@87
    66
    uint32_t disk_type;
nkeynes@87
    67
} bios_gdrom_status;
nkeynes@87
    68
nkeynes@87
    69
void bios_gdrom_run_command( gdrom_command_t cmd )
nkeynes@87
    70
{
nkeynes@87
    71
    DEBUG( "BIOS GD command %d", cmd->cmd_code );
nkeynes@87
    72
    switch( cmd->cmd_code ) {
nkeynes@87
    73
    case GD_CMD_INIT:
nkeynes@87
    74
	/* *shrug* */
nkeynes@87
    75
	cmd->status = GD_CMD_STATUS_DONE;
nkeynes@87
    76
	break;
nkeynes@87
    77
    default:
nkeynes@87
    78
	cmd->status = GD_CMD_STATUS_ERROR;
nkeynes@87
    79
	cmd->result[0] = GD_ERROR_SYSTEM;
nkeynes@87
    80
	break;
nkeynes@87
    81
    }
nkeynes@87
    82
}
nkeynes@87
    83
nkeynes@87
    84
void bios_gdrom_init( void )
nkeynes@87
    85
{
nkeynes@87
    86
    memset( &gdrom_cmd_queue, 0, sizeof(gdrom_cmd_queue) );
nkeynes@87
    87
}
nkeynes@87
    88
nkeynes@502
    89
uint32_t bios_gdrom_enqueue( uint32_t cmd, sh4ptr_t ptr )
nkeynes@87
    90
{
nkeynes@87
    91
    int i;
nkeynes@87
    92
    for( i=0; i<COMMAND_QUEUE_LENGTH; i++ ) {
nkeynes@87
    93
	if( gdrom_cmd_queue[i].status != GD_CMD_STATUS_ACTIVE ) {
nkeynes@87
    94
	    gdrom_cmd_queue[i].status = GD_CMD_STATUS_ACTIVE;
nkeynes@87
    95
	    gdrom_cmd_queue[i].cmd_code = cmd;
nkeynes@87
    96
	    gdrom_cmd_queue[i].data = ptr;
nkeynes@87
    97
	    return i;
nkeynes@87
    98
	}
nkeynes@87
    99
    }
nkeynes@87
   100
    return -1;
nkeynes@87
   101
}
nkeynes@87
   102
nkeynes@87
   103
void bios_gdrom_run_queue( void ) 
nkeynes@87
   104
{
nkeynes@87
   105
    int i;
nkeynes@87
   106
    for( i=0; i<COMMAND_QUEUE_LENGTH; i++ ) {
nkeynes@87
   107
	if( gdrom_cmd_queue[i].status == GD_CMD_STATUS_ACTIVE ) {
nkeynes@87
   108
	    bios_gdrom_run_command( &gdrom_cmd_queue[i] );
nkeynes@87
   109
	}
nkeynes@87
   110
    }
nkeynes@87
   111
}
nkeynes@87
   112
nkeynes@87
   113
gdrom_command_t bios_gdrom_get_command( uint32_t id )
nkeynes@87
   114
{
nkeynes@87
   115
    if( id >= COMMAND_QUEUE_LENGTH ||
nkeynes@87
   116
	gdrom_cmd_queue[id].status == GD_CMD_STATUS_NONE )
nkeynes@87
   117
	return NULL;
nkeynes@87
   118
    return &gdrom_cmd_queue[id];
nkeynes@87
   119
}
nkeynes@87
   120
nkeynes@87
   121
/**
nkeynes@87
   122
 * Syscall list courtesy of Marcus Comstedt
nkeynes@87
   123
 */
nkeynes@87
   124
nkeynes@87
   125
void bios_syscall( uint32_t syscallid )
nkeynes@87
   126
{
nkeynes@87
   127
    gdrom_command_t cmd;
nkeynes@87
   128
nkeynes@87
   129
    switch( syscallid ) {
nkeynes@87
   130
    case 0xB0: /* sysinfo */
nkeynes@87
   131
	break;
nkeynes@87
   132
    case 0xB4: /* Font */
nkeynes@87
   133
	break;
nkeynes@87
   134
    case 0xB8: /* Flash */
nkeynes@87
   135
	break;
nkeynes@87
   136
    case 0xBC: /* Misc/GD-Rom */
nkeynes@87
   137
	switch( sh4r.r[6] ) {
nkeynes@87
   138
	case 0: /* GD-Rom */
nkeynes@87
   139
	    switch( sh4r.r[7] ) {
nkeynes@87
   140
	    case 0: /* Send command */
nkeynes@87
   141
		if( sh4r.r[5] == 0 )
nkeynes@87
   142
		    sh4r.r[0] = bios_gdrom_enqueue( sh4r.r[4], NULL );
nkeynes@87
   143
		else
nkeynes@87
   144
		    sh4r.r[0] = bios_gdrom_enqueue( sh4r.r[4], mem_get_region(sh4r.r[5]) );
nkeynes@87
   145
		break;
nkeynes@87
   146
	    case 1:  /* Check command */
nkeynes@87
   147
		cmd = bios_gdrom_get_command( sh4r.r[4] );
nkeynes@87
   148
		if( cmd == NULL ) {
nkeynes@87
   149
		    sh4r.r[0] = GD_CMD_STATUS_NONE;
nkeynes@87
   150
		} else {
nkeynes@87
   151
		    sh4r.r[0] = cmd->status;
nkeynes@87
   152
		    if( cmd->status == GD_CMD_STATUS_ERROR &&
nkeynes@87
   153
			sh4r.r[5] != 0 ) {
nkeynes@502
   154
			mem_copy_to_sh4( sh4r.r[5], (sh4ptr_t)&cmd->result, sizeof(cmd->result) );
nkeynes@87
   155
		    }
nkeynes@87
   156
		}
nkeynes@87
   157
		break;
nkeynes@87
   158
	    case 2: /* Mainloop */
nkeynes@87
   159
		bios_gdrom_run_queue();
nkeynes@87
   160
		break;
nkeynes@87
   161
	    case 3: /* Init */
nkeynes@87
   162
		bios_gdrom_init();
nkeynes@87
   163
		break;
nkeynes@87
   164
	    case 4: /* Drive status */
nkeynes@87
   165
		if( sh4r.r[4] != 0 ) {
nkeynes@502
   166
		    mem_copy_to_sh4( sh4r.r[4], (sh4ptr_t)&bios_gdrom_status, 
nkeynes@87
   167
				      sizeof(bios_gdrom_status) );
nkeynes@87
   168
		}
nkeynes@87
   169
		sh4r.r[0] = 0;
nkeynes@87
   170
		break;
nkeynes@87
   171
	    case 8: /* Abort command */
nkeynes@87
   172
		cmd = bios_gdrom_get_command( sh4r.r[4] );
nkeynes@87
   173
		if( cmd == NULL || cmd->status != GD_CMD_STATUS_ACTIVE ) {
nkeynes@87
   174
		    sh4r.r[0] = -1;
nkeynes@87
   175
		} else {
nkeynes@87
   176
		    cmd->status = GD_CMD_STATUS_ABORT;
nkeynes@87
   177
		    sh4r.r[0] = 0;
nkeynes@87
   178
		}
nkeynes@87
   179
		break;
nkeynes@87
   180
	    case 9: /* Reset */
nkeynes@87
   181
		break;
nkeynes@87
   182
	    case 10: /* Set mode */
nkeynes@87
   183
		sh4r.r[0] = 0;
nkeynes@87
   184
		break;
nkeynes@87
   185
	    }
nkeynes@87
   186
	    break;
nkeynes@87
   187
	case -1: /* Misc */
nkeynes@87
   188
	    break;
nkeynes@87
   189
	default: /* ??? */
nkeynes@87
   190
	    break;
nkeynes@87
   191
	}
nkeynes@87
   192
	break;
nkeynes@87
   193
    case 0xE0: /* Menu */
nkeynes@87
   194
	switch( sh4r.r[7] ) {
nkeynes@87
   195
	case 0:
nkeynes@87
   196
	    WARN( "Entering main program" );
nkeynes@87
   197
	    break;
nkeynes@87
   198
	case 1:
nkeynes@87
   199
	    WARN( "Program aborted to DC menu");
nkeynes@87
   200
	    dreamcast_stop();
nkeynes@87
   201
	    break;
nkeynes@87
   202
	}
nkeynes@87
   203
    }
nkeynes@87
   204
}
nkeynes@102
   205
nkeynes@102
   206
void bios_install( void ) 
nkeynes@102
   207
{
nkeynes@102
   208
    bios_gdrom_init();
nkeynes@102
   209
    syscall_add_hook_vector( 0xB0, 0x8C0000B0, bios_syscall );
nkeynes@102
   210
    syscall_add_hook_vector( 0xB4, 0x8C0000B4, bios_syscall );
nkeynes@102
   211
    syscall_add_hook_vector( 0xB8, 0x8C0000B8, bios_syscall );
nkeynes@102
   212
    syscall_add_hook_vector( 0xBC, 0x8C0000BC, bios_syscall );
nkeynes@102
   213
    syscall_add_hook_vector( 0xE0, 0x8C0000E0, bios_syscall );
nkeynes@102
   214
}
.