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 Sat Jun 14 11:54:15 2008 +0000 (15 years ago)
permissions -rw-r--r--
last change Change colour params to float
Convert background processing over to scene structure (fixes some depth issues as well)
Add color unclamp when supported
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
}
.