Previous Thread
Next Thread
Print Thread
Page 1 of 2 1 2
#89915 08/16/13 05:08 AM
Joined: Feb 2012
Posts: 14
B
Member
OP Offline
Member
B
Joined: Feb 2012
Posts: 14
For the TRS-80 Model II, Mess can do the first stage boot from floppy. With TRSDOS 1.2, that gets to the point of prompting for the date and time, and then fails to load the rest of the OS. I spent some time tracing this to figure out where it's going off the rails.

In the TRSDOS floppy seek routine, called from the floppy read sector routine, the code issues a "force interrupt" (0xd0) command to the FDC. It then waits 24 instructions before reading the status register. The status register is reading with the BUSY bit (0x80) set, which should NEVER happen under these circumstances.

The code in wd_fdc.c uses a timer to enqueue an FDC command, and I think that the timer value (delay_command_commit) is too high for the "force interrupt" command, though it might be correct for other commands that cause the FDC chip to run its internal state machine.

Here's an edited trace showing the failure:

Code:
0CF5: push bc        fd_seek:
0CF6: push de
0CF7: push hl
0CF8: ld   a,b
0CF9: ld   e,$20
0CFB: cp   $04
0CFD: jr   nc,$0D69
0CFF: ld   hl,$0B5C
0D02: rlca
0D03: rlca
0D04: rlca
0D05: rlca
0D06: ld   e,a
0D07: ld   d,$00
0D09: add  hl,de
0D0A: push hl
0D0B: pop  ix
0D0D: call $0E70
  0E70: call $0E77
    0E77: push hl
    0E78: push bc
    0E79: ld   hl,$0E8B
    0E7C: ld   (hl),$CF
    0E7E: xor  a
    0E7F: cp   c
    0E80: jr   nz,$0E84
    0E84: ld   a,b
    0E85: ld   c,$86
    0E87: call $0E92
      0E92: ld   ($0EA1),a
      0E95: and  $07
      0E97: rlca
      0E98: rlca
      0E99: rlca
      0E9A: or   c
      0E9B: ld   ($0E9F),a
      0E9E: res  0,(hl)
      0EA0: ld   a,$00
      0EA2: ret
    0E8A: ld   a,$CE
    0E8C: out  ($EF),a
    0E8E: pop  bc
    0E8F: pop  hl
    0E90: xor  a
    0E91: ret
  0E73: call $0B9C
    0B9C: ld   a,$D0
    0B9E: out  ($E4),a
    0BA0: call $0BB1
      0BB1: push bc
      0BB2: ld   bc,$0004
      0BB5: jr   $0BB8
      0BB8: dec  bc
      0BB9: ld   a,b
      0BBA: or   c
      0BBB: jr   nz,$0BB8
      0BB8: dec  bc
      0BB9: ld   a,b
      0BBA: or   c
      0BBB: jr   nz,$0BB8

   (loops for 8 instructions)

      0BBD: pop  bc
      0BBE: xor  a
      0BBF: ret
    0BA3: in   a,($E7)
    0BA5: in   a,($E4)
    0BA7: ld   a,$D0		; write a FORCE INTERRUPT cmd to FDC
    0BA9: out  ($E4),a		; will not generate an int, but clears BUSY
    0BAB: call $0BB1
      0BB1: push bc
      0BB2: ld   bc,$0004
      0BB5: jr   $0BB8

   (loops for 16 instructions)
   [n.b.  MESS debugger doesn't show even a single iteration of the
          following four instructions, so I've inserted them here
	  by hand]
      0BB8: dec bc
      0BB9: ld a,b
      0BBA: or c
      0BBB: jr nz $0BB8

      0BBD: pop  bc
      0BBE: xor  a
      0BBF: ret
    0BAE: in   a,($E4)		; read FDC status reg
    0BB0: ret
  0E76: ret
0D10: bit  7,a			; busy bit set?
0D12: ld   e,$08		; prepare not_ready error code in E
0D14: jr   nz,$0D61		; branch if busy

				[n.b.  jump taken, FDC reported BUSY!]
0D61: xor  a			; is error code zero?
0D62: cp   e
0D63: jr   z,$0D69

0D65: dec  a			; yes, error was non-zero, so mark drive
0D66: ld   (ix+$00),a		;   as faulted in table
0D69: ld   a,e
0D6A: or   a
0D6B: pop  hl
0D6C: pop  de
0D6D: pop  bc
0D6E: ret		fd_seek returning

