LisaList2

Advanced search  

News:

2022.06.03 added links to LisaList1 and LisaFAQ to the General Category

Pages: [1]   Go Down

Author Topic: Good grief, why is it so hard to eject a disk?  (Read 16544 times)

stepleton

  • Sr. Member
  • ****
  • Karma: +127/-0
  • Offline Offline
  • Posts: 425
Good grief, why is it so hard to eject a disk?
« on: March 23, 2021, 08:46:55 pm »

Suppose you had to tell someone writing bare-metal code to make a Lisa 2 eject a floppy disk. (The code isn't in a multitasking setting --- it has full supervisor control over the processor and can just poll.) What would you tell them to do?

So far, my best guess is:

1. Disable interrupts on the 68000
2. Set parallel port VIA port B pin 6 (DSKDIAG -- is the controller busy?) to input
3. Set keyboard VIA port B pin 4 (FDIR -- floppy drive interrupt) to input

4. Poll DSKDIAG until the controller reports idle (it's probably idle to start with)

5. Issue command $85 $FF to the the controller to clear any interrupts
6. Poll DSKDIAG until the controller reports idle
7. Poll FDIR until it shows that any interrupt has been cleared

8. Issue command $81 $02 to the controller to eject the disk
9. Poll DSKDIAG until the controller reports idle
10. Poll FDIR until it shows an interrupt has been raised (i.e. the disk is out)

11. Issue command $85 $FF to the the controller to clear any interrupts
12. Poll DSKDIAG until the controller reports idle
13. Poll FDIR until it shows that any interrupt has been cleared

14. Restore interrupts on the 68000

Well, I'm not managing to get the Lisa to eject the disk. Instead, it seems to hang at step 10. Interestingly, if I put an ILLEGAL instruction between steps 8 and 9, the disk does eject (but of course my program crashes). Can anyone spot something I'm missing? Or does this look all right and instead the answer must just be a bug in my code?
Logged

rayarachelian

  • Administrator
  • Hero Member
  • *****
  • Karma: +105/-0
  • Offline Offline
  • Posts: 772
  • writing the code,writing the code,writing the code
    • LisaEm
Re: Good grief, why is it so hard to eject a disk?
« Reply #1 on: March 23, 2021, 10:25:09 pm »

Did this not work? (Shameless stolen from the Boot ROM source and ofc it's subroutines):

I expect that ILLEGAL will trigger an ISR which will then reset something back to some known state when the vector is taken to the Boot ROM.

Code: [Select]
    1E56|                       ;-------------------------------------------------------------------------
    1E56|                       ;  Subroutine to eject disk
    1E56|                       ;  Assumes A0 = ptr to disk shared memory
    1E56|                       ;-------------------------------------------------------------------------
    1E56|
    1E56|                       EJCTDSK
    1E56|                               .IF     NEWTWIG = 1
    1E56| 611A                          BSR.S   CLRFDIR          ;ensure interrupts cleared
    1E58| 6516                          BCS.S   @1               ;exit if error
    1E5A| 243C 0018 0000                MOVE.L  #EJCTTIME,D2     ;set eject timeout
    1E60|                               .ENDC
    1E60| 117C 0002 0002                MOVE.B  #UNCLAMP,CMD(A0) ;set up cmd
    1E66| 10BC 0081                     MOVE.B  #EXRW,(A0)       ;go do it
    1E6A| 61D2                          BSR.S   CHKFIN           ;wait for FDIR
    1E6C| 6502                          BCS.S   @1               ;skip if error
    1E6E| 6102                          BSR.S   CLRFDIR          ;clear intrpt and return
    1E70| 4E75                  @1      RTS
    1E72|

It's looking like the ROM code does the eject command backwards, first it writes the 02 at the higher address, and then the 81 at the CMD/GoByte address. If you're writing 81 02 in normal order by writing a long to just the odd bytes (i.e. MOVE.L #$ff02ff81,(a0) where the ff's are even addresses that are thrown away ) it's possible that the 6504 will see 81 first without the 02 and act on it? - just a wild guess.

The 68000 being big endian and the 6504 being little might make a difference here too in terms of the order they see things on the bus?

Also at step 9 you're checking for DISKDIAG, but the ROM is checking for FDIR and ignores DISKDIAG immediately after issuing the command, so this suggests that explains your infinite loop - the ILLEGAL is just a clue here.

Code: [Select]
1E3E|                       ;----------------------------------------------------------------------------
1E3E|                       ;  Subroutine to check for disk interrupt (FDIR asserted) - loop takes 8.8us
1E3E|                       ;  Destroys register D3 and A3
1E3E|                       ;----------------------------------------------------------------------------
1E3E|
1E3E|                       CHKFIN
1E3E|                               .IF  NEWTWIG = 0
1E3E|                               .ENDC
1E3E|                               .IF  NEWTWIG = 1
1E3E| 2602                          MOVE.L  D2,D3           ;set user-supplied timeout
1E40|                               .ENDC
1E40| 267C 00FC DD81                MOVE.L  #VIA1BASE,A3    ;set ptr for interface
1E46| 0813 0004             @1      BTST    #4,(A3)         ;FDIR?
1E4A| 6608                          BNE.S   @2              ;exit if yes
1E4C| 5383                          SUBQ.L  #1,D3
1E4E| 66F6                          BNE.S   @1              ;else loop
1E50| 003C 0001                     ORI.B   #$01,CCR        ;set error
1E54| 4E75                  @2      RTS
« Last Edit: March 23, 2021, 10:40:10 pm by rayarachelian »
Logged
You don't know what it's like, you don't have a clue, if you did you'd find yourselves doing the same thing, too, Writing the code, Writing the code

stepleton

  • Sr. Member
  • ****
  • Karma: +127/-0
  • Offline Offline
  • Posts: 425
Re: Good grief, why is it so hard to eject a disk?
« Reply #2 on: March 24, 2021, 06:21:51 am »

Thanks Ray. Sadly, I thought of the byte order and command-issue concerns and just didn't mention them here :)
Like the boot ROM does, I copy the command data into the Floppy IOB (memory area) byte-by-byte, first the parameter byte and then the "gobyte". (Backwards.) So it can't be a case of early triggering: since the gobyte is the last byte in, the floppy controller should have all it needs to interpret the command successfully.

I'll look into the "ignoring DSKDIAG" thing. It's confusing if this is the problem, though --- why would the 68000 polling the 6522 affect the controller ejecting the disk once it's received a command?
Logged

rayarachelian

  • Administrator
  • Hero Member
  • *****
  • Karma: +105/-0
  • Offline Offline
  • Posts: 772
  • writing the code,writing the code,writing the code
    • LisaEm
Re: Good grief, why is it so hard to eject a disk?
« Reply #3 on: March 24, 2021, 10:08:24 am »

I'll look into the "ignoring DSKDIAG" thing. It's confusing if this is the problem, though --- why would the 68000 polling the 6522 affect the controller ejecting the disk once it's received a command?

Can't say for sure other than to say if you're looping on DISKDIAG, and its value doesn't change, then 68000 might hang. It shouldn't affect what the 6504 does.
Another thing you could do is check the status in floppy RAM instead to see if it took the command byte and then report on it, though I'd put some NOPs in there to allow the 6504 to be able to access the shared RAM.

Either looking at the schematic or the 6504 code itself might give a hint as to what's happening when looping on DSKDIAG.

There are weird things in the Lisa, for example, the MMU latches can be enabled by READING their addresses, not just writing. You wouldn't expect that, but if you look at the schematic, you'd see and go, oh yes, that's why, as much as it is unexpected.

I'm not saying that's what you're seeing here, but rather, I'm saying don't assume anything is going to have no effect elsewhere.

We do have a working example in the Boot ROM source code, so moving your code closer to that code's behavior will likely help narrow things down, and once you get your code working, you can experiment and figure out what things interfere with it after.
Logged
You don't know what it's like, you don't have a clue, if you did you'd find yourselves doing the same thing, too, Writing the code, Writing the code

stepleton

  • Sr. Member
  • ****
  • Karma: +127/-0
  • Offline Offline
  • Posts: 425
Re: Good grief, why is it so hard to eject a disk?
« Reply #4 on: March 27, 2021, 12:42:43 pm »

Finally worked it out. What an almighty pain that was. I'm not sure I've even got it all yet, but I've managed to sidestep several of the booby traps. For all the hardship, at least I made my code easier to troubleshoot in the meantime.

The various Lisa Hardware Manuals you can find online do not quite prepare you for how picky the floppy drive system can be. Here are the main things that got me:

1. The documentation for the DRIVE ENABLE command (page 195 in the 1983 manual) says that the byte at $FCC003 needs to be a mask saying which drive you want to enable, and that bits 0-2,4-6 of that byte are "don't care". LIES. Those bits will be 0 or your code won't work.

2. At the bottom of just about all of those command description pages in the manual, you'll see "Pre issue requirements" for a command that usually include "DSKDIAG high" and "gobyte zeroed". You'd better pay attention to both! My fault for assuming that DSKDIAG high (which might be interpreted as the drive controller saying "I'm not busy!") would imply "gobyte zeroed". Turns out that it doesn't, and strange things happen if you plow ahead without checking the gobyte.

3. Don't issue the disk eject command and then just quit to the ROM: the Lisa will crash. You need to wait for and clear the interrupt that the ejection procedure will raise, since (I guess) the ROM won't be ready to handle it.

Combinations of getting these things wrong can either crash the machine or lead to nothing happening at all. Either way, unless you get it right, the disk will just sit there in the drive. Since your debugging interventions (e.g. putting in ILLEGAL instructions to verify that execution has reached a certain point, or just plain-old bugs in your temporary code) can also crash the machine, it's hard to tell what's going on.

I hope there aren't many more surprises now!
Logged

rayarachelian

  • Administrator
  • Hero Member
  • *****
  • Karma: +105/-0
  • Offline Offline
  • Posts: 772
  • writing the code,writing the code,writing the code
    • LisaEm
Re: Good grief, why is it so hard to eject a disk?
« Reply #5 on: March 27, 2021, 01:37:11 pm »

Finally worked it out. What an almighty pain that was. I'm not sure I've even got it all yet, but I've managed to sidestep several of the booby traps. For all the hardship, at least I made my code easier to troubleshoot in the meantime.

Congrats. :)

1. The documentation for the DRIVE ENABLE command (page 195 in the 1983 manual) says that the byte at $FCC003 needs to be a mask saying which drive you want to enable, and that bits 0-2,4-6 of that byte are "don't care". LIES. Those bits will be 0 or your code won't work.

Wow! great to know!

3. Don't issue the disk eject command and then just quit to the ROM: the Lisa will crash. You need to wait for and clear the interrupt that the ejection procedure will raise, since (I guess) the ROM won't be ready to handle it.

This makes sense because it will issue an FDIR IRQ. The Boot ROM, much like the uniplus standalone loader is a single process/single user program that tries to avoid handling interrupts as much as possible, however the hardware is designed for a multi-tasking, interrupt driven system. Which means that these programs should set the IRQ mask to 7 and poll I/O until things are settled. Depending on how you choose to structure your Lisa library this may be an issue (or not.).

For a general purpose OS, you won't want to freeze all operations while the floppy drive (or profile) is busy doing stuff and do polling I/O to wait. So specific interrupt service routines have to be written to handle this stuff properly. But to do that, you have to keep track of all things in flight and build a queuing system for requests for various things, like read this block, eject that floppy, write this block, as well as handle incoming stuff. Not easy.

And things can quickly fall out of sync when dealing with the various I/O state machines, such as profile/floppy/cops/etc.

In a single tasking system with mask 7 on for all I/O and polling everything freezes all the time and everything gets sluggish. But it's perfectly fine for a single tasking/polling pre-os loader/boot ROM environment to set the mask to 7 while an operation happens all the way through, but yes, you do have to deal with whatever the other processor expects and the docs don't always tell you exactly. That's why it's useful to see a good example, such as from the Boot ROM source. It may not say in the comments, but likely they ran into the same walls you're hitting now.

Combinations of getting these things wrong can either crash the machine or lead to nothing happening at all. Either way, unless you get it right, the disk will just sit there in the drive. Since your debugging interventions (e.g. putting in ILLEGAL instructions to verify that execution has reached a certain point, or just plain-old bugs in your temporary code) can also crash the machine, it's hard to tell what's going on.

Yup,  very true. The Lisa's a Harsh Mistress to paraphrase Heinlein.

I've recently borked the entire profile state machine while trying to get uniplus working, and while I know exactly where the bug is, I haven't yet spotted why it happens - which is a really annoying place to be when trying to fix it. A small error somewhere causes really huge effects down the line.
Logged
You don't know what it's like, you don't have a clue, if you did you'd find yourselves doing the same thing, too, Writing the code, Writing the code

stepleton

  • Sr. Member
  • ****
  • Karma: +127/-0
  • Offline Offline
  • Posts: 425
Re: Good grief, why is it so hard to eject a disk?
« Reply #6 on: March 27, 2021, 08:53:11 pm »

The Lisa never gives up without a fight. Let's say you want to eject both drives on a Lisa 1, one after the other. If you have disks in both drives, then my code will eject them both. If you have a disk in the top drive only, then my code will eject that one without troubles. If you only have a disk in the bottom drive, then after failing on the top drive saying "no disk there" (expected), it fails on the bottom drive too saying "no disk there" --- and of course the disk stays put.

I'm able to key in the same commands my code uses to the disk controller in Service Mode, and just to make life complicated, that works just fine. That said, Service Mode has different interrupt handling to the no-interrupts polling that my code uses.

I'm not sure that I/O ROM 40 is the most bulletproof software ever made. Oh well, nothing to do but keep plugging away...
Logged

rayarachelian

  • Administrator
  • Hero Member
  • *****
  • Karma: +105/-0
  • Offline Offline
  • Posts: 772
  • writing the code,writing the code,writing the code
    • LisaEm
Re: Good grief, why is it so hard to eject a disk?
« Reply #7 on: March 28, 2021, 12:58:22 pm »

If you only have a disk in the bottom drive, then after failing on the top drive saying "no disk there" (expected), it fails on the bottom drive too saying "no disk there" --- and of course the disk stays put.

Wait, so in this case were you asking for both to be ejected? It sort of makes sense that it maybe failed if the top one failed, but yeah, ideally it should still eject the bottom one. Or are you asking it to eject only the bottom one and it fails anyway just because the top one is empty? That would be most uncool, and raises questions about how LOS deals with that.

Speaking of I/O 40, the other difference is that it needs to be able to signal to the 68000 side that the user pressed one of the two eject request buttons (in addition to the disk insert signals). How does the "D" ROM or whatever handle that? Does it poll or does it answer the FDIR IRQ?

I'm able to key in the same commands my code uses to the disk controller in Service Mode, and just to make life complicated, that works just fine. That said, Service Mode has different interrupt handling to the no-interrupts polling that my code uses.

Hmmm, that may be a clue perhaps - might help to look at the source code for the Service Mode's ISR - especially in regards to FDIR handling

So about, Service Mode, are you keying in 68000 code for your routine, or are you entering commands directly to the shared floppy RAM block? If the latter, then perhaps timing has something to do with it.
Logged
You don't know what it's like, you don't have a clue, if you did you'd find yourselves doing the same thing, too, Writing the code, Writing the code

stepleton

  • Sr. Member
  • ****
  • Karma: +127/-0
  • Offline Offline
  • Posts: 425
Re: Good grief, why is it so hard to eject a disk?
« Reply #8 on: March 28, 2021, 01:42:35 pm »

Lol, this one turned out to be a pretty silly mistake on my part: I was checking the same old error value twice. Sorry about that...

I've been trying to avoid copying the ROM in this project, and my great success in doing that means that I get to relearn old lessons all over again. I can't know that the ROM authors have been as hapless as I am, but I tell myself that they must have made at least a few of the same mistakes along the way.

Anyway, my implementation is different to the ROM style --- maybe not better, but different! You'll remember the first post in this thread where I list a step-by-step process for ejecting a disk... Basically, I represent most of these steps (the ones where you change bits of the shared memory and wait for something to happen) in a compact binary language, and then I have an interpreter that interprets this language. On the one hand, it lets you reuse code for a few floppy operations. On the other hand, it doesn't make debugging a walk in the park, at least not when the interpreter had its own bugs.

But I think that's all behind me now, and I'm just now writing docs for the 1.0 release of the Cameo/Aphid Selector program.
Logged

rayarachelian

  • Administrator
  • Hero Member
  • *****
  • Karma: +105/-0
  • Offline Offline
  • Posts: 772
  • writing the code,writing the code,writing the code
    • LisaEm
Re: Good grief, why is it so hard to eject a disk?
« Reply #9 on: March 28, 2021, 02:01:10 pm »

I've been trying to avoid copying the ROM in this project, and my great success in doing that means that I get to relearn old lessons all over again. I can't know that the ROM authors have been as hapless as I am, but I tell myself that they must have made at least a few of the same mistakes along the way.

Eh, I have a different set of goals, and free time is limited in my case, so I'd rather skip the extra experiments when I can help it. To each their own. :)

I have an interpreter that interprets this language. On the one hand, it lets you reuse code for a few floppy operations. On the other hand, it doesn't make debugging a walk in the park, at least not when the interpreter had its own bugs.

Ooh! That sounds interesting, look forward to that! I was thinking as a way way on the back burner project, perhaps porting micro-python to the Lisa might be a useful way in the future thing - esp if it could interface with the UI/Clascal stuff.

The Aphid/Cameo stuff is really promising too.
Logged
You don't know what it's like, you don't have a clue, if you did you'd find yourselves doing the same thing, too, Writing the code, Writing the code

stepleton

  • Sr. Member
  • ****
  • Karma: +127/-0
  • Offline Offline
  • Posts: 425
Re: Good grief, why is it so hard to eject a disk?
« Reply #10 on: March 28, 2021, 04:23:13 pm »

If you fancy a look, here's a script and here's the interpreter. I think it's correct to call it an interpreter, but don't expect too much: it hasn't got flow control, and it only supports drive controller commands that change $FCC003 and $FCC001.
Logged
Pages: [1]   Go Up