Some help formatting a 5.25" floppy Please!!

Thread Starter

pconst168

Joined Jun 21, 2025
15
Hi there I am trying to format a 5.25" floppy via my own homebrew CPU and the loop is getting stuck trying to read the DRQ flag in the status register.
This is the WD1770 controller.
Could anyone PLEASE take a look at my code and tell me if you can see anything I am doing wrong?

Basically I issue the write track command, and then I am just waiting for DRQ in loops and when DRQ = 1 I write a byte to the data register. But it seems it never manages to read the DRQ == 1...

Here is my code. I also attached the full .asm if you need it. Please help :(
Code:
syscall_fdc_format:
mov [fdc_128_format_track], bl ; write track number to formatting data block
mov al, 1
mov [fdc_128_format_sect], al ; reset sector variable to 1
mov d, s_format_begin
call _puts
mov bl, [_FDC_WD_STAT_CMD] ; read status register to clear any errors
call print_u8x
call printnl
fdc_header_loop_start:
mov al, %11110110 ; Write Track Command: {1111, 0: Enable Spin-up Seq, 1: Settling Delay, 1: No Write Precompensation, 0}
mov [_FDC_WD_STAT_CMD], al
; write the first data block for formatting which is 40 bytes of 0xFF:
call fdc_wait_64us ; after issuing write track command, need to wait 64us before reading the status register
mov bl, [_FDC_WD_STAT_CMD] ; read status flag
call print_u8x
call printnl
mov cl, 40
fdc_drq_loop: ; for each byte, we need to wait for DRQ to be high
mov al, [_FDC_WD_STAT_CMD] ; read lost data flag
and al, $02 ; check drq bit
jz fdc_drq_loop
mov bl, $FF ; load format byte
mov [_FDC_WD_DATA], bl ; send data byte to wd1770
dec cl
jnz fdc_drq_loop
; start inner data block loop. this block is written 16 times
fdc_inner_loop:
mov si, fdc_128_format_inner
mov cl, 169 ; the inner format data block has 169 bytes total
mov ah, 1
fdc_drq_loop1:
mov al, [_FDC_WD_STAT_CMD] ; read lost data flag
and al, $02 ; check drq bit
jz fdc_drq_loop1
lodsb ; load format byte
mov [_FDC_WD_DATA], al ; send data byte to wd1770
dec cl
jnz fdc_drq_loop1 ; test whether entire data block was written
mov al, ah
inc al
mov [fdc_128_format_sect], al ; update the sector number variable in the format data block
cmp al, 17
jne fdc_inner_loop ; test whether data block was written 16 times
; here all the sectors have been written. now fill in remaining of the track until wd1770 interrupts out
fdc_format_footer:
mov a, $6500
syscall sys_io ; char in AH
fdc_footer_drq_loop:
mov al, [_FDC_WD_STAT_CMD] ; read lost data flag
and al, $02 ; check drq bit
jz fdc_footer_drq_loop
mov bl, $FF ; load format byte
mov [_FDC_WD_DATA], bl ; send data byte to wd1770
mov al, [_FDC_WD_STAT_CMD]
and al, $01 ; check busy bit
jnz fdc_format_footer ; if busy == 1, command is not finished, so loop again
fdc_format_done:
mov d, s_format_done
call _puts
mov al, %10000001 ; re-enable uart and fdc irqs
stomsk
sysret
 

Attachments

Last edited by a moderator:

sagor

Joined Mar 10, 2019
1,049
Can't help much with SOL-1, been a while since I wrote BIOS code for 8080 for floppies...
Have you checked this code:
https://github.com/Pconst167/sol-1
They seem to have a few folders with "floppy" designation, including a "floppy driver"

EDIT: I see your code is very similar to that on the web site, which I assume would be correct. Check for typo errors maybe. Good luck.
 
Last edited:

Thread Starter

pconst168

Joined Jun 21, 2025
15
Can't help much with SOL-1, been a while since I wrote BIOS code for 8080 for floppies...
Have you checked this code:
https://github.com/Pconst167/sol-1
They seem to have a few folders with "floppy" designation, including a "floppy driver"

EDIT: I see your code is very similar to that on the web site, which I assume would be correct. Check for typo errors maybe. Good luck.
Hey there. Yes that my code on github :p
Thanks anyhow. I suspect it is a problem with how I am interacting with the chip. it has a single RD/WR line while my CPU has separate RD and WR lines. I connected my WR line to the single RD/WR line of the WD1770.
 

Thread Starter

pconst168

Joined Jun 21, 2025
15
When I give read track commands I read random garbage, but this is progress from before when I was reading all 0's. What changed is that I select HEAD 1 instead of HEAD 0 on the drive. For some reason this changed the behaviour. I guess the drive is hard wired as HEAD 1.

I probed the DRQ pin on the WD for a read track, and I get high pulses around 24us long and 35us long low. It looks like the CPU is reading the pulses and not missing them. But still it reads garbage.

How much time do I have to read DRQ? even if I missed 2 or 3 of them, the WD writes 00's in its place, so I should be at least reading 00's and some data, but nope. I get periods of say AAAAAAAAAAAAAAAAAAA follows by BBBBBBBBBBBBBBBBB or FFFFFFFFFFFFFFFFFF or whatever, and then some random chars.

At the very end I read a block of E5 which is the filler bytes I wrote. But not always, sometimes I read a long block of repeating chars.

This is a mind wreck... I am totally lost. If you can help me with this I'll even pay you for that. I really want this to work.

Am I missing the DRQ? is it that tight? My loop is about 25us max for reading. This is what I have:
syscall_fdc_read:
mov al, [_FDC_WD_DATA] ; read data register to clear any errors
mov al, [_FDC_WD_STAT_CMD] ; read status register to clear any errors
mov al, %11100000
mov [_FDC_WD_STAT_CMD], al
call fdc_wait_64us

mov di, transient_area
fdc_read_loop: ; for each byte, we need to wait for DRQ to be high
mov al, [_FDC_WD_STAT_CMD] ; read busy flag
mov bl, al
and bl, $01 ; busy bit
jz fdc_read_end
and al, $02 ; check drq bit
jz fdc_read_loop
mov al, [_FDC_WD_DATA] ; send data byte to wd1770
stosb
jmp fdc_read_loop


is anything wrong with this?
 

sagor

Joined Mar 10, 2019
1,049
A few comments:
1) You should check "Busy" before giving any commands (before Read Track command)
2) Is the Busy bit set DURING the entire command, or is it only set while the chip starts the command? The datasheet is not clear on this. Datasheet says BUSY is cleared when the command is "completed". Does that mean BUSY stays on during Track Read until entire track is read? You might be doing this right, but check that signal if you can, to be sure.
3) Are you loading the head at start of Track Read? If so, you should set the 30ms delay for head load (E=1, bit 2 in command)
4) Not sure if Read Track requires a properly formatted disk (track) to be present. Are you sure the track is already formatted correctly? Without the proper track number in the read sectors, who knows what it reads.
5) Your 64uS delay is correct for single density mode between write command and read status.
 

