Libst2205
From Picframe
Contents |
Device Protocol
- The interface works by writing bytes to the raw 'disk' at certain positions.
- commands go to offset 0x6200,
- data to be read from the device comes from 0xB000,
- data to be written goes to 0x6600.
- hacked firmware has an extra address, 0x4200 / 0x4400 : bytes written there will go straight to the LCD.
- This "magic address" changed from v1.2 to v1.3 - so now its 0x4400
Known Commands
- cmd = 0: ? READ 200 bytes. arguments ignored
- cmd = 1: ? GET_FLASH_SIZE : My 32 MB device receive: 0x1f --Ben (how do you make 32Mb with 1F ?? / pixika 2MB answer 0x10) --Michu (I allmost sure it is result * 1024 * 2.. I guess this has something to do with the sector size of 512 bytes...)
- cmd = 3: GET_READY_FOR_BUFFER : tell the device to be prepared to read a buffer that need to be stored at page arg1 with a length of arg2
- cmd = 2: BUFFER_READY : tell the device a buffer has been written to memory, the device can store the buffer at page arg1 with a length of arg2
- cmd = 4: READ_BUFFER : tell the device to prepare data to be read from memory, data are read at page arg1 with a length of arg2
- cmd = 5: GET_SCREEN_RESOLUTION
- cmd = 6 : set Time/Date
- cmd = 7 :
- cmd = 8 :
- cmd = 9 : write text to screen (send special commands ???)
Where can i find, which command does what? (=> in [FirmwareDebugging])
I will add those functions in the next version
get memory:
sendcmd(fd,1,0,0,0);
read_data(fd,buff,0x200);
printf("Found device with %i kb memory\n",(buff[0]*128*1024)/512);
get screen resolution:
sendcmd(fd,5,0,0,0);
read_data(fd,buff,0x200);
tmpx = (buff[0]<<8)+buff[1];
tmpy = (buff[2]<<8)+buff[3];
printf("Found device x/y: %i/%i\n",tmpx,tmpy);
Sendcmd function
- parmeter of sendcommand(f,cmd,arg1,arg2,arg3)
- most of the time :
- arg1 is page number using 32K page. If you want to write at 0x8000 arg1=1
- arg2 is the length of data to read/write
some examples:
- check pictureframe
sendcmd(f,1,0,0,0); read_data(f,buff,0x200); buff[0] should be 8 // --Ben for pixika i get 0x10
- read memory, ex:
sendcmd(f,4,0,0x8000,0); //read 0x8000 bytes in the page arg1=0 read_data(f,buff,0x8000);
- read firmware, ex:
sendcmd(f,4,62,0x8000,0); //read 0x8000 bytes in the page 62 read_data(f,buff,0x8000); //--Ben : each page of flash is 32K (0x8000) // locate the firmware (usually at the end of flash and 64K) // so read page (2048-64)/32 and (2048-32)/32
- write to memory at page x :
sendcmd(f,3,x,0x8000,0); -- cmd=3 GET_READY_FOR_BUFFER write_data(f,buff,0x8000); sendcmd(f,2,x,0x8000,0); -- cmd=2 BUFFER_READY
- write firmware, ex:
Memory location for storing new firmware is 0x80000000 and 0x80000001
For x=0..1 {
sendcmd(f,3,x|0x80000000,0x8000,0); //get ready for writting at 0x80000000 or 0x80000001
write_data(f,buff,0x8000); //write data
sendcmd(f,2|0x80000000,x,0x8000,0); //buffer at '''0x0''' is ready -- why do the or on the cmd ???
//i would have say : sendcmd(f,2,x|0x80000000,0x8000,0);
read_data(f,buff,0x200); // --- whats that for?
sendcmd(f,3,x|0x1f40,0x8000,0); //get ready for writting at 0x1F40
// --- get ready for write at page 0x1f40/0x1f41 (mem adress 0xFA00000/0xFA08000)
//hidden fw update function (see below)
write_data(f,buff,0x8000); //write data
//no BUFFER_READY command .... strange....
}
Debugging PhotoViewer 3.03, i discovered an hidden firware update function that do this :
For x=0..1 {
sendcmd(f,3,x|0x80000000,0x8000,0); //get ready for writting at 0x80000000 or 0x80000001
write_data(f,buff,0x8000); //write data
sendcmd(f,2,x|0x80000000,0x8000,0); //buffer at '''0x80000000''' is ready
sendcmd(f,0,0x8000XX,0x04008300,0x2a040083); //x=0 XX=2B x=1 XX=10 ...probably arg1,arg2,arg3 means nothing
sendcmd(f,3,x|0x80000000,0x8000,0); //dot it again.... on '''0x80000000'''
write_data(f,buff,0x8000); //write data
//no BUFFER_READY command .... strange....
}
PhotoViewer 2.4 (which have a fw update hidden function) send the last cmd 3 at 0x1F40 ...
For pixika a new command is used to [FlashUpdate]
- write text message, ex:
sendcmd(f,9,0,0,0); write_data(f,buff,0x200);
- set DateTime :
sendcmd(6,0x0yyymmdd,0xhhmmdd00,0); where : ** yyy : year ** mm : month (03 = march) ** dd : day of month ** hh : hour ** mm : minute ** dd : day of week (monday, tuesday, ...) : not understood how to set it...
Lib to Firmware
Sprite write in his code, commands go to 0x4400 go directly to the lcd (due the new fw feature). this is the code (from libst2205):
//fill the buffer HERE
lseek(h->fd,0x4400,SEEK_SET);
return write(h->fd,buff,len);
however, in the hack fw this code exists:
;check magic write to address 4400
start
lda CMP_VAR1
cmp #$22 << ?? why compare to $22 and not $44?
bne nomagic
lda CMP_VAR2
cmp #$00 <<
bne nomagic
bra gotcha
I dont get it, why compare to $2200 and not $4400?
Also the other compare operations are, at least for me, very strange. From the newhack.txt:
- Open the disassembly file and look for something like this: LDA D037c CMP #$31 BNE L73c1 LDA D037d CMP #$00 BNE L73c1 BRA L73d3 The important thing here is that two subsequent memory locations (here 037C:037D) get compared to 0x3100, and later (not shown) to 0x3300. <<< Modify the CMP_VAR1 and CMP_VAR2 in the specs-file to reflect these memory locations. - A few lines later, you should see something like this: LDA #$ff LDX #$ff STA D037c STX D037d RTS The location of the LDA-instruction, minus 0x4000, should go into the specs-file as PATCH_AT.
Hmm why compare to 0x3100 and 0x3300 and not 0x6600 and 0xb0000?
I guess this hack works like this:
-get commands -check read command, if yes goto read procedure -check write command, if yes goto write procedure -here comes the hack, check magic command, call our hacked procedure -do whatever
So I assume, the asm code shold check against the same values as writen above, but this does no look like this. Can anyone help me with this?
- The adresses are stored in 'increments' of 512 bytes, the size of a sector. So offset 0x4400 is sector no (0x004400/0x200)=0x0022 - Sprite tm

