Post Reply 
PS1 Disc Images
07-17-2017, 04:15 AM (This post was last modified: 08-06-2017 02:51 PM by MysticLord.)
Post: #1
PS1 Disc Images
Track: 2352 bytes

* Sync field (1 to 12)
12 bytes
00 ff ff ff ff ff ff ff ff ff ff 00

* Header field (13 to 16)
3 byte (00 02 00 starts sf.bin) minutes, seconds, sectors (consider it an address of sorts)
1 byte (02 starts sf.bin) mode
aa bb cc dd

* Subheader field (17 to 24)
4 bytes (00 00 08 00 starts sf.bin) file number (chpt 3), channel number (chpt 7), submode (chpt 2), coding info (chpts 4, 5, 6)
4 bytes (00 00 08 00 starts sf.bin) repeat
ee ff gg hh ii jj kk ll

note: file number is used to ID all sectors that belong to one and the same file.
note: submode is used for global attributes of a sector for termination of a file or record, and other stuff.
note: confing info is type of data located in the sector: data, audio, or video.
note: submode is a bit field
Code:
0x80 - End Of File (EOF)     - Last sector of a file, set to true
        0x40 - Real-Time Sector (RT) - Irrelevant for our purposes
        0x20 - Form (F)              - Form 1, set to false.  Form 2, set to true.
        0x10 - Trigger (T)           - Irrelevant for our purposes
        0x08 - Data (D)              - Set to true for program related data sectors (form bit must be false).
        0x04 - Audio (A)             - Set to true for audio sectors
        0x02 - Video (V)             - Set to true for video sectors
        0x01 - End Of Record (EOR)   - Set to 1 for last sector of a logical record
note: Either Data, Audio, or Video bit must be set to true except on empty or message sectors.

* Data field (25 to 2352)
2328 bytes

Code:
-Form 1:
        Bytes 25 to 2072: Data, contents depend on sector type
        Bytes 2073 to 2076: EDC field of 4 bytes
        Bytes 2077 to 2352: ECC field
    note: The EDC used is a 32-bit CRC on the data field defined as Byte 17 through Byte 2072.
    note: The EDC codeword must by divisible by the check polynomial.
    note: The least significant bit of a data byte is used first in the CRC mechanism.  The least significant bit of the EDC parity is located at bit 7 of byte 2076.
    note: The check polynomial is P(X) = (X^16 + x^15 + X^2 + 1) * (X^16 + x^2 + X + 1).

    -Form 2:
        Bytes 25 to 2348: Data, contents depend on sector type
        Bytes 2349 to 2352: EDC, same as used in form 1 but presumably on Bytes 17 through 2348.

***

xx-yy-zz

xx : minutes
yy : seconds
zz : sectors

***

Sectors are 2352 bytes long
Minutes start at 0
Seconds start at 2 for the first minute, 0 for the second minute
Sectors start at 0

Minutes end at ?? (68 is highest value seen)
Seconds end at 59 (60 is rolled over to 0 and increments the minutes)
Sectors end at 74 (75 is rolled over to 0 and increments the seconds)

***

First sector with directory data is sector 00,02,18 - located at 0xa560.

Contains:
B_CDATA
B_EFFDA
B_EFFECT
B_MDATA 04 01 32
B_PROG
B_SOUND
B_STAGE
B_STAGE2
MCHR
MESG
MHERO
MIMF
MOUT
MSOUND
MTONO
TITLE

layout

0x00 : 1 : length of identifier
0x01 : 1 : unused [number of sectors in extended attribute record]
0x02 : 4 : convert to base 10, sector where directory contents begins/is-contained(?), accounts for starting at minute 2 (this number * 2352 = address)
0x03 : 2 : parent directory [1 is root]
0x04 : * : ASCII char[], additional 0x00 to reach even number of bytes (have code check if value is below legit alphanumberic ascii value to delimit entries?)
0x05 : ? : Null padding byte, present if 0x04 is odd

