Author Topic: 8X+ > flash writing question  (Read 13284 times)

0 Members and 1 Guest are viewing this topic.

Offline the_mad_joob

  • LV6 Super Member (Next: 500)
  • ******
  • Posts: 346
  • Rating: +47/-0
    • View Profile
8X+ > flash writing question
« on: June 27, 2014, 12:39:06 am »
Welcome...

Alright, i'm about to code a few routines that will write to archive space.
Of course, i'm gonna have to follow what is written on that page : http://wikiti.brandonw.net/index.php?title=83Plus:OS:Raw_Flash_Commands
Still, there is a part of the code that i don't understand :
Code: [Select]
ld a,b
xor (hl)
bit 7,a
jr z,programdone
bit 5,(hl)
jr z,programwaitloop
Why using XOR (HL) and checking bit 7 of A where a CP (HL) would be faster ?
Also, i really have no idea what is the point of checking bit 5 of (HL).

Any clarification greatly appreciated =]
« Last Edit: June 27, 2014, 01:15:55 am by the_mad_joob »

Offline chickendude

  • LV8 Addict (Next: 1000)
  • ********
  • Posts: 817
  • Rating: +90/-1
  • Pro-Riot Squad
    • View Profile
Re: 8X+ > flash writing question
« Reply #1 on: June 28, 2014, 10:43:37 am »
...or simply leaving out the bit 7,a. I'm also not sure what the following "bit 5, (hl)" is for. Have you tried seeing if it works without it? You're just waiting for the byte to update so i can't imagine what you'd need it for.

Offline the_mad_joob

  • LV6 Super Member (Next: 500)
  • ******
  • Posts: 346
  • Rating: +47/-0
    • View Profile
Re: 8X+ > flash writing question
« Reply #2 on: June 28, 2014, 12:03:48 pm »
No, haven't tried yet any attempt to write.
You know, that's the kind of thing you want to understand before trying on real hardware =P
I don't really believe it, but i could potentially imagine that the flash chip behaves differently when he hasn't totally finished accepting a write attempt (depending on the used op code).

Offline calc84maniac

  • eZ80 Guru
  • Coder Of Tomorrow
  • LV11 Super Veteran (Next: 3000)
  • ***********
  • Posts: 2912
  • Rating: +471/-17
    • View Profile
    • TI-Boy CE
Re: 8X+ > flash writing question
« Reply #3 on: June 28, 2014, 12:11:35 pm »
While a flash write is in progress, when you read a byte from flash, you get a status byte rather than actual data. Bit 7 is guaranteed to be the opposite of the data being written, and conversely, when it succeeds, bit 7 is guaranteed to match the data that was written. Bit 5 of the status byte gets set when there is an error, which can be either a timeout or trying to write a 1 over a 0. Bit 5 should be checked only when you already know bit 7 doesn't match, of course.
"Most people ask, 'What does a thing do?' Hackers ask, 'What can I make it do?'" - Pablos Holman

Offline the_mad_joob

  • LV6 Super Member (Next: 500)
  • ******
  • Posts: 346
  • Rating: +47/-0
    • View Profile
Re: 8X+ > flash writing question
« Reply #4 on: June 28, 2014, 06:28:19 pm »
While a flash write is in progress, when you read a byte from flash, you get a status byte rather than actual data. Bit 7 is guaranteed to be the opposite of the data being written, and conversely, when it succeeds, bit 7 is guaranteed to match the data that was written. Bit 5 of the status byte gets set when there is an error, which can be either a timeout or trying to write a 1 over a 0. Bit 5 should be checked only when you already know bit 7 doesn't match, of course.
Fat thx for the explanation =]
Anyway, whether reading returns a status byte or the actual data, i still think a simple LD A,(HL) \ CP B or LD A,B \ CP (HL) would be more appropriate (faster & lighter).
Am i wrong ?
Also, other question : What can cause a timeout ?
Thx again for your time...

Offline chickendude

  • LV8 Addict (Next: 1000)
  • ********
  • Posts: 817
  • Rating: +90/-1
  • Pro-Riot Squad
    • View Profile
Re: 8X+ > flash writing question
« Reply #5 on: June 28, 2014, 10:20:41 pm »
I think the "trick" here is that bit 7 will always be the opposite of the byte you're trying to write (here in b), so if bit 7 of b is 1, bit 7 of (hl) will be 0 (so XORing the two will always give you 1). If it's finished, then you'll get the same bit that's in b, so XORing them will give you 0 (so z will be set). I don't really know how all of it works, that's just what i got from calc84's message.

