Code Monkey home page Code Monkey logo

Comments (34)

arnoldrobbins avatar arnoldrobbins commented on May 27, 2024 1

I was able to build and use a 97 Meg disk image using 1400 cylinders X 8 heads X 17 sectors per track. I initialized the disk with the regular diagnostics floppy and the OS loaded just fine.

It sounds like that might be the biggest image one could bootstrap, but perhaps with the FIXDISK 2 and the possible changes to the emulator, it'd be possible to make a larger image to use as a second disk. That would also be pretty cool.

Thanks to Phil for the emulator and Jesse for all the additions. It's really cool to play with a 3B1 again; I had one for several years (it was my first personal computer) and I spent many happy hours with it.

from freebee.

philpem avatar philpem commented on May 27, 2024

Note that the 3B1 hard drive implementation makes this fairly straightforward. The WD2010 is shared between both drives, only the drive selects change.

The implementation would be along the lines of:

  • The hard drive controller context contains two hard drive images (and two sets of drive geometry).
    • These could be encapsulated into a "HardDiscDescriptor" structure.
  • The drive selects are passed along to the WD2010 driver.
  • Depending on the state of the drive select bits, the WD2010 driver reads from either hard disc file "A" or hard disc file "B".

from freebee.

philpem avatar philpem commented on May 27, 2024

P5.1 details are in the OSU STORE archive - http://www.unixpc.org/3b1/osu/documents/P5.1.Z
There's also the Icus II upgrade - http://www.kloepfer.org/hdinstr.html - Appendix VII of that page explains how that works.

MCR2's address is [ef][2a]xxxx - note that code is already present to pass writes along to the WD2010 driver:
The P5.1 PAL is detected by a "feedback signal" (Telephony Status bit D4) which mirrors the state of MCR2 bit 4.

MCR2 bits:

  • D0 - 4th bit of the head select nibble
  • D1 - second hard disk select bit
  • D4 - feedback/detect signal, state can be read as TEL STATUS bit D4

On reset, MCR2 is cleared, which selects the first hard drive.

Code already exists here to implement MCR2:

wd2010_write_reg(&state.hdc_ctx, UNIXPC_REG_MCR2, data);