SaGa Frontier
Code:
00 01 02          03    04                   05
01 00 16 00 00 00 01 00 00 00                   //???
07 00 44 32 04 00 01 00 42 5F 43 44 41 54 41 00 //B_CDATA
07 00 AD D5 03 00 01 00 42 5F 45 46 46 44 41 00 //B_EFFDA
08 00 57 49 04 00 01 00 42 5F 45 46 46 45 43 54 //B_EFFECT
07 00 32 01 04 00 01 00 42 5F 4D 44 41 54 41 00 //B_MDATA
06 00 44 8E 03 00 01 00 42 5F 50 52 4F 47       //B_PROG
07 00 6F C9 03 00 01 00 42 5F 53 4F 55 4E 44 00 //B_SOUND
07 00 EB AB 03 00 01 00 42 5F 53 54 41 47 45 00 //B_STAGE
08 00 A7 D7 03 00 01 00 42 5F 53 54 41 47 45 32 //B_STAGE2
04 00 A2 82 03 00 01 00 4D 43 48 52             //MCHR
04 00 4C F9 00 00 01 00 4D 45 53 47             //MESG
05 00 FD 82 03 00 01 00 4D 48 45 52 4F 00       //MHERO
04 00 5E F9 00 00 01 00 4D 49 4D 46             //MIMF
04 00 60 EA 00 00 01 00 4D 4F 55 54             //MOUT
06 00 BE F0 00 00 01 00 4D 53 4F 55 4E 44       //MSOUND
05 00 D8 EF 00 00 01 00 4D 54 4F 4E 4F 00       //MTONO
05 00 0C 6E 04 00 01 00 54 49 54 4C 45 00       //TITLE

***

This is repeated in sector immediately afterwards.

Second sector with directory data is sector 00,02,19 - located at 0xaE90.

***

This is repeated with switched endianness in next two sectors.
Sector 00,02,20
Sector 00,02,21

***

This is repeated with more information - including information on phyiscal files - in next one sectors. This is the definitive primary table.
Sector 00,02,22

note: if an secondary directory spans more than one sector, a given entry can't sit be split between sectors. The remainder of the sector is filled with zeros.
note: only the first 2 entries in a secondary directory include the root and current directory entries. Multi-sector secondary directories don't repeat the root and current directory at the beginning of each sector.

0x00 1 : R, the number of bytes in the record (which must be even)
0x01 1 : 0 [number of sectors in extended attribute record] //not used
0x02 8 : number of the first sector of file data or directory (zero for an empty file), as a both endian double word
0x03 8 : number of bytes of file data or length of directory, excluding the extended attribute record, as a both endian double word - by bytes, refers only to data portion of sector? //THIS IS KEY TO HANDLING MULTI-SECTOR DIRECTORIES
0x04 1 : number of years since 1900
0x05 1 : month, where 1=January, 2=February, etc.
0x06 1 : day of month, in the range from 1 to 31
0x07 1 : hour, in the range from 0 to 23
0x08 1 : minute, in the range from 0 to 59
0x09 1 : second, in the range from 0 to 59 (for DOS this is always an even number)
0x0a 1 : offset from Greenwich Mean Time, in 15-minute intervals, as a twos complement signed number, positive for time zones east of Greenwich, and negative for time zones west of Greenwich (DOS ignores this field)
0x0b 1 : flags, with bits as follows:
Code:
.
                  bit     value
                 ------  ------------------------------------------
                   1       0 for a norma1 file, 1 for a hidden file
                   2       0 for a file, 1 for a directory
                   4       0 [1 for an associated file]
                   8       0 [1 for record format specified]
                  10       0 [1 for permissions specified]
                  20       0
                  40       0
                  80       0 [1 if not the final record for the file]
0x0c 1 : 0 [file unit size for an interleaved file]
0x0d 1 : 0 [interleave gap size for an interleaved file]
0x0e 4 : 1, as a both endian word [volume sequence number]
0x0f 1 : N, the identifier length
0x10 N : identifier: files are terminated with 3B 31, directories are not
0x11 P : padding byte: if N is even, P = 1 and this field contains a zero; if N is odd, P = 0 and this field is omitted
0x12 6 : unspecified field for system use; must contain an even number of bytes
0x12 14 : Directories contain 00 00 00 00 8D 55 58 41, files contain 2A 00 2A 00 08 01 58 41, both end with 00 00 00 00 00 00

