diff options
| author | Xavi Del Campo <xavi.dcr@tutanota.com> | 2020-01-31 10:32:23 +0100 |
|---|---|---|
| committer | Xavi Del Campo <xavi.dcr@tutanota.com> | 2020-01-31 10:32:23 +0100 |
| commit | 7c24e9a9b02b04dcaf9507acb94091ea70a2c02d (patch) | |
| tree | c28d0748652ad4b4222309e46e6cfc82c0906220 /libpsx/src/cdrom.c | |
| parent | a2b7b6bb1cc2f4a3258b7b2dbc92399d151f864d (diff) | |
| download | psxsdk-7c24e9a9b02b04dcaf9507acb94091ea70a2c02d.tar.gz | |
Imported pristine psxsdk-20190410 from official repo
Diffstat (limited to 'libpsx/src/cdrom.c')
| -rw-r--r-- | libpsx/src/cdrom.c | 240 |
1 files changed, 240 insertions, 0 deletions
diff --git a/libpsx/src/cdrom.c b/libpsx/src/cdrom.c new file mode 100644 index 0000000..ca14fd4 --- /dev/null +++ b/libpsx/src/cdrom.c @@ -0,0 +1,240 @@ +/* + * Low-level CDROM library + */ + +#include <stdio.h> +#include <stdarg.h> +#include <psx.h> + +#define CDREG(x) *((unsigned char*)(0x1f801800+x)) + +void _internal_cdrom_handler(); +void (*cdrom_handler_callback)(); +volatile int cdrom_command_direct = 0; +volatile int cdrom_command_done = 0; +volatile int cdrom_direct_cmd; +volatile int cdrom_command_dpos = 0; +volatile unsigned char cdrom_last_command; +volatile unsigned char cdrom_command_stat[2]; + +unsigned int cdrom_queue_buf[4] = {0x0, /* Will contain next interrupt handler in queue */ + 0x0, /* func1 */ + (unsigned int)_internal_cdrom_handler, /* func2 */ + 0x0, /* pad */ + }; + +static const unsigned char cdrom_command_type[0x1F] = // 0 = single int, 1 = double int, 2,3,... = others +{ + 0, // Sync 0 + 0, // GetStat/Nop 1 + 0, // Setloc 2 + 0, // Play 3 + 0, // Forward 4 + 0, // Backward 5 + 0, // ReadN 6 + 0, // Standby 7 + 0, // Stop 8 + 1, // Pause 9 + 1, // Init A + 0, // Mute B + 0, // Demute C + 0, // Setfilter D + 0, // Setmode E + 0, // Getmode F + 0, // GetlocL 10 + 0, // GetlocP 11 + 0xFF, // ??? 12 + 0, // GetTN 13 + 0, // GetTD 14 + 1, // SeekL 15 + 1, // SeekP 16 + 0xFF, // ??? 17 + 0xFF, // ??? 18 + 0, // Test 19 + 1, // ID 1A + 0, // ReadS 1B + 0, // Reset 1C + 0xFF, // ??? 1D + 1, // ReadToc 1E +}; + +void CdSendCommand(int cmd, int num, ...) +{ + int x; + va_list ap; + va_start(ap, num); + +// Wait for command execution to end +// while(CDREG(0) & 128); + +// Flush old interrupts +// If this is not done, some events (like the opening of the shell) will hang the CD controller. + + CDREG(0) = 1; + CDREG(3) = 7; + +// Send parameters + + CDREG(0) = 0; + + while(num) + { + CDREG(2) = (unsigned char)va_arg(ap, unsigned int); + num--; + } + +// Send command + + CDREG(0) = 0; + CDREG(1) = cmd; + +// Depending on the number of INTs we expect for a command, +// we wait for an INT to occur, we store the response data returned, +// and we flush the INT. + for(x = 0; x < (cdrom_command_type[cmd] + 1); x++) + { + CDREG(0) = 1; + while((CDREG(3) & 7) == 0); + + cdrom_command_stat[x] = CDREG(1); + + CDREG(0) = 1; + CDREG(3) = 7; + } + +// Store ID number of last executed command (this) + cdrom_last_command = cmd; + + va_end(ap); +} + +int CdReadResults(unsigned char *out, int max) +{ + int x; + unsigned char *outo = out; + unsigned char b; + + for(x = 0; x < (cdrom_command_type[cdrom_last_command] + 1); x++) + { + if(max > 0) + { + *(out++) = cdrom_command_stat[x]; + max--; + } + } + + CDREG(0) = 1; + + while(CDREG(0) & 0x20) + { + b = CDREG(1); + if(max>0) + { + *(out++) = b; + max--; + } + } + + return (out-outo); +} + +void _internal_cdromlib_callback() +{ + // 0 = ACKNOWLEDGE (0x*2) + // 1 = ACKNOWLEDGE (0x*2), COMPLETE (0x*3) + +/* int x; + + + + unsigned char i; + + + if(cdrom_command_done) + return; + + for(x = 0; x < 100; x++); // Waste time + + CDREG(0) = 1; + i=CDREG(3); + + if((i&0xf)==5) // Error + cdrom_command_done = 1; + + //printf("i&0xf = %x\n", i&0xf); +// printf("cdrom_direct_cmd = %x\n", cdrom_direct_cmd); + + switch(kind[cdrom_direct_cmd]) + { + case 0: + if(((i&0xf)==3) || ((i&0xf) == 2)) + cdrom_command_done = 1; + break; + + case 1: + if((i&0xf)==2) + cdrom_command_done = 1; + break; + + case 0xFF: // Unknown command! + cdrom_command_done = 1; + return; + break; + } + + cdrom_command_stat[0] = i; + + for(x = 0; x < 100; x++); // Waste time + + CDREG(0) = 1; + CDREG(3) = 7; + i = CDREG(1); + cdrom_command_stat[1] = i; + + //printf("cdrom_command_done = %d\n", cdrom_command_done);*/ +} + +void _internal_cdromlib_init() +{ + printf("Starting CDROMlib...\n"); + + EnterCriticalSection(); // Disable IRQs + + SysEnqIntRP(0, cdrom_queue_buf); + + IMASK|=4; + + cdrom_handler_callback = _internal_cdromlib_callback; + + ExitCriticalSection(); // Enable IRQs +} + +int CdGetStatus() +{ + unsigned char out; + + CdSendCommand(CdlGetstat, 0); + CdReadResults(&out, 1); + + return out; +} + +int CdPlayTrack(unsigned int track) +{ + while(CdGetStatus() & CDSTATUS_SEEK); + CdSendCommand(CdlSetmode, 1, 0x20); + CdSendCommand(CdlPlay, 1, ((track/10)<<4)|(track%10)); + + return 1; +} + +unsigned char CdRamRead(unsigned short addr) +{ + unsigned char b; + addr &= 0x3ff; + + CdSendCommand(0x19, 0x60, addr&0xff, addr >> 8); + CdReadResults(&b, 1); + + return b; +} |