Thread Starter

pconst168

Joined Jun 21, 2025
15
A few comments:
1) You should check "Busy" before giving any commands (before Read Track command)
2) Is the Busy bit set DURING the entire command, or is it only set while the chip starts the command? The datasheet is not clear on this. Datasheet says BUSY is cleared when the command is "completed". Does that mean BUSY stays on during Track Read until entire track is read? You might be doing this right, but check that signal if you can, to be sure.
3) Are you loading the head at start of Track Read? If so, you should set the 30ms delay for head load (E=1, bit 2 in command)
4) Not sure if Read Track requires a properly formatted disk (track) to be present. Are you sure the track is already formatted correctly? Without the proper track number in the read sectors, who knows what it reads.
5) Your 64uS delay is correct for single density mode between write command and read status.
Hi there and thank you for your time.

Yes to pretty much everything.

When I format a track, it goes overboard and writes 1700 filler bytes at the end, instead of ~369. I can read back some data now which is corrupt, but I can see that it writes FF filler bytes to beginning of track as well as at the end. it seems like its missing the index pulses. But a scope shows index pulses coming on OK.

This is an example of a track being read:

0000 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0010 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0020 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0030 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0040 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0050 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0060 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0070 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0080 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0090 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
00A0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
00B0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
00C0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
00D0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
00E0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
00F0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0100 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0110 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0120 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0130 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0140 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0150 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0160 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0170 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0180 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0190 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
01A0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
01B0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
01C0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
01D0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
01E0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
01F0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0200 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0210 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0220 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0230 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0240 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0250 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0260 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0270 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0280 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0290 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
02A0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
02B0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
02C0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
02D0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
02E0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
02F0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0300 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0310 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0320 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0330 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0340 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0350 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0360 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0370 FF FF FF CF 00 00 9F 00 E9 27 FF FF FF FF FF FF .........'......
0380 FF FF FF FF FF 00 00 00 00 00 00 FB E5 E5 E5 E5 ................
0390 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
03A0 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
03B0 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
03C0 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
03D0 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
03E0 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
03F0 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
0400 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 5D 30 FF FF ............]0..
0410 FF FF FF FF FF FF FF FF 00 00 00 00 00 00 FE 00 ................
0420 00 9F 00 E9 27 FF FF FF FF FF FF FF FF FF FF FF ....'...........
0430 00 00 00 00 00 00 FB E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
0440 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
0450 E5 E5 E5 E5 E5 E5 E7 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
0460 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
0470 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E7 E5 E5 ................
0480 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
0490 E5 E5 E5 E7 E5 E7 E5 E7 E5 E5 E5 E5 E5 E5 E5 E5 ................
04A0 E5 E5 E7 E5 E5 E5 E5 E5 E7 E5 E7 E5 E5 E5 E5 E5 ................
04B0 E5 E5 E5 E5 E5 E5 E5 5D 30 FF FF FF FF FF FF FF .......]0.......
04C0 FF FF FF 00 00 00 00 00 00 FE 00 00 9F 00 E9 27 ...............'
04D0 FF FF FF FF FF FF FF FF FF FF FF 00 00 00 00 00 ................
04E0 00 FB E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
04F0 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
0500 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
0510 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
0520 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
0530 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
0540 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
0550 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
0560 F5 E5 DF 75 FF FF FF FF FF FF FF FF FF FF 00 00 ...u............
0570 00 00 00 00 FF 00 00 9F 80 E9 27 FF FF FF FF FF ..........'.....
0580 FF FF FF FF FF FF 00 00 00 00 00 00 FB E5 E5 E5 ................
0590 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
05A0 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
05B0 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
05C0 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
05D0 E5 E5 E5 E5 E5 E5 E7 E5 E7 E5 E7 E5 E7 E5 E5 E5 ................
05E0 E7 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
05F0 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
0600 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 5D 30 FF .............]0.
0610 FF FF FF FF FF FF FF FF FF 00 00 00 00 00 00 FE ................
0620 00 00 9F 00 E9 27 FF FF FF FF FF FF FF FF FF FF .....'..........
0630 FF 00 00 00 00 00 00 FB E5 E5 E5 E5 E5 E5 E5 E5 ................
0640 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
0650 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
0660 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
0670 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
0680 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
0690 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
06A0 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
06B0 E5 E5 E5 E5 E5 E5 F5 E5 DD 35 FF FF FF FF FF FF .........5......
06C0 FF FF FF FF 00 00 00 00 00 00 FE 00 00 9F 80 E9 ................
06D0 27 FF FF FF FF FF FF FF FF FF FF FF 00 00 00 00 '...............
06E0 00 00 FB E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
06F0 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
0700 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
0710 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
0720 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
0730 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
0740 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
0750 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
0760 E5 E5 E5 5D 30 FF FF FF FF FF FF FF FF FF FF 00 ...]0...........
0770 00 00 00 00 00 FE 00 00 9F 00 E9 27 FF FF FF FF ...........'....
0780 FF FF FF FF FF FF FF 00 00 00 00 00 00 FB E5 E5 ................
0790 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
07A0 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
07B0 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
07C0 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
07D0 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
07E0 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
07F0 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
0800 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 F5 E5 DF 75 ...............u
0810 FF FF FF FF FF FF FF FF FF FF 00 00 00 00 00 00 ................
0820 FF 00 40 9F 00 E9 27 FF FF FF FF FF FF FF FF FF ..@...'.........
0830 FF FF 00 00 00 00 00 00 FB E5 E5 E5 E5 E5 E5 E5 ................
0840 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
0850 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
0860 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
0870 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
0880 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
0890 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
08A0 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
08B0 E5 E5 E5 E5 E5 E5 E5 E5 E5 5D 30 FF FF FF FF FF .........]0.....
08C0 FF FF FF FF FF 00 00 00 00 00 00 FE 00 00 9F 00 ................
08D0 E9 27 FF FF FF FF FF FF FF FF FF FF FF 00 00 00 .'..............
08E0 00 00 00 FB E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
08F0 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
0900 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
0910 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
0920 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
0930 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
0940 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
0950 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 E5 ................
0960 E5 E5 F5 E5 DD 31 FF FF FF FF FF FF FF FF FF FF .....1..........
0970 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0980 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0990 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
09A0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
09B0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
09C0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
09D0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
09E0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
09F0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0A00 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0A10 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0A20 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0A30 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0A40 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0A50 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0A60 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0A70 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0A80 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0A90 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0AA0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0AB0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0AC0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0AD0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0AE0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0AF0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0B00 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0B10 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0B20 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0B30 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0B40 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0B50 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0B60 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0B70 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0B80 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0B90 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0BA0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0BB0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0BC0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0BD0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0BE0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
0BF0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF ................
 

