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 Mon Mar 13 12:38:39 2006 +0000 (13 years ago)
permissions -rw-r--r--
last change Refactor bios into more generic syscall structure. Add initial hooks for
dc-load functions
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 }
.