EDIT: And (hl) doesn't really return the value of (hl) but rather a status byte, so i think you could read from anywhere in flash (like "ld a,($4000) \ xor b") and it would return the same thing until the thing finishes. Also, if you just cp (hl) there's a chance that the status byte has the same value as the byte you're trying to write.
« Last Edit: June 28, 2014, 10:25:21 pm by chickendude »

Offline the_mad_joob

  • LV6 Super Member (Next: 500)
  • ******
  • Posts: 346
  • Rating: +47/-0
    • View Profile
Re: 8X+ > flash writing question
« Reply #6 on: June 28, 2014, 11:39:10 pm »
I think the "trick" here is that bit 7 will always be the opposite of the byte you're trying to write (here in b), so if bit 7 of b is 1, bit 7 of (hl) will be 0 (so XORing the two will always give you 1). If it's finished, then you'll get the same bit that's in b, so XORing them will give you 0 (so z will be set). I don't really know how all of it works, that's just what i got from calc84's message.

EDIT: And (hl) doesn't really return the value of (hl) but rather a status byte, so i think you could read from anywhere in flash (like "ld a,($4000) \ xor b") and it would return the same thing until the thing finishes. Also, if you just cp (hl) there's a chance that the status byte has the same value as the byte you're trying to write.
That is how i understood it, too.
2 cases :
1) writing complete, reading will return the effective byte at the address, therefore all bits will match between the write & the read.
2) writing incomplete, reading will return a status byte which bit 7 is the opposite of bit 7 of the byte you asked to write (ugly sentence, i know XD).
The thing is, that if bit 7 of the status byte is "guaranteed" to be the opposite, then i don't see how there is a chance to have a match when comparing the 2 bytes.
I mean, comparing byte %1XXXXXXX and byte %0XXXXXXX can never set the zero flag, so why wasting some cycles with that slow BIT instruction ?

Sorry again to bother you with that guyz, but that's important, cause such code can be iterated a lot when writing to flash and highly deserves to be speed-optimized.
« Last Edit: June 28, 2014, 11:48:51 pm by the_mad_joob »

Offline calc84maniac

  • eZ80 Guru
  • Coder Of Tomorrow
  • LV11 Super Veteran (Next: 3000)
  • ***********
  • Posts: 2912
  • Rating: +471/-17
    • View Profile
    • TI-Boy CE
Re: 8X+ > flash writing question
« Reply #7 on: June 28, 2014, 11:59:34 pm »
I think the "trick" here is that bit 7 will always be the opposite of the byte you're trying to write (here in b), so if bit 7 of b is 1, bit 7 of (hl) will be 0 (so XORing the two will always give you 1). If it's finished, then you'll get the same bit that's in b, so XORing them will give you 0 (so z will be set). I don't really know how all of it works, that's just what i got from calc84's message.

EDIT: And (hl) doesn't really return the value of (hl) but rather a status byte, so i think you could read from anywhere in flash (like "ld a,($4000) \ xor b") and it would return the same thing until the thing finishes. Also, if you just cp (hl) there's a chance that the status byte has the same value as the byte you're trying to write.
That is how i understood it, too.
2 cases :
1) writing complete, reading will return the effective byte at the address, therefore all bits will match between the write & the read.
2) writing incomplete, reading will return a status byte which bit 7 is the opposite of bit 7 of the byte you asked to write (ugly sentence, i know XD ).
The thing is, that if bit 7 of the status byte is "guaranteed" to be the opposite, then i don't see how there is a chance to have a match when comparing the 2 bytes.
I mean, comparing byte %1XXXXXXX and byte %0XXXXXXX can never set the zero flag, so why wasting some cycles with that slow BIT instruction ?

Sorry again to bother you with that guyz, but that's important, cause such code can be iterated a lot when writing to flash and highly deserves to be speed-optimized.
According to the documentation, due to some sort of timing/synchronization issue, the first time you get a match in bit 7, the rest of the data is not guaranteed to be correct (it says to read again to get the actual data). But really, the BIT instruction is indeed superfluous; I usually check the sign flag after the XOR instead of doing a BIT followed by checking the zero flag.

Edit: Oh yeah, you also asked what could cause a timeout. Well, I think it just happens if enough time passes without the write succeeding, due to some sort of hardware failure. This prevents it from ever getting stuck in an infinite wait loop.
« Last Edit: June 29, 2014, 12:09:26 am by calc84maniac »
"Most people ask, 'What does a thing do?' Hackers ask, 'What can I make it do?'" - Pablos Holman

Offline the_mad_joob

  • LV6 Super Member (Next: 500)
  • ******
  • Posts: 346
  • Rating: +47/-0
    • View Profile
