6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Mon May 13, 2024 12:46 pm

All times are UTC




Post new topic Reply to topic  [ 14 posts ] 
Author Message
PostPosted: Sat Oct 08, 2022 1:23 am 
Offline
User avatar

Joined: Tue Mar 05, 2013 4:31 am
Posts: 1373
As I've been using a 6GB Microdrive for a while now on a prototype 3.3v system, I've been using a ROM based version of Richard Leary's DOS/65. I just use a Ctrl key from the Monitor code and it starts up DOS/65 and you're off an running.

As I'm looking to go to a more capable system (more memory, banking, faster CPU) I'm also looking to have the operating system booted from the drive and run entirely in RAM (sans the ROM based BIOS).

The memory configuration for the C02 Pocket:
- 32KB SRAM from $0000 - $7FFF
- 32KB EEPROM from $8000 - $FFFF
An I/O window is configure at $FE00 and has 5- 32-byte wide selects

The updated memory configuration for the 3.3V prototype:
- 56KB SRAM from $0000 - $DFFF
- 8KB EEPROM from $E000 - $FFFF
An I/O window is unchanged at $FE00

The 8KB of EEPROM will remain as:
- BIOS from $F800 - $FFFF (sans the I/O window)
- Monitor from $E000 - $F7FF

Rather than enable an autoboot from the Microdrive, I prefer to be able to run the system without the bootable OS so I have options on doing other things... the Monitor supports Xmodem CRC upload and download capability.

Now the fun part... I actually wrote custom partition loaders back in the 80's, as the PC-AT only had a handful of defined disk drive parameters, so if you had a drive that wasn't part of the ROM table, you couldn't really use it fully or maybe worse. I wrote a a custom partition loader that would softload the disk parameters for the BIOS and then load the boot record to kick off the OS load... worked like a charm. So I get to do some of this stuff again.

Here's my basic scheme:

******************************************************************************************************
Microdrive Bootable design:
******************************************************************************************************
LBA mode is used exclusively!

When the C02 Pocket is powered up:
- BIOS initializes the system:
- Clear Page Zero
- Load Page $03 with Vector and Soft Config data
- Initialize SC28L92 DUART and Timer/Counter
- Show BIOS version message
- Initialize additional hardware
- Maxim DS15x1 Realtime Clock
- Microdrive IDE interface
- Cold start System Monitor

- Monitor code will display some version information, user prompt
- Using a Ctrl-B will Load LBA zero from Microdrive to memory $0600
- Will sense Partition code signature (0x02 0x65)
- If signature Valid, will Jump to Boot code in memory
- If signature Invalid, will show error message and warm start monitor
******************************************************************************************************
LBA zero contains an Ontrack Disk Manager partition record.

- 252 bytes of code
- optional 2 byte signature: suggested use as (0x02 0x65) 6502 in little-endian

- There are 4 standard partition entries - 16 bytes each
- There are 12 expanded partition entries - 16 bytes each

- 2 bytes final signature (0x55, 0xAA)

******************************************************************************************************
Note: Partition type for CPM is hex “DB”

A 16-byte partition record is defined as:

Offset: Length Description
0x00 1 byte Status byte - bit 7 set (0x80) = active, else 0x00
0x01 3 bytes CHS address first sector in partition
0x04 1 byte Partition Type (CPM = hex DB)
0x05 3 bytes CHS address last sector in partition
0x08 4 bytes LBA of first block in partition
0x0C 4 bytes Number of Blocks in partition

Note: Will only use the last two entries for LBA addressing.
- this means that both CHS fields are zeroed out.

The Partition Record Boot code will determine the active partition and size.
- it will set parameters for the BIOS/SIM modules.
- It will then load the Boot Record for the active partition
- The Boot Record:
Contains 16KB of system tracks (separate from drive partitions)
System Tracks contain:
- SIM Module - interfaces PEM to BIOS
- Disk Parameter Blocks
- Disk Allocation Maps
- PEM module - core filesystem for DOS/65

The Boot Record code will load the system tracks into high memory
- Memory Locations are contained in the Boot Record
- Once loaded, a jump to SIM entry will start the boot process
for DOS/65. SIM will:
- initialize all of the DPBs and Allocation Maps
- Jump to PEM to initialize the filesystem
PEM starts:
- PEM will cold boot
- PEM will select Drive A for default
- PEM will load CCM from Drive A into high memory
- PEM will jump to CCM and the user is up and running

******************************************************************************************************

Writing a disk setup utility (dare I call it fdisk) will allow multiple partitions to be booted. With 6GB of space, I can have multiple OSes on the drive and even keep multiple versions for testing, etc.
Of course, one of the plans is to get CPM65 up and running as well (see other other thread for that).

I have a plan.... modify the hardware first, update the BIOS and Monitor code as required, write a fdisk style utility and get SYSGEN running for the updated DOS/65 code. It's not going to happen super fast, but this is the plan to get there.

Ideas, feedback, criticism, all welcome.

_________________
Regards, KM
https://github.com/floobydust


Top
 Profile  
Reply with quote  
PostPosted: Sat Oct 08, 2022 10:30 am 
Offline
User avatar

Joined: Fri Aug 03, 2018 8:52 am
Posts: 746
Location: Germany
I was also thinking about adding bootable drive support to my 65816 SBC, but i would personally keep everything within the file system.
mainly to avoid having to fiddle with the raw bytes of the storage drive. but also to make it simplier to create a bootable drive using a modern System like a PC.

So my idea would be to just have a text file in the root directory called "boot.cfg", if a drive is not present or the file doesn't exist then the system just boots into the monitor or from serial.
but if the file is found it is read out. the format is pretty simple, every line has a path to the executable file, and a name that gets displayed in a list to choose from:
Code:
"DISPLAY NAME" = "FILE PATH"

the qoutes are used to allow for spaces in both the name and file path.
so for example if you have a "boot.cfg" file that looks like this:
Code:
"DOS/65" = "DOS65\main.bin"
"CP/M65 (custom)" = "CPM65\custom\cpm.bin"
"CP/M65 (original)" = "CPM65\custom\cpm.bin"
"Test Monitor" = "Monitor\test version\mon.bin"

then upon power up, the System could display the a selection like this (example):
Code:
Press a key corresponding to the program you want to load:
Disk:
0 - DOS/65
1 - CP/M65 (custom)
2 - CP/M65 (original)
3 - Test Monitor
Internal:
y - ROM Monitor
z - Serial

of course there would have to be limits for how many lines the boot.cfg file can have, or how long a display name can be. but i still like this idea, also because the system itself can add/remove entries from boot.cfg, allowing programs to be "installed" onto the drive.


Top
 Profile  
Reply with quote  
PostPosted: Sat Oct 08, 2022 3:26 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8182
Location: Midwestern USA
Proxy wrote:
I was also thinking about adding bootable drive support to my 65816 SBC, but i would personally keep everything within the file system.

