Search
lxdream.org :: lxdream/src/bios.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/bios.c
changeset 736:a02d1475ccfd
prev586:2a3ba82cf243
next1065:bc1cc0c54917
author nkeynes
date Wed Jul 30 03:00:40 2008 +0000 (11 years ago)
permissions -rw-r--r--
last change Add debian changelog file
view annotate diff log raw
     1 /**
     2  * $Id$
     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 "dreamcast.h"
    23 #include "sh4/sh4.h"
    25 #define COMMAND_QUEUE_LENGTH 16
    27 /* TODO: Check if these are the real ATAPI command codes or not */
    28 #define GD_CMD_PIOREAD     16
    29 #define GD_CMD_DMAREAD     17
    30 #define GD_CMD_GETTOC      18
    31 #define GD_CMD_GETTOC2     19
    32 #define GD_CMD_PLAY        20
    33 #define GD_CMD_PLAY2       21
    34 #define GD_CMD_PAUSE       22
    35 #define GD_CMD_RELEASE     23
    36 #define GD_CMD_INIT        24
    37 #define GD_CMD_SEEK        27
    38 #define GD_CMD_READ        28
    39 #define GD_CMD_STOP        33
    40 #define GD_CMD_GETSCD      34
    41 #define GD_CMD_GETSES      35
    43 #define GD_CMD_STATUS_NONE 0
    44 #define GD_CMD_STATUS_ACTIVE 1
    45 #define GD_CMD_STATUS_DONE 2
    46 #define GD_CMD_STATUS_ABORT 3
    47 #define GD_CMD_STATUS_ERROR 4
    49 #define GD_ERROR_OK          0
    50 #define GD_ERROR_NO_DISC     2
    51 #define GD_ERROR_DISC_CHANGE 6
    52 #define GD_ERROR_SYSTEM      1
    55 typedef struct gdrom_command {
    56     int status;
    57     uint32_t cmd_code;
    58     sh4ptr_t data;
    59     uint32_t result[4];
    60 } *gdrom_command_t;
    62 static struct gdrom_command gdrom_cmd_queue[COMMAND_QUEUE_LENGTH];
    64 static struct bios_gdrom_status {
    65     uint32_t status;
    66     uint32_t disk_type;
    67 } bios_gdrom_status;
    69 void bios_gdrom_run_command( gdrom_command_t cmd )
    70 {
    71     DEBUG( "BIOS GD command %d", cmd->cmd_code );
    72     switch( cmd->cmd_code ) {
    73     case GD_CMD_INIT:
    74         /* *shrug* */
    75         cmd->status = GD_CMD_STATUS_DONE;
    76         break;
    77     default:
    78         cmd->status = GD_CMD_STATUS_ERROR;
    79         cmd->result[0] = GD_ERROR_SYSTEM;
    80         break;
    81     }
    82 }
    84 void bios_gdrom_init( void )
    85 {
    86     memset( &gdrom_cmd_queue, 0, sizeof(gdrom_cmd_queue) );
    87 }
    89 uint32_t bios_gdrom_enqueue( uint32_t cmd, sh4ptr_t ptr )
    90 {
    91     int i;
    92     for( i=0; i<COMMAND_QUEUE_LENGTH; i++ ) {
    93         if( gdrom_cmd_queue[i].status != GD_CMD_STATUS_ACTIVE ) {
    94             gdrom_cmd_queue[i].status = GD_CMD_STATUS_ACTIVE;
    95             gdrom_cmd_queue[i].cmd_code = cmd;
    96             gdrom_cmd_queue[i].data = ptr;
    97             return i;
    98         }
    99     }
   100     return -1;
   101 }
   103 void bios_gdrom_run_queue( void ) 
   104 {
   105     int i;
   106     for( i=0; i<COMMAND_QUEUE_LENGTH; i++ ) {
   107         if( gdrom_cmd_queue[i].status == GD_CMD_STATUS_ACTIVE ) {
   108             bios_gdrom_run_command( &gdrom_cmd_queue[i] );
   109         }
   110     }
   111 }
   113 gdrom_command_t bios_gdrom_get_command( uint32_t id )
   114 {
   115     if( id >= COMMAND_QUEUE_LENGTH ||
   116             gdrom_cmd_queue[id].status == GD_CMD_STATUS_NONE )
   117         return NULL;
   118     return &gdrom_cmd_queue[id];
   119 }
   121 /**
   122  * Syscall list courtesy of Marcus Comstedt
   123  */
   125 void bios_syscall( uint32_t syscallid )
   126 {
   127     gdrom_command_t cmd;
   129     switch( syscallid ) {
   130     case 0xB0: /* sysinfo */
   131         break;
   132     case 0xB4: /* Font */
   133         break;
   134     case 0xB8: /* Flash */
   135         break;
   136     case 0xBC: /* Misc/GD-Rom */
   137         switch( sh4r.r[6] ) {
   138         case 0: /* GD-Rom */
   139             switch( sh4r.r[7] ) {
   140             case 0: /* Send command */
   141                 if( sh4r.r[5] == 0 )
   142                     sh4r.r[0] = bios_gdrom_enqueue( sh4r.r[4], NULL );
   143                 else
   144                     sh4r.r[0] = bios_gdrom_enqueue( sh4r.r[4], mem_get_region(sh4r.r[5]) );
   145                 break;
   146             case 1:  /* Check command */
   147                 cmd = bios_gdrom_get_command( sh4r.r[4] );
   148                 if( cmd == NULL ) {
   149                     sh4r.r[0] = GD_CMD_STATUS_NONE;
   150                 } else {
   151                     sh4r.r[0] = cmd->status;
   152                     if( cmd->status == GD_CMD_STATUS_ERROR &&
   153                             sh4r.r[5] != 0 ) {
   154                         mem_copy_to_sh4( sh4r.r[5], (sh4ptr_t)&cmd->result, sizeof(cmd->result) );
   155                     }
   156                 }
   157                 break;
   158             case 2: /* Mainloop */
   159                 bios_gdrom_run_queue();
   160                 break;
   161             case 3: /* Init */
   162                 bios_gdrom_init();
   163                 break;
   164             case 4: /* Drive status */
   165                 if( sh4r.r[4] != 0 ) {
   166                     mem_copy_to_sh4( sh4r.r[4], (sh4ptr_t)&bios_gdrom_status, 
   167                             sizeof(bios_gdrom_status) );
   168                 }
   169                 sh4r.r[0] = 0;
   170                 break;
   171             case 8: /* Abort command */
   172                 cmd = bios_gdrom_get_command( sh4r.r[4] );
   173                 if( cmd == NULL || cmd->status != GD_CMD_STATUS_ACTIVE ) {
   174                     sh4r.r[0] = -1;
   175                 } else {
   176                     cmd->status = GD_CMD_STATUS_ABORT;
   177                     sh4r.r[0] = 0;
   178                 }
   179                 break;
   180             case 9: /* Reset */
   181                 break;
   182             case 10: /* Set mode */
   183                 sh4r.r[0] = 0;
   184                 break;
   185             }
   186             break;
   187             case -1: /* Misc */
   188             break;
   189             default: /* ??? */
   190                 break;
   191         }
   192         break;
   193         case 0xE0: /* Menu */
   194             switch( sh4r.r[7] ) {
   195             case 0:
   196                 WARN( "Entering main program" );
   197                 break;
   198             case 1:
   199                 WARN( "Program aborted to DC menu");
   200                 dreamcast_stop();
   201                 break;
   202             }
   203     }
   204 }
   206 void bios_install( void ) 
   207 {
   208     bios_gdrom_init();
   209     syscall_add_hook_vector( 0xB0, 0x8C0000B0, bios_syscall );
   210     syscall_add_hook_vector( 0xB4, 0x8C0000B4, bios_syscall );
   211     syscall_add_hook_vector( 0xB8, 0x8C0000B8, bios_syscall );
   212     syscall_add_hook_vector( 0xBC, 0x8C0000BC, bios_syscall );
   213     syscall_add_hook_vector( 0xE0, 0x8C0000E0, bios_syscall );
   214 }
.