Code:
SCUS_942.30 record starts at 0xcdba in sagafrontier.bin.
   00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
00 01 02                      03                      04 05 06 07 08 09 0a 0b 0c 0d 0e          0f 10                                  11 12

30 00 16 00 00 00 00 00 00 16 00 08 00 00 00 00 08 00 62 01 13 0E 09 38 24 02 00 00 01 00 00 01 01 00                                     00 00 00 00 8D 55 58 41 00 00 00 00 00 00 //.(curr dir)
30 00 16 00 00 00 00 00 00 16 00 08 00 00 00 00 08 00 62 01 13 0E 09 38 24 02 00 00 01 00 00 01 01 01                                     00 00 00 00 8D 55 58 41 00 00 00 00 00 00 //..(root/parent dir)
36 00 44 32 04 00 00 04 32 44 00 10 00 00 00 00 10 00 62 01 13 0E 09 38 24 02 00 00 01 00 00 01 07 42 5F 43 44 41 54 41                   00 00 00 00 8D 55 58 41 00 00 00 00 00 00 //B_CDATA
36 00 AD D5 03 00 00 03 D5 AD 00 08 00 00 00 00 08 00 62 01 13 0E 09 38 24 02 00 00 01 00 00 01 07 42 5F 45 46 46 44 41                   00 00 00 00 8D 55 58 41 00 00 00 00 00 00 //B_EFFDA
38 00 57 49 04 00 00 04 49 57 00 68 00 00 00 00 68 00 62 01 13 0E 09 38 24 02 00 00 01 00 00 01 08 42 5F 45 46 46 45 43 54             00 00 00 00 00 8D 55 58 41 00 00 00 00 00 00 //B_EFFECT
36 00 32 01 04 00 00 04 01 32 00 40 00 00 00 00 40 00 62 01 13 0E 09 38 24 02 00 00 01 00 00 01 07 42 5F 4D 44 41 54 41                   00 00 00 00 8D 55 58 41 00 00 00 00 00 00 //B_MDATA
36 00 44 8E 03 00 00 03 8E 44 00 08 00 00 00 00 08 00 62 01 13 0E 09 38 24 02 00 00 01 00 00 01 06 42 5F 50 52 4F 47                   00 00 00 00 00 8D 55 58 41 00 00 00 00 00 00 //B_PROG
36 00 6F C9 03 00 00 03 C9 6F 00 08 00 00 00 00 08 00 62 01 13 0E 09 38 24 02 00 00 01 00 00 01 07 42 5F 53 4F 55 4E 44                   00 00 00 00 8D 55 58 41 00 00 00 00 00 00 //B_SOUND
36 00 EB AB 03 00 00 03 AB EB 00 28 00 00 00 00 28 00 62 01 13 0E 09 38 24 02 00 00 01 00 00 01 07 42 5F 53 54 41 47 45                   00 00 00 00 8D 55 58 41 00 00 00 00 00 00 //B_STAGE
38 00 A7 D7 03 00 00 03 D7 A7 00 28 00 00 00 00 28 00 62 01 13 0E 09 38 24 02 00 00 01 00 00 01 08 42 5F 53 54 41 47 45 32             00 00 00 00 00 8D 55 58 41 00 00 00 00 00 00 //B_STAGE2
34 00 A2 82 03 00 00 03 82 A2 00 10 00 00 00 00 10 00 62 01 13 0E 09 38 24 02 00 00 01 00 00 01 04 4D 43 48 52                         00 00 00 00 00 8D 55 58 41 00 00 00 00 00 00 //MCHR
34 00 4C F9 00 00 00 00 F9 4C 00 08 00 00 00 00 08 00 62 01 13 0E 09 38 24 02 00 00 01 00 00 01 04 4D 45 53 47                         00 00 00 00 00 8D 55 58 41 00 00 00 00 00 00 //MESG
34 00 FD 82 03 00 00 03 82 FD 00 20 00 00 00 00 20 00 62 01 13 0E 09 38 24 02 00 00 01 00 00 01 05 4D 48 45 52 4F                         00 00 00 00 8D 55 58 41 00 00 00 00 00 00 //MHERO
34 00 5E F9 00 00 00 00 F9 5E 00 E8 01 00 00 01 E8 00 62 01 13 0E 09 38 24 02 00 00 01 00 00 01 04 4D 49 4D 46                         00 00 00 00 00 8D 55 58 41 00 00 00 00 00 00 //MIMF
34 00 60 EA 00 00 00 00 EA 60 00 08 00 00 00 00 08 00 62 01 13 0E 09 38 24 02 00 00 01 00 00 01 04 4D 4F 55 54                         00 00 00 00 00 8D 55 58 41 00 00 00 00 00 00 //MOUT
36 00 BE F0 00 00 00 00 F0 BE 00 20 00 00 00 00 20 00 62 01 13 0E 09 38 24 02 00 00 01 00 00 01 06 4D 53 4F 55 4E 44                   00 00 00 00 00 8D 55 58 41 00 00 00 00 00 00 //MSOUND
34 00 D8 EF 00 00 00 00 EF D8 00 08 00 00 00 00 08 00 62 01 13 0E 09 38 24 02 00 00 01 00 00 01 05 4D 54 4F 4E 4F                         00 00 00 00 8D 55 58 41 00 00 00 00 00 00 //MTONO
3C 00 18 00 00 00 00 00 00 18 00 60 07 00 00 07 60 00 62 01 13 0E 00 20 24 00 00 00 01 00 00 01 0D 53 43 55 53 5F 39 34 32 2E 33 30 3B 31 2A 00 2A 00 08 01 58 41 00 00 00 00 00 00 //SCUS_942.30;1
3C 00 17 00 00 00 00 00 00 17 44 00 00 00 00 00 00 44 61 0C 0F 11 10 3A 24 00 00 00 01 00 00 01 0C 53 59 53 54 45 4D 2E 43 4E 46 3B 31 00 2A 00 2A 00 08 01 58 41 00 00 00 00 00 00 //SYSTEM.CNF;1 (0x3b 0x31 0x00)
34 00 0C 6E 04 00 00 04 6E 0C 00 08 00 00 00 00 08 00 62 01 13 0E 09 38 24 02 00 00 01 00 00 01 05 54 49 54 4C 45                         00 00 00 00 8D 55 58 41 00 00 00 00 00 00 //TITLE

