filename | src/bios.c |
changeset | 736:a02d1475ccfd |
prev | 586:2a3ba82cf243 |
next | 1065:bc1cc0c54917 |
author | nkeynes |
date | Wed Jan 07 04:39:58 2009 +0000 (15 years ago) |
branch | lxdream-mem |
permissions | -rw-r--r-- |
last change | Add missed file from previous commit - remove sh4_translate_flush_cache, change exit to use pre-recovery |
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 }
.