filename | src/bios.c |
changeset | 102:844a3f2a76ff |
prev | 87:11208d725b61 |
next | 422:61a0598e07ff |
author | nkeynes |
date | Sat May 20 02:38:58 2006 +0000 (17 years ago) |
permissions | -rw-r--r-- |
last change | Add repeating memory mode Load flash as ram rather than rom |
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 }
.