01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60


Attached File(s)
.txt  discImageIO.txt (Size: 20.98 KB / Downloads: 1)
.txt  printout.txt (Size: 251.46 KB / Downloads: 1)
Find all posts by this user
Quote this message in a reply
07-20-2017, 03:15 AM (This post was last modified: 07-20-2017 03:27 AM by MysticLord.)
Post: #2
RE: PS1 Disc Images
Some things you should know about navigating disc images.

* When dealing with an entry that is a directory, its size will always be divisible by 2048. This is how many sectors it takes up. This does not indicate how many entries are in that sector - file/directory names can vary in size, any given file/directory entry DOES NOT span multiple directories, and leftover space at the end of a sector is padded with 0x00.

* It is possible - likely, even - that the game uses some other method of loading files into memory. If it does, then you're fucked to some degree until you figure out how. You can still navigate the directory structure and edit files, but you can't change their size or move them around unless you also update the size and location of the file in the method the game actually uses to locate files.

* If SaGa Frontier uses only the directory structures built into disc images then we are pretty much golden. I already have code to navigate the directories and read from files. Writing to files requires only the EDC and ECC calculation code - it's almost identical to the code for reading from files. Moving files around and resizing them really dependns on the needs of the application doing it (to be maximally useful a script editor will need this), and on the limitations of the PS1 instruction set and hardware, but once we know what those are we can automate much of the work.

* How do we determine if SaGa Frontier uses directory structures or something else? Simple, we move files around and resize them. If the game still loads correctly (assuming we moved/resized files within the limits of the hardware and instruction set), then it uses the directory structures.

* How else is this information useful? Well, if you want to find out what file a random PFF patch (perhaps a Japanese one) modifies, you can look up the addresses in the directories to find the file, then count from the beginning of that directory until you find the location within the file that the patch edits.
Find all posts by this user
Quote this message in a reply
Post Reply 


Forum Jump:


User(s) browsing this thread: 1 Guest(s)