sagor

Joined Mar 10, 2019
1,049
Ok, you do have formatting errors. Besides way too many FF to start with, the first sector header is all wrong. There is no 6 x "00" and FE to mark the start (ID Address Mark). This is all around address 370H
At end of 417H, you then start second sector with 6x"00" properly, but have an invalid sector number. From the datasheet for standard 128 byte sectors in IBM format, the sector number must be between 1 and 10. You have "9F". You repeat this invalid sector number through all the sectors. You also only have 9 sectors showing.
In sector located around 6C4, you have an invalid sector length as 80H, should be 00.
At sector starting at 81A, you have an invalid ID Address Mark of FF instead of FE and then a side select of 40H instead of 00.
Your sector numbers should be incrementing from 1 to 10, instead of being the same (incorrect) value of 9F

So, your code is really close to producing the right track format, but seems to be messing up once in a while. This could be related to timing loops or bit testing (status) that is too soon or too late. Since you may be missing at least one sector, that can explain some of the extra FF fillers at the end.
Too many FF at the beginning suggests you are not detecting the index pulse properly or reacting to it too slowly. Or is it possible the index pulse is noisy?

It has been over 45 years since I wrote BIOS code for an 8080 (ASM) to handle my WD floppy controller, my brain is real rusty.
 

sagor

