LisaList2

Advanced search  

News:

2022.06.03 added links to LisaList1 and LisaFAQ to the General Category

Pages: [1]   Go Down

Author Topic: Boot device global  (Read 3870 times)

cheesestraws

  • Jr. Member
  • **
  • Karma: +10/-0
  • Offline Offline
  • Posts: 23
Boot device global
« on: July 17, 2020, 05:20:48 pm »

I'm looking at using $1B3 to determine which device the Lisa booted from.

Looking at the Lisa Boot ROM manual, it says that 0 at this address can mean either the upper 871 floppy or the builtin hard disc.

Is there a "normal" way to disambiguate between these cases?  My immediate idea was to look at the system type at $2AF, but I'm not sure whether there are edge cases here I need to be aware of.
Logged

rayarachelian

  • Administrator
  • Hero Member
  • *****
  • Karma: +101/-0
  • Offline Offline
  • Posts: 772
  • writing the code,writing the code,writing the code
    • LisaEm
Re: Boot device global
« Reply #1 on: July 17, 2020, 07:05:37 pm »

well upper is misleading, it should be lower floppy and 400k. that 871 probably means 860K twiggy. and it gets worse than that, the device number is based on the keystroke to boot off it:

Code: [Select]

125E|                       ;---------------------------------------------------------------------
125E|                       ;  Subroutine to translate keycodes to boot device codes.  Returns
125E|                       ;  with boot code in D2 if match found, else D2 = $F for no match.
125E|                       ;  Also saves boot id in memory, and sets alternate boot indicator.
125E|                       ;  Destroys A3 and D2.
125E|                       ;---------------------------------------------------------------------
125E|
125E| 47FA 001A             XLATE   LEA     KEYTBL,A3       ;get ptr to keycode table
1262| 4282                          CLR.L   D2              ;clear for counter
1264| B01B                  @1      CMP.B   (A3)+,D0        ;do search until match
1266| 6708                          BEQ.S   @2              ;skip if match
1268| 5242                          ADDQ    #1,D2           ;else bump cntr
126A| 4A13                          TST.B   (A3)            ;at end?
126C| 66F6                          BNE.S   @1              ;if not continue scan
126E| 747F                          MOVEQ   #$7F,D2         ;else set for invalid code
1270|                       @2
1270| 11C2 01B3                     MOVE.B  D2,BOOTDVCE     ;save as boot device code
1274| 08C7 001C                     BSET    #ALTBOOT,D7     ;set indicator
1278| 4E75                          RTS                     ;and exit
127A|
127A| F4 F1 F2              KEYTBL  .BYTE   KEY1,KEY2,KEY3            ;1,2,3
127D| F3 E4 01                      .BYTE   KEY4,KEY5,01              ;4,5,reserved (01 is invalid keycode)
1280| E1 E2 01                      .BYTE   KEY6,KEY7,01              ;6,7,reserved
1283| E3 D0 01                      .BYTE   KEY8,KEY9,01              ;8,9,reserved
1286| 01 01 01                      .BYTE   01,01,01                  ;reserved
1289| 01                            .BYTE   01                        ;reserved for power-cycle mode
128A| AF                            .BYTE   ENTRKEY                   ;Enter on numeric key pad
128B|                                                                 ;  (for Monitor access)
128B| 00                    TBLEND  .BYTE   0                         ;ensure on word boundary

i.e. apple-1 for the top (nonexistant on Lisa 2) floppy, apple-2 for (lower) floppy, 3 for the motherboard parallel port (or widget), 4-9 for the cards in slots 1-3
and ofc on a Lisa 1 that's not going to match, and external devices can shift around.
This will help a little bit for the expansion slots:
Code: [Select]
1306|                       ;       Saves card id's in locations $298-$29C
So then you can check for the 2 port card at those addresses. The Dual Parallel port card shows up as ID E002.
Key 8,9 are in slot 3 and if I remove the 2xparallel from slots 1,2 only apple-8+9 show up from the expansion slots, so there is that at least and at 298 we now get 0000 0000 E002. So that's not too bad.

Unfortunately it clears 1b3 before it goes into the service mode so I wasn't able to see the value there to verify if it's 0 for both floppy + profile, or something else, but I expect it'll be mapped to the apple-number from the menu, so most likely 2,3,...9.

I did see 0x0a in there for 09, so not sure if that was something else. I suppose I could patch LisaEm to dump that memory address early during boot.

