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