Difference between revisions of "83Plus:OS:Raw Flash Commands"

From WikiTI
Jump to: navigation, search
(Created page with 'Raw Flash Commands The TI-83+ through TI-84+SE has a flash chip whose data can be erased and rewritten. Issuing write and erase commands is don…')
 
Line 1: Line 1:
 
[[Category:83Plus:OS Information|Raw Flash Commands]]
 
[[Category:83Plus:OS Information|Raw Flash Commands]]
The TI-83+ through TI-84+SE has a flash chip whose data can be erased and rewritten. Issuing write and erase commands is done through memory-mapped writes. The flash chip will not accept any commands unless flash is unlocked. Additionally, any read from flash while issuing a command sequence will abort the command sequence. Consequentially, command sequences can only be issued from RAM.
+
The TI-83+ through TI-84+SE has a flash chip whose data can be erased and rewritten. Issuing write and erase commands is done through memory-mapped writes. The flash chip will not accept any commands unless flash is unlocked. Additionally, any read from flash while issuing a command sequence will abort the command sequence. Consequentially, command sequences can only be issued from RAM and interrupts must be disabled.
  
== Writing and Erasing ==
+
== Flash Commands ==
 
It takes the flash chip a long time to perform a write or erase operation. During this time, it is impossible to read data from the flash chip, because all reads will simply report a status byte.
 
It takes the flash chip a long time to perform a write or erase operation. During this time, it is impossible to read data from the flash chip, because all reads will simply report a status byte.
 +
 +
=== Reset ===
 +
You can reset the flash chip at any time by writing 0F0h to 0000h.
 +
ld a, 0F0h
 +
ld (0), a
 +
Reset the flash chip if a program or erase operation fails, to abort either of those, and to leave autoselect mode.
  
 
=== Writing ===
 
=== Writing ===
<nowiki>
+
The design of flash memory is such that a 0 can be written over a 1, but the reverse is not possible. Any write attempting to do this will fail. To write a 1 over a 0, see the below.
 +
<nowiki>
 
writeFlashByte:
 
writeFlashByte:
 
; Writes a byte to flash.  Flash must be unlocked.  Be aware that pressing CLEAR
 
; Writes a byte to flash.  Flash must be unlocked.  Be aware that pressing CLEAR
Line 28: Line 35:
 
di
 
di
 
call writeFlashByteRaw
 
call writeFlashByteRaw
; ei
+
ei
 
pop bc ; restore page without screwing up flags
 
pop bc ; restore page without screwing up flags
 
ld a, b
 
ld a, b
Line 42: Line 49:
 
ld (0AAAh), a
 
ld (0AAAh), a
 
ld (hl), b ; Fourth bus cycle---program data
 
ld (hl), b ; Fourth bus cycle---program data
; Wait for data to be good
+
; Wait for the write operation to complete
 
ld a, 0FDh ; This checks for the CLEAR key.
 
ld a, 0FDh ; This checks for the CLEAR key.
 
out (keyPort), a ; If pressed, it aborts.
 
out (keyPort), a ; If pressed, it aborts.
Line 63: Line 70:
 
programDone:
 
programDone:
 
ret</nowiki>
 
ret</nowiki>
 +
 +
=== Erasing ===
 +
The design of flash memory is such that writing a 1 over a 0 is not possible, except in large blocks known as sectors. The flash chips TI likes to use have sectors that are almost all 64 K in size, except the last which, which is broken up into several sectors. Erase operations take a long time, during which running code from flash is impossible. If you want, you could probably make a something blink or something while you're waiting.
 +
<nowiki>
 +
eraseSector:
 +
; Erases a sector of flash. Note: Use eraseSectorRaw for the certificate.
 +
; Inputs:
 +
;  - C: Page
 +
; Outputs:
 +
;  - Z on fail (this is opposite of writeFlashByte)
 +
; Kills:
 +
;  - AF, BC, HL
 +
in a, (memPageAPort)
 +
push af
 +
ld a, c
 +
out (memPageAPort), a
 +
ld hl, 4000h
 +
di
 +
call eraseSectorRaw
 +
ei
 +
pop bc
 +
ld a, b
 +
out (memPageAPort), a
 +
ret
 +
eraseSectorRaw:
 +
; Flash program sequence
 +
ld a, 0AAh ; First bus cycle---unlock
 +
ld (0AAAh), a
 +
ld a, 55h ; Second bus cycle---unlock
 +
ld (0555h), a
 +
ld a, 080h ; Third bus cycle---write command
 +
ld (0AAAh), a
 +
ld a, 0AAh ; Fourth bus cycle---unlock (again)
 +
ld (0AAAh), a
 +
ld a, 55h ; Fifth bus cycle---unlock (again)
 +
ld (0555h), a
 +
ld a, 30h ; Do not change this value. In theory, you could superbrick your calculator.
 +
ld (hl), a
 +
; Wait for the erase operation to complete
 +
ld a, 0FDh
 +
out (keyPort), a
 +
inc hl
 +
dec hl       
 +
eraseWaitLoop:
 +
in a, (keyPort)
 +
cp 0BFh
 +
jr z, abortErase
 +
ld a, (hl)
 +
bit 7, a
 +
jr nz, eraseDone
 +
bit 5, a
 +
jr z, eraseWaitLoop
 +
abortErase:
 +
ld a, 0F0h
 +
ld (4000h), a
 +
xor a
 +
eraseDone:
 +
