Ah, I must not have seen that x.x
Thanks, DrDnar!
SirCmpwn wrote:
Ah, I must not have seen that x.x
Thanks, DrDnar!
Did you give his code a try? I'm curious what the differences between your and his code are.
KermMartian wrote:
Did you give his code a try? I'm curious what the differences between your and his code are.

Both versions are posted in this thread.
SirCmpwn wrote:
KermMartian wrote:
Did you give his code a try? I'm curious what the differences between your and his code are.

Both versions are posted in this thread.
Yeah, but I have important schoolwork I should be doing right now and all the time, so I didn't bother doing the comparison myself. I thought perhaps you had noticed the differences off the top of your head, but if not, I'm just glad that it works.
There are many things wrong with his code.

He forgot to DI, unless it's done before the routine is called. While issuing special commands to the flash chips command register, the flash chip must not receive any other requests, including read requests. TIOS's general ISR is located in flash, and therefore must not be active during the flash operation or it could interrupt the flash command sequence and prevent the flash chip from getting the command. (So DI or set IM 2.) Or, worse, it could trigger during the erase operation, and the CPU would execute the flash chip's "busy" signal.

He used the 16-bit erase sequence codes. The flash chip is operated in 8-bit mode. The Z80 does not perform 16-bit reads; any 16-bit loads the Z80 does are done as two 8-bit loads.

He completely forgot to write code that waits for the flash chip to finish. Flash operations are non-blocking, and the CPU continues to run while the flash chip is doing its thing. Erase operations can take up to eight seconds according to the data sheet. During this time, normal reading and executing of flash is not possible. All attempts to read from the flash chip will instead yield a status code. You must read this status code and idle loop until it indicates the operation is complete. (The flash chip has an erase suspend command, which I'm not sure I've tried.) If you wanted, your program/erase routines could display a busy animation while waiting.

The flash erase/write are actually one of the few OS routines I've read personally. You might try looking in there yourself. When you find writes to the 4000-7FFF bank, you know you've found the meat of the routine. You'll also notice that my code has a few differences from the OS routines.
Thanks for that very-well-stated overview, DrDnar. I'm almost tempted to try to write a series of Flash routines myself; it sounds pretty interesting. Note of course that I said almost, because you already seem to have done an extremely thorough job in yours, and I don't have the time anyway. SirCmpwn, hope that helps your understanding; it seems that you should review the datasheet again based on DrDnar's critique of your code.
Thank you both, I appreciate it.
SirCmpwn wrote:
Thank you both, I appreciate it.
So everything's working for you with regards to Flash now? I hope this means we're going to see new KnightOS progress soon. Smile
Weeeellll... I have to implement it here in a bit. I'm just acknowledging your help at the moment, not necessarily saying it worked Smile
SirCmpwn wrote:
Weeeellll... I have to implement it here in a bit. I'm just acknowledging your help at the moment, not necessarily saying it worked Smile
Ah, makes sense. This would seem to indicate you're going to (sooner or later) go the route of having your own flash routines for KnightOS, correct?
Yes. I can't afford to have OP1 be required.
My routines were written to be used from a RAM program in the first place. If you use them in an OS, you have to copy them to RAM first. Of course, my code only uses relative jumps. By the way, I consider that code to be public domain. There are only so many ways to do this, and two people could easily write exactly the same code.
Thanks, I appreciate it. What I don't appreciate is that Cemetech has problems with dynamic userbars Razz
SirCmpwn wrote:
Thanks, I appreciate it. What I don't appreciate is that Cemetech has problems with dynamic userbars Razz
It doesn't have problems with them; it's an intentional limitation to avoid people having millions of annoying dynamic signatures.
*cough* someone here has 6, two of them dynamic Razz
SirCmpwn wrote:
*cough* someone here has 6, two of them dynamic Razz
The two dynamic ones are htaccess'ed scripts. If you had your own web hosting you could do the same. Wink
So, I took DrDnar's routine and loaded it into RAM, only slightly modified. Unfortunately, it does not work. Below is the code, and when jp (hl) is called, assume that HL points to the routine in RAM, DE is 4000 (I also tested 0), and A is 3Dh. Flash is also unlocked.

Code:
WriteFlashByte:
    push hl
    push af
    ld bc, ProgramRoutineEnd - ProgramFlashRoutine
    call AllocateExecutableMem
    ex hl, de
    ld hl, ProgramFlashRoutine
    ldir
    pop af
    pop hl
    ex hl, de
    ld bc, WriteFlashRet
    push bc
    jp (hl)
    WriteFlashRet:
    ret
ProgramFlashRoutine:
; a = value, hl = address
; Flash program sequence
; This is being done according to how the datasheet says it should be done.
; The standard interrupt must not trigger during this sequence or the flash chip
; will not get the write command.
; At 6MHz, one clock cycle will be 167ns
; At 15MHz, one clock cycle will be 67ns
    ex hl, de
    push af
    push hl
    push af
    di
    xor    a
    out    (6), a
    ; reset bus (not needed by the books)
    ;ld    a, 0F0h
    ;ld    (4000h), a
    ; First bus cycle---unlock
    ld    a, 0AAh
    ld    (4AAAh), a
    ; Second bus cycle---unlock
    ld    a, 55h
    ld    (4555h), a
    ; Third bus cycle---write command
    ld    a, 0A0h
    ld    (4AAAh), a
    ; Fourth bus cycle---program data
    pop    af
    out    (6), a
    pop    hl
    pop    af
    ld    (hl), a
; Wait for data to be good
; "During the Embedded Program Algorithm, an attempt to read the devices will
; produce the complement of the data last written to DQ7. Upon completion of the
; Embedded Program Algorithm, an attempt to read the device will produce the
; true data last written to DQ7"
; "DQ5 will indicate if the program or erase time has exceeded the specified
; limits (internal pulse count).  If this occurs, reset the device with command
; sequence."---Fujitsu documentation
programWaitLoop:
    ld    b, a
    ld    a, 0FDh        ; This checks for the CLEAR key.
    out    (1), a        ; If pressed, it aborts.
    in    a, (1)
    cp    0BFh
    jr    z, abortProgram
    xor    (hl)
    bit    7, a
    ld    a, b
    jr    z, programDone
    bit    5, (hl)
    jr    z, programWaitLoop
abortProgram:
    ld    a, 0F0h
    ld    (4000h), a
    ret
programDone:
    ei
    ret
ProgramRoutineEnd:
First, you can optimize the opening, assuming that this code is always, always CALLed, and never jumped to, which it already assumes.

Code:
WriteFlashByte:
    push hl
    push af
    ld bc, ProgramRoutineEnd - ProgramFlashRoutine
    call AllocateExecutableMem
    ex hl, de
    ld hl, ProgramFlashRoutine
    ldir
    pop af
    pop de
    jp (hl)

Second, how does the routine know which page to write to? It uses the write value you pass as the page. You can probably get rid of setting the page to 0 before starting the write sequence, and then have the caller map the page to write to into the 4000h bank.

Third, writing to 0000h is great way to make your unit unbootable, at least until you resend the OS.
Writing to 0000h was intentional Razz It's just for testing.
How would I go about simply writing the byte into the currently swapped in bank?
Try reading my last post again.
Quote:
You can probably get rid of setting the page to 0 before starting the write sequence, and then have the caller map the page to write to into the 4000h bank.
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 4 of 5
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement