Search
lxdream.org :: lxdream/src/bios.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/bios.c
changeset 87:11208d725b61
next102:844a3f2a76ff
author nkeynes
date Mon Mar 13 12:37:06 2006 +0000 (18 years ago)
permissions -rw-r--r--
last change Add sh4addr_t type, need to start propagating it instead of uint32_t
file annotate diff log raw
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/bios.c Mon Mar 13 12:37:06 2006 +0000
1.3 @@ -0,0 +1,213 @@
1.4 +/**
1.5 + * $Id: bios.c,v 1.1 2006-01-22 22:40:53 nkeynes Exp $
1.6 + *
1.7 + * "Fake" BIOS functions, for operation without the actual BIOS.
1.8 + *
1.9 + * Copyright (c) 2005 Nathan Keynes.
1.10 + *
1.11 + * This program is free software; you can redistribute it and/or modify
1.12 + * it under the terms of the GNU General Public License as published by
1.13 + * the Free Software Foundation; either version 2 of the License, or
1.14 + * (at your option) any later version.
1.15 + *
1.16 + * This program is distributed in the hope that it will be useful,
1.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.19 + * GNU General Public License for more details.
1.20 + */
1.21 +
1.22 +#include "dream.h"
1.23 +#include "mem.h"
1.24 +#include "bios.h"
1.25 +#include "sh4/sh4core.h"
1.26 +
1.27 +#define COMMAND_QUEUE_LENGTH 16
1.28 +
1.29 +/* TODO: Check if these are the real ATAPI command codes or not */
1.30 +#define GD_CMD_PIOREAD 16
1.31 +#define GD_CMD_DMAREAD 17
1.32 +#define GD_CMD_GETTOC 18
1.33 +#define GD_CMD_GETTOC2 19
1.34 +#define GD_CMD_PLAY 20
1.35 +#define GD_CMD_PLAY2 21
1.36 +#define GD_CMD_PAUSE 22
1.37 +#define GD_CMD_RELEASE 23
1.38 +#define GD_CMD_INIT 24
1.39 +#define GD_CMD_SEEK 27
1.40 +#define GD_CMD_READ 28
1.41 +#define GD_CMD_STOP 33
1.42 +#define GD_CMD_GETSCD 34
1.43 +#define GD_CMD_GETSES 35
1.44 +
1.45 +#define GD_CMD_STATUS_NONE 0
1.46 +#define GD_CMD_STATUS_ACTIVE 1
1.47 +#define GD_CMD_STATUS_DONE 2
1.48 +#define GD_CMD_STATUS_ABORT 3
1.49 +#define GD_CMD_STATUS_ERROR 4
1.50 +
1.51 +#define GD_ERROR_OK 0
1.52 +#define GD_ERROR_NO_DISC 2
1.53 +#define GD_ERROR_DISC_CHANGE 6
1.54 +#define GD_ERROR_SYSTEM 1
1.55 +
1.56 +
1.57 +typedef struct gdrom_command {
1.58 + int status;
1.59 + uint32_t cmd_code;
1.60 + char *data;
1.61 + uint32_t result[4];
1.62 +} *gdrom_command_t;
1.63 +
1.64 +static struct gdrom_command gdrom_cmd_queue[COMMAND_QUEUE_LENGTH];
1.65 +
1.66 +static struct bios_gdrom_status {
1.67 + uint32_t status;
1.68 + uint32_t disk_type;
1.69 +} bios_gdrom_status;
1.70 +
1.71 +void bios_gdrom_run_command( gdrom_command_t cmd )
1.72 +{
1.73 + DEBUG( "BIOS GD command %d", cmd->cmd_code );
1.74 + switch( cmd->cmd_code ) {
1.75 + case GD_CMD_INIT:
1.76 + /* *shrug* */
1.77 + cmd->status = GD_CMD_STATUS_DONE;
1.78 + break;
1.79 + default:
1.80 + cmd->status = GD_CMD_STATUS_ERROR;
1.81 + cmd->result[0] = GD_ERROR_SYSTEM;
1.82 + break;
1.83 + }
1.84 +}
1.85 +
1.86 +void bios_gdrom_init( void )
1.87 +{
1.88 + memset( &gdrom_cmd_queue, 0, sizeof(gdrom_cmd_queue) );
1.89 +}
1.90 +
1.91 +uint32_t bios_gdrom_enqueue( uint32_t cmd, char *ptr )
1.92 +{
1.93 + int i;
1.94 + for( i=0; i<COMMAND_QUEUE_LENGTH; i++ ) {
1.95 + if( gdrom_cmd_queue[i].status != GD_CMD_STATUS_ACTIVE ) {
1.96 + gdrom_cmd_queue[i].status = GD_CMD_STATUS_ACTIVE;
1.97 + gdrom_cmd_queue[i].cmd_code = cmd;
1.98 + gdrom_cmd_queue[i].data = ptr;
1.99 + return i;
1.100 + }
1.101 + }
1.102 + return -1;
1.103 +}
1.104 +
1.105 +void bios_gdrom_run_queue( void )
1.106 +{
1.107 + int i;
1.108 + for( i=0; i<COMMAND_QUEUE_LENGTH; i++ ) {
1.109 + if( gdrom_cmd_queue[i].status == GD_CMD_STATUS_ACTIVE ) {
1.110 + bios_gdrom_run_command( &gdrom_cmd_queue[i] );
1.111 + }
1.112 + }
1.113 +}
1.114 +
1.115 +gdrom_command_t bios_gdrom_get_command( uint32_t id )
1.116 +{
1.117 + if( id >= COMMAND_QUEUE_LENGTH ||
1.118 + gdrom_cmd_queue[id].status == GD_CMD_STATUS_NONE )
1.119 + return NULL;
1.120 + return &gdrom_cmd_queue[id];
1.121 +}
1.122 +
1.123 +void bios_install( void )
1.124 +{
1.125 + bios_gdrom_init();
1.126 + sh4_write_long( 0x8C0000B0, 0xFFFFFFB0 );
1.127 + sh4_write_long( 0x8C0000B4, 0xFFFFFFB4 );
1.128 + sh4_write_long( 0x8C0000B8, 0xFFFFFFB8 );
1.129 + sh4_write_long( 0x8C0000BC, 0xFFFFFFBC );
1.130 + sh4_write_long( 0x8C0000E0, 0xFFFFFFE0 );
1.131 +}
1.132 +
1.133 +/**
1.134 + * Syscall list courtesy of Marcus Comstedt
1.135 + */
1.136 +
1.137 +void bios_syscall( uint32_t syscallid )
1.138 +{
1.139 + gdrom_command_t cmd;
1.140 +
1.141 + switch( syscallid ) {
1.142 + case 0xB0: /* sysinfo */
1.143 + break;
1.144 + case 0xB4: /* Font */
1.145 + break;
1.146 + case 0xB8: /* Flash */
1.147 + break;
1.148 + case 0xBC: /* Misc/GD-Rom */
1.149 + switch( sh4r.r[6] ) {
1.150 + case 0: /* GD-Rom */
1.151 + switch( sh4r.r[7] ) {
1.152 + case 0: /* Send command */
1.153 + if( sh4r.r[5] == 0 )
1.154 + sh4r.r[0] = bios_gdrom_enqueue( sh4r.r[4], NULL );
1.155 + else
1.156 + sh4r.r[0] = bios_gdrom_enqueue( sh4r.r[4], mem_get_region(sh4r.r[5]) );
1.157 + break;
1.158 + case 1: /* Check command */
1.159 + cmd = bios_gdrom_get_command( sh4r.r[4] );
1.160 + if( cmd == NULL ) {
1.161 + sh4r.r[0] = GD_CMD_STATUS_NONE;
1.162 + } else {
1.163 + sh4r.r[0] = cmd->status;
1.164 + if( cmd->status == GD_CMD_STATUS_ERROR &&
1.165 + sh4r.r[5] != 0 ) {
1.166 + mem_copy_to_sh4( sh4r.r[5], &cmd->result, sizeof(cmd->result) );
1.167 + }
1.168 + }
1.169 + break;
1.170 + case 2: /* Mainloop */
1.171 + bios_gdrom_run_queue();
1.172 + break;
1.173 + case 3: /* Init */
1.174 + bios_gdrom_init();
1.175 + break;
1.176 + case 4: /* Drive status */
1.177 + if( sh4r.r[4] != 0 ) {
1.178 + mem_copy_to_sh4( sh4r.r[4], &bios_gdrom_status,
1.179 + sizeof(bios_gdrom_status) );
1.180 + }
1.181 + sh4r.r[0] = 0;
1.182 + break;
1.183 + case 8: /* Abort command */
1.184 + cmd = bios_gdrom_get_command( sh4r.r[4] );
1.185 + if( cmd == NULL || cmd->status != GD_CMD_STATUS_ACTIVE ) {
1.186 + sh4r.r[0] = -1;
1.187 + } else {
1.188 + cmd->status = GD_CMD_STATUS_ABORT;
1.189 + sh4r.r[0] = 0;
1.190 + }
1.191 + break;
1.192 + case 9: /* Reset */
1.193 + break;
1.194 + case 10: /* Set mode */
1.195 + sh4r.r[0] = 0;
1.196 + break;
1.197 + }
1.198 + break;
1.199 + case -1: /* Misc */
1.200 + break;
1.201 + default: /* ??? */
1.202 + break;
1.203 + }
1.204 + break;
1.205 + case 0xE0: /* Menu */
1.206 + switch( sh4r.r[7] ) {
1.207 + case 0:
1.208 + WARN( "Entering main program" );
1.209 + break;
1.210 + case 1:
1.211 + WARN( "Program aborted to DC menu");
1.212 + dreamcast_stop();
1.213 + break;
1.214 + }
1.215 + }
1.216 +}
.