Joined: Aug 2004
Posts: 1,444
Likes: 6
Very Senior Member
Offline
Very Senior Member
Joined: Aug 2004
Posts: 1,444
Likes: 6
I've had problems using wd_fdc as well. In my case (2 different drivers), firstly 0xd0 is sent (which seems to work), followed by 0xc0, which causes the fdc to stop responding, returning status 0x81 forever. I've been patiently waiting for the author of the code to fix it, but nothing so far.

I should point out that using WD1772 works fine, but 1793/2793 etc does not.

Joined: Mar 2001
Posts: 16,805
Likes: 32
R
Very Senior Member
Offline
Very Senior Member
R
Joined: Mar 2001
Posts: 16,805
Likes: 32
brouhaha: are the Z80 and FDC clocks verified correct in that driver? That's generally the first thing to check in a case like that. Does the TRS-80 have any unemulated wait states that would impact how quickly the CPU executes those 24 instructions?

Joined: Feb 2012
Posts: 14
B
Member
OP Offline
Member
B
Joined: Feb 2012
Posts: 14
I have no idea whether the CPU and FDC clocks are configured correctly. I'm not very familiar with MAME or MESS internals, despite MAME containing a tiny bit of C code I wrote. :-)

I mostly brought this up in case anyone else still wants to hack on the Model II support, because I've done some reverse-engineering of Model II TRSDOS that makes it easier for me to interpret captured traces than it might be for someone who hasn't delved into that.

Joined: Mar 2006
Posts: 1,059
Likes: 1
L
Very Senior Member
Offline
Very Senior Member
L
Joined: Mar 2006
Posts: 1,059
Likes: 1
To start with, do you know what mhz z80 and fdc clocks are on a real trs80 model II? (i.e. without waitstates, or if waitstates happen in a consistent pattern which 'steals' clocks like on the appleII, perhaps then with them)
Once we have that information, we can verify or fix that part of the code; if the problem remains after that then we need further fixes elsewhere.

LN


"When life gives you zombies... *CHA-CHIK!* ...you make zombie-ade!"
Joined: Aug 2004
Posts: 1,444
Likes: 6
Very Senior Member
Offline
Very Senior Member
Joined: Aug 2004
Posts: 1,444
Likes: 6
TRS80 Model II was written by Curt, and he would normally have checked his numbers beforehand. In other words, whatever is in there is most likely correct (not counting waitstates of course).

Joined: Feb 2005
Posts: 449
C
Senior Member
Offline
Senior Member
C
Joined: Feb 2005
Posts: 449
If the FDC clock is incorrect, it usually won't load anything at all.

Joined: Feb 2012
Posts: 14
B
Member
OP Offline
Member
B
Joined: Feb 2012
Posts: 14
I'm far from certain where the problem is down in the bowels of MESS, but the FDC is definitely claiming that it's busy 179 CPU clocks (more than 44 microseconds) after the code issues a "force interrupt" command that should abort any operation in progress and set it to "not busy". A real 179x definitely doesn't do that.

Joined: Feb 2012
Posts: 14
B
Member
OP Offline
Member
B
Joined: Feb 2012
Posts: 14
OK, I feel like an idiot. It wasn't the busy bit that was set, it was the drive not ready bit.

Maybe the head load timer simulation isn't correct?

Joined: Feb 2012
Posts: 14
B
Member
OP Offline
Member
B
Joined: Feb 2012
Posts: 14
Looked into it. Nothing to do with head load timer. What's happening is that at some point before continuing to load the system, TRSDOS tries to poll all four drives. It eventually selects drive 0 again, and looks (briefly) for it to report ready before continuing to load the system. However, in MESS drive 0 doesn't go ready again quickly enough after being selected.

With a real 8-inch drive with no motor control, like the Seagate 80x used in the Model II, the ready state of a drive doesn't change when the drive is deselected, it just isn't driven over the interface. When the drive is reselected, the ready state is driven on the interface immediately. If the disk hasn't been removed from the drive, this means that ready will be true instantly (well under a microsecond after the drive is selected). It appears that this is not the case for the set_floppy() implementation, though I haven't yet delved into what it's actually doing.

Page 1 of 2 1 2

Link Copied to Clipboard
Who's Online Now
1 members (box), 29 guests, and 5 robots.
Key: Admin, Global Mod, Mod
ShoutChat
Comment Guidelines: Do post respectful and insightful comments. Don't flame, hate, spam.
Forum Statistics
Forums9
Topics8,973
Posts117,881
Members5,001
Most Online890
Jan 17th, 2020
Forum Host
These forums are hosted by www.retrogamesformac.com
Forum hosted by www.retrogamesformac.com