Created
March 16, 2020 00:43
-
-
Save JayFoxRox/6b2adee2ea3c5ebd164d8f6e4c4c5a8a to your computer and use it in GitHub Desktop.
Analysis of SDG605B x010 firmware
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void FUN_CODE_33cd_12__handle_INQUIRY(void) | |
{ | |
// EVPD must be zero | |
if (BYTE_INTMEM_9b & 1) { | |
FUN_CODE_27e2_error_tracking_probably(SPC_SK_ILLEGAL_REQUEST,0x24,0); | |
return; | |
} | |
// Page code must be zero | |
if (BYTE_INTMEM_9c != 0) { | |
FUN_CODE_27e2_error_tracking_probably(SPC_SK_ILLEGAL_REQUEST,0x24,0); | |
return; | |
} | |
// Skip empty access | |
if (BYTE_INTMEM_9e == 0) { | |
return; | |
} | |
// Clamp to 0x60 if necessary | |
if (BYTE_INTMEM_9e >= 0x60) { | |
DAT_INTMEM_8b = 0x00; | |
DAT_INTMEM_8c = 0x60; | |
} else { | |
DAT_INTMEM_8b = 0x00; | |
DAT_INTMEM_8c = BYTE_INTMEM_9e; | |
} | |
// Return the data that was written in init.c | |
FUN_CODE_79a4_return_data_from_master_maybe(0x200); | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Uses `MOV @R0,A` (ptr is R0, so 8-bit ptr.) | |
void FUN_CODE_1f3d(uint8_t ptr,uint32_t param_2) { | |
INTMEM[ptr+0] = param_2 >> 24; | |
INTMEM[ptr+1] = param_2 >> 16; | |
INTMEM[ptr+2] = param_2 >> 8; | |
INTMEM[ptr+3] = param_2 >> 0; | |
} | |
void FUN_CODE_4467_25__READ_CAPACITY(void) | |
{ | |
byte bVar1; | |
byte bVar2; | |
char cVar3; | |
byte bVar4; | |
byte bVar5; | |
char cVar6; | |
undefined uVar7; | |
DAT_EXTMEM_807e &= ~0x20; | |
if (26.1 == 0) { | |
cVar3 = read_volatile_1(DAT_EXTMEM_805e); | |
if ((cVar3 == 0x00) || (cVar3 == 0x03)) { | |
write_volatile_1(DAT_EXTMEM_8010,0x10); | |
write_volatile_1(DAT_EXTMEM_8093,0x10); | |
} | |
DAT_EXTMEM_807f &= ~0x80; | |
} else { | |
//FIXME: Similar code is already found in the PFI read stuff for 0xAD! | |
if (20.4 == 0) { | |
// Assumption: Single-layer? | |
bVar1 = read_volatile_1(DAT_EXTMEM_8081); | |
if (bVar1 & 0x80) { | |
write_volatile_1(DAT_EXTMEM_8010,6); | |
write_volatile_1(DAT_EXTMEM_8093,6); | |
} else if (bVar1 & 0x40) { | |
write_volatile_1(DAT_EXTMEM_8010,6); | |
write_volatile_1(DAT_EXTMEM_8093,6); | |
} else { | |
write_volatile_1(DAT_EXTMEM_8010,6); | |
write_volatile_1(DAT_EXTMEM_8093,6); | |
} | |
} else { | |
// Assumption: Dual-layer? | |
write_volatile_1(DAT_EXTMEM_8010,6); | |
write_volatile_1(DAT_EXTMEM_8093,6); | |
} | |
} | |
FUN_CODE_1f3d(0x94, DAT_EXTMEM_8043804480458046 - 1); // MMIO loaded from left to right | |
// Set response length? | |
write_volatile_1(DAT_EXTMEM_4024,8); | |
// Write response | |
{ | |
// From MMC spec: | |
// > The returned Logical Block Address shall be the | |
// > last sector in the last complete session. | |
// > | |
// > The Block Length shall be reported, in bytes, as 2048d. | |
// > A block length of 512 is obsolete. | |
// > | |
// > For CD media, the last logical block shall be | |
// > determined by converting the last recorded | |
// > Lead-out to an LBAand subtracting one. | |
// > If the resulting address points to a run out block | |
// > (because the session was recorded withpackets or | |
// > track at once in data mode), the Logical Unit shall | |
// > subtract 2 from the LBA to point to the actual | |
// > last user data block. If no complete session | |
// > exists on the medium, this field shall be set to zero. | |
// Logical Block Address | |
DAT_EXTMEM_4010 = DAT_INTMEM_94; // = ( DAT_EXTMEM_8043.. | |
DAT_EXTMEM_4010 = DAT_INTMEM_95; // = ..DAT_EXTMEM_8044.. | |
DAT_EXTMEM_4010 = DAT_INTMEM_96; // = ..DAT_EXTMEM_8045.. | |
DAT_EXTMEM_4010 = DAT_INTMEM_97; // = ..DAT_EXTMEM_8046 ) - 1 | |
// Block Length in Bytes | |
DAT_EXTMEM_4010 = 0x00; | |
DAT_EXTMEM_4010 = 0x00; | |
DAT_EXTMEM_4010 = DAT_EXTMEM_8057; | |
DAT_EXTMEM_4010 = DAT_EXTMEM_8058; | |
} | |
//FIXME: WTF is this? | |
29.6 = 1; | |
return; | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// State when entering FUN_CODE_4b5e | |
// | |
// AD 00 FF02FDFF FE 00 0800 xx C0 | The SCSI ATAPI CDB | |
// 9a 9b 9c9d9e9f a0 a1 a2a3 a4 a5 | INTMEM_* address | |
// 9a | operation code (READ DVD STRUCTURE) | |
// 9b | ??? | |
// 9c9d9e9f | sector number | |
// a0 | layer number | |
// a1 | format | |
// a2a3 | size | |
// a4 | "Authentication Grant ID" (AGID) | |
// a5 | control | |
// | |
// This feels like it might be accepted by this firmware, too: | |
// (Tested on 23 Jan. 2020 Does not work.. why?) | |
// | |
// AD 00 00FD0200 01 00 0800 xx 00 | The SCSI ATAPI CDB Hack | |
// 9c9d9e9f | 0xFF02FDFF xor 0xFFFFFFFF | |
// a0 | 0xFE xor 0xFF | |
// a5 | Anything but 0xC0 | |
// WARNING: Expects: | |
// - EXTMEM_8003 (unknown) | |
// - INTMEM_8b8c (read length) | |
// - EXTMEM_80048005 (some base address [always set to zero?] - param_1 gets added) | |
// Uses: | |
// - INTMEM_8b8c (size calculation) | |
// - INTMEM_a6a7 (offset calculation) | |
//FIXME: Possibly missing volatile writes to EXTMEM | |
void FUN_CODE_79a4(ushort param_1) { | |
// If 8b8c is odd, make it even by incrementing by one | |
if (DAT_INTMEM_8b8c & 1) { | |
DAT_INTMEM_8b8c += 1; | |
} | |
DAT_INTMEM_a6a7 = DAT_EXTMEM_80048005 + param_1; | |
DAT_EXTMEM_4031 = DAT_EXTMEM_8003; //FIXME: unknown | |
DAT_EXTMEM_40324033 = DAT_INTMEM_a6a7; // read offset? [4033 is written last] | |
DAT_EXTMEM_40344035 = DAT_INTMEM_8b8c; // read length [4034 is written last] | |
29.6 = 1; //FIXME: What does this do? | |
return; | |
} | |
// Probably almost same inputs as FUN_CODE_79a4 [very similar] | |
void FUN_CODE_79de(ushort param_1) { | |
DAT_INTMEM_a6a7 = DAT_EXTMEM_80048005 + param_1; | |
DAT_EXTMEM_4031 = DAT_EXTMEM_8003; //FIXME: unknown | |
DAT_EXTMEM_40324033 = DAT_INTMEM_a6a7; // read offset? | |
DAT_EXTMEM_4036 = DAT_INTMEM_8c; // read length? | |
return; | |
} | |
void FUN_CODE_7966(void) { | |
DAT_EXTMEM_400e &= ~0x20; | |
DAT_EXTMEM_4012 = 0x00; | |
DAT_EXTMEM_4015 = 0x00; | |
DAT_EXTMEM_4017 = 0x50; | |
DAT_EXTMEM_4021 = 0x20; | |
DAT_EXTMEM_8000 = 0x00; | |
DAT_EXTMEM_8001 = 0x64; | |
while(!(DAT_EXTMEM_400f & 0x20)) { | |
if (DAT_EXTMEM_8000 != 0) { continue; } | |
if (DAT_EXTMEM_8001 != 0) { continue; } | |
break; | |
} | |
// Why u no XOR?! | |
DAT_EXTMEM_400e += 0x20; | |
return; | |
} | |
// Error handler? | |
void FUN_CODE_27e2(byte param_1,byte param_2,byte param_3) { | |
DAT_EXTMEM_8035 = param_2; | |
DAT_EXTMEM_8049 = param_1; | |
DAT_EXTMEM_805f = param_3; | |
return; | |
} | |
void FUN_CODE_4b5e_handle_AD__READ_DVD_STRUCTURE(void) | |
{ | |
// FIXME: WTF is this shit? | |
byte bVar1 = read_volatile_1(DAT_EXTMEM_8080); | |
bVar1 |= 0x20; | |
write_volatile_1(DAT_EXTMEM_8080,bVar1); | |
bVar1 &= ~0x8; | |
write_volatile_1(DAT_EXTMEM_8080,bVar1); | |
//FIXME: WTF is this shit? (maybe check for CD or non-DVD disc?) | |
if (26.1 == 0) { | |
DAT_EXTMEM_807e |= 0x10; | |
FUN_CODE_27e2(2,0x30,5); | |
return; | |
} | |
// Handle Xbox specific SS request | |
if (BYTE_INTMEM_a5 == 0xC0) { | |
// Flip bits in sector number and layer number | |
BYTE_INTMEM_9c9d9e9f = ~BYTE_INTMEM_9c9d9e9f; | |
BYTE_INTMEM_a0 = ~BYTE_INTMEM_a0; | |
} | |
// If layer number is not 0 or 1, error? | |
if ((BYTE_INTMEM_a0 != 0) && (BYTE_INTMEM_a0 != 1)) { | |
FUN_CODE_27e2(0,0x24,5); | |
return; | |
} | |
// Do some extra checks for higher layers | |
if (BYTE_INTMEM_a0 != 0) { | |
// From MMC spec: | |
// > Requests for Format FFh shall always be fullfilled, | |
// > even if there is no medium or an incompatible medium installed | |
// Probably checks if this is a dual-layer disk (20.4?) | |
// If this isn't a dual layer disk, we'd have to supply 0xFF. | |
// Otherwise it would be considered "no media" | |
if ((20.4 == 0) && (BYTE_INTMEM_a1 != 0xff)) { | |
FUN_CODE_27e2(0,0x24,5); | |
return; | |
} | |
} | |
// Set layer number to 0 if ??? | |
//FIXME: What's this? | |
if (20.5 == 0) { | |
BYTE_INTMEM_a0 = 0; | |
} | |
// Reduce size by 4 as we'll add a header. | |
// INTMEM_9c stores header size, 8b8c stores data size | |
if (BYTE_INTMEM_a2a3 < 4) { | |
BYTE_INTMEM_9c = BYTE_INTMEM_a3; | |
DAT_INTMEM_8b8c = 0x0000; | |
} else { | |
BYTE_INTMEM_9c = 4; | |
DAT_INTMEM_8b8c = BYTE_INTMEM_a2a3 - 4; | |
} | |
// Copyright | |
if (BYTE_INTMEM_a1 == 1) { | |
DAT_EXTMEM_807e |= 0x10; | |
write_volatile_1(DAT_EXTMEM_8034,0); | |
FUN_CODE_7300(); | |
return; | |
} | |
// Disc Key | |
if (BYTE_INTMEM_a1 == 2) { | |
FUN_CODE_7341(); | |
return; | |
} | |
// BCA | |
if (BYTE_INTMEM_a1 == 3) { | |
bVar1 = read_volatile_1(DAT_EXTMEM_8080); | |
if ((bVar1 & 1) == 0) { | |
signed char ret = FUN_CODE_a801(0xE10); | |
if (ret >= 0) { | |
FUN_CODE_27e2(0,0x24,5); | |
return; | |
} | |
FUN_CODE_73d0(); | |
return; | |
} | |
bVar1 = read_volatile_1(DAT_EXTMEM_8080); | |
if ((bVar1 & 1) == 1) { | |
signed char ret = FUN_CODE_a801(0x2A10); | |
if (ret >= 0) { | |
FUN_CODE_27e2(0,0x24,5); | |
return; | |
} | |
FUN_CODE_73d0(); | |
return; | |
} | |
FUN_CODE_27e2(0,0x24,5); | |
return; | |
} | |
// Manufacturer | |
if (BYTE_INTMEM_a1 == 4) { | |
FUN_CODE_7476(); | |
return; | |
} | |
// Physical | |
if (BYTE_INTMEM_a1 == 0) { | |
DAT_EXTMEM_807e &= ~0x20; | |
// Compiler bug / bad hand-assembly? | |
// (All paths run the same code?) | |
// Something to do with dual layer? | |
if (20.4 == 0) { | |
// Assumption: Single-layer disc | |
bVar1 = read_volatile_1(DAT_EXTMEM_8081); | |
if (bVar1 & 0x80) { | |
write_volatile_1(DAT_EXTMEM_8010,6); | |
write_volatile_1(DAT_EXTMEM_8093,6); | |
} else if (bVar1 & 0x40) { | |
write_volatile_1(DAT_EXTMEM_8010,6); | |
write_volatile_1(DAT_EXTMEM_8093,6); | |
} else { | |
write_volatile_1(DAT_EXTMEM_8010,6); | |
write_volatile_1(DAT_EXTMEM_8093,6); | |
} | |
} else { | |
// Assumption: Dual-layer disc [feels like this should be the single layer case?] | |
write_volatile_1(DAT_EXTMEM_8010,6); | |
write_volatile_1(DAT_EXTMEM_8093,6); | |
} | |
DAT_EXTMEM_807e |= 0x10; | |
write_volatile_1(DAT_EXTMEM_8034,0); | |
FUN_CODE_728c(); | |
return; | |
} | |
// Structure List | |
if (BYTE_INTMEM_a1 == 0xff) { | |
FUN_CODE_74b7(); | |
return; | |
} | |
// Some error handler? | |
//FIXME: Check if this is SK, ASQ, ASQC | |
// Probably not? | |
FUN_CODE_27e2(0,0x24,5); | |
return; | |
} | |
// Physical (PFI) | |
void FUN_CODE_728c(void) { | |
// Skip if size is zero | |
if (DAT_INTMEM_a2a3 == 0) { | |
return; | |
} | |
// Handle SS requests | |
if (DAT_INTMEM_a5 == 0xC0) { | |
// Transfer header | |
DAT_EXTMEM_4024 = DAT_INTMEM_9c; | |
write_volatile_1(DAT_EXTMEM_4010,0x06); // 0x664 | |
write_volatile_1(DAT_EXTMEM_4010,0x64); | |
write_volatile_1(DAT_EXTMEM_4010,0x00); | |
write_volatile_1(DAT_EXTMEM_4010,0x00); | |
// Limit the read size to allowed portion of SS | |
//FIXME: Ensure this is the same: if (-1 < (DAT_INTMEM_8b < 6U - (((DAT_INTMEM_8c <= 0x64) << 7) >> 7)) << 7) { | |
if (DAT_INTMEM_8b8c > 0x664) { | |
DAT_INTMEM_8b8c = 0x664; | |
} | |
FUN_CODE_79a4(0x2A00); | |
} else { | |
// Transfer header (why is this 0x802 ahd not 804?) | |
DAT_EXTMEM_4024 = BYTE_INTMEM_9c; | |
write_volatile_1(DAT_EXTMEM_4010,0x08); // 0x802 | |
write_volatile_1(DAT_EXTMEM_4010,0x02); | |
write_volatile_1(DAT_EXTMEM_4010,0x00); | |
write_volatile_1(DAT_EXTMEM_4010,0x00); | |
//FIXME: Ensure this is the same: if (-1 < (DAT_INTMEM_8b < 8U - (((DAT_INTMEM_8c <= 0) << 7) >> 7)) << 7) { | |
if (DAT_INTMEM_8b8c > 0x800) | |
DAT_INTMEM_8b8c = 0x800; | |
} | |
if (DAT_INTMEM_a0 == 0) { | |
FUN_CODE_79a4(0xE00); | |
} else { | |
FUN_CODE_79a4(0x2A00); | |
} | |
} | |
} | |
// Manufacturer (DMI) | |
void FUN_CODE_7476(void) { | |
// Skip if read size is zero | |
if (BYTE_INTMEM_a2a3 == 0) { | |
return; | |
} | |
write_volatile_1(DAT_EXTMEM_4024,BYTE_INTMEM_9c); | |
write_volatile_1(DAT_EXTMEM_4010,0x08); // 0x802? | |
write_volatile_1(DAT_EXTMEM_4010,0x02); | |
write_volatile_1(DAT_EXTMEM_4010,0x00); | |
write_volatile_1(DAT_EXTMEM_4010,0x00); | |
// Clamp read size to 0x800 | |
//FIXME: Ensure that this is the same as if (-1 < (DAT_INTMEM_8b < 8U - (((DAT_INTMEM_8c == 0x00) << 7) >> 7)) << 7) { | |
if (DAT_INTMEM_8b8c > 0x800) { | |
DAT_INTMEM_8b8c = 0x800; | |
} | |
// Differentiate target layer | |
if (BYTE_INTMEM_a0 == 0) { | |
FUN_CODE_79a4(0x1600); | |
} else { | |
FUN_CODE_79a4(0x3200); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// These are some commands I could make out: | |
// Unknown | |
// | |
// F2 01 ... | |
// | |
// No idea, but does stuff in >= 0xC000 region which is assumed to be MMIO for mechanical stuff | |
// Unknown | |
// | |
// 9a 9b 9c 9d 9e 9f a0 a1 a2 a3 | |
// F2 02 00 00 00 00 00 00 10 02 | |
// ## ## ## | |
// ## flash bank (00 is bank 0, anything else is bank 01) | |
// ## ## offset | |
// # ## must be zero | |
// ## ## length (must be 0x1002) | |
// Unknown | |
// | |
// 9a 9b 9c 9d 9e 9f a0 a1 a2 a3 | |
// F2 03 00 00 00 00 00 00 10 02 | |
// ## ## ## | |
// ## ## ## offset | |
// # ## must be zero | |
// ## ## length (must be 0x1002) | |
// Write flash block(s) | |
// | |
// F2 04 <INTMEM_94=unused?> <INTMEM_95=bank> <INTMEM_96_97=address> <INTMEM_88_89_8a=size> | |
// | |
// F2 04 00 01 000000 000100 should flash 0x100 bytes in bank 1 (firmware file offset 0x10000?) | |
// | |
// Goes into 0xE800 (bank1) flasher routine. | |
// Probably explodes if bank is not 0 (flasher unmaps itself?). | |
// Size will have to be a multiple of 0x100 probably. | |
// Not sure how data is pushed into it. | |
// Read RAM(?) (the one set up by init.c) | |
// | |
// F2 05 <INTMEM_9C=unused?> <INTMEM_9D_9E_9F=address> <INTMEM_A0=unused?> <INTMEM_A1=unused?> <INTMEM_A2_A3=size> | |
// | |
// XX should probably be 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80 ? (maybe also 0x3) | |
// F2 05 00 000000 00 00 0200 should dump ATA IDENTIFY information | |
// F2 05 00 000200 00 00 0060 should dump ATAPI INQUIRY information | |
// F2 05 00 002A00 00 00 0800 should dump SS.bin (or PFI.bin.. who the fuck knows) | |
// | |
// Size must be even, if odd it will be rounded up. | |
// Data returned in same style as from ATAPI INQUIRY. | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// The SH-D162D flasher uses the following (none of which are found here?!): | |
// cmdFCSupport: FF 02 FC 00 ... | |
// cmdStartDownload: FF 00 01 00 ... (fw_size follows) | |
// cmdSupportDownload: FF 00 FF 00 ... | |
// | |
// FIXME: Analyze sfndwin or mtkflash to figure out what the old commands used to be? | |
// Maybe look for further handlers? | |
//FIXME: This function should probably have a 32-bit argument | |
//FIXME: Most functions in this don't parse all arguments properly. fuck ghidra meh. | |
void FUN_CODE_7bdd_handle_FF__vendor(void) | |
{ | |
bool bVar1; | |
byte bVar2; | |
undefined uVar3; | |
byte bVar4; | |
undefined uVar5; | |
byte bVar6; | |
undefined uVar7; | |
byte bVar8; | |
uint uVar9; | |
char cVar10; | |
char cVar11; | |
undefined uVar12; | |
uint3 uVar13; | |
uint in_R4R5R6R7; | |
uint uVar14; | |
undefined4 uVar16; | |
uint32_t uVar17; | |
byte bVar18; | |
byte bVar19; | |
byte bVar20; | |
char cVar21; | |
byte bVar22; | |
DAT_INTMEM_4a = 0; | |
// This is interesting - it implies these handlers take an 32-bit argument of some sort? | |
uint uVar15 = in_R4R5R6R7 & 0xffffff00; | |
// FF 66 ... | |
// FF 06 ... | |
if ((BYTE_INTMEM_9b == 0x66) || (BYTE_INTMEM_9b == 0x06)) { | |
bVar18 = BYTE_INTMEM_9c ^ 5; | |
// FF 66 05 | |
// FF 06 05 | |
if (BYTE_INTMEM_9c == 0x05) { | |
bVar18 = 0x00; | |
uVar15 = in_R4R5R6R7 & 0xffff0000; | |
DAT_INTMEM_4b = 0x00; | |
DAT_INTMEM_4c = 0x00; | |
do { | |
bVar1 = CARRY1(*(byte *)uVar15,DAT_INTMEM_4c); | |
DAT_INTMEM_4c = *(byte *)uVar15 + DAT_INTMEM_4c; | |
DAT_INTMEM_4b -= (bVar1 << 7) >> 7; | |
bVar18 = (char)uVar15 + 1; | |
uVar14 = uVar15 & 0xffffff00 | (uint)bVar18; | |
if (bVar18 == 0) { | |
uVar14 = uVar15 & 0xffff0000 | (uint)((char)((uVar15 & 0xffffff00) >> 8) + 1) << 8; | |
} | |
bVar18 = (byte)(uVar14 >> 0x18); | |
uVar15 = uVar14; | |
} while (((byte)(uVar14 >> 8) < 0xffU - ((((char)uVar14 != -1) << 7) >> 7)) << 7 < '\0'); | |
//FIXME: Thanks ghidra. wtf is this shit? | |
bVar1 = CARRY1(bCODEffff,DAT_INTMEM_4c); | |
DAT_INTMEM_4c = bCODEffff + DAT_INTMEM_4c; | |
DAT_INTMEM_4b -= (bVar1 << 7) >> 7; | |
FUN_CODE_01dc(bVar18); | |
bVar1 = CARRY1(DAT_INTMEM_99,DAT_INTMEM_4c); | |
DAT_INTMEM_4c = DAT_INTMEM_99 + DAT_INTMEM_4c; | |
DAT_INTMEM_4b = DAT_INTMEM_98 + (DAT_INTMEM_4b - ((bVar1 << 7) >> 7)); | |
write_volatile_1(EXT_4024_data_out_length,2); | |
write_volatile_1(EXT_4010_write_data_out,DAT_INTMEM_4b); | |
write_volatile_1(EXT_4010_write_data_out,DAT_INTMEM_4c); | |
29.6 = 1; | |
uVar15 = (uint)bVar18 << 24; | |
FUN_CODE_27e2(0,0,0); | |
} | |
} | |
// FF 08 01 [terminating if EXTMEM_8080 & 1 == 0] | |
if ((BYTE_INTMEM_9b == 0x08) && (BYTE_INTMEM_9c == 0x01)) { | |
bVar18 = read_volatile_1(DAT_EXTMEM_8080); | |
if (bVar18 & 1) { | |
DAT_EXTMEM_8022 = 0x00); | |
DAT_EXTMEM_8023 = FUN_CODE_a801(0x2a,0x05); | |
DAT_EXTMEM_8024 = FUN_CODE_a801(0x2a,0x06); | |
DAT_EXTMEM_8025 = FUN_CODE_a801(0x2a,0x07); | |
DAT_EXTMEM_8060,0x00); | |
DAT_EXTMEM_8061 = FUN_CODE_a801(0x2a,0x0d); | |
DAT_EXTMEM_8062 = FUN_CODE_a801(0x2a,0x0e); | |
DAT_EXTMEM_8063 = FUN_CODE_a801(0x2a,0x0f); | |
DAT_INTMEM_8e = 0xff; | |
DAT_INTMEM_8f = FUN_CODE_a801(0x2a,0x09); | |
DAT_INTMEM_90 = FUN_CODE_a801(0x2a,0x0A); | |
DAT_INTMEM_91 = FUN_CODE_a801(0x2a,0x0B); | |
uVar12 = read_volatile_1(DAT_EXTMEM_8060); | |
uVar3 = read_volatile_1(DAT_EXTMEM_8061); | |
uVar5 = read_volatile_1(DAT_EXTMEM_8062); | |
uVar7 = read_volatile_1(DAT_EXTMEM_8063); | |
uVar16 = CONCAT31(CONCAT21(CONCAT11(uVar12,uVar3),uVar5),uVar7); | |
FUN_CODE_1eca(uVar12); | |
uVar14 = (uint)uVar16 >> 0x18; | |
uVar15 = (uint)uVar16 >> 0x10; | |
uVar9 = (uint)uVar16 >> 8; | |
bVar18 = (byte)uVar16; | |
FUN_CODE_1f24(0x8e); //FIXME: Missing arguments? | |
bVar19 = (byte)uVar16 - bVar18; | |
bVar22 = (byte)((uint)uVar16 >> 8); | |
bVar18 = (char)uVar9 - ((((byte)uVar16 < bVar18) << 7) >> 7); | |
bVar8 = (byte)((uint)uVar16 >> 0x10); | |
bVar2 = (char)uVar15 - (((bVar22 < bVar18) << 7) >> 7); | |
uVar15 = (uint)CONCAT12(bVar8 - bVar2,CONCAT11(bVar22 - bVar18,bVar19)); | |
cVar21 = read_volatile_1(DAT_EXTMEM_8060); | |
bVar4 = read_volatile_1(DAT_EXTMEM_8061); | |
bVar6 = read_volatile_1(DAT_EXTMEM_8062); | |
bVar18 = read_volatile_1(DAT_EXTMEM_8063); | |
bVar20 = bVar18 + bVar19; | |
bVar18 = (char)(uVar15 >> 8) - ((CARRY1(bVar18,bVar19) << 7) >> 7); | |
bVar22 = (char)(uVar15 >> 0x10) - ((CARRY1(bVar6,bVar18) << 7) >> 7); | |
uVar15 = (uint)CONCAT12(bVar4 + bVar22,CONCAT11(bVar6 + bVar18,bVar20)); | |
uVar17 = CONCAT13(cVar21 + (((char)((uint)uVar16 >> 0x18) - | |
((char)uVar14 - (((bVar8 < bVar2) << 7) >> 7))) - | |
((CARRY1(bVar4,bVar22) << 7) >> 7)), | |
CONCAT12((char)(uVar15 >> 0x10), | |
CONCAT11((char)(uVar15 >> 8) - (((0xfe < bVar20) << 7) >> 7), | |
bVar20 + 1))); | |
FUN_CODE_1f3d_set_intmem_at_ptr8_to_val32(0x8e,uVar17); | |
cVar21 = read_volatile_1(DAT_EXTMEM_8022); | |
cVar10 = read_volatile_1(DAT_EXTMEM_8023); | |
cVar11 = read_volatile_1(DAT_EXTMEM_8024); | |
bVar18 = read_volatile_1(DAT_EXTMEM_8025); | |
FUN_CODE_1f24(0x8e,cVar10,cVar11,bVar18); //FIXME: cVar21, too probably | |
FUN_CODE_1f49(0x8043,cVar21, | |
(char)(uVar17 >> 0x18) - | |
(cVar21 - ((((byte)(uVar17 >> 0x10) < | |
(byte)(cVar10 - ((((byte)(uVar17 >> 8) < | |
(byte)(cVar11 - ((((byte)uVar17 < bVar18) << 7) >> 7 | |
))) << 7) >> 7))) << 7) >> 7))); | |
26.6 = 1; | |
return; | |
} | |
} | |
// FF | |
if (BYTE_INTMEM_a8 == 0) { | |
FUN_CODE_27e2(0,0x3a,2); | |
return; | |
} | |
uVar14 = uVar15 & 0xffffff00; | |
// FF 50 | |
// FF 55 | |
// FF 70 | |
if (((BYTE_INTMEM_9b == 0x50) || (BYTE_INTMEM_9b == 0x55) || (BYTE_INTMEM_9b == 0x70))) { | |
FUN_CODE_27e2(0,0x20,5); | |
return; | |
} | |
// FF ?? ?? ?? ?? ?? ?? ?? ?? ?? AA ?? | |
// FF ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? AA | |
if (((BYTE_INTMEM_a4 == 0xaa) || (BYTE_INTMEM_a5 == 0xaa))) { | |
FUN_CODE_27e2(0,0x20,5); | |
return; | |
} | |
uVar12 = (undefined)(uVar14 >> 24); | |
bVar18 = BYTE_INTMEM_9c ^ 0x30; | |
// FF ?? 30 | |
if (BYTE_INTMEM_9c == 0x30) { | |
bVar18 = 0x00; | |
if (26.1 == 1) { | |
23.2 = 0; | |
write_volatile_1(DAT_EXTMEM_c060,0x0A); | |
write_volatile_1(DAT_EXTMEM_4084,0x80); | |
cVar21 = 0; | |
DAT_INTMEM_4a = 0; | |
DAT_INTMEM_98 = 0x00; | |
DAT_INTMEM_99 = 0x00; | |
do { | |
FUN_CODE_01e1(cVar21,(char)(uVar14 >> 0x18)); //FIXME: Missing arguments? | |
bVar18 = DAT_INTMEM_4a; | |
cVar21 = read_volatile_1(DAT_EXTMEM_808c); | |
if (cVar21 == 0) { | |
break; | |
} | |
uVar14 &= 0xffffff00; | |
cVar21 = bVar18 + 0x37; | |
DAT_INTMEM_4a += 1; | |
} while (-1 < (bVar18 < 0xc9) << 7); | |
// FIXME: Some MMIO magic? | |
write_volatile_1(DAT_EXTMEM_808f = 0x00; | |
cVar21 = DAT_EXTMEM_808f; | |
// FIXME: Thanks obama.. probably missing arguments on next call | |
bVar18 = read_volatile_1(DAT_EXTMEM_8090); | |
read_volatile(DAT_EXTMEM_8091); | |
// Probably writes to EXTMEM or something? | |
FUN_CODE_1f49(0x808f,cVar21 + (((bVar18 < 3) << 7) >> 7)); | |
EXT_4010_write_data_out = DAT_EXTMEM_808f | 0x80; | |
EXT_4010_write_data_out = DAT_EXTMEM_8090; | |
EXT_4010_write_data_out = DAT_EXTMEM_8091; | |
EXT_4010_write_data_out = DAT_EXTMEM_8092; | |
EXT_4010_write_data_out = DAT_EXTMEM_c015; | |
EXT_4010_write_data_out = DAT_EXTMEM_c014; | |
EXT_4010_write_data_out = DAT_EXTMEM_c017; | |
EXT_4010_write_data_out = DAT_EXTMEM_c016; | |
} else { | |
DAT_INTMEM_98 = 0; | |
DAT_INTMEM_99 = 0; | |
23.2 = 0; | |
FUN_CODE_01a0(uVar12); | |
cVar21 = 0; | |
DAT_INTMEM_4a = 0; | |
do { | |
FUN_CODE_01e6(cVar21); | |
bVar18 = DAT_INTMEM_4a; | |
if (23.4 == 1) { | |
break; | |
} | |
uVar14 &= 0xffffff00; | |
DAT_INTMEM_4a += 1; | |
cVar21 = bVar18 + 0x9b; | |
} while (((bVar18 < 0x65) << 7) < 0); | |
EXT_4010_write_data_out = 0x00; | |
uVar15 = uVar14 & 0xffffff00 | (uint)DAT_INTMEM_39; | |
FUN_CODE_adbe((char)((uVar14 & 0xffffff00) >> 0x18)); | |
EXT_4010_write_data_out = (char)uVar15; | |
uVar14 = uVar15 & 0xffffff00 | (uint)DAT_INTMEM_3a; | |
FUN_CODE_adbe((char)((uVar15 & 0xffffff00) >> 0x18)); | |
EXT_4010_write_data_out = (char)uVar14; | |
uVar12 = DAT_INTMEM_3b; | |
FUN_CODE_adbe((char)(uVar14 >> 0x18)); //FIXME: Missing arguments? | |
EXT_4010_write_data_out = uVar12; //FIXME: Weird ordering? [setter before call] | |
// Endianess swap? | |
EXT_4010_write_data_out = DAT_EXTMEM_c015; | |
EXT_4010_write_data_out = DAT_EXTMEM_c014; | |
// Endianess swap? | |
EXT_4010_write_data_out = DAT_EXTMEM_c017; | |
EXT_4010_write_data_out = DAT_EXTMEM_c016; | |
} | |
//FIXME: Interesting! So this can also be set later! | |
write_volatile_1(EXT_4024_data_out_length,8); | |
//FIXME: Is this a busy / ready flag maybe? | |
29.6 = 1; | |
return; | |
} | |
// FF ?? BB ... | |
// FF ?? FB | |
if ((BYTE_INTMEM_9c == 0xbb) || (BYTE_INTMEM_9c == 0xfb)) { | |
28.6 = 0; | |
write_volatile_1(DAT_EXTMEM_803e,0); | |
// FF ?? BB ... | |
if (BYTE_INTMEM_9c == 0xbb) { | |
// FF ?? BB 00 | |
if (BYTE_INTMEM_9d == 0) { | |
FUN_CODE_01d2(uVar12); | |
26.0 = 0; | |
28.6 = 1; | |
return; | |
} | |
BYTE_INTMEM_a1 = BYTE_INTMEM_9d; | |
} | |
//FIXME: !!!! These are jumptable handlers! everything after this might be broken | |
if (26.1 == 0) { | |
FUN_CODE_1f9f(BYTE_INTMEM_a1,uVar12); | |
} else { | |
FUN_CODE_1f9f(BYTE_INTMEM_a1,uVar12); | |
} | |
} | |
//FIXME: ------------------------------ Potentially broken from here because of jumptables | |
... This used to be part of the previous scope.. which no longer exists ... | |
This function needs to be rewritten (essentially) from scratch. | |
write_volatile_1(DAT_EXTMEM_40b8,EXT_MEM_0x803e); //FIXME: The second argument came from `undefined *puVar23;` (why ptr?) | |
uVar12 = read_volatile_1(EXT_4010_write_data_out); | |
write_volatile_1(DAT_EXTMEM_40b9,uVar12); | |
do { | |
bVar18 = read_volatile_1(DAT_EXTMEM_40c0); | |
} while ((bVar18 & 3) != 1); | |
write_volatile_1(DAT_EXTMEM_8029,2); | |
return; | |
} | |
uVar13 = (uint3)(uVar14 >> 8); | |
// FF ?? F1 | |
if (BYTE_INTMEM_9c == 0xf1) { | |
28.6 = 0; | |
if (26.1 == 0) { | |
write_volatile_1(DAT_EXTMEM_8093,0x30); | |
uVar12 = (undefined)(((uint)uVar13 << 8) >> 0x18); | |
FUN_CODE_ec24(uVar12); | |
write_volatile_1(DAT_EXTMEM_c006,1); | |
DAT_INTMEM_5d = 0; | |
FUN_CODE_0196(2,uVar12); | |
write_volatile_1(DAT_EXTMEM_c006,0); | |
} else { | |
write_volatile_1(DAT_EXTMEM_8093,0x10); | |
uVar12 = (undefined)(((uint)uVar13 << 8) >> 0x18); | |
FUN_CODE_ec24(uVar12); | |
write_volatile_1(DAT_EXTMEM_803d,0); | |
write_volatile_1(DAT_EXTMEM_c006,1); | |
DAT_INTMEM_5d = 0; | |
FUN_CODE_0196(0,uVar12); | |
write_volatile_1(DAT_EXTMEM_c006,0); | |
} | |
27.2 = 1; | |
26.0 = 1; | |
DAT_INTMEM_99 = 0; | |
DAT_INTMEM_98 = 0; | |
write_volatile_1(DAT_EXTMEM_4084,9); | |
27.0 = 0; | |
if (DAT_INTMEM_92 != 0x12) { | |
FUN_CODE_ab79(); | |
} | |
FUN_CODE_018c(); | |
DAT_INTMEM_98 = 0; | |
DAT_INTMEM_99 = 0; | |
return; | |
} | |
// FF ?? 22 | |
if (BYTE_INTMEM_9c == 0x22) { | |
// FF ?? 22 00 | |
if (BYTE_INTMEM_9d == 0) { | |
FUN_CODE_01eb((char)(((uint)uVar13 << 8) >> 0x18)); | |
return; | |
} | |
// FF ?? 22 FF | |
if (BYTE_INTMEM_9d == 0xff) { | |
// FF ?? 22 FF 6E | |
if (BYTE_INTMEM_9e == 0x6e) { | |
DAT_EXTMEM_c031 &= ~(0xC0 | 0x8); | |
DAT_EXTMEM_c039 = DAT_EXTMEM_80ad | 4 | 1; | |
DAT_EXTMEM_c0b0 = 0x00; | |
DAT_EXTMEM_c0ef = 0x00; | |
} | |
FUN_CODE_01aa((char)(((uint)uVar13 << 8) >> 24)); | |
DAT_INTMEM_4a = 0; | |
do { | |
bVar22 = 0x80 + EXTMEM[0xC000 | BYTE_INTMEM_9e]; | |
bVar18 = bVar22 + DAT_INTMEM_4c; | |
int x = DAT_INTMEM_4b - ((CARRY1(bVar22,DAT_INTMEM_4c) << 7) >> 7); | |
DAT_INTMEM_4c += bVar22; | |
DAT_INTMEM_4b = (0x80 <= EXTMEM[0xC000 | BYTE_INTMEM_9e]) + x; | |
DAT_INTMEM_4a += 1; | |
} while (DAT_INTMEM_4a != 100); | |
FUN_CODE_1d0c(0); | |
// FF ?? 22 FF 6E | |
if (BYTE_INTMEM_9e == 0x6e) { | |
write_volatile_1(DAT_EXTMEM_c0ef,1); | |
} | |
write_volatile_1(EXT_4024_data_out_length,2); | |
write_volatile_1(EXT_4010_write_data_out,bVar18); | |
write_volatile_1(EXT_4010_write_data_out,0); | |
DAT_INTMEM_4a = bVar18; | |
29.6 = 1; | |
return; | |
} | |
return; | |
} | |
// FF ?? 33 | |
if (BYTE_INTMEM_9c == 0x33) { | |
// FF ?? 33 00 | |
if (BYTE_INTMEM_9d == 0) { | |
// FF ?? 33 00 ?? ?? ?? ?? ?? 01 | |
if (BYTE_INTMEM_a3 == 0x01) { | |
DAT_INTMEM_4a = 0x00; | |
DAT_INTMEM_4b = 0x00; | |
DAT_INTMEM_4c = 0x1e; | |
// FF ?? 33 00 ?? ?? ?? ?? ?? 02 | |
} else if (BYTE_INTMEM_a3 == 0x02) { | |
DAT_INTMEM_4a = 0x1e; | |
DAT_INTMEM_4b = 0x00; | |
DAT_INTMEM_4c = 0x3c; | |
// FF ?? 33 00 ?? ?? ?? ?? ?? 03 | |
} else if (BYTE_INTMEM_a3 == 0x03) { | |
DAT_INTMEM_4a = 0x3c; | |
DAT_INTMEM_4b = 0x00; | |
DAT_INTMEM_4c = 0x5a; | |
// FF ?? 33 00 ?? ?? ?? ?? ?? 04 | |
} else if (BYTE_INTMEM_a3 == 0x04) { | |
DAT_INTMEM_4a = 0x5a; | |
DAT_INTMEM_4b = 0x00; | |
DAT_INTMEM_4c = 0x78; | |
// FF ?? 33 00 ?? ?? ?? ?? ?? 05 | |
} else if (BYTE_INTMEM_a3 == 0x05) { | |
DAT_INTMEM_4a = 0x78; | |
DAT_INTMEM_4b = 0x00; | |
DAT_INTMEM_4c = 0x80; | |
// FF ?? 33 00 ?? ?? ?? ?? ?? ?? | |
} else { | |
uVar14 = uVar15 & 0xff000000; | |
FUN_CODE_27e2(0,0x24,5); | |
} | |
while (true) { | |
cVar21 = DAT_INTMEM_4b - (((DAT_INTMEM_4a < DAT_INTMEM_4c) << 7) >> 7); | |
if (((cVar21 != 0) << 7) >= 0) { | |
break; | |
} | |
uVar15 = uVar14 & 0xffffff00; | |
uVar14 = uVar15 | DAT_INTMEM_4a; | |
FUN_CODE_01f0(-cVar21,(char)(uVar15 >> 0x18)); | |
write_volatile_1(EXT_4010_write_data_out,(char)uVar14); | |
DAT_INTMEM_4a += 1; | |
} | |
write_volatile_1(EXT_4024_data_out_length,0x1e); | |
29.6 = 1; | |
return; | |
} | |
return; | |
} | |
// Error handling | |
// 5 = SPC_SK_ILLEGAL_REQUEST [from sg_utils.. why can't I find this in the spec?] ? | |
// sg_utils also does: if ((0x20 == ssh.asc) && (0x0 == ssh.ascq)) { ret = SG_LIB_CAT_INVALID_OP; } | |
// So this is almost certainly: set_error(ASCQ, ASC, SK); | |
FUN_CODE_27e2(0,0x20,5); | |
return; | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Some BCD (4 bit) to decimal | |
// Converts 0x88 to 88 | |
// Converts 0x10 to 10 | |
byte FUN_CODE_adbe_HEX_to_DEC(byte param_1) { | |
return (param_1 >> 4) * 10 + (param_1 & 0xf); | |
} | |
undefined1 * FUN_CODE_1f85_copy_byte_and_return_advanced_dst_ptr(undefined1 *src,undefined1 *dst) { | |
*dst = *src; | |
return dst + 1; | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Actually part of the ATA function | |
//FIXME: Missing a bunch of code | |
void FUN_CODE_2446_find_some_command_handlers(byte param_1) { | |
byte bVar1; | |
char cVar2; | |
// INQUIRY | |
if (9A_cdb_operation_code == 0x12) { | |
FUN_CODE_27e2_error_tracking_probably(SPC_SK_NO_SENSE,0,0); | |
FUN_CODE_33cd(); | |
return; | |
} | |
// GET CONFIGURATION | |
if (9A_cdb_operation_code == 0x46) { | |
FUN_CODE_27e2_error_tracking_probably(SPC_SK_ILLEGAL_REQUEST,0x24,0); | |
return; | |
} | |
// GET EVENT STATUS NOTIFICATION | |
if (9A_cdb_operation_code == 0x4a) { | |
FUN_CODE_27e2_error_tracking_probably(SPC_SK_ILLEGAL_REQUEST,0x24,0); | |
return; | |
} | |
// REQUEST SENSE | |
if (9A_cdb_operation_code == 0x03) { | |
FUN_CODE_552f(); | |
return; | |
} | |
if (29.2 == 1) { | |
29.2 = 0; | |
2a.5 = 0; | |
FUN_CODE_27e2_error_tracking_probably(SPC_SK_UNIT_ATTENTION,0x29,0); | |
return; | |
} | |
// START STOP UNIT | |
if (9A_cdb_operation_code == 0x1b) { | |
// 00 = 0/4 | |
// 01 = 1/5 | |
// 10 = 2/6 LOEJ | |
// 11 = 3/7 LOEJ+START | |
// 1xx = NO_FLUSH | |
// 1xxx = Reserved | |
// ####xxxx = Power condition | |
// Check if only LOEJ is set = Eject | |
if (BYTE_INTMEM_9e == 2) { | |
2a.5 = 0; | |
FUN_CODE_27e2_error_tracking_probably(SPC_SK_NO_SENSE,0,0); | |
} | |
bool c1 = FUN_CODE_015a(); | |
if (c1) { | |
// Check if only LOEJ + START are set = Load | |
if (BYTE_INTMEM_9e == 3) { | |
FUN_CODE_27e2_error_tracking_probably(SPC_SK_NO_SENSE,0,0); | |
return; | |
} | |
} | |
bool c2 = FUN_CODE_015f(); | |
if (c2) { | |
// Check if only LOEJ is set = Eject | |
if (BYTE_INTMEM_9e == 2) { | |
FUN_CODE_27e2_error_tracking_probably(SPC_SK_NO_SENSE,0,0); | |
return; | |
} | |
} | |
} | |
// If this is not PREVENT ALLOW MEDIUM REMOVAL, do some extra stuff | |
// FIXME: Why is this special? | |
if (9A_cdb_operation_code != 0x1e) { | |
if (2a.5 == 1) { | |
2a.5 = 0; | |
FUN_CODE_27e2_error_tracking_probably(SPC_SK_UNIT_ATTENTION,0x28,0); | |
return; | |
} | |
} | |
bool a = (9A_cdb_operation_code == 0x1e) || // PREVENT ALLOW MEDIUM REMOVAL | |
(9A_cdb_operation_code == 0x5a) || // MODE SENSE (10) | |
(9A_cdb_operation_code == 0x55) || // MODE SELECT (10) | |
(9A_cdb_operation_code == 0xbd) || // MECHANISM STATUS | |
(9A_cdb_operation_code == 0x1b); // START STOP UNIT | |
bool c = (9A_cdb_operation_code == 0xa3) && ((BYTE_INTMEM_a4 & 0x3f) == 6); // SEND KEY with ??? | |
bool b = (9A_cdb_operation_code == 0xa4) && ((BYTE_INTMEM_a4 & 0x3f) == 8); // REPORT KEY with ??? | |
bool d = (9A_cdb_operation_code == 0xff) || // Vendor specific | |
(9A_cdb_operation_code == 0x23) || // READ FORMAT CAPACITIES | |
(9A_cdb_operation_code == 0x46); // GET CONFIGURATION | |
if (a || b || c || d) { | |
goto LAB_CODE_2572; | |
} else { | |
if (BYTE_INTMEM_a8 == 0) { | |
bVar1 = read_volatile_1(DAT_EXTMEM_8050); | |
if ((bVar1 >> 6 & 1) != 1) { | |
FUN_CODE_27e2_error_tracking_probably(SPC_SK_NOT_READY,0x3a,0); | |
return; | |
} | |
} | |
cVar2 = read_volatile_1(DAT_EXTMEM_8026); | |
if (cVar2 != 0) { | |
write_volatile_1(DAT_EXTMEM_8026,0); | |
} | |
cVar2 = read_volatile_1(DAT_EXTMEM_8037); | |
if ((cVar2 != 1) && (9A_cdb_operation_code != 0)) { | |
DAT_EXTMEM_8081 |= 0x8; | |
FUN_CODE_01a5(); | |
DAT_EXTMEM_8081 &= ~0x8; | |
2c.5 = 0; | |
FUN_CODE_abe6(1); | |
} | |
} | |
LAB_CODE_2572: | |
FUN_CODE_27e2_error_tracking_probably(SPC_SK_NO_SENSE,0,0); | |
// READ (10) | |
if (9A_cdb_operation_code == 0x28) { | |
2c.4 = 0; | |
FUN_CODE_420e(); | |
return; | |
} | |
// READ (12) | |
if (9A_cdb_operation_code == 0xa8) { | |
2c.4 = 1; | |
FUN_CODE_420e(); | |
return; | |
} | |
// READ CD | |
if (9A_cdb_operation_code == 0xbe) { | |
FUN_CODE_4518(); | |
return; | |
} | |
// D5=??? | |
// READ CD MSF | |
if ((9A_cdb_operation_code == 0xd5) || | |
(9A_cdb_operation_code == 0xb9)) { | |
FUN_CODE_47e2(); | |
return; | |
} | |
/* WARNING: Subroutine does not return */ | |
//FIXME: This is the instruction after the call into the handler. | |
// So the return address is the jump table address! | |
// Reflect using switch/case? | |
void* jumptable = 0x25b1; // CODE:25b1 | |
#if 0 | |
{ | |
CODE:2666: handle_00h__TEST UNIT READY # table entry at CODE:0x25B1 | |
CODE:266A: handle_01h__??? # table entry at CODE:0x25B4 | |
CODE:2662: handle_1Bh__START STOP UNIT # table entry at CODE:0x25B7 | |
CODE:267B: handle_1Eh__PREVENT ALLOW MEDIUM REMOVAL # table entry at CODE:0x25BA | |
CODE:2632: handle_23h__READ FORMAT CAPACITIES # table entry at CODE:0x25BD | |
CODE:2626: handle_25h__READ CAPACITY # table entry at CODE:0x25C0 | |
CODE:264E: handle_2Bh__SEEK (10) # table entry at CODE:0x25C3 | |
CODE:263A: handle_42h__??? # table entry at CODE:0x25C6 | |
CODE:263E: handle_43h__READ TOC/PMA/ATIP # table entry at CODE:0x25C9 | |
CODE:2636: handle_44h__??? # table entry at CODE:0x25CC | |
CODE:2612: handle_45h__??? # table entry at CODE:0x25CF | |
CODE:261E: handle_47h__??? # table entry at CODE:0x25D2 | |
CODE:260E: handle_4Bh__??? # table entry at CODE:0x25D5 | |
CODE:265E: handle_4Eh__??? # table entry at CODE:0x25D8 | |
CODE:262A: handle_51h__READ DISC INFORMATION # table entry at CODE:0x25DB | |
CODE:2642: handle_52h__READ TRACK INFORMATION # table entry at CODE:0x25DE | |
CODE:2606: handle_55h__MODE SELECT (10) # table entry at CODE:0x25E1 | |
CODE:260A: handle_5Ah__MODE SENSE (10) # table entry at CODE:0x25E4 | |
CODE:2652: handle_A3h__SEND KEY # table entry at CODE:0x25E7 | |
CODE:2646: handle_A4h__REPORT KEY # table entry at CODE:0x25EA | |
CODE:2618: handle_A5h__??? # table entry at CODE:0x25ED | |
CODE:2656: handle_A7h__SET READ AHEAD # table entry at CODE:0x25F0 | |
CODE:262E: handle_ADh__READ DISC STRUCTURE # table entry at CODE:0x25F3 | |
CODE:264A: handle_BAh__??? # table entry at CODE:0x25F6 | |
CODE:265A: handle_BBh__SET CD SPEED # table entry at CODE:0x25F9 | |
CODE:2622: handle_BDh__MECHANISM STATUS # table entry at CODE:0x25FC | |
CODE:266E: handle_FFh__??? # table entry at CODE:0x25FF | |
} | |
#endif | |
FUN_CODE_1f9f_command_handler_jumptable_acceptor(9A_cdb_operation_code,jumptable); | |
return; | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This stuff is in bank1 | |
#define BUSY_WAIT() { \ | |
uint8_t tmp; \ | |
do { \ | |
tmp = read_volatile_1(DAT_EXTMEM_4000); \ | |
} while (tmp & 0x80); \ | |
} | |
// CODE:ec00 | |
typedef union { | |
uint8_t b[4]; | |
struct { | |
uint16_t chip_id; | |
uint8_t block_erase; //FIXME: maybe? | |
uint8_t block_size; //FIXME: maybe? | |
}; | |
} FlashType; | |
FlashType flash_types[8] = { | |
{ 0xDAC1, 0x00,0x00 }, // AE29F1008, | |
// W29C010, W29C011, | |
// W29EE010, W29EE011, W29EE012 | |
{ 0x1FD5, 0x00,0x00 }, // AT29C010A | |
{ 0xBFB5, 0x01,0x10 }, // SST39SF010A | |
{ 0xBFD5, 0x01,0x10 }, // SST39VF010 | |
{ 0x0120, 0x01,0x40 }, // AM29F010, AM29F010B, NX29F010, TMS29F010 | |
{ 0x1F05, 0x01,0x20 }, // AT49BV001, AT49BV001A, AT49BV001AN, AT49BV001N, | |
// AT49F001, AT49F001A, AT49F001AN, AT49F001N | |
// AT49LV001, AT49LV001N | |
{ 0x374C, 0x01,0x00 }, // A29001U, A290011U | |
{ 0x37A1, 0x01,0x00 }, // A29001T, A290011T, A29512A | |
// Followed by 0xFFFF | |
}; | |
static inline void flash_type1(uint8_t bVar6) { | |
//FIXME: Isn't this always true? bVar6 is also 0x100 aligned. | |
// Shouldn't these always match? | |
// Would only be relevant if it's misaligned in the beginning. | |
assert(DAT_INTMEM_97 == 0) | |
// If we are in the first byte of a 0x100 block, we also have to erase the chip | |
if (DAT_INTMEM_97 == 0) { | |
bVar8 = flash_types[bVar2].b[3]; | |
// If block size is smaller than 0x100, then check our offset in small block | |
if (bVar8 != 0) { | |
bVar8 = DAT_INTMEM_96 % bVar8; | |
} | |
if (bVar8 == 0) { | |
// Flash Chip Erase | |
write_volatile_1(DAT_EXTMEM_5555,0xaa); | |
write_volatile_1(DAT_EXTMEM_2aaa,0x55); | |
write_volatile_1(DAT_EXTMEM_5555,0x80); | |
write_volatile_1(DAT_EXTMEM_5555,0xaa); | |
write_volatile_1(DAT_EXTMEM_2aaa,0x55); | |
*(undefined *)((ushort)DAT_INTMEM_96 << 8) = 0x30; | |
// Check if completed? | |
while ((*(byte *)((ushort)DAT_INTMEM_96 << 8) & 0x80) != 0x80); | |
} | |
} | |
// Appears to write 256 bytes?! (aligns bVar6 to next 0x100 boundary) | |
for(int i = 0; i < 0x100; i++) { | |
// Flash Byte Program | |
write_volatile_1(DAT_EXTMEM_5555,0xaa); | |
write_volatile_1(DAT_EXTMEM_2aaa,0x55); | |
write_volatile_1(DAT_EXTMEM_5555,0xa0); | |
BUSY_WAIT(); | |
bVar8 = read_volatile_1(DAT_EXTMEM_400c); | |
*(byte*)(DAT_INTMEM_96_97 + bVar6) = bVar8; | |
while ((bVar8 & 0x80) != (*(byte *)(DAT_INTMEM_96_97 + bVar6) & 0x80)); | |
bVar6 += 1; | |
} | |
assert(bVar6 == 0x00); | |
return bVar6; | |
} | |
// 128-byte sector based programming; from https://media.digikey.com/pdf/Data%20Sheets/Atmel%20PDFs/AT29C010A.pdf | |
// | |
// > Reprogramming the AT29C010A is performed on a sector basis; | |
// > 128 bytes of data are loadedinto the device and then simultaneously | |
// > programmed. | |
// > | |
// > During a reprogram cycle, the address locations and 128 bytes of data | |
// > are internally latched, freeing the address and data bus for other | |
// > operations. | |
// > Following the initiation ofa program cycle, the device will | |
// > automatically erase the sector and then program the latched data using | |
// > an internal control timer. | |
// > The end of a program cycle can be detected by DATA polling of I/O7. | |
// > Once the end of a program cycle has been detected, a new access for a | |
// > read or program can begin. | |
// | |
static inline uint8_t flash_type_non1(uint8_t bVar6) { | |
// Appears to write 256 bytes?! (aligns bVar6 to next 0x100 boundary) | |
for (int loop = 0; loop < 2; loop++) { | |
// Flash Byte Program | |
write_volatile_1(DAT_EXTMEM_5555,0xaa); | |
write_volatile_1(DAT_EXTMEM_2aaa,0x55); | |
write_volatile_1(DAT_EXTMEM_5555,0xa0); | |
// Appears to write 128 bytes?! (aligns bVar6 to next 0x80 boundary) | |
for(int i = 0; i < 0x80; i++) { | |
BUSY_WAIT(); | |
bVar1 = read_volatile_1(DAT_EXTMEM_400c); | |
*(byte*)(DAT_INTMEM_96_97 + bVar6) = bVar1; | |
bVar6++; | |
} | |
assert(bVar6 == 0x80); | |
// Check if the last byte was written? | |
while ((bVar1 & 0x80) != (*(byte *)(DAT_INTMEM_96_97 + bVar6) & 0x80)); | |
} | |
assert(bVar6 == 0x00); | |
return bVar6; | |
} | |
// Spin-loop to waste CPU cycles | |
static inline void spin() { | |
volatile uint16_t cVar34 = 0x0000; | |
do { | |
volatile uint8_t cVar7 = 0x00; | |
while (cVar7++ != 32); | |
cVar34 += 1; | |
} while(cVar34 < 0xFFFF); | |
} | |
// bank1 | |
//FIXME: Missing all volatile writes to SFR-bits | |
void UndefinedFunction_e800(void) { | |
byte bVar1; | |
byte bVar2; | |
char cVar4; | |
char cVar5; | |
byte bVar6; | |
char cVar7; | |
byte bVar8; | |
byte bVar9; | |
// Flash Product ID Entry | |
write_volatile_1(DAT_EXTMEM_5555,0xaa); | |
write_volatile_1(DAT_EXTMEM_2aaa,0x55); | |
write_volatile_1(DAT_EXTMEM_5555,0x90); | |
// Read product ID? | |
//FIXME: Probably some JEDEC standard | |
cVar5 = read_volatile_1(UNK_EXTMEM_0000); | |
DAT_INTMEM_51 = read_volatile_1(UNK_EXTMEM_0001); | |
// Flash Product ID Exit | |
write_volatile_1(DAT_EXTMEM_5555,0xaa); | |
write_volatile_1(DAT_EXTMEM_2aaa,0x55); | |
write_volatile_1(DAT_EXTMEM_5555,0xf0); | |
// Look for this flash in the list of flashes | |
for(int i = 0; i < 8; i++) { | |
if (flash_types[i].b[0] == cVar5) && (flash_types[i].b[1] == DAT_INTMEM_51) { | |
break; | |
} | |
} | |
// Remember which entry we matched | |
bVar2 = i; | |
BUSY_WAIT(); | |
//FIXME: Set some address | |
write_volatile_1(DAT_EXTMEM_4005,0x03); | |
write_volatile_1(DAT_EXTMEM_4006,0x33); | |
write_volatile_1(DAT_EXTMEM_4007,0x00); | |
// Write back flash information *somewhere* | |
write_volatile_1(DAT_EXTMEM_400c,0x33); | |
write_volatile_1(DAT_EXTMEM_400c,bVar2); // flash type index | |
write_volatile_1(DAT_EXTMEM_400c,cVar5); // product_id[0] | |
write_volatile_1(DAT_EXTMEM_400c,DAT_INTMEM_51); // product_id[0] | |
write_volatile_1(DAT_EXTMEM_400c,0x33); | |
// If we found a known flash | |
if (bVar2 < 8) { | |
// Set offset to write in block to zero | |
bVar6 = 0; | |
// Main writer loop which allows up to 100 retries | |
DAT_INTMEM_51 = 0; | |
while(DAT_INTMEM_51 <= 100) { | |
// Stop if we ran out of data to process | |
if (DAT_INTMEM_88_89_8a == 0) { | |
break; | |
} | |
// Bank select for flash write | |
//FIXME: This code is not mirrored in bank0. | |
// Wouldn't the flasher crash because it removes its own code? | |
if (DAT_INTMEM_95 == 0) { | |
P1.0 = 0; | |
} else { | |
P1.0 = 1; | |
} | |
BUSY_WAIT(); | |
// Set address for writing | |
write_volatile_1(DAT_EXTMEM_4007,DAT_INTMEM_97); | |
write_volatile_1(DAT_EXTMEM_4006,DAT_INTMEM_96); | |
write_volatile_1(DAT_EXTMEM_4005,DAT_INTMEM_95); | |
// Block based flash or not? | |
if (flash_types[bVar2].b[2] == 0x01) { | |
bVar6 = flash_type1(bVar6); | |
} else { | |
bVar6 = flash_type_non1(bVar6); | |
} | |
BUSY_WAIT(); | |
// Set address for readback | |
write_volatile_1(DAT_EXTMEM_4007,DAT_INTMEM_97); | |
write_volatile_1(DAT_EXTMEM_4006,DAT_INTMEM_96); | |
write_volatile_1(DAT_EXTMEM_4005,DAT_INTMEM_95); | |
// Verify the block was written successfully | |
while( true ) { | |
BUSY_WAIT(); | |
cVar5 = read_volatile_1(DAT_EXTMEM_400c); | |
if (*(char*)(DAT_INTMEM_96_97 + bVar6) != cVar5) { | |
// Increase error count and retry | |
DAT_INTMEM_51 += 1; | |
break; | |
} | |
bVar6 += 1; | |
// if we reached the end of a 0x100 block.. | |
if (bVar6 == 0) { | |
//FIXME: Missing wrap into _95 / _88 and overflow? | |
DAT_INTMEM_95_96_97 += 0x100; | |
DAT_INTMEM_88_89_8a -= 0x100; | |
break; | |
} | |
} | |
} | |
} | |
//FIXME: What is this? | |
P1.5 = 1; | |
if (27.5 != 0) { | |
27.5 = 0; | |
write_volatile_1(DAT_EXTMEM_4002,0x80); | |
if (DAT_INTMEM_51 <= 100) { | |
// Flash OK | |
write_volatile_1(DAT_EXTMEM_401b,0x50); | |
write_volatile_1(DAT_EXTMEM_4011,0x54); | |
} else { | |
// Too many errors | |
write_volatile_1(DAT_EXTMEM_401b,0x51); | |
write_volatile_1(DAT_EXTMEM_4011,0x54); | |
} | |
write_volatile_1(DAT_EXTMEM_4014,0); | |
write_volatile_1(DAT_EXTMEM_4015,0); | |
write_volatile_1(DAT_EXTMEM_4021,8); | |
} | |
if (DAT_INTMEM_51 <= 100) { | |
// Flash OK | |
for(int i = 0; i < 6; i++) { | |
write_volatile_1(DAT_EXTMEM_c006,1); | |
spin(); | |
write_volatile_1(DAT_EXTMEM_c006,0); | |
spin(); | |
} | |
} else { | |
// Too many errors | |
write_volatile_1(DAT_EXTMEM_c006,0); | |
} | |
P1.6 = 1; | |
write_volatile_1(DAT_EXTMEM_403b,0); | |
write_volatile_1(DAT_EXTMEM_c020,0); | |
write_volatile_1(DAT_EXTMEM_c079,0); | |
thunk_FUN_CODE_002e(); | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Note: These inline functions do not exist in the actual code! | |
static inline void busy_loop(void) { | |
byte cVar7 | |
do { | |
cVar7 = read_volatile_1(4000_master_status); | |
} while (cVar7 & 0x80); | |
} | |
// src is an EXTMEM offset | |
static inline uint8_t copy(const uint8_t a, const uint8_t b, uint8_t* src) { | |
INTMEM_4e_loop_counter_lo = a; | |
do { | |
busy_loop(); | |
write_volatile_1(400c_master_data, src[INTMEM_4e_loop_counter_lo]); | |
INTMEM_4e_loop_counter_lo++; | |
} while(INTMEM_4e_loop_counter_lo != b) | |
return INTMEM_4e_loop_counter_lo; | |
} | |
static inline uint8_t set(const uint8_t a, const uint8_t b, uint8_t value) { | |
INTMEM_4e_loop_counter_lo = a; | |
do { | |
busy_loop(); | |
write_volatile_1(400c_master_data, value); | |
INTMEM_4e_loop_counter_lo++; | |
} while (INTMEM_4e_loop_counter_lo != b); | |
return INTMEM_4e_loop_counter_lo; | |
} | |
void FUN_CODE_9e9d_initialize_some_buffered_values(void) { | |
// 0x0 - 0x1FF | |
FUN_CODE_a7bf_master_skip16_and_write8(identify_data_start._0_1_,0); | |
copy(0x01, 0xBE, &identify_data_start); //FIXME: add addr of identify data | |
set(0xBE, 0x100, 0x00); | |
set(0x00, 0x100, 0x00); | |
// 0x200 - 0x25F ... | |
HIFLG.2 = FUN_CODE_a7bf_master_skip16_and_write8(1701_inquiry_data,0x200); | |
copy(0x01, 0x60, &1701_inquiry_data); | |
// ... 0x260 - 0x2EF | |
// ... 0x2F0 - 0x37F | |
for(int i = 0; i < 2; i++) { | |
copy(0x00, 0x0C, &BYTE_ARRAY_CODE_1761); | |
copy(0x00, 0x08, &BYTE_ARRAY_CODE_176D); | |
copy(0x00, 0x10, &BYTE_ARRAY_CODE_1775); | |
copy(0x00, 0x1C, &BYTE_ARRAY_CODE_1785); | |
copy(0x00, 0x0C, &BYTE_ARRAY_CODE_17A1); | |
copy(0x00, 0x0A, &BYTE_ARRAY_CODE_17AD); | |
copy(0x00, 0x0C, &BYTE_ARRAY_CODE_17B7); | |
copy(0x00, 0x1A, &BYTE_ARRAY_CODE_17C3); | |
copy(0x00, 0x14, &auth_page_look_alike_contest_winner); //FIXME: Add address | |
} | |
unsigned uVar2 = read_volatile_1(DAT_EXTMEM_8002); | |
char cVar6 = read_volatile_1(DAT_EXTMEM_8003); | |
byte bVar3 = read_volatile_1(DAT_EXTMEM_8004); | |
unsigned uVar4 = read_volatile_1(DAT_EXTMEM_8005); | |
// Looks like DAT_INTMEM_8b8c = FUN_CODE_1efe(DAT_EXTMEM_8002800380048005 + 0x4300, 0x0A) | |
uVar5 = FUN_CODE_1efe(CONCAT13(uVar2,CONCAT12(cVar6 - (((0xbc < bVar3) << 7) >> 7), CONCAT11(bVar3 + 0x43,uVar4))),10); | |
DAT_INTMEM_8b = (byte)((ushort)uVar5 >> 8); | |
DAT_INTMEM_8c = (byte)uVar5; | |
// 0x2CE - 0x2CF (in previous array [0] offset 0x6E) | |
FUN_CODE_a7bf_master_skip16_and_write8(DAT_INTMEM_8b,0x2ce); | |
FUN_CODE_a7bf_master_skip16_and_write8(DAT_INTMEM_8c,0x2cf); | |
// 0x35E - 0x35F (in previous array [1] offset 0x6E) | |
FUN_CODE_a7bf_master_skip16_and_write8(DAT_INTMEM_8b,0x35e); | |
FUN_CODE_a7bf_master_skip16_and_write8(DAT_INTMEM_8c,0x35f); | |
// 0x380 - 0x40F | |
// Note: Part [2] of previous arrays! | |
// Offset 0x6E would be at 0x3EE - 0x3EF (not written?) | |
FUN_CODE_a7bf_master_skip16_and_write8(DAT_CODE_17f1,0x380); | |
copy(0x01, 0x0C, &DAT_CODE_17f1); | |
copy(0x00, 0x08, &DAT_CODE_17fd); | |
copy(0x00, 0x10, &DAT_CODE_1805); | |
copy(0x00, 0x1C, &SUB_CODE_1815); | |
copy(0x00, 0x0C, &DAT_CODE_1831); | |
copy(0x00, 0x0A, &DAT_CODE_183d); | |
copy(0x00, 0x0C, &DAT_CODE_1847); | |
copy(0x00, 0x1A, &DAT_CODE_1853); | |
copy(0x00, 0x14, &DAT_CODE_186d); | |
// 0x410 - 0x417 | |
FUN_CODE_a7bf_master_skip16_and_write8(0,0x410); | |
set(0x01, 0x08, 0x00); | |
// 0x418 - 0x46F | |
HIFLG.2 = FUN_CODE_a7bf_master_skip16_and_write8(DAT_CODE_1881,0x418); | |
copy(0x01, 0x58, &DAT_CODE_1881); | |
return; | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This is a misnomer. I'm not sure how to call it properly though. | |
// Changing it now is tricky as I use master in some files already. | |
void FUN_CODE_79a4_return_data_from_master_maybe(ushort param_1) { | |
// Calculate target address | |
BYTE_INTMEM_a6_a7 = DAT_EXTMEM_8004_8005 + param_1; // 8005 is loaded first | |
// Write some address | |
DAT_EXTMEM_4031 = DAT_EXTMEM_8003; | |
DAT_EXTMEM_4032 = BYTE_INTMEM_a6; | |
DAT_EXTMEM_4033 = BYTE_INTMEM_a7; | |
// If 8b8c is odd, make it even (round up) | |
DAT_INTMEM_8b8c += DAT_INTMEM_8b8c & 1; | |
// Write length for DMA? | |
write_volatile_1(DAT_EXTMEM_4035_dma_out_count_lo_maybe,DAT_INTMEM_8c); | |
write_volatile_1(DAT_EXTMEM_4034_dma_out_count_hi_exec_maybe,DAT_INTMEM_8b); | |
// Enable DMA? Or maybe something unrelated? | |
29.6_dma_out_enable_maybe = 1; | |
return; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment