[TI ASM] (unlocking) the flash

Got questions? Got answers? Go here for both.

Moderator: MaxCoderz Staff

Post Reply
King Harold
Calc King
Posts: 1513
Joined: Sat 05 Aug, 2006 7:22 am

[TI ASM] (unlocking) the flash

Post by King Harold »

As for unlocking (which is in fact no more than 'leaving read mode')
I know it'd been everywhere, especially on DS, but as far as I could find there is no place where the facts are gathered.
Boot 1.00, Base 1.16
Put a jump at FFCD, install a cursorhook, enable the cursor, and set curTime to 1. Then 1 to port 5, 7F to 6, SP at OP1+27d+4000h, jump to 4314h.
On OS 2.22 (presumably also on 2.21; I don't have that OS so I can't check (*)): SP = OP1+4000h+11d, catch at FF67h and with the cursorhook at 0067h.
On OS 2.30 only: SP = OP1+4000h+23d, catch at FF7Ch and with the cursorhook at 007Ch.
Regardless of base version, your jump is at 43B3.
so is that all? no! what about all other versions? With my awesome (cough) google skills, I have not been able to find anything about them.

Anyway, the flash itself, and doing anything but reading from it, is easier, but by far not easy.

SE calcs do not have the same flash as BE calcs, they support additional commands, but luckily they are backwards compilable (if you can speak of that at all, seeing as they aren't the same brand)
they are both CFI-compitable, but on the SE's flash you can use fast-write (which you must enable first).

There is a lot to find and read about CFI (common flash interface), but these are the most important (can found in PongOS) and don't even think about going in 16 bit mode:
PongOS wrote:;;; Commands are sent to the Flash chip by ordinary write cycles.
;;; Keep in mind that a physical address ppppp dddddd dddddddd
;;; corresponds to a logical address 000ppppp:01dddddd dddddddd.

;;; Any unrecognized command, including an attempt to read data, will
;;; reset the chip. Thus you cannot execute code to write Flash from
;;; within Flash; the code must be copied into RAM and executed there.

;;; When the chip is busy programming or erasing, commands written are
;;; usually ignored. Reading from the appropriate address will give
;;; status information.

;;; <AA>: Write AA to address *AAAA
;;; <55>: Write 55 to address *5555
;;; [nn]: Write nn to address *AAAA
;;; (nn): Write nn to any relevant address
;;; {nn}: Write nn anywhere, address doesn't matter

;;; The commands for the BE (AMD Am29F400B) are:
;;;
;;; {30} Resume suspended erase operation
;;;
;;; <AA><55>[80]<AA><55>[10] Automatically erase entire chip
;;;
;;; <AA><55>[80]<AA><55>(30) Automatically erase single sector
;;;
;;; <AA><55>[90] Read auto-select data
;;; (device ID, manufacturer, and sector
;;; protect states; used by an embedded
;;; device that supports many similar
;;; Flash chips but doesn't know which
;;; will be used; unneeded since the
;;; TI's provide port 2 for this
;;; purpose)
;;;
;;; <AA><55>[A0](xx) Program one byte
;;;
;;; {B0} Temporarily suspend current erase operation
;;;
;;; {F0} Reset (return to read mode)

;;; The SE (Fujitsu MBM29LV160) supports all of the above plus:
;;;
;;; <AA><55>[20] Enable fast programming mode
;;;
;;; {90}{F0} Exit fast mode
;;;
;;; {A0}(xx) Program one byte while in fast mode
;;;
;;; [98] Read CFI (Common Flash Interface) data
;;; (a generalization of the same
;;; concept as autoselect; the system
;;; can find out everything it needs to
;;; know -- size of the chip, sizes of
;;; sectors, supported command set --
;;; and a whole lot more besides.
;;; Again, the TI's don't need this.)
Which is the same as stated in the manuals and references that can be found all over the internet (even on Intel's site).
The mangling of the addresses is a result of the connections of pin A14 and A15, which (as most of us know) are not connected to the memory chips, but are used (together with the memory mode and ports 5, 6 and 7) to decide which chip should be accessed. All well and good, you may think, but it means that we won't write to AAAAh but 6AAAh.

Don't forget to return to read mode, your calc will most likely die if you don't.

Now, post your info :)

ps: don't look at your certificate if you live in the US, and if you do, don't remember it, because that's copying to your brain.
User avatar
Dwedit
Maxcoderz Staff
Posts: 579
Joined: Wed 15 Dec, 2004 6:06 am
Location: Chicago!
Contact:

Post by Dwedit »

I always thought the way to reflash your calc with custom firmware was to pull batteries after reflashing, but before validation.
You know your hexadecimal output routine is broken when it displays the character 'G'.
King Harold
Calc King
Posts: 1513
Joined: Sat 05 Aug, 2006 7:22 am

Post by King Harold »

Could someone please explain why and how
On OS 2.22 (presumably also on 2.21; I don't have that OS so I can't check (*)): SP = OP1+4000h+11d, catch at FF67h and with the cursorhook at 0067h.
On OS 2.30 only: SP = OP1+4000h+23d, catch at FF7Ch and with the cursorhook at 007Ch.
Regardless of base version, your jump is at 43B3.
works?

This is just a little too odd for me to understand..
brandonw
New Member
Posts: 17
Joined: Thu 21 Jun, 2007 1:11 pm

Post by brandonw »

Basically, he's swapping the same RAM page into both of the last two banks, and pointing SP to near where OP1 is (which is possible because of port 5). Then he's jumping to a part in CheckOSValidated which will read a byte (always a zero) to OP1, which will corrupt the stack and throw you down into the interrupt, where you can regain control using the cursor hook, which will fire because curTime is 1.

This only works on SEs (naturally, because port 5 doesn't exist on the original 83+), and as you've discovered, genius as it is, it's a little icky and OS version-specific. There are dozens of others, and if you're doing serious universal Flash unlocking, I would look into other methods.

EDIT: Dwedit, that battery-pull trick was fixed in the 84+/SE boot code.
King Harold
Calc King
Posts: 1513
Joined: Sat 05 Aug, 2006 7:22 am

Post by King Harold »

Ok, I see, partly anyway, why does the stack corruption get you into the interrupt?
brandonw
New Member
Posts: 17
Joined: Thu 21 Jun, 2007 1:11 pm

Post by brandonw »

The interrupt starts at 0038h, very low on page 0. If you put the stack pointer at something like 0FFCDh (like Ben says), and then you write a zero over the upper byte, you've changed it to 00CDh, which is deep into the interrupt. It's just blind luck that you can jump to a spot where the cursor hook will be called. Because of this, you have to hard-code this address based on OS version (because it shifts around, and why he mentioned several different versions, and also why he stresses boot code version 1.00 only).
King Harold
Calc King
Posts: 1513
Joined: Sat 05 Aug, 2006 7:22 am

Post by King Harold »

Ok I see thanx :)
Post Reply