static int write_device_memory(const struct buffer *buffer) { uint32_t address = buffer->origin; uint8_t *data = buffer->data; size_t size = buffer->size; while (size) { int result; size_t count = size < 256 ? size : 256; device_buffer[0] = 0x31; if ((result = device_request(1))) return result; device_buffer[0] = address >> 24; device_buffer[1] = address >> 16; device_buffer[2] = address >> 8; device_buffer[3] = address; if ((result = device_request(4))) return result; device_buffer[0] = count - 1; memcpy(device_buffer + 1, data, count); if ((result = device_request(1 + count))) return result; size -= count; data += count; address += count; } return DONE; }
void cd_set_volume(int c0, int c1) { struct { unsigned char length; unsigned char subunit; unsigned char comcode; unsigned short status; char ununsed[8]; unsigned char media; unsigned long address; unsigned short bytes; unsigned char unused[4]; } cd_request; vol.mode = 3; vol.volume0 = MID(0, c0, 255); vol.volume1 = MID(0, c1, 255); vol.volume2 = 0; vol.volume3 = 0; vol.input0 = 0; vol.input1 = 1; vol.input2 = 2; vol.input3 = 3; cd_request.length = sizeof cd_request; cd_request.subunit = 0; cd_request.comcode = 12; cd_request.media = 0; cd_request.address = (unsigned long)&vol; cd_request.bytes = 9; device_request(&cd_request); }
void cd_get_volume(int *c0, int *c1) { struct { unsigned char length; unsigned char subunit; unsigned char comcode; unsigned short status; char ununsed[8]; unsigned char media; unsigned long address; unsigned short bytes; unsigned short sector; unsigned long volid; } tray_request; memset(&tray_request, 0, sizeof tray_request); tray_request.length = sizeof tray_request; tray_request.comcode = 3; tray_request.address = (unsigned long)&vol; tray_request.bytes = sizeof vol; vol.mode = 4; device_request(&tray_request); if (c0) *c0 = vol.volume0; if (c1) *c1 = vol.volume1; }
static void cd_cmd(unsigned char mode) { struct { unsigned char length; unsigned char subunit; unsigned char comcode; unsigned short status; char ununsed[8]; unsigned char media; unsigned long address; unsigned short bytes; unsigned char unused[4]; } tray_request; unsigned char cd_mode; cd_mode = mode; tray_request.length = sizeof tray_request; tray_request.subunit = 0; tray_request.comcode = 12; tray_request.media = 0; tray_request.address = (unsigned long)&cd_mode; tray_request.bytes = 1; device_request(&tray_request); cdrom_data.error = tray_request.status; }
static int play(unsigned long begin, unsigned long end) { unsigned long leng; struct { unsigned char length; unsigned char subunit; unsigned char comcode; unsigned short status; char ununsed[8]; unsigned char addressmode; unsigned long start; unsigned long playlength; } play_request; stop(); play_request.length = sizeof play_request; play_request.subunit = 0; play_request.comcode = 132; play_request.addressmode = 0; play_request.start = begin; play_request.playlength = end - begin; device_request(&play_request); cdrom_data.error = play_request.status; paused = 0; return !(cdrom_data.error & 0x8000); }
static int device_status(void) { struct { unsigned char length; unsigned char subunit; unsigned char comcode; unsigned short status; char ununsed[8]; unsigned char media; unsigned long address; unsigned short bytes; unsigned short sector; unsigned long volid; } tray_request; struct { unsigned char mode; unsigned long status; } cd_data; tray_request.length = sizeof tray_request; tray_request.subunit = 0; tray_request.comcode = 3; tray_request.media = 0; tray_request.media = tray_request.sector = tray_request.volid = 0; tray_request.address = (unsigned long)&cd_data; tray_request.bytes = 5; cd_data.mode = 0x06; device_request (&tray_request); cdrom_data.status = cd_data.status; cdrom_data.error = tray_request.status; return cdrom_data.status; }
static unsigned long head_position(void) { struct { unsigned char length; unsigned char subunit; unsigned char comcode; unsigned short status; char ununsed[8]; unsigned char media; unsigned long address; unsigned short bytes; unsigned short sector; unsigned long volid; unsigned char unused[4]; } tray_request; struct { unsigned char mode; unsigned char adr_mode; unsigned long address; } head_data; memset(&tray_request, 0, sizeof tray_request); tray_request.length = sizeof tray_request; tray_request.comcode = 3; tray_request.address = (unsigned long)&head_data; tray_request.bytes = 6; head_data.mode = 0x01; head_data.adr_mode = 0x00; device_request(&tray_request); cdrom_data.error = tray_request.status; return head_data.address; }
static int erase_device(void) { int result; fprintf(stdout, TTY_NONE "Erasing..."); device_buffer[0] = device_erase_command; if ((result = device_request(1))) return result; device_buffer[0] = 0xFF; device_buffer[1] = 0xFF; if ((result = device_request(device_erase_command == 0x44 ? 2 : 1))) return result; return DONE; }
static int connect_device(const char *file) { int result; fprintf(stdout, TTY_NONE "Connect \"%s\"...", file); if ((result = open_serial_port(file))) return result; if ((result = reset_device(1))) return result; if ((result = handshake_device())) return result; device_buffer[0] = 0x00; if ((result = device_request(1))) return result; if ((result = device_response(13))) return result; device_version = device_buffer[1]; device_erase_command = device_buffer[8]; fprintf(stdout, TTY_NONE "V%1X.%1X...", device_version >> 4, device_version & 0x0F); device_buffer[0] = 0x02; if ((result = device_request(1))) return result; if ((result = device_response(3))) return result; if ((result = select_device(device_buffer[1] << 8 | device_buffer[2]))) return result; return DONE; }
static int read_device_memory(const struct buffer *buffer) { uint32_t address = buffer->origin; uint8_t *data = buffer->data; size_t size = buffer->size; while (size) { int result; size_t count = size < 256 ? size : 256; device_buffer[0] = 0x11; if ((result = device_request(1))) return result; device_buffer[0] = address >> 24; device_buffer[1] = address >> 16; device_buffer[2] = address >> 8; device_buffer[3] = address; if ((result = device_request(4))) return result; device_buffer[0] = count - 1; if ((result = device_request(1))) return result; if ((result = read_serial_port(data, size))) return result; size -= count; data += count; address += count; } return DONE; }
static void stop(void) { struct { unsigned char length; unsigned char subunit; unsigned char comcode; unsigned short status; char ununsed[8]; } stop_request; stop_request.length = sizeof stop_request; stop_request.subunit = 0; stop_request.comcode = 133; device_request(&stop_request); cdrom_data.error = stop_request.status; }
static int protect_device(void) { int result; fprintf(stdout, TTY_NONE "Readout protecting..."); device_buffer[0] = 0x82; if ((result = device_request(1))) return result; if ((result = device_response(0))) return result; if ((result = handshake_device())) return result; return DONE; }
static int get_audio_info(void) { struct { unsigned char length; unsigned char subunit; unsigned char comcode; unsigned short status; char ununsed[8]; unsigned char media; long address; short bytes; short sector; long volid; } ioctli; struct { unsigned char mode; unsigned char lowest; unsigned char highest; unsigned long address; } track_data; ioctli.length = sizeof ioctli; ioctli.subunit = 0; ioctli.comcode = 3; ioctli.media = 0; ioctli.sector = 0; ioctli.volid = 0; ioctli.address = (long)&track_data; ioctli.bytes = sizeof track_data; track_data.mode = 0x0a; device_request(&ioctli); memcpy(&cdrom_data.diskid, &track_data.lowest, 6); cdrom_data.low_audio = track_data.lowest; cdrom_data.high_audio = track_data.highest; red_book(track_data.address, &cdrom_data.disk_length_min, &cdrom_data.disk_length_sec, &cdrom_data.disk_length_frames); cdrom_data.endofdisk = hsg (track_data.address); cdrom_data.error = ioctli.status; return !(cdrom_data.error & 0x8000); }
static void set_track(short tracknum) { struct { unsigned char length; unsigned char subunit; unsigned char comcode; unsigned short status; char ununsed[8]; unsigned char media; unsigned long address; unsigned short bytes; unsigned short sector; unsigned long volid; } tray_request; struct { unsigned char mode; unsigned char track; unsigned long address; unsigned char control; } track_data; tray_request.length = sizeof tray_request; tray_request.subunit = 0; tray_request.comcode = 3; tray_request.media = 0; tray_request.media = tray_request.sector = tray_request.volid = 0; tray_request.address = (unsigned long)&track_data; tray_request.bytes = 7; track_data.mode = 0x0b; track_data.track = tracknum; device_request(&tray_request); cdrom_data.error = tray_request.status; cdrom_data.track_position = hsg(track_data.address); cdrom_data.current_track = tracknum; cdrom_data.track_type = (track_data.control & TRACK_MASK); }