Not to start any kind of a war, but I think flooby’s scheme is better and more flexible with regard to the types of mass storage that can be supported. Reading physical block zero (the MBR in the PC world) from the medium will work no matter the medium capacity, layout, block size, etc. That’s what I do in my POC units: read a boot block, which contains enough code to load a stage two loader that can then load and execute an operating system, mount filesystems, etc.

Quote:
mainly to avoid having to fiddle with the raw bytes of the storage drive...

That, in my opinion, is an unattainable goal. At the very start of the ISL process, you have to read the boot device at the raw level. In modern systems, that happens in the firmware, usually as the final stage of POST and basic system configuration.

Quote:
...but also to make it simplier to create a bootable drive using a modern System like a PC.

To make a disk bootable, I run a small program on my POC unit that prepares the boot disk. It writes a logical boot block (physical blocks $00 and $01—logical block size on a hard disk is 1KB), creates an empty filesystem table and gives the disk a “volume name” that uniquely identifies it to the system (as POC uses “narrow” SCSI storage, there can be up to seven disks attached). The boot block includes a “magic number” that marks the disk as bootable, with the first and second bytes of the block being a vector to the start of the boot loader.

What the boot block structure doesn’t do is make any assumptions about filesystem types. The second-stage boot loader is where the filesystem table is examined, which is done by a raw disk read operation..

The only part in which a PC gets involved is in assembling the prep software and sending it (as S-records) to the POC unit for execution. Once that software has been run, the POC unit is capable of booting without external assistance.

Quote:
So my idea would be to just have a text file in the root directory called "boot.cfg", if a drive is not present or the file doesn't exist then the system just boots into the monitor or from serial.

That doesn’t eliminate the need to access the disk at the raw level. Something has to have enough knowledge about the disk to be able to find the origin of the root directory and locate a boot loader and configuration file.

Quote:
so for example if you have a "boot.cfg" file that looks like this:
Code:
"DOS/65" = "DOS65\main.bin"
"CP/M65 (custom)" = "CPM65\custom\cpm.bin"
"CP/M65 (original)" = "CPM65\custom\cpm.bin"
"Test Monitor" = "Monitor\test version\mon.bin"

What’s with those ‘\’ characters in the pathname? :shock:

What you are proposing is a monolithic filesystem containing disparate operating environments. I can see some potential headaches with such an arrangement.

As for the monitor, it might be more useful if it is part of the firmware, not a loadable binary. Having it readily available in the firmware would be handy for debugging your setup, especially in getting your boot loader to function. As you have it, you wouldn’t be able to use the monitor to debug the boot loader if the latter is on the fritz.

BTW, CP/M and MS-DOS are not sterling examples of how to developing mass storage software.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
PostPosted: Sat Oct 08, 2022 4:02 pm 
Offline
User avatar

Joined: Wed Feb 14, 2018 2:33 pm
Posts: 1412
Location: Scotland
I've watched bootstrap systems change over the years - from keying in a loader to having enough ROM on-board to read a file out of a FAT filing system. (With the BBC Micro being a curiosity in that both the OS and filing system code would normally be all in ROM - although separate ROMs as there are many different filing systems to choose from including network)

Also, I've recently done some work on a "bare-metal" system on the Raspberry Pi - the Pi boots (this is specifically, older Pi's) by having the ROM read a single file (bootcode.bin) from the first (MBR style) partition on the SD card and executing that file. Current versions of that file will try to read the rest of the bootstrap files from the SD card, or if not present can network boot.

Based on that, if I were developing another 65xx SBC, I suspect I'd try to get enough code inside a ROM to do just that - read a single file from the media - if that's not present, read a file from serial (using e.g. XModem) and jump to it - or, based on e.g. a keyboard flag drop into a monitor.

I'm fairly sure I could get enough code together to do that inside a modest ROM in a 65xx system, but I've never tried, so don't quite know for sure. My own filing system (a bit like ProDOS) compiled on an ATmega is about 5KB of compiled C and that's quite full featured. ProDOS on the Apple II is some 10KB (I think), so I suspect that a very cut-down fragment of code to read a single file would be much smaller on the 65xx - especially with relatively simple hardware such as SPI interface to SD or some form of 8-bit parallel IDE interface.

