VOGONS


First post, by videogamer555

User metadata
Rank Member
Rank
Member

Using nasm to compile my own boot disk image I am using interrupt 0x13 to read additional data after the first sector (initially a boot program only can access the first sector). However using interrupt 0x13 keeps failing, and gives this error in the debugger version of dosbox "BIOS:Disk 0 is not active". The asm code (with comments) is shown below.

BITS 16 ; set assembler to use the 16bit instructions

mov ax,0x0013 ; Graphics mode to use is 0x13
int 0x10 ; Call interupt 0x10

mov ax,0xA000 ; Set ES register to start of VRAM (part 1)
mov es,ax ; Set ES register to start of VRAM (part 2)
mov ah,2 ; Operation type is Read Disk Sectors
mov al,125 ; Number of sectors to read is 125 (64000 bytes)
mov ch,0 ; First track/cylinder number to read is 0
mov cl,2 ; First sector to read on this track/cylinder is number 2 (the first sector after the boot sector)
mov dh,0 ; First read-write head to use is number 0
mov dl,0 ; Drive to read from is 0 (the "A drive")
mov bx,0 ; First offset in VRAM to write to is 0
int 0x13 ; Call interupt 0x13

Loop: ; loop to keep the program running
jmp Loop

section .picture start=512 ; start of section that contains picture data is at byte 512 (first byte of sector 2)
incbin "~RESOURCES\VGA.raw" ; copy all bytes of raw pixels to the disk image

Reply 1 of 10, by Jorpho

User metadata
Rank l33t++
Rank
l33t++

I can't say I'm familiar with ASM code, but I did a little Googling and found this StackOverflow page that suggests "mov dl,0" is unnecessary.
http://stackoverflow.com/questions/34092965/s … nt-0x10-ah-0x0e

Reply 2 of 10, by NewRisingSun

User metadata
Rank Oldbie
Rank
Oldbie

Don't know about the drive inactive problem, but there are two more things that will prevent your code from working with a real floppy drive:

mov al,125 ; Number of sectors to read is 125 (64000 bytes)

You cannot read more than one track in one Int13 call on a real system. You must issue a separate call for each and every cylinder and head.

mov ax,0xA000 ; Set ES register to start of VRAM (part 1)
mov es,ax ; Set ES register to start of VRAM (part 2)

Reading directly into video memory will not work on 1990s mainboards, because their DMA controller does not support transfers that do not involve any system memory at all.

Reply 3 of 10, by videogamer555

User metadata
Rank Member
Rank
Member
NewRisingSun wrote:
Don't know about the drive inactive problem, but there are two more things that will prevent your code from working with a real […]
Show full quote

Don't know about the drive inactive problem, but there are two more things that will prevent your code from working with a real floppy drive:

mov al,125 ; Number of sectors to read is 125 (64000 bytes)

You cannot read more than one track in one Int13 call on a real system. You must issue a separate call for each and every cylinder and head.

mov ax,0xA000 ; Set ES register to start of VRAM (part 1)
mov es,ax ; Set ES register to start of VRAM (part 2)

Reading directly into video memory will not work on 1990s mainboards, because their DMA controller does not support transfers that do not involve any system memory at all.

According to the documentation at http://stanislavs.org/helppc/int_13-2.html the number of sectors to read, that's specified in the AL register, can be between 1 and 128, so it sounds like you can read that many sectors in one call, without having to worry about specifying other things.
Also, segment 0xA000 is in fact part of system RAM. It starts at address 0xA0000. It's not like I'm trying to access the VRAM that's on the graphics card itself (as opposed to system RAM). On old computers, part of system RAM actually is directly linked to VRAM, starting at 0xA0000 for VGA graphics.

Reply 4 of 10, by NewRisingSun

User metadata
Rank Oldbie
Rank
Oldbie