For the profile I see 02 (bf is in 1b2 as I read the word there):
src/host/wxui/lisaem_wx.cpp:OnMouseMove:5702:Boot device:bf02 slots1-3: 0000 0000 e002| 20:50:18.5 43899151

And from floppy I get 01:
src/host/wxui/lisaem_wx.cpp:OnMouseMove:5702:Boot device:bf01 slots1-3: 0000 0000 e002| 20:52:34.3 39420131

So looks like it's the apple-number -1.
« Last Edit: July 17, 2020, 08:53:56 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

cheesestraws

  • Jr. Member
  • **
  • Karma: +10/-0
  • Offline Offline
  • Posts: 23
Re: Boot device global
« Reply #2 on: July 18, 2020, 07:06:34 am »

Well, I was assuming 871 was Twiggy, since several of the other options say Sony (which I took to mean the 3.5" floppy) and as far as I know those were the only two floppy drives used on Lisas.  At least on the machine I have here (a 2/10), $01 is, correctly, the only floppy drive (Sony).  When I boot from the internal hard disc (apple-1), the boot device is set to 2 ("Profile attached to parallel port or built in hard disc (default)"), even if I do not manually choose a boot device.  So far, so reasonable.  The 2/10 is the only hardware I have actual access to here.

When I run my dump program on IDLE (which allegedly emulates a 2/5), it shows 1 as the boot device for the Sony floppy, and 0 for the internal hard disc.  I don't know if that's just an emulator quirk (after all, "incomplete" is right there in the name :-) ) but the fact that the boot ROM docs show it as possibly an internal hard drive give me pause.