That does sort of limit you to FAT for at least the first partition, (and an MBR partition table for the entire 'disk') but Pi's use subsequent partitions for native Linux file systems, so if you have a different filesystem then it shouldn't be hard - with the advantage that you can at least read/write the first partition from any computer that supports the physical media (something I regret about developing my own FS in my Ruby boards... One day I'll either change it to FAT or write a Linux FUSE driver, but that day is not going to happen soon...)

My Pi development system currently boots off SD then network boots everything else. It adds a few seconds but is better than swapping out SD cards. I'm sure that with the right smart terminal program you could reset the 65xx, have it Xmodem a file and be running your "kernel" in just a few seconds too. your kernel can then access the disk as normal and take it from there....

-Gordon

_________________
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/


Top
 Profile  
Reply with quote  
PostPosted: Sat Oct 08, 2022 4:32 pm 
Offline

Joined: Fri Dec 21, 2018 1:05 am
Posts: 1076
Location: Albuquerque NM USA
Floobydust,
You've mentioned possibly using CPLD like ATF1504 in your design. If so you can easily include 64 bytes of ROM in CPLD that serves as power-on/bootstrap code to load & execute the 446 bytes in the master boot record reserve for this purpose. 446 bytes are a lot of program so you can do most everything after that. You really don't need a ROM chip, your mass storage is your ROM.
Bill


Top
 Profile  
Reply with quote  
PostPosted: Sat Oct 08, 2022 6:12 pm 
Offline
User avatar

Joined: Fri Aug 03, 2018 8:52 am
Posts: 746
Location: Germany
BigDumbDinosaur wrote:
Proxy wrote:
I was also thinking about adding bootable drive support to my 65816 SBC, but i would personally keep everything within the file system.

Not to start any kind of a war, but I think flooby’s scheme is better and more flexible with regard to the types of mass storage that can be supported. Reading physical block zero (the MBR in the PC world) from the medium will work no matter the medium capacity, layout, block size, etc. That’s what I do in my POC units: read a boot block, which contains enough code to load a stage two loader that can then load and execute an operating system, mount filesystems, etc.

oh so you mean that reading a raw block is always possible regardless of the actual filesystem of the rest of the storage drive. yea that makes sense, but i just don't like invisible things sitting on the drive because i know i would somehow frick up the code and overwrite the entire FAT table or something.
BigDumbDinosaur wrote:
Quote:
mainly to avoid having to fiddle with the raw bytes of the storage drive...

That, in my opinion, is an unattainable goal. At the very start of the ISL process, you have to read the boot device at the raw level. In modern systems, that happens in the firmware, usually as the final stage of POST and basic system configuration.

what does ISL mean? google only brings up things related to mining underground ore deposits using pipes.
anyways, yes of course you still have to actually implement the filesystem in the first place (unless you don't with chips like the CH376 or similar), but the idea was that you would only need to implement the filesystem itself, no additional functions required to access boot sectors/blocks.
BigDumbDinosaur wrote:
Quote:
...but also to make it simplier to create a bootable drive using a modern System like a PC.

To make a disk bootable, I run a small program on my POC unit that prepares the boot disk. It writes a logical boot block (physical blocks $00 and $01—logical block size on a hard disk is 1KB), creates an empty filesystem table and gives the disk a “volume name” that uniquely identifies it to the system (as POC uses “narrow” SCSI storage, there can be up to seven disks attached). The boot block includes a “magic number” that marks the disk as bootable, with the first and second bytes of the block being a vector to the start of the boot loader.

What the boot block structure doesn’t do is make any assumptions about filesystem types. The second-stage boot loader is where the filesystem table is examined, which is done by a raw disk read operation..

The only part in which a PC gets involved is in assembling the prep software and sending it (as S-records) to the POC unit for execution. Once that software has been run, the POC unit is capable of booting without external assistance.

yea that works fine because your POC is designed to be very independent. but my idea was something that allows any (modern-ish) system to prepare a drive without the need for an hex editor for example to manually write boot blocks or for the target system to run a specific program to do it itself. so building it entirely ontop of the filesystem is pretty much the only choice for that goal.
BigDumbDinosaur wrote:
Quote:
So my idea would be to just have a text file in the root directory called "boot.cfg", if a drive is not present or the file doesn't exist then the system just boots into the monitor or from serial.

That doesn’t eliminate the need to access the disk at the raw level. Something has to have enough knowledge about the disk to be able to find the origin of the root directory and locate a boot loader and configuration file.
[/quote]
that is true, but i assume the system ROM contains enough code to handle a storage device and the filesystem (or again some external chip/co-processor does that work for the system).
BigDumbDinosaur wrote:
Quote:
so for example if you have a "boot.cfg" file that looks like this:
Code:
"DOS/65" = "DOS65\main.bin"
"CP/M65 (custom)" = "CPM65\custom\cpm.bin"
"CP/M65 (original)" = "CPM65\custom\cpm.bin"
"Test Monitor" = "Monitor\test version\mon.bin"

What’s with those ‘\’ characters in the pathname? :shock:

i'm not sure if you're joking or not, but in case you're not, those denote subdirectories. again it's just an example so a more finalized version might use normal slashes or allow for both, or use something entirely different. it's a matter of personal preference.
BigDumbDinosaur wrote:
What you are proposing is a monolithic filesystem containing disparate operating environments. I can see some potential headaches with such an arrangement.

I mean that's how i work on multiple projects on my PC, each of them just gets their own folder to put stuff into. definitely more convenient and less expensive than having a seperate drive for each.
i don't know how else you would handle having multiple programs on the same drive without introcuding too much complexity and inconveniences like multiple partitions.
BigDumbDinosaur wrote:
As for the monitor, it might be more useful if it is part of the firmware, not a loadable binary. Having it readily available in the firmware would be handy for debugging your setup, especially in getting your boot loader to function. As you have it, you wouldn’t be able to use the monitor to debug the boot loader if the latter is on the fritz.

i never meant to imply that it would be a loadable binary, the selection example listed it as "internal" and it had the word "ROM" infront of it. the "Test Monitor" that was in the boot.cfg example was meant as a, well... TEST monitor, something someone could be currently developing as an improvement to the current ROM one, without having to constantly reprogram the ROM to test it.
BigDumbDinosaur wrote:
BTW, CP/M and MS-DOS are not sterling examples of how to developing mass storage software.

I'm not really sure what you mean with "mass storage software". i'm not that familiar with CP/M and it is somewhat similar to how MS-DOS handles programs, but with DOS you have to manually go through subdirectories to find the executables, while this handles the full path for you and just gives you a list of the ones you wanted to be listed.
drogon wrote:
Based on that, if I were developing another 65xx SBC, I suspect I'd try to get enough code inside a ROM to do just that - read a single file from the media - if that's not present, read a file from serial (using e.g. XModem) and jump to it - or, based on e.g. a keyboard flag drop into a monitor.

yes that was my intial idea too, but i didn't like only having a single bootable file with a hardcoded name and location. so that's where the idea came from to instead have a text file with a hardcoded name and location that would then point to the location of bootable files. (sort of like an indirect addressing mode)

.

anyways this reply got waaaay too long, sorry for taking up so much of the page! :oops:


Top
 Profile  
Reply with quote  
PostPosted: Sat Oct 08, 2022 6:16 pm 
Offline

Joined: Fri Dec 21, 2018 1:05 am
Posts: 1076
Location: Albuquerque NM USA
drogon wrote:
Based on that, if I were developing another 65xx SBC, I suspect I'd try to get enough code inside a ROM to do just that - read a single file from the media - if that's not present, read a file from serial (using e.g. XModem) and jump to it - or, based on e.g. a keyboard flag drop into a monitor.
-Gordon

This is my power-on/bootstrap program in CRC65. It resides in EPM7064/ATF1504 CPLD. It is 64 bytes long with two options; CF bootstrap from master boot record or serial bootstrap. It polls both serial data ready and CF busy and take advantage of the fact that CF needs 1/2 second after reset to be ready. So if a keypress is sent to the serial port immediately after reset, CRC65 will enter the serial bootstrap mode; otherwise it boots from CF disk. I also take advantage of the IDE spec that the CF disk will always point to the master boot record after a reset to minimize the amount of initialization code. CF does default to the native 16-bit mode and I don't have code space to change it to 8-bit mode, so I discard the high byte of 16-bit word in the master boot record, so effectively only have half of 446 bytes (223 bytes) for level 2 bootstrap code--it is more than enough, the actual code is 119 bytes.

The 64-macrocell CPLD can accommodate the 64-byte ROM code and still have logic left for a serial port, CF interface, memory decode, and I2C interface.
Bill

Code:
000000r 1               ;1/7/20
000000r 1               ;ROM in CPLD of CRC65
000000r 1               ; two sections of code:
000000r 1               ;   serial bootstrap is 21 bytes, strapped to high ROM
000000r 1               ;   CF bootstrap is 38 bytes, strapped to low ROM
000000r 1               ; CF is in native 16 bit mode
000000r 1               ; only the low byte contains meaningful program
000000r 1               ; read data from master boot sector
000000r 1               ;   execute the program in master boot sector to load more program
000000r 1               
000000r 1               ;load 256-byte binary file to 0xB000
000000r 1               SerData = $f0f9      ;CPLD serial register
000000r 1               SerStat = $f0f8      ;CPLD serial status, bit 0 is receive ready, bit 1 is txempty
000000r 1               CFdata   = $ee00       ;CF data register
000000r 1               CFerr   = $ee01       ;CF error reg
000000r 1               CFsectcnt   = $ee02       ;CF sector count reg
000000r 1               CF07   = $ee03      ;CF LA0-7
000000r 1               CF815   = $ee04          ;CF LA8-15
000000r 1               CF1623   = $ee05          ;CF LA16-23
000000r 1               CF2427   = $ee06          ;CF LA24-27
000000r 1               CFstat   = $ee07          ;CF status/command reg
000000r 1               
000000r 1                  .ORG $ff80
00FF80  1               readbsy:
00FF80  1  AD F8 F0        LDA SerStat   ;check receive ready
00FF83  1  29 01           AND #1      ;receive ready is bit 0
00FF85  1  D0 1F           BNE serboot   ;if serial data ready, do serial bootstrap
00FF87  1  AA              TAX      ;initialize X to zero
00FF88  1  AD 07 EE        LDA CFstat   ;read CF status
00FF8B  1  2A              ROL      ;busy bit is bit 7
00FF8C  1  B0 F2           BCS readbsy   ;loop until either CF ready or received serial data
00FF8E  1  A9 20           LDA #$20   ;issue read CF command
00FF90  1  8D 07 EE        STA CFstat
00FF93  1               chkdrq:
00FF93  1  AD 07 EE        LDA CFstat   ;check data request bit set before read CF data
00FF96  1  29 08           AND #8      ;bit 3 is DRQ, wait for it to set
00FF98  1  F0 F9           BEQ chkdrq
00FF9A  1               getCFdata:
00FF9A  1  AD 00 EE        LDA CFdata
00FF9D  1  9D 00 B0        STA $b000,x   ;get 256 bytes of data to $b000
00FFA0  1  E8              INX
00FFA1  1  D0 F7           BNE getCFdata
00FFA3  1  4C 00 B0        JMP $b000
00FFA6  1               serboot:
00FFA6  1  AD F9 F0        LDA SerData   ;discard the first serial data
00FFA9  1               serboot1:
00FFA9  1  AD F8 F0        LDA SerStat
00FFAC  1  6A              ROR      ;receive ready is bit 0
00FFAD  1  90 FA           BCC serboot1   ;if serial data ready, do serial bootstrap
00FFAF  1  AD F9 F0        LDA SerData
00FFB2  1  9D 00 B0        STA $b000,x
00FFB5  1  E8              INX
00FFB6  1  D0 F1           BNE serboot1
00FFB8  1  4C 00 B0        JMP $b000


Top
 Profile  
Reply with quote  
PostPosted: Sat Oct 08, 2022 6:30 pm 
Offline
User avatar

Joined: Wed Feb 14, 2018 2:33 pm
Posts: 1412
Location: Scotland
Proxy wrote:
drogon wrote:
Based on that, if I were developing another 65xx SBC, I suspect I'd try to get enough code inside a ROM to do just that - read a single file from the media - if that's not present, read a file from serial (using e.g. XModem) and jump to it - or, based on e.g. a keyboard flag drop into a monitor.

yes that was my intial idea too, but i didn't like only having a single bootable file with a hardcoded name and location. so that's where the idea came from to instead have a text file with a hardcoded name and location that would then point to the location of bootable files. (sort of like an indirect addressing mode)

.

anyways this reply got waaaay too long, sorry for taking up so much of the page! :oops:


Sooooo... Rather than a fixed name boot code you have a fixed name config file ;-)

And oddly enough that's almost how the Pi does it - after the bootcode.bin loads it then looks for a config.txt file with all the gory details of what to load next, video modes, serial speeds, overclocking, and much stuff like that. That's pulled from local SD card or over the 'net. I guess it's quite a small ROM in there...

(Although not relevant here, the way the Pi boots is to boot the GPU processor(s) first - that's bootcode.bin this then pulls in the ARM executable for the ARM side of things - not that far from the way my Ruby boards boot - the ATmega boots first from it's internal flash, then it copied 200 bytes of 1st stage bootloader into 6502/816 RAM from the internal flash and lets the 6502/816 run which then pulls in the rest of the OS)

-Gordon

_________________
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/


Top
 Profile  
Reply with quote  
PostPosted: Sat Oct 08, 2022 8:04 pm 
Offline

Joined: Fri Jul 09, 2021 10:12 pm
Posts: 741
A point in favour of using FAT32 and not storing things outside the filesystem is that you don't need to use unusual and dangerous commands to update it. Whenever writing raw sectors or images to devices, either in Linux or Windows, I always feel that I'm only one character away from destroying my boot drive.


Top
 Profile  
Reply with quote  
PostPosted: Sat Oct 08, 2022 9:54 pm 
Offline
User avatar

Joined: Tue Mar 05, 2013 4:31 am
Posts: 1373
Pretty active thread quickly. Nice to see other ideas and such. For the project I'm working on, the actual drive will never be attached to a normal (whatever that is these days) PC type machine. There's no reason to do that, nor would it be a simple process. The drive I'm using is a Microdrive (IBM/Hitachi) which is an IDE interface but uses a very small 35-pin ZIF connector with 0.3mm spacing. It's also a 3.3-volt device only. Granted, I could build a small interface board to use a standard 44-pin 2.5-inch disk IDE connector, but I don't really have the need to.

As this is intended to run on a 65C02 system (and can easily be attached to a 65C816 system using the same hardware), keeping the code simple and small is high on the list. To address some of the input from others:

- Proxy: I think BDD's response is inline with my thoughts. Unless you already have some amount of filesystem support in ROM, you're not going to easily be able to read a directory and present boot options. Then again, if your goal was to to hard code it into the first 2-3 blocks, then you could present some fancy text to the user and manage a simple entry to load an actual OS.

- Plasmo: True enough, I do plan on using a CPLD for a future system. Likely the EPM570, as I want to provide memory banking and a separate I/O bus which will run at a lower CPU clock rate when I/O devices are being accessed. I still prefer having some amount of onboard EEPROM. This will contain things like POST, BIOS, hardware detection and initialization, etc., as well as a system monitor program. With banking capability, the memory config will be more flexible.

- gfoot: No argument that FAT32 is pretty much supported by most OSes everywhere. However, as the drive will never be attached to a standard PC (as noted above), I don't think FAT32 makes a lot of sense for the 65C02 ( I could be wrong). The filesystem code will likely be too large. My longer term goal is to have a more elaborate hardware system with memory banking and the ability to run Fuzix, which currently uses the Minix filesystem.

Using onboard ROM, I gain a pretty functional system up front, and can communicate with a standard PC with serial (via a UART to USB interface). With the routines between the BIOS and Monitor, I can do a lot to configure and access the Microdrive, including an autoboot with a timeout to allow the end user to interrupt it. As BDD noted, I could also take the approach and load multiple blocks and have a fair amount of code to execute (the BIOS supports multiple sector read and write functions) from a single read or write command to the drive.

I'm still reading through some of these responses a second/third time (and some deeper thinking I guess). I've done a bit of playing around with the R-Pi (have a few of these), several Arduinos (which I gave away) and have a couple nVidia Jetson Nanos. a couple of Plasmo's Tiny68K and a CrC65, a Khadas VIM2 decked out and a recent RC2014 Z80 system which is currently running Fuzix, which requires a pretty loaded system. Anyway, I keep gravitating back to my 65C02 systems... though I do have both of the WDC SXB boards, just didn't warm up to them. So my plan is to continue moving the prototype Microdrive system forward with more RAM and moving DOS/65 to a disk based boot. This will give me a tested system to port David's CPM65 over to as well.

Keep the cards and letters comming... :-)