According to the documentation at http://stanislavs.org/helppc/int_13-2.html the number of sectors to read, that's specified in the AL register, can be between 1 and 128, so it sounds like you can read that many sectors in one call, without having to worry about specifying other things.

Yes, you absolutely have to worry about "specifying other things". The maximum number of sectors you can read in one call is limited by the floppy diskette, not by the Int13 calling interface. A standard floppy diskette only has 8 to 18 sectors per track, depending on the format, and the BIOS' Int13 routine will not seek to subsequent tracks for you within one single call. If you call Int13 like in your listing, BIOS will assume that all 125 sectors are on cylinder 0, which they obviously are not, so you will inevitably get a "Sector not found" error. If you don't believe me, just step-trace through any self-booting game's loading code; they always read only one track at a time. At most, you can read both sides of the same cylinder within a single call.

It's not like I'm trying to access the VRAM that's on the graphics card itself (as opposed to system RAM).

That's exactly what you're doing.

On old computers, part of system RAM actually is directly linked to VRAM, starting at 0xA0000 for VGA graphics.

Bullshit. Old computers have no system RAM at 0xA0000 precisely because the graphics card provides its own video RAM there, and old ISA computers certainly have no means of "linking system RAM to VRAM". Such capability was only introduced with the PCI bus.

Reply 5 of 10, by videogamer555

User metadata
Rank Member
Rank
Member
NewRisingSun wrote:
Yes, you absolutely have to worry about "specifying other things". The maximum number of sectors you can read in one call is lim […]
Show full quote

According to the documentation at http://stanislavs.org/helppc/int_13-2.html the number of sectors to read, that's specified in the AL register, can be between 1 and 128, so it sounds like you can read that many sectors in one call, without having to worry about specifying other things.

Yes, you absolutely have to worry about "specifying other things". The maximum number of sectors you can read in one call is limited by the floppy diskette, not by the Int13 calling interface. A standard floppy diskette only has 8 to 18 sectors per track, depending on the format, and the BIOS' Int13 routine will not seek to subsequent tracks for you within one single call. If you call Int13 like in your listing, BIOS will assume that all 125 sectors are on cylinder 0, which they obviously are not, so you will inevitably get a "Sector not found" error. If you don't believe me, just step-trace through any self-booting game's loading code; they always read only one track at a time. At most, you can read both sides of the same cylinder within a single call.

It's not like I'm trying to access the VRAM that's on the graphics card itself (as opposed to system RAM).

That's exactly what you're doing.

On old computers, part of system RAM actually is directly linked to VRAM, starting at 0xA0000 for VGA graphics.

Bullshit. Old computers have no system RAM at 0xA0000 precisely because the graphics card provides its own video RAM there, and old ISA computers certainly have no means of "linking system RAM to VRAM". Such capability was only introduced with the PCI bus.

Ok, so my understanding of what was happening "under the hood" so to speak, was incorrect. But that still doesn't explain the "BIOS:Disk 0 not active" error. When you use the Boot command in Dosbox, it treats the disk being booted as the A drive, and the A drive is supposed to be "Disk 0" for the purposes of an Int13 call. So it seems that there's something more fundamentally wrong with the interaction between Dosbox and my code, than simply being that I tried to read too many sectors at a time. It seems almost like there's some fundamental flaw in the way Dosbox handles Int13 (possibly part of those optimizations that Dosbox uses that make it suitable "only for games"). I'd like an expert opinion from a developer of Dosbox, if they even visit these forums, as to what in my code is triggering this specific error, because I have a feeling that I won't be able to use Int13 for ANYTHING (even if I do take cylinders, heads, etc into account), as long as it keeps giving me this "BIOS:Disk 0 not active" error.

Reply 7 of 10, by Joey_sw

User metadata
Rank Oldbie
Rank
Oldbie

I believe older computer do not have MULTITRACK in their implementation of INT 13H bios, on such computer each tracks must be accessed seperately.

as for the VRAM, i suspect confusion were there because old BASIC lines like this:

SCREEN 1: CLS
DEF SEG = &HB800
BLOAD "PICTURE.PIC", 0, 16384

which load the binary data into CGA memory addresses.

as for "disk 0 not active", how did you mount the image?

-fffuuu

Reply 8 of 10, by NewRisingSun

User metadata
Rank Oldbie
Rank
Oldbie
Joey_sw wrote:

I believe older computer do not have MULTITRACK in their implementation of INT 13H bios

The MULTITRACK feature refers to reading both side 0 and side 1 of the same cylinder in a single Int13 call, not to several cylinders at once.

videogamer555 wrote:

section .picture start=512 ; start of section that contains picture data is at byte 512 (first byte of sector 2)
incbin "~RESOURCES\VGA.raw" ; copy all bytes of raw pixels to the disk image

It seems that you are ending the image file right after the picture. This might be the reason, as DOSBox uses the image size to determine the disk geometry, and if the image file's size is not in the list of known sizes, DOSBox' internal "active" variable will remain at "false". The BOOT command does not care about that, as it just needs the 512 bytes from the start of the image, a task for which no geometry information is needed. But the emulated Int13 handler does care about that, so you are getting the error message only at that point in time when you are attempting to do an Int13 read.

In other words, pad the image at the end to a size of 368,640, 737,280 or 1,474,560 bytes and try again.

Reply 9 of 10, by Joey_sw

User metadata
Rank Oldbie
Rank
Oldbie
NewRisingSun wrote:

The MULTITRACK feature refers to reading both side 0 and side 1 of the same cylinder in a single Int13 call, not to several cylinders at once.

ah, you're right i miss-interpret that part somehow.
Several tracks/cylinders read using INT 13h only available with LBA-assisted extension which i'm not convinced if its functionality were extended for floppy disk operation.

-fffuuu

Reply 10 of 10, by videogamer555

User metadata
Rank Member
Rank
Member
NewRisingSun wrote:
The MULTITRACK feature refers to reading both side 0 and side 1 of the same cylinder in a single Int13 call, not to several cyli […]
Show full quote
Joey_sw wrote:

I believe older computer do not have MULTITRACK in their implementation of INT 13H bios

The MULTITRACK feature refers to reading both side 0 and side 1 of the same cylinder in a single Int13 call, not to several cylinders at once.

videogamer555 wrote:

section .picture start=512 ; start of section that contains picture data is at byte 512 (first byte of sector 2)
incbin "~RESOURCES\VGA.raw" ; copy all bytes of raw pixels to the disk image

It seems that you are ending the image file right after the picture. This might be the reason, as DOSBox uses the image size to determine the disk geometry, and if the image file's size is not in the list of known sizes, DOSBox' internal "active" variable will remain at "false". The BOOT command does not care about that, as it just needs the 512 bytes from the start of the image, a task for which no geometry information is needed. But the emulated Int13 handler does care about that, so you are getting the error message only at that point in time when you are attempting to do an Int13 read.

In other words, pad the image at the end to a size of 368,640, 737,280 or 1,474,560 bytes and try again.

It seems that was the problem. Padding it to exactly 1,474,560 bytes worked. However, while it works in Dosbox, it doesn't work in other emulators, such as Microsoft Virtual PC or Oracle Virtual Box. That multi-sector read of the disk that crosses track boundaries, or reading the disk directly into VRAM, must cause problems with real PCs, or with emulators that more accurately emulate real PCs (such as Virtual PC or Virtual Box). Dosbox must take what the intent of the command is (start at such-and-such a place, and read 125 sectors into this memory address) and successfully perform this action, even if it crosses tracks (which wouldn't be allowed on real PCs), and even if it tries to read into VRAM (which may also not be allowed on real PCs, though I'm not sure if this would be a problem for all real PCs or just some of them). This must be one of those optimizations that makes Dosbox not a perfect x86 PC emulator, but rather more of a DOS game emulator.