(Note that at the moment I am not necessarily interested in the actual mechanics of how to access the disc; I'm trying to work out essentially a boolean as to whether we booted off an HD or a floppy so I know what driver to use to load the command line interpreter.)

My thought process to implement this as simply as possible is: "the upper floppy drive only exists on lisa1s; there is no such thing as a lisa2 with an upper floppy drive.  Therefore, 0 on a lisa2 must refer to the internal hard drive".
Logged

rayarachelian

  • Administrator
  • Hero Member
  • *****
  • Karma: +101/-0
  • Offline Offline
  • Posts: 772
  • writing the code,writing the code,writing the code
    • LisaEm
Re: Boot device global
« Reply #3 on: July 18, 2020, 11:09:58 am »

To quote Rick and Morty, "Gentlemen, there's an option here you're not seeing":

You can have a different boot block for floppies than for profiles/widgets. This will simplify a lot of things and likely why LOS implements in this way.

A single boot block to boot them all is a lofty goal, but might not be necessary. Sure you'll need to build an installer that once running, knows the device it's writing to is a floppy, twiggy, profile, widget, or SCSI drive, or whatever, and will have to store 2 or 3 different sets of boot blocks (and optionally boot loaders.)

This way, once the boot block loads, it already knows it's booting off a floppy or off a profile. Really the boot block just needs a loop that says, load the next N blocks from the device in some specific sequence and then when you successfully get them all, execute them.

If the boot block is for a 400k floppy (or Twiggy), it needn't do anything but call the boot ROM routines in a loop to read from the drive. When you get far enough to worry about Twiggies, then you can add code to differentiate between upper and lower by looking at 1b3. And I really wouldn't worry about porting this to a Lisa 1. I mean, it's a great thing if you manage to do it, but there are so very few of them out there and likely you're not going to get access to one anytime soon, so don't worry about it until it comes up.

In terms of twiggies upper/lower I suspect that the shared floppy RAM address that holds the DRIVE number (0x00FCC003) doesn't change after reading a block, so when booting off Twiggies, as long as you don't overwrite it (and the BOOT ROM will set for you based on the user picking upper/lower), it will continue to read from the same drive if you call DOREAD.

So you wouldn't need to worry about upper vs lower in the boot block, nor the loader, but maybe the OS will need to know which device it booted from, but it can just read that drive parameter once it's up and knows it booted off a floppy. Looking at the code in the TWGBOOT routine, it even copies the drive number to address 0x535 for you, so if you need it, you can look there, though we don't know if other boot ROMs do the same exact thing or not.

I was wrong about one thing, the Lisa's BOOT ROM (at least H source) doesn't accept VIA address + I/O port spacing parameters, so you can only call the PROREAD function to read off the motherboard parallel port and nothing else. You'll have to use the expansion slot ROMs routines that get copied to RAM to boot from those.

You do have to make the boot block code location independent as the boot ROM will copy status/boot routines from expansion slots to 20000 if they exist.
But you could also cheat a little bit and load your loader blocks to a fixed address in memory that's high enough to be above all the expansion slot ROM copies. Off the top of my head it's either 4K or 2K for each ROM (I forget), so multiply by that 3 and add to 0x20000 and it should be fine as a loader address.

Once your loader is done loading the kernel (or in your case BDOS/BIOS), the boot loader can be discarded and the memory reclaimed.

With hard drives, it's a bit more complex because of expansion slots. But it's fine to hard code the assumptions for the hard disk vs floppy in the boot block itself. You could even add a third type of boot block to boot off expansion slot devices if that makes it easier. But the boot block itself should be as simple as possible.

I wouldn't be surprised if some code in the routines to boot off a specific expansion slot parallel port leave some crumbs behind somewhere to let you know what device to continue reading the next blocks from. You'd need to disassemble them to see however.

In terms of how many blocks to load, you can either hard code the number of blocks in the boot block to read off the device, or rely on the AAAA tags convention. That is, read block 1, if it has AAAA, load block 2, if it has AAAA, read block 3 in memory, ... read block N if it has AAAA, read block N+1, if it doesn't have have AAAA, discard it, and start executing the boot loader you just loaded.

This will ignore interleaving, but that probably doesn't matter all that much as you're not going to load more than maybe 20k-30k worth of loader.

If you want to get fancy, you can use the other tags to tell you the next block number to load, and you can address interleaving that way, but the boot block doesn't have to worry about that.

You could add some sanity checking - if you run out of RAM or load too many blocks or get a read error, then you can put up an error message via the boot ROM code. But you don't have to add all the logic in the boot block itself, and it's ok to have 2-3 different types of boot blocks, and optionally even different loaders depending on how complex/flexible vs small and simple you want to make it.

The boot loader itself can add a checksum routine to ensure it wasn't modified or corrupted, or if you have a bit of space left over in the boot block you can call VFYCHKSM before executing it.

The loader then has to be smart enough to find the other files (BDOS/BIOS/or Kernel in the case of a unixy system) it needs to load and know where to put them before it passes control to them. Some are smart enough to know about whole file systems (such as modern EFI ones).

Others have stringent requirements, or use parameters saved on the disk (or hardcoded in the loader itself) to find where to load the things they need are. They wouldn't need a whole entire file system driver, just enough to find the directory blocks, find the files they need, figure out the sequence of blocks to read and where to put them in memory before passing control to them (i.e. unixy loader that know where to find the kernel in the root directory by a given name that the user can provide/override.)

My advice would be to take Tom's boot loader project and library routines, and add to them as needed, but keep the resulting code as flexible/generic as possible so they can be continued to be used for other things as well as providing you features for GEM.

Since the boot block and loader are going to be released from RAM after the OS is up, it's ok to make them a bit larger than is optimum to make them more flexible, but they still need to be able to fit on a 400k floppy along with whatever OS/installer/apps you want to provide.

Then whatever formatter/installer program you'll provide can install bespoke boot blocks and loaders to the media once the OS is up. So this is where the complexity will be taken care of.

You can even do fun things like map the boot block and loader blocks to a file name inside the OS but mark it somehow as untouchable (in FAT12/16 this would be the System flag + Hidden + Read only Flag in DOSy terms). That way you don't have to duplicate one of the 2 or 3 types of loaders/bootblocks and save some space on the installation/boot disk. Or the boot block/loader can be outside the bounds of the file system and not normally accessible as a file, as UniPlus does (it reserves the 1st 100 blocks for the boot block + loader and they're totally inaccessible from the OS once it's up.)

Those are all valid options.

I'd guess the way IDLE does things for device picking is valid, or else it would have trouble booting anything. If in doubt you can play around with LisaEm as well to verify. And feel free to recompile these emulators and add code to print out what's in memory where, etc.

So tl;dr - have the boot block save a flag in low memory that you pass to the command interpreter.
« Last Edit: July 18, 2020, 11:19:15 am 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

cheesestraws

  • Jr. Member
  • **
  • Karma: +10/-0
  • Offline Offline
  • Posts: 23
Re: Boot device global
« Reply #4 on: July 19, 2020, 08:40:11 am »

Thanks.  This has given me a lot to think about.  I will go and process :-)
Logged
Pages: [1]   Go Up