_________________
Regards, KM
https://github.com/floobydust


Top
 Profile  
Reply with quote  
PostPosted: Mon Oct 17, 2022 5:32 am 
Offline
User avatar

Joined: Tue Mar 05, 2013 4:31 am
Posts: 1373
Status update:

Step 1: I changed my C02 Monitor code to enable a "Ctrl-B" key sequence to Load the first block on the Microdrive (which is an IDE device). It checks for the $6502 2-byte signature after it's successfully loaded. If the signature is good, it jumps to the Partition sector loaded in and control is turned over there. Otherwise, it displays an error and returns the to the Monitor warm entry. Note: making this an auto-loader with a timeout will be trivial, if needed.

Step 2: I wrote a Partition Table loader which will get written to the first block of the IDE device. It's written to call some BIOS and Monitor routines only and uses the first 7 bytes of Page zero for pointers. The partition table can be loaded pretty much anywhere in memory (provided it doesn't clobber the system, e.g., page zero, stack, soft vectors, etc.). The loader figures out where it's been loaded, then checks for a proper 2-byte signature at end of the table. If not found, an error is displayed and control returns to the Monitor warm entry. If the signature is good, it scans for an active boot record (total of 16 record are present). If none are found, a message is displayed and again, the Monitor is entered via the warm entry. If an active boot record is found, it attempts to load the boot record into memory at a predefined location (defaults to the defined TEA area for DOS/65, CP/M or whatever). If the block can not be loaded successfully, an error is display and again, back to the Monitor. If the load is good, it jumps to the start of the boot record in memory and we're off to the races.

