• Please review our updated Terms and Rules here

ISA USB board

The reason for the "DANGER" warning is that this tries to specify consistent geometry in the INT 41 table. Since this is just fixed data in ROM, it's hard coded as max cylinders/heads/sectors, so it's going to say 8Gb, even though we know the drive is 4Gb.

You can change the line right after DISK_1_TABLE near the end of disc.asm from MAX_CYL to 0x01FF and it should silence the warning.
 
I started to review the BIOS Code.

This code:
%if DOUBLE_WIDE = 1 %rep 32 IN AX, DX ;Read a word at a time MOV WORD [ES:BX], AX INC BX INC BX ; bump counter by two %endrep %else %rep 64 IN AL, DX ;READ BYTE MOV [ES:BX], AL ;STORE BYTE INC BX ;INC BX %endrep %endif

Can be replaced by this:
MOV DI,BX %if DOUBLE_WIDE = 1 %rep 32 IN AX, DX ;Read a word at a time STOSW %endrep %else %rep 64 IN AL, DX ;READ BYTE STOSB %endrep %endif MOV BX,DI

It will be really faster and smaller.
 
I started to review the BIOS Code.
I couldn't resist, Just tried on my XT with stock 8088, It's much better on the Read now, Before i was getting 137 KB/s and now i'm getting 177 KB/s on the Read, No change on the Write @ 137 KB/s
 
I couldn't resist, Just tried on my XT with stock 8088, It's much better on the Read now, Before i was getting 137 KB/s and now i'm getting 177 KB/s on the Read, No change on the Write @ 137 KB/s
Of course, I did not publish the write code change :)
 
MOV AL, CH ;GET LOWER CYLINDER NUMBER SHR CL, 0X01 ;SHIFT RIGHT 6 TIMES FOR UPPER 2 BITS CYLINDER SHR CL, 0X01 ; SHR CL, 0X01 ; SHR CL, 0X01 ; SHR CL, 0X01 ; SHR CL, 0X01 ; MOV AH, CL ;AX HOLDS CYLINDER NUMBER ;

And

MOV AL, CH ;GET LOWER CYLINDER NUMBER SHR CL, 0X06 ;SHIFT RIGHT 6 TIMES FOR UPPER 2 BITS CYLINDER MOV AH, CL ;AX HOLDS CYLINDER NUMBER ;

can be replaced by :
XOR AH,AH MOV AL,CL SHL AX, 0X01 ; SHL AX, 0X01 ; MOV AL, CH ;GET LOWER CYLINDER NUMBER

In both CONVERT_CHS_TO_LBA and CONVERT_CHS_TO_LBA_8086.
So, at the end, only one function will remain.
Then all the _8086 functions needing this can be removed, lot of space saved.

For the FORMAT_TRACK_8086: and FORMAT_TRACK you can simply use the FORMAT_TRACK_8086 all the time, there will be no performance difference. (We "Format" a disk only one time)
Also, If I am not wrong, you can even not write anything and return Ok directly, I think it is like this in other BIOS.
 
Thanks for the suggestions. I started to do a "golfing" attempt at it, but got distracted when my CH375 module came in and I spent too much time trying to get it to detect that one dodgy drive. :)

I've baked the suggestions in and it gets back below 4k with unrolled loops.
 
Hi,

I did some more correction, little code size reduction.
Speed increase in 8086 Mode, Write not Double Wide.

I have a question, what is the role of "DISK_IN_BOUND" ?
Is it really needed ?
 

Attachments

  • disc.zip
    15.5 KB · Views: 22
Well, the point of DISK_IN_BOUND was to be able to blow up early in a request if you asked for a sector beyond what the disc's reported geometry included. It may not be necessary, but I feel like it's reasonably appropriate, in case you have stupid software that says "I want to seek to cylinder 1000 of a 600-cylinder drive and I expect to get a rejection". I'm suddenly thinking of how (I think) Commodore drives would home themselves by just seeking a fixed number of tracks forward, even if it just caused the drive to bang against the end of its travel.

Since I have a day off, I spent way too much of it on some fairly significant retooling:


Highlights:
* It includes some of the speedup suggestions for 8088. A quick disktest run on a 4.77MHz, no wait states, no double-wide mode, on a nearly empty ~440Mb partition, gives ~139k read/write. YMMV; I've found that the IOPS scores in particular are very dependent on filesystem-related overhead (empty discs are faster). I wonder if smaller discs are faster for a similar reason.

* HUGE internal renovations to disc operations. It passes a lot of temporaries and variables relative to the stack at the moment we enter a function. This gives us much more flexibility to define extra "parameters" and "variables" without running out of precious registers.

* It tries to combine setup and teardown stuff for read/write/format calls. I had hoped this would reduce duplication, but I think we didn't save that much space. With full bells and whistles, I see 4416 bytes :/

* Rather than supporting a single command/data port pair, it tries to remain aware of DL (the drive selected), and look up referenced ports based on it. The short-and-long of this is that you can try to configure it to support two CH37X modules. This was inspired by several people mentioning considering building dual-CH37X cards.

If you set COMMAND_PORT_2 and DATA_PORT_2, it will treat that as a "secondary" drive-- BIOS drive 0x81 requests will try to hit it. Note that it still expects COMMAND_PORT and DATA_PORT for a "permanent" drive, mostly because the detection logic is pretty basic and doesn't bother to try the second slot if the first one doesn't detect.

This is super-experimental because I cannot currently properly test it at the moment. The motherboard I use can accommodate one CH37X module onboard, and I'm waiting on an ISA card in the mail.

When I set both devices to the same ports, I was able to boot and see the "real" drive at C and E and the "second" one at D and F, but I'd be very hesitant to try playing with formatting or writing the drives in this scenario, as I suspect DOS would be surprised to see changes on one drive mysteriously appearing elsewhere. If someone has two CH375 cards, or a card and an EMM mainboard with CH37X module, they may be able to get a more realistic result.

I suspect it may be *marginally* slower than the original version, because the cleanup/teardown of read-write calls is a little more complex, and reading port stuff from the stack is a few clocks slower than reading immediates, but I'm hoping it's not noticable; the big I/O loop should still be the bottleneck. Since it;'s such a big change, it's in a seperate branch, and if it turns out a nightmare, we can ignore it.
 
Nice, it go in the good direction :)

I still need my new board (I did not sent the PCB to production) and a way to test to continue to help.
Other things to do are having it working with the XTIDE BIOS to have some disk on the CF, other on the USB.
In this case, I am not sure how it work, I suppose that the first BIOS that is run (Based on its @) is configures a 80h, the other 81h and so on.

I see in your BIOS that it go to 80h by default : You can check in the BIOS Variable the number of Disk present, and use 81h if another one is there.
Also, of course, support for 286 and more will need to add delay functions. I did not progress on this side, I should do it in my driver (Run a benchmark code to configure the delay fonctions)

And of course, support of bigger disk, Split a USB Key in 2 Disk, Try to use the CH376 to use files (.IMG)...

At the same time, I am motivated to work on a Pi Nano based board, to add memory and DISK (USB as well) so the way to access it will be really different, and the speed is supposed to be much faster.
Easily some Mb/s It is possible as the Pi Pico can directly shadow the full PC Memory, then there is even no need to copy the disk buffers :)
I already said too much, somebody will steal my idea :) (Yes, I am too slow...)
 
I think the XT-IDE BIOS is designed to look at how many drives already exist and position above it. In my build, I was loading the CH37X BIOS at a low address, then the XT-IDE stuff later, and they played fairly well together. I have not tried them together since the latest update, so it may well not be happy with two discs supported.

There are a few naive assumptions baked into the CH37X BIOS-- that it's the first disc system available, and can safely claim device 80 (and possibly 81). A lot of this is because we don't have a great way to relay something between initialization and use, like "There was a drive already when I got there, I'm 0x81". I imagine the XT-IDE has to be smarter (it will do things like virtually swapping drives) because it has to coexist with equally naive controllers from back in the time when two hard disc controllers would be an unimaginable luxury.

There's a similar lack of communication on dual-slot mode. INT13 function 8 returns two drives, and INT46 is populated, as long as two modules are configured in the BIOS, even if the second didn't initialize.

After boot, if we see "2 drives" in the BIOS data area, or a sensible INT46 value, I'm not sure we could reliably disambiguate "Two CH37X modules successfully enabled" from "One CH37X succeeded, one failed, and some other controller added a second disc".

The concept of shadowing the whole system memory is sort of interesting. I feel like you'd run out of I/Os.

The simplest model I can imagine is mapping the address and data busses to the RPi, along with the memory-read/write signals, then just run a tight loop listening to the bus and updating. This would require 30 pins if you don't multiplex them (i. e. send address, then send data and read/write indicators). The BIOS would have to operate by monitoring a magic memory area-- i. e. write your desired command to F0000. if you wanted to go more deluxe, 40 would be nice (20 lines for address, 16 for data for 8086 use, and both memory and I/O read-write lines, so you could use communication commands in I/O space instead. Then just implement the card as a "fills the entire address space" memory board. This would avoid some hard spots about writing back to motherboard RAM. (Of course, once you have the pins on the bus, you could certainly output a request that stuffed something back into motherboard memory.

The various STM32 pill boards look to have enough I/O to do it, but are lacking in memory; I'd expect what you want is something with like 2Mb of RAM or more on it, 1M for the shadow memory, and then enough to run your USB-drive-integration tools and bringup code (i. e. somewhere to include the ROM images you wanted and a map of "this is device memory, don't shadow it"
 
One challenge might be that the system board buffers make placement difficult. On 5160 for example, we cannot DMA from slot 8 but I think we also cannot present Fxxx except from slot 8 (or the ROM sockets of course).
 
Since I have a day off, I spent way too much of it on some fairly significant retooling:
Latest update not working for me, I get the ' Non system disc ' error, but it's not corrupting the drive, I tried setting up a fresh flash drive on my XT, I start FDISK and then my XT Freezes and all i can do is switch off. I go back to previous bios and all is good.
 
The simplest model I can imagine is mapping the address and data busses to the RPi, along with the memory-read/write signals, then just run a tight loop listening to the bus and updating. This would require 30 pins if you don't multiplex them (i. e. send address, then send data and read/write indicators). The BIOS would have to operate by monitoring a magic memory area-- i. e. write your desired command to F0000. if you wanted to go more deluxe, 40 would be nice (20 lines for address, 16 for data for 8086 use, and both memory and I/O read-write lines, so you could use communication commands in I/O space instead. Then just implement the card as a "fills the entire address space" memory board. This would avoid some hard spots about writing back to motherboard RAM. (Of course, once you have the pins on the bus, you could certainly output a request that stuffed something back into motherboard memory.

The various STM32 pill boards look to have enough I/O to do it, but are lacking in memory; I'd expect what you want is something with like 2Mb of RAM or more on it, 1M for the shadow memory, and then enough to run your USB-drive-integration tools and bringup code (i. e. somewhere to include the ROM images you wanted and a map of "this is device memory, don't shadow it"
Exactly,

Use a Pi Pico, with an SPI RAM and Multiplex the @/Data Bus, there is sufficient pin to have the full @, Data, Memory and I/O plus one aditionnal pin for an IRQ, (For Keyboard/Mouse support on USB for example)
Forget about DMA, it is not needed as the Pi will be able to shadow the RAM...

I also planned Write to the F000 Segment as it is supposed to contain ROM, to not disturb the system to configure it.
I/O Read / write may still be possible, but obsolete, memory read/Write is more efficient. We can keep I/O Read Write for example to emulate the EMS Cards, and not needing to do another driver.

We can have an initialisation BIOS doing a memory scan, Fill all the empty memory space with Memory and cold reboot to present the Disk BIOS.
Or Configuration menu, with config save in the Pi ROM.
when a dedicated memory segment is reserved to the board, it can be used to emulate ROM, have memory buffer for Disk access or other...
(Why not some basic "DSP"/Computing functions like : Cleanup the 16Kb buffer, Mix audio samples to play a .MOD file and so on)

Extended BIOS functions, with Hot swappable ROM Bank (Virtually unlimitted BIOS library) and whatever else.....
Everything can be done in one core, and the second core can be used to manage the USB Functions (USB Stick support)

Also... Network, Wifi with the Pico W, anything we can thing about.


The CH375/CH386 solutions will be obsolete with this...
 
Latest update not working for me, I get the ' Non system disc ' error, but it's not corrupting the drive, I tried setting up a fresh flash drive on my XT, I start FDISK and then my XT Freezes and all i can do is switch off. I go back to previous bios and all is good.
What options do you have set?
 
Back
Top