He pensado que quizá sería posible incluir una buena optimización en las ROMs del +3. Se trata de modificar la rutina de formateo de disquete para que numere de manera diferente los sectores físicos del disco, de manera que el acceso a varios sectores lógicos consecutivos esté optimizado. Todo esto viene perfectamente explicado en un artículo de la Microhobby nº168:
http://microhobby.speccy.cz/mhf/168/MH168_18.jpg
http://microhobby.speccy.cz/mhf/168/MH168_19.jpg
http://microhobby.speccy.cz/mhf/168/MH168_20.jpg
El orden de sectores propuesto es el siguiente:
Código: Seleccionar todo
SEC.FISICO SEC.LOGICO ROM SEC.LOGICO PRO-FORMAT INTERLEAVE
0 1 1 5
1 2 6 4
2 3 2 5
3 4 7 4
4 5 3 5
5 6 8 4
6 7 4 5
7 8 9 4
8 9 5 5
Es decir, en lugar de incrementar el sector lógico uno a uno, existe un interleave de 5 y 4 que se va alternando. He encontrado el desemsablado de la rutina asociada al comando FORMAT de la ROM en EmuScriptoria por gentileza de Antonio Villena:
Código: Seleccionar todo
(...)
define tmp_buff $ed11 ; (2048) temporary buffer for FORMAT/COPY
; *BUG* means COPY uses page 0 instead of 7
(...)
; The FORMAT command
m026c rst $28
defw $0018 ; get character after FORMAT
m026f cp $e0
jp z,m03e3 ; move on if LPRINT
cp $ca
IF garry
jp z, m1e02 ; move on if not LINE
cp $cc
jp z, m1dd9
ELSE
jr nz,m027e ; move on if not LINE
rst $28
defw $0020 ; get next character
jp m1e05 ; and move on for FORMAT LINE
ENDIF
m027e rst $28
defw $1c8c ; get a string expression
call m10b1 ; check for end-of-statement
rst $28
defw $2bf1 ; get string from stack
ld a,c
dec a
dec a
or b
jr z,m0291 ; move on if length is 2
m028d call m2ada
defb $4e ; else error "Invalid drive"
m0291 inc de
ld a,(de) ; check 2nd char
dec de
cp ':'
jr z,m029c
call m2ada
defb $4e ; error "Invalid drive" if not colon
m029c ld a,(de)
and $df ; get capitalised drive letter
cp 'A'
jr z,m02ab ; move on if A:
cp 'B'
jr z,m02ab ; or B:
call m2ada
defb $4e ; else error "Invalid drive"
m02ab call m2b89 ; page in DOS workspace
sub 'A'
push af ; save unit number to format
ld hl,FLAGS3
bit 4,(hl)
jr nz,m02bf ; move on if disk interface present
call m2b64 ; page in normal memory
call m2ada
defb $4c ; else error "Format not supported on +2A"
m02bf pop af
or a
jr z,m02d3 ; move on for unit 0
push af
ld hl,FLAGS3
bit 5,(hl)
jr nz,m02d2 ; move on if drive B: present
call m2b64 ; page in normal memory
call m2ada
defb $4b ; else error "Drive B: not present"
m02d2 pop af ; get unit
m02d3 push af
ld c,a
push bc
add a,'A'
call m32b6 ; save TSTACK in page 7
call m3f00
defw DOS_REF_XDPB ; point IX at XDPB
call m32ee ; restore TSTACK
jr c,m02ec ; move on if no error
call m2b64 ; page in DOS memory
call m0e9a ; cause DOS error
defb $ff
m02ec pop bc
call m32b6 ; save TSTACK in page 7
call m3f00
defw DD_LOGIN ; login disk
call m32ee ; restore TSTACK
jr nc,m0306 ; move on if error
or a
jr nz,m0315 ; move on if disk isn't +3 format
call m0381 ; ask if wish to abandon
jr nz,m0315 ; move on if not
call m2b64 ; page in normal memory
ret ; exit
m0306 cp $05
jr z,m0315 ; move on if error was "missing address mark"
cp $09
jr z,m0315 ; or "unsuitable media"
call m2b64 ; page in normal memory
call m0e9a ; cause DOS error
defb $ff
m0315 pop af ; get unit number
push af
add a,'A'
call m32b6 ; save TSTACK in page 7
call m3f00
defw DOS_REF_XDPB ; point IX to XDPB
call m32ee ; restore TSTACK
jr c,m032d
call m2b64 ; page in normal memory
call m0e9a ; cause any DOS error
defb $ff
m032d xor a
call m32b6 ; save TSTACK in page 7
call m3f00
defw DD_SEL_FORMAT ; select +3 format
call m32ee ; restore TSTACK
jr c,m0342
call m2b64 ; page in normal memory
call m0e9a ; cause any DOS error
defb $ff
m0342 pop af
ld c,a ; C=unit number
xor a ; start at track 0
m0345 ld d,a
call m036f ; fill format buffer
ld e,$e5 ; filler byte
ld b,$07 ; page 7
ld hl,tmp_buff ; buffer address
push af
call m32b6 ; save TSTACK in page 7
call m3f00
defw DD_FORMAT ; format a track
call m32ee ; restore TSTACK
jr c,m0365
call m2b64 ; page in normal memory
call m0e9a ; cause any DOS error
defb $ff
m0365 pop af
inc a ; increment track
cp $28
jr nz,m0345 ; back if more to do
call m2b64 ; page in normal memory
ret ; done
; Subroutine to fill scratch area with format buffer details
m036f ld b,$09 ; 9 sectors
ld hl,tmp_buff+$23 ; end of scratch area
m0374 ld (hl),$02 ; 512-byte sectors
dec hl
ld (hl),b ; sector number
dec hl
ld (hl),$00 ; head 0
dec hl
ld (hl),d ; track number
dec hl
djnz m0374
ret
; Subroutine to display "disk already formatted message",
; and get a key, exiting with Z set if user wishes to abandon
m0381 ld hl,m03a7
m0384 ld a,(hl) ; get next char
or a
jr z,m038e ; move on if null
rst $28
defw $0010 ; output char
m038b inc hl
jr m0384 ; loop back
m038e res 5,(iy+$01) ; signal "no key"
m0392 bit 5,(iy+$01)
jr z,m0392 ; wait for key
ld a,(LAST_K) ; get key
and $df ; capitalise
cp 'A' ; is it "A"?
push af
push hl
rst $28
defw $0d6e ; clear lower screen
pop hl
pop af
ret ; exit with Z set if abandon requested
; Formatting message
IF spanish
m03a7 defm "Ya formateado. Tecla A para", $0d
defm "abandonar/otra para continuar", 0
ELSE
m03a7 defm "Disk is already formatted.", $0d
defm "A to abandon, other key continue", 0
ENDIF
Código: Seleccionar todo
; Subroutine to fill scratch area with format buffer details
m036f ld b,$09 ; 9 sectors
ld hl,tmp_buff+$23 ; end of scratch area
m0374 ld (hl),$02 ; 512-byte sectors
dec hl
ld (hl),b ; sector number
dec hl
ld (hl),$00 ; head 0
dec hl
ld (hl),d ; track number
dec hl
djnz m0374
ret
Un saludo.