Re: 8X+ > flash writing question
« Reply #8 on: June 29, 2014, 12:57:23 am »
Hmm, i find that "rest of the data is not guarenteed to be correct" pretty scary.
Looks to me like when the chip changes the read byte from "status" to "data", it doesn't update the bits all at once (theory).
Then, checking all the bits would be even more safe...

Thx for the data about timeout, too.
Maybe batteries becoming low in the middle of a writing procedure could also cause a timeout (another theory)...
« Last Edit: June 29, 2014, 01:10:40 am by the_mad_joob »

Offline DrDnar

  • LV7 Elite (Next: 700)
  • *******
  • Posts: 546
  • Rating: +97/-1
    • View Profile
Re: 8X+ > flash writing question
« Reply #9 on: June 30, 2014, 04:15:49 pm »
Writing and erasing flash requires pulsing the flash memory with high voltages. Older flash chips had a 12-20 V pin to supply the high voltage directly, but today's chips instead use a device known as a charge pump to multiply the supply voltage into the correct voltage. Charge pumps work by charging capacitors, so some time is required between when you request a write or erase and when the voltage is available. When you request a write or erase, the chip enters a status mode, in which reads return a status instead of real data, so that you know when the operation has completed.

Each time a flash cell is pulsed with high voltage, it is also damaged a little, causing the flash memory to wear out over time. In heavily used flash chips, multiple pulses may be required for a write or erase to take effect, so the operation may take longer. A write or erase may fail if the flash cell is worn out. In these circumstances, some bits are likely to have the correct value, while others won't. If the batteries are low during a flash operation, charging the charge pump will take longer, and it is possible the voltage will stay depressed for so long that the flash chip gets confused and stops working right. In other words, low batteries may cause the calculator to crash outright.

The datasheet indicates that if there's an error, the chip does not immediately return to read mode. Instead, you have to issue a reset command before it will enter read mode. If you simply do CP (HL) until Z is set, you will hang if there's an error writing.

Checking the sign flag is a possible optimization, with the downside that the code is no longer relocatable.

The BIT 7, A thing and jump instead of RET Z also add a delay between when bit 7 is correct and we start trying to fetch opcodes from flash again; TI and I essentially make an assumption that the flash chip won't return garbage for the other bits for more than a few clock cycles. In reality, the warning calc84 mentioned most likely only applies to CPUs that can fetch one byte per clock cycle, so a read on the very next clock cycle should be correct. The Z80 can't do another read on the very next clock cycle, so RET Z should be fine.
« Last Edit: June 30, 2014, 04:35:37 pm by DrDnar »
"No tools will make a man a skilled workman, or master of defense, nor be of any use to him who has not learned how to handle them, and has never bestowed any attention upon them. . . . Yes, [] the tools which would teach men their own use would be beyond price."—Plato's The Republic, circa 380 BC

Offline the_mad_joob

  • LV6 Super Member (Next: 500)
  • ******
  • Posts: 346
  • Rating: +47/-0
    • View Profile
Re: 8X+ > flash writing question
« Reply #10 on: July 01, 2014, 11:31:25 am »
Thx a lot for all that in-depth infos DrD =]
Just a question, what you mean by "the code is no longer relocatable" ?

Also, i have another question now.
I was thinking of optimizing the 4 bus cycles part, using registers as much as possible.
As a result, the commands may be sent faster, maybe too fast.
Is a delay needed between the unlocks, write command, and data sending ?

Offline chickendude

  • LV8 Addict (Next: 1000)
  • ********
  • Posts: 817
  • Rating: +90/-1
  • Pro-Riot Squad
    • View Profile
Re: 8X+ > flash writing question
« Reply #11 on: July 01, 2014, 01:28:32 pm »
Because you'd have to change the jr to a jp, which uses an absolute address rather than a relative one.

And thanks calc84 and DrDnar for the explanations.

Offline the_mad_joob

  • LV6 Super Member (Next: 500)
  • ******
  • Posts: 346
  • Rating: +47/-0
    • View Profile
Re: 8X+ > flash writing question
« Reply #12 on: July 02, 2014, 01:43:24 am »
Oh, of course...
Thx chickendude =]

Offline Streetwalrus

  • LV12 Extreme Poster (Next: 5000)
  • ************
  • Posts: 3821
  • Rating: +80/-8
    • View Profile
Re: 8X+ > flash writing question
« Reply #13 on: July 02, 2014, 08:14:56 am »
So um... With all these low level questions, are you making an OS or something ? :P

Offline the_mad_joob

  • LV6 Super Member (Next: 500)
  • ******
  • Posts: 346
  • Rating: +47/-0
    • View Profile
Re: 8X+ > flash writing question
« Reply #14 on: July 02, 2014, 12:06:11 pm »
Yo Streety =]
Something between an OS and a shell...