PKP
VS1000 P
ROGRAMMER
’
S
G
UIDE
VSMPG
7.4
Hooking custom storage controller
Hooks are software jump vectors, that are linked into fixed positions in the VS1000 RAM.
Their function is essentially the same as for instance the interrupt vector of a 80x86 pro-
cessor. For instance, when the player is playing music, it reads a disk sector (512 bytes)
of data by calling a function ReadDiskSector(u_int16 *buffer, u_int32 sector). For this
call, the linker generates a call to a fixed address 0x000c. In that address (which is in
RAM) is a jump instruction to the start address of the ROM function MapperReadDisk-
Sector(), which retrieves the data from a logical NAND Flash mapper interface using
map->Read().
By replacing the jump location of the ReadDiskSector() hook vector, it is easy to re-
place the storage device, which contains the files the player plays. Only the service
that delivers a sectorful of data from a storage device is changed while rest of the ROM
functionality remains the same.
The image below demonstrates the disk data flow of VS1000:
MassStorage
USB block
interface
Flash Mapper
Logical Disk +
wear levelling
Flash Physical
Physical disk
interface
minifat
Read only FAT
filesystem
(register __i0 u_int16 *buffer,
register __a u_int32 sector) {
/* Own Code */
}
auto u_int16 MyReadSector
storage
Own
when USB connected:
when playing:
Nand Flash
ReadDiskSector
Figure 4: Disk Data Flow
Below is an example of hookable disk read function that uses a previously declared
EEReadBlock()
function to read 512 bytes to
*buffer
and returns 0 signifying no error:
auto u_int16 MyReadDiskSector(register __i0 u_int16 *buffer,
register __a u_int32 sector) {
EEReadBlock(FAT_START_SECTOR, buffer);
return 0;
}
This can then be hooked to the ReadDiskSector hook by calling
SetHookFunction((u_int16)ReadDiskSector, MyReadDiskSector);
in
main()
or some other convenient function.
Rev. 0.20
2011-10-04
Page