if (addr == UNIXPC_REG_MCR2) {

Requirements to do this would be:

  • Implement the P5.1 Feedback line
  • Implement support for a second hard disk file in the WD2010 driver

from freebee.

agentbooth avatar agentbooth commented on May 27, 2024

Given the call from main.c:
wd2010_init(&state.hdc_ctx, state.hdc_disc0, 512, 16, 8); // 8 heads, 16 sec/trk
a 16-head hard drive isn't currently supported to an end user unless this call was changed to 16 heads?
A user recently ran into trouble trying a 187MB hd image.

from freebee.

agentbooth avatar agentbooth commented on May 27, 2024

I created a 134217728 (1024cyl, 16head, 16sec/track) hd.img, and changed the call in main.c to:
wd2010_init(&state.hdc_ctx, state.hdc_disc0, 512, 16, 16); // 16 heads, 16 sec/trk
then used the Enhanced Diagnostics disk to initialize with custom params:
1024 (cyl)
16 (trks/cyl)
17 (sec/trk)
This worked but all calls to WD2010 looked to be with head values 0-7, and no writes to MCR2 with the bit set for the extra head. Hmm.. I then tried to install the OS and ended up with a core dump on disk 3. @philpem have you successfully used 16 head images? Low priority issue but just curious if I'm doing something wrong.

from freebee.

philpem avatar philpem commented on May 27, 2024

I've never tried any of this though I think software versions may well be critical. It's probably necessary to use the latest kernel (3.51m) and Diag disks (3.5) -- P5.1 (text file linked above) echoes that.

There might be an upper limit to the number of blocks on the disk too.

I dug out my folder of notes from Freebee -- there's a file called "HWNotes01-15" which goes into a lot of detail about the second hard disk select, and the second head select bit: http://unixpc.taronga.com/documents/HWNotes01-15 . John mostly talks about adding the second hard drive.

The bits are documented in <sys/hardware.h> on the UNIX PC as:

#define HDSEL3  0x0001  /* Hard disk head select bit 3 */
#define DDRIVE1 0x0001  /* Hard disk drive select bit 1 */

I'm wondering if you have the correct diag disk and kernel (FIXDISK 2.0 / 3.51m)?

The head number in the WD2010 register will be between 0 and 7, as it only has three head select bits.

from freebee.

philpem avatar philpem commented on May 27, 2024

Hold up - 17 sectors per track?

https://stason.org/TULARC/pc/3b1-faq/5-6-Can-I-put-a-larger-hard-disk-drive-in-the-UNIX-PC.html

Says the largest disks which can be handled are:

    o   Motherboard revision P3...P5 (WD1010 disk controller)
8 heads x 1024 cyls x 16 sectors/track x 512 bytes/sector  =  67.1MB
  
    o   Motherboard revision P3...P5 (WD2010 disk controller)
8 heads x 1400 cyls x 16 sectors/track x 512 bytes/sector  =  91.7MB
  
    o   Motherboard revision P5.1 (modified) (WD1010 disk controller) 
16 heads x 1024 cyls x 16 sectors/track x 512 bytes/sector = 134.2MB
  
    o   Motherboard revision P5.1 (modified) (WD2010 disk controller)
16 heads x 1400 cyls x 16 sectors/track x 512 bytes/sector = 183.5MB

So 1400 cyl * 16 head * 16 spt is the best possible for a WD2010. Same but with 1024 cyl with a WD1010 controller.

Sounds like the MCR2 logic might be a bit broken, although if memory serves the OS does boot and detect a P5.1 motherboard. That suggests the PAL emulation (at least the detect side) is working.

from freebee.

agentbooth avatar agentbooth commented on May 27, 2024

Yes, I see 17 sectors/track in the /usr/lib/vi data for the drives. (Including the Option 9 - Miniscribe 64MB that we create the 1024x8x16x512byte hd.img) It's probably something related to reserving a sector for a bad block? Maybe we should be creating a 1024x8x17x512byte hd.img, though the current 1024x8x16x512 seems to work fine.. I believe when I tried initializing using 16 sec/tk instead of 17sec/tk, I got some warnings. So went with the 17sec/tk when initializing but used 16 when creating the hd.img (e.g. 1400x8x16x512 when I was trying to make the biggest 8 head HD supported).
17 sectors

from freebee.

agentbooth avatar agentbooth commented on May 27, 2024

I did some research into the MCR2 bit 4 "feedback signal" / P5.1 handling. It does seem to currently be detecting as P5.1 due to PHSTAT* returning 0. I'll check in the MCR2 bit 4 mirroring code I put together. If you change PHSTAT* bit 4 to the opposite, it detects as "P3..P5". Your suggestion about newer 3.51m / FIXDISK2.0 is a good one as I'm not using either on my current testing. In wd2010.c, you have:
// The SDH register provides 3 head select bits; the 4th comes from MCR2.
ctx->head = (ctx->sdh & 0x07) + (ctx->mcr2_hdsel3 ? 8 : 0);
So head should be set > 8 if MCR2 bit 0 DOES get set high. I see writes to MCR2, but bit 0 (HDSEL3) and bit 1 (DDRIVE1) are always zero. I'll probably not mess around with this more right now, but may test with FIXDISK 2.0 and/or 3.51m.

from freebee.

agentbooth avatar agentbooth commented on May 27, 2024

@arnoldrobbins glad you are enjoying Phil’s emulator as much as I have been! So much fun to keep learning new things about the system. According to the Unix PC FAQ:
The operating system, from at least release 3.0, supported an unreleased motherboard revision, P5.1.
And given that the enhanced diagnostics disk offers a hard drive with 15 heads (the maxtor 2190), I feel like we should be seeing accesses to heads greater than 8 when attempting to initialize a 16 head HD in the enhanced diag. (Which I’m not) So I think more work may need to be done on the P5.1 PAL implementation.

from freebee.

arnoldrobbins avatar arnoldrobbins commented on May 27, 2024

@shadyjesse Thanks for the comments. I'm hoping that the emulator will eventually support what's needed. Then perhaps we can make bigger disks. In particular, also being able to support a second hard drive would be really cool.

from freebee.

agentbooth avatar agentbooth commented on May 27, 2024

I spent a bunch of time researching this today.
According to HWNotes01-15,
revlev: 0 = P2 or less
revlev: 1 = P3..P5
revlev: 2 = P5.1

  • If you mirror MCR2 bit 4 to PHSTAT* bit 4, you get P3..P5 on startup, and revlev=1.
  • If you mirror the inverse of MCR2 bit 4 to PHSTAT* bit 4, you get P5.1 on startup (good), BUT revlev=0 (bad).

If you manually edit the revlev to 2 using adb, sure enough you magically start getting access attempts to the 2nd hard drive bit if you try to mount /dev/fp012 (2nd HDD)! So it seems to me, the current display of P5.1 on startup may be a bug/misnomer as the revlev in the running kernel is revlev=0. It should be revlev=2 if we are properly detected a P5.1. That's all I have for now! Getting pretty burned out on this as it seems fairly straightforward to just mirror the bit 4 but it's not working...

from freebee.

arnoldrobbins avatar arnoldrobbins commented on May 27, 2024

This is really nice progress.

Have you tried the 3.51m kernel, supposedly from the FIXDISK 2.0? Maybe that will make the difference?

from freebee.

agentbooth avatar agentbooth commented on May 27, 2024

from freebee.

arnoldrobbins avatar arnoldrobbins commented on May 27, 2024

So, it sounds like it's necessary to get the emulator to give the kernel the right bits... OK. I hope this can be made to work. Thanks!

from freebee.

philpem avatar philpem commented on May 27, 2024

Seems like the revision level checking implementation isn't quite complete.

One of my 3B1s came with source code on the hard disk, so I went digging:

// from /usr/include/sys/hardware.h
#define PE_INT_GCR_ADDR ((unsigned short *)0xE41000) /* PIE+ */
#define PE_INT_ENABLE  0x8000  /* PIE 1=enable PE's */
#define PE_INT_DISABLE 0x0000  /* PIE 0=disable PE's */
#define GSR_ADDR  ((unsigned short *)0x410000)
#define REV_LSB  0x8000  /* hardware revision - NC in P2 */
#define REV_MSB 0x0800  /* REV_LSB = PIE status in P3 */

// Version check from the kernel sources

/* Check the revision level of the board in GSR.
 *
 *           D15     D11
 *  P2       NC      NC
 *  P3       PIE     NC
 */
revlev = 0;  /* default is P2 */

/* This code depends on parity being already enabled.
 * First check for P2 or P3 */

if (*GSR_ADDR & REV_LSB) {
  *PE_INT_GCR_ADDR = PE_INT_DISABLE;
  if (!(*GSR_ADDR & REV_LSB))
    revlev = 1;
  *PE_INT_GCR_ADDR = PE_INT_ENABLE;
}


/* Now check for P6 */
{
  int lev = 0;
  int i;
  for (i=0; i<5; i++)
  {
    *MCR2_ADDR = (mcr2_save |= P3_P6);
    if( *PHONE_STATUS & P3_P6 )
    {
      *MCR2_ADDR = (mcr2_save &= ~P3_P6);
      if( !( *PHONE_STATUS & P3_P6 ) )
        lev++;
    }
  }
  if (lev == i) revlev++;
}

The valid values for revlev are:

revlev Motherboard revision
0 P1 or P2 (I've never seen one of these, but the kernel apparently 'kinda' supports them)
1 P3, P4 or P5 (standard 3B1/7300 UNIX PC)
2 P5 with P5.1 disk expansion PAL (aka P6)

The failure mode is:

  • The PIE loopback in GSR (REV_LSB) is missing, which makes the first revision check fail. (revlev == 0)
  • The P5.1 (P6 according to this) PAL check passes, because we're emulating a "P5.1" disk expansion PAL. (revlev++)

End result is revlev ends up (incorrectly) set at 1, which is a P3..P5 motherboard with no disk expansion PAL.

The disk driver checks revlev is at least 2 before writing to MCR2 -- which is why we're not seeing upper head or second disc selects.

So why does the version check say P3..P5 on boot?

// from /usr/src/UTS/kern/os/machdep.c
printf("Main board is %s", revlev - 1 ? "P5.1" : "P3...P5" );

revlev == 0 would show as a P5.1 (wrong!)
revlev == 1 would show as a P3..P5 (only correct if the first rev check passes)
revlev == 2 would show as a P5.1 (unconditionally correct)

Time for a patch...

from freebee.

philpem avatar philpem commented on May 27, 2024

Hardware rev wise, it seems like P3 added the line printer interrupt status -- and possibly the printer port:

./usr/include/sys/hardware.h:#define LPINTRQ»···»···0x200»··»···/* ???»·1=line printer intr (P3 only) */

Regardless, there's little sense emulating anything below P3, because the kernel doesn't seem to support it correctly!
There might be an argument for adding a P5.1 on/off switch, but it's a thin one as the P5.1 mod is fully backwards compatible.

from freebee.

agentbooth avatar agentbooth commented on May 27, 2024

from freebee.

agentbooth avatar agentbooth commented on May 27, 2024

Just checked in a fix which gets us to revlev = 2, yay!

from freebee.

agentbooth avatar agentbooth commented on May 27, 2024

from freebee.

philpem avatar philpem commented on May 27, 2024

Merged PR #27 which is related to this

from freebee.

agentbooth avatar agentbooth commented on May 27, 2024

HD 16 head
I just did an install using the Enhanced Diagnostics disk, initializing a drive to 512 cyl, 16 heads, 17 sec/tk. Heads > 8 was being written to MCR2. Looks like it works! Theoretically a 1400 cyl x 16 head drive should now work too. 😎

from freebee.

arnoldrobbins avatar arnoldrobbins commented on May 27, 2024

This is cool. I tried to do a disk with 1400 cylinders and 16 heads and the enhanced diag disk wouldn't do it.

I remain confused how 17 sectors/track can work when the code has a hard limit of 16 sectors per track in the call to wd2010_init.

Can you try a 1400 cyl X 16 head drive?

It seems like any number above 512 for number of cylinders won't work with 15 or 16 heads. So some more work is still needed somewhere.... Thanks!

from freebee.

agentbooth avatar agentbooth commented on May 27, 2024

from freebee.

agentbooth avatar agentbooth commented on May 27, 2024

big boy format complete
big boy formatting
big boy installed
big boy ivt
This drive is HUGE! Install seemed to go fine.

from freebee.

philpem avatar philpem commented on May 27, 2024

I'm not sure the "spare sector" idea is correct. If I remember rightly, the UNIX PC version of SysV uses sectors in pairs to form 1K-blocks. I don't think the disk driver is smart enough to use the 17th sector as a "spare" (as it'd only have one spare per 2 tracks). I wouldn't be at all surprised if it wasted 1/17th of the disk capacity.

If you calculate back from the numbers it gives you, it seems like that's what's happening:

  • 179200 blocks / 1400 cylinders = 128 sectors per cylinder
  • 128 sectors / 16 heads = 16 sectors per track

It formats 17 sectors as specified by the drive manufacturer, but only uses 16.

The S4 FS mounter (https://github.com/dad4x/s4-3b1-pc7300) source code might give a better idea.

1400x16x16 = 175MB sounds like a pretty incredible amount of disk space for a 3B1, especially if there were two disks set up in parallel. Pretty crazy to think about, actually.

from freebee.

agentbooth avatar agentbooth commented on May 27, 2024

from freebee.

arnoldrobbins avatar arnoldrobbins commented on May 27, 2024

@shadyjesse I cannot format a 1400 x 16 x 16 x 512 file. See screenshot. Just to be safe I did a git pull and rebuild from scratch, but no luck. See attached screenshot. How are you doing it? Thanks.
Screenshot at 2020-11-21 20-40-34

I get a lot of "WD2010 ALERT: track 0 out of range" errors. (BTW, you need \n on those messages you changed from LOG to fprintf. :-) )

from freebee.

arnoldrobbins avatar arnoldrobbins commented on May 27, 2024

@philpem I think the filesystem on the 3B1 was the original Unix 512 byte sector filesystem. It's a System V Release 1 kernel with some enhancements from the SVR2 user space in 3.51 set. There was a 1K block filesystem but I think that wasn't until SVR3 or SVR4.

I am guessing that the 17th sector was for bad block handling; there was often a table in the superblock as to the location of bad blocks and then there were spare blocks that could be used. HOWEVER, I could be totally wrong on this; the OS source code might shed some light here too. Jessy's question about 16 vs. 17 tracks to use with the s4 tools is a good one and should be investigated...

And of course, one more "why won't he just go away" question from me. Now that it looks to be possible to support 2 drives, what's involved in making the emulator support a second hd.img file?

THANKS again for all the work both of you are doing and have done.

from freebee.

philpem avatar philpem commented on May 27, 2024

@arnoldrobbins You haven't created the hard disk file -- check the README for instructions on how to do that.

This dd command should create a 1400x17x16x512 disc image for you:

dd if=/dev/zero of=hd.img bs=512 count=$(expr 17 \* 16 \* 1400)

You'll also need to modify main.c to call wd2010_init like this:

wd2010_init(&state.hdc_ctx, state.hdc_disc0, 512, 17, 16);

The default is 8 heads, 16 sectors per track, and the track count is autodetected.

Supporting a second drive select would involve modifying the WD2010 driver to open two hard disk files at startup, figure out the geometry for both, and pick the appropriate one when doing a disk access.

The hard-coded hard disk geometry isn't ideal, and seems (to me) like fixing that would be a pretty good excuse to add a config file. My preference would be something like JSON (using the cJSON library, https://github.com/DaveGamble/cJSON). That would also give us the option of having lists of floppy images which can be stepped through for e.g. software installation.

from freebee.

philpem avatar philpem commented on May 27, 2024

... and as for that printf issue, I just pushed a commit to fix it!

from freebee.

arnoldrobbins avatar arnoldrobbins commented on May 27, 2024

@philpem Bless your heart! (An old Southern US saying.) I made that change and now it's humming along just fine! I will try an install.

Any reason not to just push that? Thanks!!!!

from freebee.

agentbooth avatar agentbooth commented on May 27, 2024

@philpem Thanks for fixing those printf's.

By this logic, using 17sec/trk, I think we should change the instructions to:
dd if=/dev/zero of=hd.img bs=512 count=$(expr 17 \* 8 \* 1024)
This creates a "Miniscribe 64MB" (CHS 1024:8:17, 512 bytes per sector).

Which should then match the /usr/lib/iv for the miniscribe 64.
And change the reference:
"Sectors per track fixed at 16." to 17
and the init call to:
wd2010_init(&state.hdc_ctx, state.hdc_disc0, 512, 17, 8);

Does that make sense to you Phil?
Power users like Arnold can edit the wd2010_init call to 16 heads and make a bigger hd.img and track down the Enhanced Diagnostics disk if desired -- until there's a proper config file.

from freebee.

arnoldrobbins avatar arnoldrobbins commented on May 27, 2024

With the merge of PR #29, the code reads the geometry from the header supplied by the diagnostic disk or by the new makehdimg program, and sets things up correctly. Additionally, that PR provides support for emulating the second disk. So I think this issue can be closed. :-) Thanks!

from freebee.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.