Fantastic, amazing! I'm sure we can figure it out from the ROM and a disk image.
Given that the intention of the Byte Disk was to be the disk drive for every platform, showing only the relevant files on each, it might also be fun to try to figure out the on-disk format. There's possibly non-Oric versions of BD-DOS on that disk too.
EDIT: other than 6502 vectors, this is a complete disassembly of the ROM, by the way:
Code: Select all
E000 78 SEI ; Disable interrupts.
E001 A9 08 LDA #$08
E003 8D 20 03 STA $0320 ; Store 8 to $0320; assuming that to be a WD command
; register, that's a restore, with either:
;
; no spin-up sequence, if a WD177x; or
; a set head-load request and wait for head load response, if a 179x.
;
; => a 179x, almost certainly, with a Microdisc-esque capacity to switch the
; motor on upon a head load request, and indicate head loaded in response.
E006 2C 12 03 BIT $0312 ; Loop until bit 6 of $0312 is set. Bit 6 of $0312 is the WD's IRQ line,
E009 50 FB BVC $E006 ; and this is waiting for end of operation.
E00B AD 20 03 LDA $0320 ; Read WD status.
E00E A2 00 LDX #$00 ; Set output pointer to 0.
E010 A9 01 LDA #$01
E012 8D 22 03 STA $0322 ; Store 1 to WD sector register.
E015 A9 80 LDA #$80
E017 8D 20 03 STA $0320 ; Store $80 to WD command register. That's read sector, no initial delay,
E01A 2C 12 03 BIT $0312 ; Check IRQ and DRQ outputs from the WD.
E01D 70 10 BVS $E02F ; If the command has finished, jump off to E02F.
E01F 10 F9 BPL $E01A ; If there's not yet any more data to read, repeat the status read.
E021 AD 23 03 LDA $0323 ; Read the next byte.
E024 9D 00 04 STA $0400,X ; Store to $400 + X
E027 E8 INX ; Increment X.
E028 4C 1A E0 JMP $E01A ; Go back to polling.
E02B EA NOP
E02C EA NOP
E02D EA NOP
E02E EA NOP
E02F AD 20 03 LDA $0320
E032 29 9C AND #$9C ; If the drive is signalling not ready, sector 1 wasn't found,
E034 D0 DF BNE $E015 ; it had a CRC error, or data was lost in transfer, try the read again.
E036 4C 00 04 JMP $0400 ; Otherwise, branch to $400.
; i.e. Read sector 1 from track 0, which may be at most 256 bytes long, to $400,
; and execute it. If it doesn't load, retry until it does.
;
; Assuming a classic 5.25" drive, the ready signal implies motor on + two index holes passed.
; So it can be used approximately to evaluate completion of spin-up. If they shipped an
; IBM PC-style drive it'd instead indicate that the head had stepped and the disk had not been
; ejected since. We can probably assume the former, as a restore won't necessarily step the
; head — if it's already at track 0 then no motion will occur. So it's not really an indicator of
; anything in this code.
Vectors are NMI -> $022b, reset -> 0xe000, IRQ -> 0228, for the record. So guesses:
- * the ROM is paged at startup; and
* it's possibly incompatible with BASIC 1.1 (motivation for guess: it duplicates the 1.0 IRQ and NMI vectors, which differ from the 1.1).
EDIT: inspecting what we can therefore conclude is the boot sector reveals a weird result: it's a 512-byte sector. Which means that the ROM loop above will overwrite the first half with the second half. But also the sector itself just contains the same 256-byte sequence repeated twice. Disassembling that:
Code: Select all
* = 0400
0400 2C 11 03 BIT $0311
0403 2C 17 03 BIT $0317
0406 A9 1A LDA #$1A
0408 8D 80 BB STA $BB80
040B A9 00 LDA #$00
040D A0 68 LDY #$68
040F 85 60 STA $60
0411 84 61 STY $61
0413 A9 01 LDA #$01
0415 2C A9 00 BIT $00A9
0418 2C A9 07 BIT $07A9
041B AA TAX
041C 48 PHA
041D 49 01 EOR #$01
041F 29 03 AND #$03
0421 8D 23 03 STA $0323
0424 A9 13 LDA #$13
0426 8D 20 03 STA $0320
0429 2C 12 03 BIT $0312
042C 50 FB BVC $0429
042E AD 20 03 LDA $0320
0431 A0 FF LDY #$FF
0433 E6 39 INC $39
0435 E6 39 INC $39
0437 88 DEY
0438 D0 F9 BNE $0433
043A BD E0 04 LDA $04E0,X
043D 8D 22 03 STA $0322
0440 A0 00 LDY #$00
0442 A9 80 LDA #$80
0444 8D 20 03 STA $0320
0447 2C 12 03 BIT $0312
044A 70 12 BVS $045E
044C 10 F9 BPL $0447
044E AD 23 03 LDA $0323
0451 91 60 STA ($60),Y
0453 C8 INY
0454 D0 F1 BNE $0447
0456 E6 61 INC $61
0458 4C 47 04 JMP $0447
045B 4C 00 04 JMP $0400
045E AD 20 03 LDA $0320
0461 29 9C AND #$9C
0463 D0 F6 BNE $045B
0465 E8 INX
0466 68 PLA
0467 48 PHA
0468 C9 07 CMP #$07
046A D0 04 BNE $0470
046C E0 0A CPX #$0A
046E B0 04 BCS $0474
0470 E0 0B CPX #$0B
0472 90 C6 BCC $043A
0474 68 PLA
0475 F0 A2 BEQ $0419
0477 C9 01 CMP #$01
0479 F0 9B BEQ $0416
047B 78 SEI
047C D8 CLD
047D A2 FF LDX #$FF
047F 9A TXS
0480 AD 80 03 LDA $0380
0483 A0 00 LDY #$00
0485 98 TYA
0486 99 00 00 STA $0000,Y
0489 99 00 02 STA $0200,Y
048C 99 37 98 STA $9837,Y
048F C8 INY
0490 D0 F4 BNE $0486
0492 20 1C 95 JSR $951C
0495 A9 0C LDA #$0C
0497 20 D4 96 JSR $96D4
049A 20 2E 6C JSR $6C2E
049D 20 44 6F JSR $6F44
04A0 B0 B9 BCS $045B
04A2 20 0A 96 JSR $960A
04A5 AD 01 C0 LDA $C001
04A8 C9 59 CMP #$59
04AA F0 16 BEQ $04C2
04AC 20 B2 68 JSR $68B2
04AF A9 03 LDA #$03
04B1 20 B8 73 JSR $73B8
04B4 90 0A BCC $04C0
04B6 A9 EB LDA #$EB
04B8 A0 04 LDY #$04
04BA 20 0C 73 JSR $730C
04BD 4C 7B 04 JMP $047B
04C0 A9 00 LDA #$00
04C2 8D FD 97 STA $97FD
04C5 A2 02 LDX #$02
04C7 BD DD 04 LDA $04DD,X
04CA 9D 05 E9 STA $E905,X
04CD A9 3F LDA #$3F
04CF 9D E0 02 STA $02E0,X
04D2 CA DEX
04D3 10 F2 BPL $04C7
04D5 A9 60 LDA #$60
04D7 8D 09 F4 STA $F409
04DA 4C 00 C0 JMP $C000
04DD 4C 00 68 JMP $6800
04E0 01 03 ORA ($03,X)
04E2 05 07 ORA $07
04E4 09 0B ORA #$0B
04E6 02 ???
04E7 04 ???
04E8 06 08 ASL $08
04EA 0A ASL A
04EB 07 ???
04EC 2A ROL A
04ED 45 52 EOR $52
04EF 52 ???
04F0 2D 4E 4F AND $4F4E
04F3 20 43 4F JSR $4F43
04F6 4D 2E 2A EOR $2A2E
04F9 3F ???
04FA 0D 0A 00 ORA $000A
04FD D4 ???
04FE C5 C5 CMP $C5
0500 .END
One further quick observation before bed: the supplied disk is an MFM_DISK but appears to use longer-than-usual tracks. For now I'm detecting this by just not truncating any sector that is in-progress when you hit the 6250 byte mark. I guess if there's only one BD-DOS disk image in existence then whether to think of that as a rule is somewhat moot. But otherwise I was truncating sector 11, leading inevitably to a portion of nonsense and a CRC error when reading.
I have so far implemented:
- a WD1973;
- with motors tied to a head load request, but head loaded signalled only when a drive is signalling ready.
... and that gets me beyond the boot sector, and a few sectors further, to needing to figure out the expectations around the non-WD registers. I have Fabrice's notes, so will proceed with those.
As an aside, tying the head load request directly to the head loaded input might work on real drives; mine still reach their proper velocity instantaneously so I declined to do that because then sectors will be loaded before they're signalling ready, which causes BD-DOS to enter a temporary retry loop in its boot ROM and a perpetual one in its boot sector. As long as a real drive takes at least two revolutions to reach full speed I don't think that should be an issue (and these are reputedly 5.25" drives, so we're talking a real physical index hole, not a virtual one, meaning it'll signal even at low speeds).