Joined Mar 10, 2019
1,049
Another idea is to debug the status return bits a little more, see if you are getting any errors like Lost Data (bit 2). If set, that means you are not reading the data quick enough (not responding to DRQ quick enough)
 

Futurist

Joined Apr 8, 2025
753
Hi there I am trying to format a 5.25" floppy via my own homebrew CPU and the loop is getting stuck trying to read the DRQ flag in the status register.
This is the WD1770 controller.
Could anyone PLEASE take a look at my code and tell me if you can see anything I am doing wrong?

Basically I issue the write track command, and then I am just waiting for DRQ in loops and when DRQ = 1 I write a byte to the data register. But it seems it never manages to read the DRQ == 1...

Here is my code. I also attached the full .asm if you need it. Please help :(
Code:
syscall_fdc_format:
mov [fdc_128_format_track], bl ; write track number to formatting data block
mov al, 1
mov [fdc_128_format_sect], al ; reset sector variable to 1
mov d, s_format_begin
call _puts
mov bl, [_FDC_WD_STAT_CMD] ; read status register to clear any errors
call print_u8x
call printnl
fdc_header_loop_start:
mov al, %11110110 ; Write Track Command: {1111, 0: Enable Spin-up Seq, 1: Settling Delay, 1: No Write Precompensation, 0}
mov [_FDC_WD_STAT_CMD], al
; write the first data block for formatting which is 40 bytes of 0xFF:
call fdc_wait_64us ; after issuing write track command, need to wait 64us before reading the status register
mov bl, [_FDC_WD_STAT_CMD] ; read status flag
call print_u8x
call printnl
mov cl, 40
fdc_drq_loop: ; for each byte, we need to wait for DRQ to be high
mov al, [_FDC_WD_STAT_CMD] ; read lost data flag
and al, $02 ; check drq bit
jz fdc_drq_loop
mov bl, $FF ; load format byte
mov [_FDC_WD_DATA], bl ; send data byte to wd1770
dec cl
jnz fdc_drq_loop
; start inner data block loop. this block is written 16 times
fdc_inner_loop:
mov si, fdc_128_format_inner
mov cl, 169 ; the inner format data block has 169 bytes total
mov ah, 1
fdc_drq_loop1:
mov al, [_FDC_WD_STAT_CMD] ; read lost data flag
and al, $02 ; check drq bit
jz fdc_drq_loop1
lodsb ; load format byte
mov [_FDC_WD_DATA], al ; send data byte to wd1770
dec cl
jnz fdc_drq_loop1 ; test whether entire data block was written
mov al, ah
inc al
mov [fdc_128_format_sect], al ; update the sector number variable in the format data block
cmp al, 17
jne fdc_inner_loop ; test whether data block was written 16 times
; here all the sectors have been written. now fill in remaining of the track until wd1770 interrupts out
fdc_format_footer:
mov a, $6500
syscall sys_io ; char in AH
fdc_footer_drq_loop:
mov al, [_FDC_WD_STAT_CMD] ; read lost data flag
and al, $02 ; check drq bit
jz fdc_footer_drq_loop
mov bl, $FF ; load format byte
mov [_FDC_WD_DATA], bl ; send data byte to wd1770
mov al, [_FDC_WD_STAT_CMD]
and al, $01 ; check busy bit
jnz fdc_format_footer ; if busy == 1, command is not finished, so loop again
fdc_format_done:
mov d, s_format_done
call _puts
mov al, %10000001 ; re-enable uart and fdc irqs
stomsk
sysret
Why not control the device using some MCU board like a Nucleo? that might make it easier to experiment, debug and fully understand the subtleties of the drive, once you've done that you can just transfer your acquired knowledge back to the homebrew machine to replicate it all...
 

Thread Starter

pconst168

Joined Jun 21, 2025
15
Ok, you do have formatting errors. Besides way too many FF to start with, the first sector header is all wrong. There is no 6 x "00" and FE to mark the start (ID Address Mark). This is all around address 370H
At end of 417H, you then start second sector with 6x"00" properly, but have an invalid sector number. From the datasheet for standard 128 byte sectors in IBM format, the sector number must be between 1 and 10. You have "9F". You repeat this invalid sector number through all the sectors. You also only have 9 sectors showing.
In sector located around 6C4, you have an invalid sector length as 80H, should be 00.
At sector starting at 81A, you have an invalid ID Address Mark of FF instead of FE and then a side select of 40H instead of 00.
Your sector numbers should be incrementing from 1 to 10, instead of being the same (incorrect) value of 9F

So, your code is really close to producing the right track format, but seems to be messing up once in a while. This could be related to timing loops or bit testing (status) that is too soon or too late. Since you may be missing at least one sector, that can explain some of the extra FF fillers at the end.
Too many FF at the beginning suggests you are not detecting the index pulse properly or reacting to it too slowly. Or is it possible the index pulse is noisy?

It has been over 45 years since I wrote BIOS code for an 8080 (ASM) to handle my WD floppy controller, my brain is real rusty.
Hey Sagor. Thank you for your time with this.

So the datasheet says that the sector number should go from 1 to 10, but I think they mean 0x10 and not 10. Because they also say the sector blocks should be repeated 16 times. So do I need to write 10 sectors or 16 then? I think it's 16 because 10 sectors would still leave almost half the track filled with FF...
It does seem to me there's a problem with finding the start of the disk, but a scope shows the index pulses coming fine and they are active low.

I will try writing a tighter loop to see if this is a timing issue, but I really thought I had around 47.5us to respond ...
 

sagor

Joined Mar 10, 2019
1,049
I just realized that you may be writing only 10 (decimal) sectors. The sector count is from 1 to 10 HEX. There are normally 16 sectors per track in that IBM format. That is why you have all those extra FF at the end of the track.
So, you read track code may be ok, but your write track (format) code is what needs work. Try to write only one sector, the rest FF. Read it back until you see the proper construct of a sector, with proper headers and track/sector information. Then write 2 sectors. Once that is correct, only then try to write all 16 sectors on the track.

Good luck.
 

sagor

Joined Mar 10, 2019
1,049
Hello,

What type of diskformat do you want to use?
There are 5 types for the 5.25 inch disks:
https://retrocmp.de/fdd/general/floppy-formats.htm
This page has more info on what is on a track:
https://www.infania.net/misc/PSBOOK/book4/floppyd.htm

Bertus
Bertus, the IBM format is not MS-DOS compatible, so that table you show is not compatible with the original "IBM" format of 128 bytes per sector.
There is some confusion about the sectors per track as well. There is lots of room on a track, even SD FM mode.
 

Thread Starter

pconst168

Joined Jun 21, 2025
15
Hi Bertus! I am uisng the format recommended by the datasheet, 128 bytes per sector...
In fact I am writing 16 sectors. I also noticed the datasheet says 10 but they mean 0x10...

I will try the idea of writing only 1 sector to see what happens...

It seems to me there is a timing issue... I am writing code to format RAm first and then more rapidly copying the format to the WD and see if that fixes any timing issue. But still this is crazy. I should have 47.5us to write...
 

sagor

Joined Mar 10, 2019
1,049
I'm noticing on several different datasheets for the 1771 controller, some give the read track command as "11100100", with that extra second bit set. Not sure why, but no harm in trying it.
 

Thread Starter

pconst168

Joined Jun 21, 2025
15
In fact I am writing 16 sectors. I also noticed the datasheet says 10 but they mean 0x10...

I will try the idea of writing only 1 sector to see what happens...

It seems to me there is a timing issue... I am writing code to format RAm first and then more rapidly copying the format to the WD and see if that fixes any timing issue. But still this is crazy. I should have 47.5us to write...
Hey Sagor. The chip I am using is WD1770. Those bits at the end are option bits, for extra delays and things, so I usually set them as per the datasheet... I have just written a tighter routine that formats memory first, and then sends data from memory to the WD and I am about to test it now.... let's see if it does any different...
 

Thread Starter

pconst168

Joined Jun 21, 2025
15
I'm noticing on several different datasheets for the 1771 controller, some give the read track command as "11100100", with that extra second bit set. Not sure why, but no harm in trying it.
My drive specifies 16 sectors per track, but 256 bytes per sector. Does this mean I cannot actually write 128 bytes per sector? Or does it not matter? The drive datasheet TEC-FB-501, specifies the number 256 bytes per sector only, but I dont know if its just a recommendation. If it cannot actually do 128 byte sectors then this could be the problem too?
 

sagor

Joined Mar 10, 2019
1,049
I suspect your drive is capable of doing 16 sectors at 256 bytes/sector in "high density" mode. That matches in the drive datasheet and the WD1771 datasheet. However, there is no reason why you can't write single density at 128 Bytes/sector, but you may have to experiment with maximum number of sectors. I think the issue is that FM mode uses up twice the space on the track per byte, whereas high density (MFM) uses the same physical space but squeezes in twice the data. For example, under the old CP/M system, 5-1/4" floppies had either 18 sectors at 128 bytes at low density, or 18 sectors of 256 bytes in high density.
The bytes/sector is part of the header format (Sector Length) where 00 is 128 bytes, 01 is 256 bytes. Of course, if writing 256 byte sectors, the filler bytes change from FF to 4E and there are a few additional control bytes.
 
Top