ret
 +
</nowiki>
 +
 +
=== Erase Suspend ===
 +
The flash chip support suspending an erase operation in program. This allows you to read data from the flash chip again. I'm not sure why would want to do this, but
 +
ld a, 0B0h
 +
ld (0), a
 +
will suspend an erase operation. Then
 +
ld a, 30h
 +
ld (0), a
 +
will resume the erase operation. According to the data sheet, you can start writing data to another sector and resume the erase later.

Revision as of 00:04, 29 June 2011

The TI-83+ through TI-84+SE has a flash chip whose data can be erased and rewritten. Issuing write and erase commands is done through memory-mapped writes. The flash chip will not accept any commands unless flash is unlocked. Additionally, any read from flash while issuing a command sequence will abort the command sequence. Consequentially, command sequences can only be issued from RAM and interrupts must be disabled.

Flash Commands

It takes the flash chip a long time to perform a write or erase operation. During this time, it is impossible to read data from the flash chip, because all reads will simply report a status byte.

Reset

You can reset the flash chip at any time by writing 0F0h to 0000h.

ld a, 0F0h
ld (0), a

Reset the flash chip if a program or erase operation fails, to abort either of those, and to leave autoselect mode.

Writing

The design of flash memory is such that a 0 can be written over a 1, but the reverse is not possible. Any write attempting to do this will fail. To write a 1 over a 0, see the below.

writeFlashByte:
; Writes a byte to flash.  Flash must be unlocked.  Be aware that pressing CLEAR
; will abort the write.
; Inputs:
;  - B: Byte to write
;  - C: Page
;  - HL: Address to write to.  This will not be wrapped.
; Outputs:
;  - NZ on failure
; Kills:
;  - AF, BC
; Protips:
;  - Calling writeFlashByteRaw instead will skip the page changing
;  - Do push bc \ pop af afterwards to restore flags to pre-call values.  That's
;    right, documented side-effect programming! 
	in	a, (memPageAPort)	; save page
	push	af
	ld	a, c
	out	(6), a
	di
	call	writeFlashByteRaw
	ei
	pop	bc	; restore page without screwing up flags
	ld	a, b
	out	(memPageAPort), a
	ret
writeFlashByteRaw:
; Flash program sequence
	ld	a, 0AAh	; First bus cycle---unlock
	ld	(0AAAh), a
	ld	a, 55h	; Second bus cycle---unlock
	ld	(0555h), a
	ld	a, 0A0h	; Third bus cycle---write command
	ld	(0AAAh), a
	ld	(hl), b	; Fourth bus cycle---program data
; Wait for the write operation to complete
	ld	a, 0FDh		; This checks for the CLEAR key.
	out	(keyPort), a		; If pressed, it aborts.
	inc	hl
	dec	hl
programWaitLoop:
	in	a, (keyPort)
	cp	0BFh
	jr	z, abortProgram
	ld	a, b
	xor	(hl)
	bit	7, a
	jr	z, programDone
	bit	5, (hl)
	jr	z, programWaitLoop
abortProgram:
	ld	a, 0F0h
	ld	(0000h), a
	inc	a
programDone:
	ret

Erasing

The design of flash memory is such that writing a 1 over a 0 is not possible, except in large blocks known as sectors. The flash chips TI likes to use have sectors that are almost all 64 K in size, except the last which, which is broken up into several sectors. Erase operations take a long time, during which running code from flash is impossible. If you want, you could probably make a something blink or something while you're waiting.

eraseSector:
; Erases a sector of flash. Note: Use eraseSectorRaw for the certificate.
; Inputs:
;  - C: Page
; Outputs:
;  - Z on fail (this is opposite of writeFlashByte)
; Kills:
;  - AF, BC, HL
	in	a, (memPageAPort)
	push	af
	ld	a, c
	out	(memPageAPort), a
	ld	hl, 4000h
	di
	call	eraseSectorRaw
	ei
	pop	bc
	ld	a, b
	out	(memPageAPort), a
	ret
eraseSectorRaw:
; Flash program sequence
	ld	a, 0AAh	; First bus cycle---unlock
	ld	(0AAAh), a
	ld	a, 55h	; Second bus cycle---unlock
	ld	(0555h), a
	ld	a, 080h	; Third bus cycle---write command
	ld	(0AAAh), a
	ld	a, 0AAh	; Fourth bus cycle---unlock (again)
	ld	(0AAAh), a
	ld	a, 55h	; Fifth bus cycle---unlock (again)
	ld	(0555h), a
	ld	a, 30h ; Do not change this value. In theory, you could superbrick your calculator.
	ld	(hl), a
; Wait for the erase operation to complete
	ld	a, 0FDh
	out	(keyPort), a
	inc	hl
	dec	hl        
eraseWaitLoop:
	in	a, (keyPort)
	cp	0BFh
	jr	z, abortErase
	ld	a, (hl)
	bit	7, a
	jr	nz, eraseDone
	bit	5, a
	jr	z, eraseWaitLoop
abortErase:
	ld	a, 0F0h
	ld	(4000h), a
	xor	a
eraseDone:
	ret

Erase Suspend

The flash chip support suspending an erase operation in program. This allows you to read data from the flash chip again. I'm not sure why would want to do this, but

ld a, 0B0h
ld (0), a

will suspend an erase operation. Then

ld a, 30h
ld (0), a

will resume the erase operation. According to the data sheet, you can start writing data to another sector and resume the erase later.