So far, so good. Next... I need to write a FDISK style utility that will setup the IDE drive with the Partition loader and allow configuring the multiple boot records and marking one as active. Once that's done, the second utility will need to be written, which will access the active boot record and write a boot loader and do the basic formatting of the drive, which is the typical FORMAT utility. Once these are written, installing an OS will be much easier and somewhat standardized perhaps. So quite a ways to go, but I can at least cobble together a boot loader and hardcode the blocks to load a RAM-configured DOS/65. I''l try to get that working near term... and start figuring out how to get the FDISK and FORMAT utilities written.

Just for chagrins, here's the partition loader code:

Code:
;**************************************************************************************************
;*                                                                                                *
;*                        Microdrive Partition Block for Booting an OS                            *
;*                                                                                                *
;*                                                                                                *
;*                                  17/10/2022 (Day/Month/Year)                                   *
;*                                                                                                *
;*                                    Copyright Kevin Maier                                       *
;*                                                                                                *
;*                                     GNU GPL V3 License                                         *
;*                                                                                                *
;**************************************************************************************************
; Partition Block 1.00                                                                            *
; - Initial Partition Block format for enabling a boot from the Microdrive.                       *
; - Based on the  Ontrack Disk Manager Partition Table, but with 65C02 boot software.             *
;                                                                                                 *
;**************************************************************************************************
        PL      66      ;Page Length
        PW      132     ;Page Width (# of char/line)
        CHIP    W65C02S ;Enable WDC 65C02 instructions
        PASS1   OFF     ;Set ON for debugging
        INCLIST ON      ;Set ON for listing Include files
;**************************************************************************************************
 ;Include required constants/equates/tables for SIM to assemble
;
        INCLUDE         C02Constants4.asm       ;Constants/Equates - C02 BIOS/Monitor/Hardware
        INCLUDE         C02JMP_Table.asm        ;Jump Table entries for C02 BIOS/Monitor
;
;**************************************************************************************************
;
; Note that the ORG statement below is bogus, it just marks the starting offset of the block
; - The BIOS/Monitor will load the Partition Record into low memory first.
;       - The block is test for the signature at the end
;       - If invalid, an error is shown and boot code warm boots Monitor
;       - If valid, boot code signature is checked at offset 253 ($0265)
;       - If invalid, an error is shown and boot code wamr boots Monitor
;       - If valid, boot code continues execution to determine active partition entry
;       - If none are active, boot code displays a message and warm boots monitor
;       - If an active partition entry is found, the Boot Block is loaded into memory
;
; Once the Boot Block from the active partition is loaded into memory:
;       - A signature is checked to test for a valid Boot Block
;       - If invalid, an error is show and drops back to the Monitor
;       - If valid, the Boot loader will continue by loading block into memory
;
; The Block data is part of the Boot loader code, i.e., it knows how many blocks to load
; from the drive into memory and the memory address to load to. It also has a pointer to
; start of executable code, which completes the basic Boot process.
; - Control is now turned over to the executable code that boots the OS.
;
        .ORG    $1000           ;Start of partition block offset - bogus, can't be $0000
;
        LDA     #'*'            ;Get an asterisk
        JSR     B_CHROUT        ;Send to the console
;
; We send an asterisk to the console first for two reasons:
; - it's a visual sign that the partition record was successfully loaded and executed
; - we need to know where it's loaded, so we can now look at the stack and get the return address
;
        TSX                     ;Get stack pointer
        LDA     $0100,X         ;Get return address high byte
        STA     $01             ;Save it as a Page Zero pointer
        DEX                     ;Decrement pointer
        LDA     $0100,X         ;Get return address low byte
        STA     $00             ;Save it as a Page Zero pointer
;
; Now, subtract 4 from the 16-bit address to point to our entry address
        SEC                     ;Set carry for subtraction
        LDA     $00             ;Get low byte address
        SBC     #$04            ;Subtract 4
        STA     $00             ;Store it back
        STA     $02             ;Save it for Text Printing
        LDA     $01             ;Get high byte address
        SBC     #$00            ;Subtract carry flag
        STA     $01             ;Store it back
        STA     $03             ;Store it for Text Printing
;
; We have now the location the partition record was loaded to as a Page Zero indirect pointer
; - We now need to ccheck the partition record for the correct signature. The signature is
; - the standard $AA55 at the end, which is on one page further down. So we increment the
; - high byte address pointer to access the second page.
;
        INC     $01             ;Increment high byte address to get to second page of record
        LDY     #$FF            ;Load index to past byte of partition record
        LDA     ($00),Y         ;Get signature of last byte
        CMP     #$AA            ;Check for correct bit pattern
        BNE     BAD_PART        ;Branch if not equal
        DEY                     ;Decrement index to next signature byte
        LDA     ($00),Y         ;Get signature of next to last byte
        CMP     #$55            ;Check for correct bit pattern
        BNE     BAD_PART        ;Branch if not equal
;
; Partition Record has the correct signature, yay!
; - Now we need to scan the boot record entries to see if we have an active one
; - If not, we send a message to the console showing no active parition, then
; - we warm boot to the Monitor code.
;
; If we find an active partition, we will check the starting block address, ensure
; - it's within the range of out BIOS, then load the parameters and read the boot block
; - Once loaded, we will jump to the starting address of the boot block, we're done!
;
        DEC     $01             ;Decrement back to the first page
        LDX     #16             ;Set count for 16 Boot Records
BOOT_REC_LP
        LDY     #<BOOT_RECORD   ;Get low byte offset to Boot record start
        LDA     ($00),Y         ;Get first byte of Boot record
        BMI     BOOT_FOUND      ;Active Boot record found!
        DEX                     ;Decrement count
        BEQ     NO_ACTIVE       ;No active Boot Record found, branch
;
; Next, add 16 to the page zero indirect address.
; - This is done so we can step through each of the boot records scanning for one
; - that is active. It's just a simple add 16 to the pointers.
;
        CLC                     ;Clear carry for add
        LDA     $00             ;Get low byte of pointer
        ADC     #16             ;Add 16 for offset to next boot record
        STA     $00             ;Store it back
        LDA     $01             ;Get high byte of pointer
        ADC     #00             ;Add in carry
        STA     $01             ;Store it back
;
        BRA     BOOT_REC_LP     ;Loop back for next
;
BOOT_FOUND
        CLC                     ;Clear carry for add
        LDA     $00             ;Get Boot record offset
        ADC     #$FE            ;Add offset to LBA start
        STA     $00             ;Store it back
        LDA     $01             ;Get high byte
        ADC     #$00            ;Add in carry
        STA     $01             ;store it back
;
        LDY     #08             ;Get offset to Boot record first LBA
        LDA     ($00),Y         ;Get first byte
        STA     $04             ;Store it
        INY                     ;Increment to next byte value
        LDA     ($00),Y         ;Get second byte
        STA     $05             ;Store it
        INY                     ;Increment to next byte value
        LDA     ($00),Y         ;Get third byte
        STA     $06             ;Store it
        INY                     ;Increment to next byte value
        LDA     ($00),Y         ;Get fourth byte
        STA     $07             ;Store it
;
        LDA     $04             ;Load LBA number to load (24-bit)
        LDY     $05
        LDX     $06   
        JSR     B_IDE_SET_LBA   ;Call BIOS to Set address
;
        LDX     #$01            ;Set Block count to 1
        LDA     #<BOOT_BUFFER   ;Set low byte of BOOT Buffer
        LDY     #>BOOT_BUFFER   ;Set high byte of BOOT buffer
        JSR     B_IDE_SET_ADDR  ;Call BIOS to set address/count
;
        JSR     B_IDE_READ_LBA  ;Call BIOS to read block into memory
        LDA     IDE_STATUS_RAM  ;Get Status from BIOS call
        LSR     A               ;Shift error bit to carry
        BCS     BOOT_ERROR      ;Branch if error
        JMP     BOOT_BUFFER     ;Jump to Boot record, we're done!
;
BOOT_ERROR
        LDY     $03             ;Get High byte to our location
        CLC                     ;Clear carry for add
        LDA     #<BAD_BLOCK     ;Get low byte offset
        ADC     $02             ;Add any offset from record location
        BRA     MSG_FINISH      ;Use routine above to finish message and Monitor entry
;
; We have a bad partition record! The two signature bytes at the end of the record are
; not correct. Therefore, we send a message out the to console, then enter the Monitor
; via the Warm Boot vector (JMP table call).
;
BAD_PART
        LDY     $03             ;Get High byte to our location
        CLC                     ;Clear carry for add
        LDA     #<BAD_REC_MSG   ;Get low byte offset
        ADC     $02             ;Add any offset from record location
MSG_FINISH
        JSR     M_PROMPTR       ;Send message to console
        JMP     M_WARM_MON      ;Warm Boot Monitor
;
; We have not found any of the Boot Records to have an active flag. Therefore, we can not
; attempt to load a boot record and continue booting from the disk. We simply send a message
; to the console and go back to the Monitor via the Warm Boot entry.
;
NO_ACTIVE
        LDY     $03             ;Get High byte to our location
        CLC                     ;Clear carry for add
        LDA     #<NO_ACT_PART   ;Get low byte offset
        ADC     $02             ;Add any offset from record location
        BRA     MSG_FINISH      ;Use routine above to finish message and Monitor entry
;
BAD_REC_MSG
        .DB     13,10,'Bad Partition Record',13,10,0  ;Bad record message
;
NO_ACT_PART
        .DB     13,10,'No Active Partition',13,10,0   ;No active partition record
;
BAD_BLOCK
        .DB     13,10,'Bad Boot Block!',13,10,0 ;Bad boot block read
;
COPYRIGHT
        .DB     'K.E. Maier'
;
        .ORG    $10FC           ;Offset for 2-byte signature
;
        .DW     $6502           ;Litte-Endian signature for 6502 partition
;
;**************************************************************************************************
;
;Partition Records are 16 bytes in length and have the following format:
;
;       Offset          Length          Description
;       0x00            1 byte          Status: bit 7 used for active (1), all other bits zero
;       0x01            3 bytes         CHS address of first sector in partition
;       0x04            1 byte          Partition Type: "db" is for CPM
;       0x05            3 bytes         CHS addres of last sector in partition
;       0X08            4 bytes         LBA of first Block in partition
;       0x0C            4 bytes         Number of Blocks in partition
;
; note: if LBA addressing is used, both CHS fields should be zeroed out!
;
; For Partitioning, LBA will is used, as the BIOS only supports LBA addressing for the drive.
;
;**************************************************************************************************
;
;       .ORG    $10FE           ;Offset to boot records
;
BOOT_RECORD                     ;Start of Boot records
;
;Partition Records start here:
; - The first 12 records are Expanded Partition Entries per Ontrack Disk Manager
; - The last 4 records are the standard Primary partition Entries
;
Partition_0x04
;
        .DB     %00000000       ;Bit Mask for active partition bit 7 shows as active
        .DB     $00, $00, $00   ;First CHS Field - zeros as LBA mode is used
        .DB     $DB             ;CPM Partition identifier
        .DB     $00, $00, $00   ;Last CHS Field - zeros as LBA mode is used
        .LONG   $0              ;First LBA Block in partition
        .LONG   $0              ;Number of Blocks in partition
;
Partition_0x05
;
        .DB     %00000000       ;Bit Mask for active partition bit 7 shows as active
        .DB     $00, $00, $00   ;First CHS Field - zeros as LBA mode is used
        .DB     $DB             ;CPM Partition identifier
        .DB     $00, $00, $00   ;Last CHS Field - zeros as LBA mode is used
        .LONG   $0              ;First LBA Block in partition
        .LONG   $0              ;Number of Blocks in partition
;
Partition_0x06
;
        .DB     %00000000       ;Bit Mask for active partition bit 7 shows as active
        .DB     $00, $00, $00   ;First CHS Field - zeros as LBA mode is used
        .DB     $DB             ;CPM Partition identifier
        .DB     $00, $00, $00   ;Last CHS Field - zeros as LBA mode is used
        .LONG   $0              ;First LBA Block in partition
        .LONG   $0              ;Number of Blocks in partition
;
Partition_0x07
;
        .DB     %00000000       ;Bit Mask for active partition bit 7 shows as active
        .DB     $00, $00, $00   ;First CHS Field - zeros as LBA mode is used
        .DB     $DB             ;CPM Partition identifier
        .DB     $00, $00, $00   ;Last CHS Field - zeros as LBA mode is used
        .LONG   $0              ;First LBA Block in partition
        .LONG   $0              ;Number of Blocks in partition
;
Partition_0x08
;
        .DB     %00000000       ;Bit Mask for active partition bit 7 shows as active
        .DB     $00, $00, $00   ;First CHS Field - zeros as LBA mode is used
        .DB     $DB             ;CPM Partition identifier
        .DB     $00, $00, $00   ;Last CHS Field - zeros as LBA mode is used
        .LONG   $0              ;First LBA Block in partition
        .LONG   $0              ;Number of Blocks in partition

;
Partition_0x09
;
        .DB     %00000000       ;Bit Mask for active partition bit 7 shows as active
        .DB     $00, $00, $00   ;First CHS Field - zeros as LBA mode is used
        .DB     $DB             ;CPM Partition identifier
        .DB     $00, $00, $00   ;Last CHS Field - zeros as LBA mode is used
        .LONG   $0              ;First LBA Block in partition
        .LONG   $0              ;Number of Blocks in partition
;
Partition_0x0A
;
        .DB     %00000000       ;Bit Mask for active partition bit 7 shows as active
        .DB     $00, $00, $00   ;First CHS Field - zeros as LBA mode is used
        .DB     $DB             ;CPM Partition identifier
        .DB     $00, $00, $00   ;Last CHS Field - zeros as LBA mode is used
        .LONG   $0              ;First LBA Block in partition
        .LONG   $0              ;Number of Blocks in partition
;
Partition_0x0B
;
        .DB     %00000000       ;Bit Mask for active partition bit 7 shows as active
        .DB     $00, $00, $00   ;First CHS Field - zeros as LBA mode is used
        .DB     $DB             ;CPM Partition identifier
        .DB     $00, $00, $00   ;Last CHS Field - zeros as LBA mode is used
        .LONG   $0              ;First LBA Block in partition
        .LONG   $0              ;Number of Blocks in partition
;
Partition_0x0C
;
        .DB     %00000000       ;Bit Mask for active partition bit 7 shows as active
        .DB     $00, $00, $00   ;First CHS Field - zeros as LBA mode is used
        .DB     $DB             ;CPM Partition identifier
        .DB     $00, $00, $00   ;Last CHS Field - zeros as LBA mode is used
        .LONG   $0              ;First LBA Block in partition
        .LONG   $0              ;Number of Blocks in partition
;
Partition_0x0D
;
        .DB     %00000000       ;Bit Mask for active partition bit 7 shows as active
        .DB     $00, $00, $00   ;First CHS Field - zeros as LBA mode is used
        .DB     $DB             ;CPM Partition identifier
        .DB     $00, $00, $00   ;Last CHS Field - zeros as LBA mode is used
        .LONG   $0              ;First LBA Block in partition
        .LONG   $0              ;Number of Blocks in partition
;
Partition_0x0E
;
        .DB     %00000000       ;Bit Mask for active partition bit 7 shows as active
        .DB     $00, $00, $00   ;First CHS Field - zeros as LBA mode is used
        .DB     $DB             ;CPM Partition identifier
        .DB     $00, $00, $00   ;Last CHS Field - zeros as LBA mode is used
        .LONG   $0              ;First LBA Block in partition
        .LONG   $0              ;Number of Blocks in partition
;
Partition_0x0F
;
        .DB     %00000000       ;Bit Mask for active partition bit 7 shows as active
        .DB     $00, $00, $00   ;First CHS Field - zeros as LBA mode is used
        .DB     $DB             ;CPM Partition identifier
        .DB     $00, $00, $00   ;Last CHS Field - zeros as LBA mode is used
        .LONG   $0              ;First LBA Block in partition
        .LONG   $0              ;Number of Blocks in partition
;
Partition_0x00
;
        .DB     %10000000       ;Bit Mask for active partition bit 7 shows as active
        .DB     $00, $00, $00   ;First CHS Field - zeros as LBA mode is used
        .DB     $DB             ;CPM Partition identifier
        .DB     $00, $00, $00   ;Last CHS Field - zeros as LBA mode is used
        .LONG   16384           ;First LBA Block in partition
        .LONG   131072          ;Number of Blocks in partition
;
Partition_0x01
;
        .DB     %00000000       ;Bit Mask for active partition bit 7 shows as active
        .DB     $00, $00, $00   ;First CHS Field - zeros as LBA mode is used
        .DB     $DB             ;CPM Partition identifier
        .DB     $00, $00, $00   ;Last CHS Field - zeros as LBA mode is used
        .LONG   147456          ;First LBA Block in partition
        .LONG   131072          ;Number of Blocks in partition
;
Partition_0x02
;
        .DB     %00000000       ;Bit Mask for active partition bit 7 shows as active
        .DB     $00, $00, $00   ;First CHS Field - zeros as LBA mode is used
        .DB     $DB             ;CPM Partition identifier
        .DB     $00, $00, $00   ;Last CHS Field - zeros as LBA mode is used
        .LONG   278528          ;First LBA Block in partition
        .LONG   131072          ;Number of Blocks in partition
;
Partition_0x03
;
        .DB     %00000000       ;Bit Mask for active partition bit 7 shows as active
        .DB     $00, $00, $00   ;First CHS Field - zeros as LBA mode is used
        .DB     $DB             ;CPM Partition identifier
        .DB     $00, $00, $00   ;Last CHS Field - zeros as LBA mode is used
        .LONG   409600          ;First LBA Block in partition
        .LONG   131072          ;Number of Blocks in partition
;
;**************************************************************************************************
; Partition Block ends with standard 2-byte signature to show valid record
;
        .DW     $AA55           ;Signature bytes - mark as valid partition record
;
;**************************************************************************************************
        .END



It's still a little rough... lipstick needed, but it's functional.

The boot sequence from the Monitor is here:

Code:
;[CTRL-B] Boot from the Microdrive:
; - A Partition Record format has been decided to allow an OS to be booted from the Microdrive.
; - The Partition Record is located at LBA 0 on the Microdrive. This routine will set the block
; - parameters to load the first LBA from the drive and store it at the default buffer location.
; - The Partition Record has a 2-byte signature at an offset of 252 bytes. It's been decided that
; - the 2-byte signature will be $6502 as a hex word, i.e., stored $02, $65. If this is found.
; - the Monitor will jump to the beginning of the partition block loaded and it will be up to the
; - the Parition Record code to either continue a boot from disk or return to the Monitor via a
; - warm boot. The only two reasons to return are:
;       - An invalid 2-byte signature was found at the end of the Partition Record ($AA55).
;       - No Boot Record was found to be marked as Active, so there's no bootable partition.
;
BOOT_MICRODRIVE
                LDA     #$00            ;Load low byte LBA address
                TAY                     ;Same for high LBA address
                TAX                     ;Same for extended LBA address
                JSR     B_IDE_SET_LBA   ;Call BIOS to setup LBA number
;
                LDA     #<LBA_BUFFER    ;Set Address low byte
                LDY     #>LBA_BUFFER    ;Set Address high byte
                LDX     #$01            ;Set Block count to 1
                JSR     B_IDE_SET_ADDR  ;Set Xfer address and block count
;
                JSR     B_IDE_READ_LBA  ;Read Block Zero to Buffer
                LDA     IDE_STATUS_RAM  ;Get Status from BIOS call
                LSR     A               ;Shift error bit to carry
                BCS     IDE_RD_ERR      ;Branch if error
;
                LDX     #252            ;Get offset to signature
                LDA     LBA_BUFFER,X    ;Get signature byte
                CMP     #$02            ;Compare to $02
                BNE     BAD_PART_BLK    ;Branch if incorrect
                INX                     ;Increment index to next signature byte
                LDA     LBA_BUFFER,X    ;Get signature byte
                CMP     #$65            ;Compare to $65
                BNE     BAD_PART_BLK    ;Branch if incorrect
;
;Signature is good! Now just jump to the Partition Record in LBA_BUFFER
                JMP     LBA_BUFFER
;
IDE_RD_ERR
                LDA     #$4A            ;Microdrive Error message
                JMP     PROMPT          ;Send message and exit
;
BAD_PART_BLK
                LDA     #$4B            ;Partition Error message
                JMP     PROMPT          ;Send message and exit
;


There's a couple messages if things go wrong, but this is pretty failsafe.

_________________
Regards, KM
https://github.com/floobydust


Top
 Profile  
Reply with quote  
PostPosted: Sat Oct 22, 2022 2:58 am 
Offline
User avatar

Joined: Tue Mar 05, 2013 4:31 am
Posts: 1373
I'm still working on a boot block as a next step... however, I decided to look at putting together a fully ram based version of DOS/65 (based on my ROM version 3.04), so I have something working to test with.

As of right now, it's very cobbled together... so the source is messy. The good news is that I have it built in a 6KB block of space. This contains CCM, PEM, SIM, all data areas for those modules and support for 8 drives, each at 8MB. There's also a minimal bit of init code to kick it off. The drive allocation maps gobble up 4KB for the 8 drives, so the total RAM footprint is 10KB.

The boot code will contain the starting block (and number of total blocks) for the partition, as SIM will need to build it's access offsets relative to the starting block on the drive. The access offsets will be calculated during initialization of SIM and loaded into RAM. This will allow a working partition to be moved to a different location on the disk without having to regenerate the disk offsets.

_________________
Regards, KM
https://github.com/floobydust


Top
 Profile  
Reply with quote  
PostPosted: Sun Oct 23, 2022 1:58 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8182
Location: Midwestern USA
Proxy wrote:
BigDumbDinosaur wrote:
Quote:
mainly to avoid having to fiddle with the raw bytes of the storage drive...

That, in my opinion, is an unattainable goal. At the very start of the ISL process, you have to read the boot device at the raw level. In modern systems, that happens in the firmware, usually as the final stage of POST and basic system configuration.

what does ISL mean? google only brings up things related to mining underground ore deposits using pipes.

Sorry, I somehow missed your question.

ISL means “initial system load.” It’s a throwback term to the days of 1950s- and 1960s-era main frames, when bringing up a system was done in multiple stages, starting with manually setting up some boot code with console toggle switches and push buttons that would be enough to for the CPU to read a tape. The reading of the tape’s contents into core was the ISL. In the early systems, the ISL code loaded from the first tape would then be used to read in the operating system kernel from a second tape and eventually the system would be ready to do some computing.

Even after disk drives with reasonable capacity became available, the ISL-from-tape method persisted for some time because the early disk drives were prone to head crashes after prolonged usage, which sad event would usually wipe out most of data on the disk. Had the disk pack that got head-crashed contained to operating system, it would have been impossible to boot unless a spare disk pack with the current OS was available. Spare tapes were far cheaper, which was the compulsion to stick to loading the OS from tape.

Disk reliability problems were largely resolved when the Winchester technology, which used flying heads, was developed by IBM in the early 1970s. The early versions were somewhat shock-sensitive and could be head-crashed if the mechanism was subjected to excessive vibration, but that too was resolved as technology advanced to where it was possible to make the drives physically smaller for the same capacity. The result was much less head mass, which gave the heads better flying characteristics.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
PostPosted: Fri Oct 28, 2022 11:40 pm 
Offline
User avatar

Joined: Tue Mar 05, 2013 4:31 am
Posts: 1373
I'm still working on this... and I continue to work out the details of the Boot Block, my design is going thru a bit of change to ensure it's flexible for what my long term goals are.

So far, there is a Partition Block (first LBA of the drive) that will support up to 16 different bootable partitions. That piece is basically completed. The next bit is the Boot Block, which I'm currently working on. The design has changed a bit, hence taking longer that I hoped it would. I've now opted for a Load Header as part of the Boot Image for whatever OS is being loaded. This has some details that the Boot Block uses to ensure we have a matching image and where it gets loaded, where the execution entry is, what drive space is required (in total blocks) and where the LBA offset is placed in the Boot Image to ensure the Boot Image (once loaded and executed) is accessing the correct range of LBAs and not stomping on another partitions data.

I've also decided on having the Boot Image in it's own dedicated space at the front of the partition. As of now (future planning) I'm reserving 256 blocks of space (512-bytes times 256 = 128KB) for the Boot Block and Boot Image. The additional space required for data to the Boot Image is separate and can be configured as such, with a preference being in the same partition as defined in the Partition Record. The offset is a 32-bit long word, so it can easily span a pretty large drive (24-bits gives us 8GB).

My Mouser parts arrived today, so I grabbed the soldering iron and made a quick & dirty piggy-back socket to install a 128KB SRAM (32-pin DIP) into the 32KB (28-pin DIP) socket. A couple jumpers on the socket and a single wire to connect to A15 on the CPU was all that was required, along with a quick config and re-program to the ATF22LV10 PLD glue chip. My prototype 3.3V system now has 56KB of RAM and 8KB or EEPROM. A quick change and assemble resulted in my DOS/65 RAM version up and running in a couple minutes, albeit that it is being loaded via Xmodem as a S19 record from my C02 Monitor. If needed, I could make the system bootable and forego my Monitor code, which would yield another 6KB of RAM space... but I like my Monitor ;-)

I'm hoping the weekend yields some bootable progress... but there is Formula 1 this weekend!

_________________
Regards, KM
https://github.com/floobydust


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 14 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 7 guests


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 post attachments in this forum

Search for:
Jump to: