flat assembler
Message board for the users of flat assembler.

Index > OS Construction > Disk drive switching shenanigans

Author
Thread Post new topic Reply to topic
nkeck72



Joined: 28 May 2015
Posts: 83
Location: 0000:7C00
nkeck72 26 May 2017, 22:42
In NOS, I have been attempting to write a small program that changes the logged disk drive (stored as one byte at 0x10003, which is in kernel space) so I can possibly begin to experiment with hard disk support. My current code for this program is as follows (if you want to see the entire source, you can find it on the git repository under the branch "disk-change"):
Code:
;
; CHGLOG.ASM - This program is an experimental command for NOS that will change the logged (or system) disk
; drive that the kernel and INT21 interfaces use.
;
org 0000h
use16
db "F"
jmp start
startup db "Logged Disk Changer v0.1", 0Dh, 0Ah, 00h
current db "Current active disk is: ", 00h
flop1   db "Floppy Disk 0", 0Dh, 0Ah, 00h
flop2   db "Floppy Disk 1", 0Dh, 0Ah, 00h
hard    db "Hard Disk", 0Dh, 0Ah, 00h
prompt  db "Pick disk to switch to, or enter 'C' to cancel (0,1,H): ", 00h
success db "Successfully changed disks.", 0Dh, 0Ah, 00h
failure db "Unable to change disks. Check drives and try again.", 0Dh, 0Ah, 00h
invalid db "Invalid selection, please try again.", 0Dh, 0Ah, 00h
same    db "You cannot change to the current drive!", 0Dh, 0Ah, 00h
cdisk   db 00h
ndisk   db 00h
newline db 0Dh, 0Ah, 00h
start:
        push cs
        pop ds
        mov ah, 01h
        mov dx, startup
        int 21h
        mov ah, 01h
        mov dx, current
        int 21h
        ; Parse the current disk drive in the kernel
        mov bx, 1000h
        mov es, bx
        mov ah, byte ptr es:0003h
        ; Save it
        mov byte ptr cdisk, ah
        cmp ah, 00h
        je  fdisk1
        cmp ah, 01h
        je  fdisk2
        ; Otherwise, assume a hard disk
        jmp hdisk
fdisk1:
        mov ah, 01h
        mov dx, flop1
        int 21h
        jmp disk_switch
fdisk2:
        mov ah, 01h
        mov dx, flop2
        int 21h
        jmp disk_switch
hdisk:
        mov ah, 01h
        mov dx, hard
        int 21h
        jmp disk_switch
disk_switch:
        mov ah, 01h
        mov dx, prompt
        int 21h
        mov ah, 00h
        int 16h
        push ax
        mov ah, 0Eh
        int 10h
        ; Check to see if we can read the disk
        mov ah, 01h
        mov dx, newline
        int 21h
        pop ax
        cmp al, 'C'
        je  exit
        cmp al, 'c'
        je  exit
        cmp al, '0'
        je  check_pri_flop
        cmp al, '1'
        je  check_sec_flop
        cmp al, 'H'
        je  check_hdd
        cmp al, 'h'
        je  check_hdd
        ; Otherwise tell the user they selected an invalid disk
        mov ah, 01h
        mov dx, invalid
        int 21h
check_pri_flop:
        mov ah, 02h
        mov al, 01h
        mov ch, 00h
        mov cl, 01h
        mov dh, 00h
        mov dl, 00h
        mov bx, garbage
        push cs
        pop es
        int 13h
        call check_dc
        jc  disk_error
        mov byte ptr ndisk, 00h
        jmp switch
check_sec_flop:
        mov ah, 02h
        mov al, 01h
        mov ch, 00h
        mov cl, 01h
        mov dh, 00h
        mov dl, 01h
        mov bx, garbage
        push cs
        pop es
        int 13h
        call check_dc
        jc  disk_error
        mov byte ptr ndisk, 01h
        jmp switch
check_hdd:
        mov ah, 02h
        mov al, 01h
        mov ch, 00h
        mov cl, 01h
        mov dh, 00h
        mov dl, 80h
        mov bx, garbage
        push cs
        pop es
        int 13h
        call check_dc
        jc  disk_error
        mov byte ptr ndisk, 80h
        jmp switch
switch:
        ; Load the FSB of the new disk and modify the kernel
        ; drive pointer to match, and also check to see if the
        ; disk we are loading is the same as the current one.
        mov ah, byte ptr cdisk
        cmp ah, byte ptr ndisk
        je  same_disk
        mov ah, 02h
        mov al, 01h
        mov ch, 00h
        mov dh, 00h
        mov cl, 02h
        mov bx, 2000h
        mov es, bx
        mov bx, 0000h
        int 13h
        jc  disk_error
        mov ah, byte ptr ndisk
        mov bx, 1000h
        mov es, bx
        xor bx, bx
        mov byte ptr es:0003h, ah
        ; Return to the kernel
        mov ah, 01h
        mov dx, success
        int 21h
        jmp exit
check_dc:
        cmp ah, 06h
        je  change_line
        stc
        ret
change_line:
        clc
        ret
disk_error:
        mov ah, 01h
        mov dx, failure
        int 21h
        jmp exit
same_disk:
        mov ah, 01h
        mov dx, same
        int 21h
        jmp exit
        
exit:
        db 0CBh
db "EF", 0FFh
garbage:
times 1024-($-$$) db 0
    


I have tried running this program on three different machines, two of them being Bochs and VirtualBox. Each time, I had the boot disk in floppy disk drive 0, and a NOS-formatted floppy in drive 1. I attempted to change the logged disk drive from drive 0 to drive 1.

On real hardware, the program prints the message that the disk drive was successfully changed, but something causes the computer to indefinitely hang and I never get back to the NOS prompt. In Bochs, the disk drive (1) flat out refuses to respond and I get dumped back to the NOS prompt as expected for a failure, this may be a bug on Bochs' side. VirtualBox also refuses to switch drives for unknown reasons as I cannot debug with VirtualBox.

Does anyone else see something I may be missing as the problem? I will upload a freshly built disk image for those who wish to test on their systems.

EDIT: To run the program I am referring to, boot NOS from floppy drive 0, and at the 'NOS>' prompt type "chglog". Make sure that you have a NOS-formatted floppy in drive 1 and use the program's prompt to switch to the appropriate drive.


Description: Freshly built NOS disk with the CHGLOG program on it.
Download
Filename: NOS.zip
Filesize: 5.23 KB
Downloaded: 837 Time(s)


_________________
It may look hard, but it won't take long if you take it one byte at a time.

NOS: www.github.com/nkeck720/nos


Last edited by nkeck72 on 03 Jun 2017, 15:38; edited 1 time in total
Post 26 May 2017, 22:42
View user's profile Send private message Visit poster's website Reply with quote
smiddy



Joined: 31 Oct 2004
Posts: 557
smiddy 30 May 2017, 15:56
nkeck72,

I don't know a lot about NOS. Does NOS run on top of DOS? Does NOS utilize INT 21h as its own, instead of DOS?

I am running into a similar result with using the floppy interface, where I am using two different drive types, the first floppy is a standard 1.44 MB floppy, with FAT 12. The second floppy is a 2.88 MB floppy, formatted with FAT 12 also, but due to their distinct differences, the timing setup for 1.44 MB versus 2.88 MB is entirely different. Therefore my FDC driver hasn't been accounting for the timing differences, since the controller can only house within its register, one set of timing data. I am working to develop this more thoroughly. My other alternative, which I'm giving serious thought to, is getting rid of floppy altogether since they are not being used with current systems.

I wonder if you are running into similar situation, when you change the disk, there may be subtle differences that are impacting the timing hence causing you hangs.

I am currently at work and cannot run your code. If I get the opportunity to this evening I will.

Smiddy
Post 30 May 2017, 15:56
View user's profile Send private message Reply with quote
nkeck72



Joined: 28 May 2015
Posts: 83
Location: 0000:7C00
nkeck72 30 May 2017, 17:19
Thank you for replying. To answer your question, NOS is completely standalone, and doesn't use and DOS interfaces at all. The file system has been built from the ground up, and the INT 21 calls are referring to my own API (viewable at https://github.com/nkeck720/nos/blob/master/src/int21.asm). For the most part I'm only controlling the disk system using the BIOS INT 13 interfaces, so is the BIOS returning something I have overlooked? I would think that the BIOS would be able to handle the timing differences that you mentioned, but maybe not. Also, to clear up any confusion about the "exit" label, NOS uses a far call to start its programs, and in order to return to NOS cleanly the program must use a far ret (in this case 0xCB). Could this be my problem as well?

_________________
It may look hard, but it won't take long if you take it one byte at a time.

NOS: www.github.com/nkeck720/nos
Post 30 May 2017, 17:19
View user's profile Send private message Visit poster's website Reply with quote
SeproMan



Joined: 11 Oct 2009
Posts: 70
Location: Belgium
SeproMan 11 Jun 2017, 21:46
Code:
     int 13h 
      call check_dc 
      jc  disk_error    


An important reason why this might fail is that you don't properly treat potential errors that were reported by BIOS. By first checking for a status value of 06h, you neglect all other errors that were reported under CF=1.

Code:
     int 13h 
      jc disk_error
      call check_dc 
      jc  disk_error    


A better way to detect a disk change is through using BIOS function 16h instead of interpreting the success of reading 1 sector.
On the other hand I don't get why you would need to insist on a change-line-status if all you want is just successfully starting to use another drive.


A point to consider:
By loading the FSB for the new drive at 2000h:0000h, don't you overwrite the FSB for the kernel disk that was put there on booting?

_________________
Real Address Mode.
Post 11 Jun 2017, 21:46
View user's profile Send private message Reply with quote
nkeck72



Joined: 28 May 2015
Posts: 83
Location: 0000:7C00
nkeck72 11 Jun 2017, 22:11
Thank you for your reply. To address all of your points:

Quote:

An important reason why this might fail is that you don't properly treat potential errors that were reported by BIOS. By first checking for a status value of 06h, you neglect all other errors that were reported under CF=1.

You make a valid point here, and this is what I was talking about earlier when I said that the BIOS is returning something that I may be overlooking. I currently am busy with other things right now, but when I can I will implement a handler for each condition and post here what CHGLOG returns on each of the systems.

Quote:

A point to consider:
By loading the FSB for the new drive at 2000h:0000h, don't you overwrite the FSB for the kernel disk that was put there on booting?

Thank you for pointing this out. This is intentional, as NOS is supposed to act like DOS in that it handles one logged filesystem (disk) at a time, and in preparing to do this it loads everything that the kernel needs from the boot disk at boot time and holds it in RAM, thus eliminating the need from then on for the original boot disk to be present. The system can theoretically run perfectly from then on (until a bug or crash of some sort happens, at which point it can then be booted from the boot disk again).

Quote:

A better way to detect a disk change is through using BIOS function 16h instead of interpreting the success of reading 1 sector.

I didn't know the BIOS provided disk change status checking on INT 16h. I'll do more research on this Very Happy

Quote:

On the other hand I don't get why you would need to insist on a change-line-status if all you want is just successfully starting to use another drive.


My intention here is NOS currently supports only the use of floppy disks natively (you can, with a hex editor and some patience, format a hard disk to NOSFS), and with floppy disks the change line can still be active in the case that, for example, the user had a disk in disk drive 1 that they then swapped out for another disk before switching. I want to effectively handle that here.
Post 11 Jun 2017, 22:11
View user's profile Send private message Visit poster's website Reply with quote
SeproMan



Joined: 11 Oct 2009
Posts: 70
Location: Belgium
SeproMan 12 Jun 2017, 12:34
Quote:
I didn't know the BIOS provided disk change status checking on INT 16h. I'll do more research on this.


Exclamation Please note this is function AH=16h on disk drive interrupt Int 13h.
It has nothing to do with the well-known keyboard interrupt Int 16h.

Additionally there's also function AH=15h on Int 13h that tells you if the disk that you want to investigate does support Change-Line at all.

_________________
Real Address Mode.
Post 12 Jun 2017, 12:34
View user's profile Send private message Reply with quote
nkeck72



Joined: 28 May 2015
Posts: 83
Location: 0000:7C00
nkeck72 12 Jun 2017, 12:54
Quote:

Please note this is function AH=16h on disk drive interrupt Int 13h.


Ah, my bad for misinterpreting. I thought that sounded a bit odd. Razz

Quote:

Additionally there's also function AH=15h on Int 13h that tells you if the disk that you want to investigate does support Change-Line at all.


Handy, I didn't know that existed.
Post 12 Jun 2017, 12:54
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
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 vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.