filename | src/bios.c |
changeset | 586:2a3ba82cf243 |
prev | 502:c4ecae2b1b5e |
next | 736:a02d1475ccfd |
author | nkeynes |
date | Thu Feb 14 13:54:11 2008 +0000 (16 years ago) |
branch | lxdream-render |
permissions | -rw-r--r-- |
last change | Commit render work in progress. Main changes: * Preliminary OSMesa support * Move the generic gl code out to pvr2/ * Implement scene data structure + reader * Remove the 1/z adjustments |
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 | } |
.