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
Esta es mi versión de la subrutina. Hay que tener en cuenta que en lugar de nombrar los sectores lógicos del 1 al 9, lo hace del $c1 al $c9 (no sé el porqué porque no se explica), y que los procesa de forma inversa; por tanto, hay que o bien sumar 4 o restar 5 según el caso:
Código: Seleccionar todo
SEC.FISICO SEC.LOGICO RUTINA ROM SEC.LOGICO RUTINA PRO-FORMAT INCREMENTO
8 9 5
7 8 9 +4
6 7 4 -5
5 6 8 +4
4 5 3 -5
3 4 7 +4
2 3 2 -5
1 2 6 +4
0 1 1 -5
Este es el código:
Código: Seleccionar todo
m036f ld b,$09 ; 9 sectors
ld a,$c5 ; last logical sector
ld hl,tmp_buff+$23 ; end of scratch area
pista ld (hl),$02 ; 512-byte sectors
dec hl
ld (hl),a ; sector number
dec hl
ld (hl),$00 ; head 0
dec hl
ld (hl),d ; track number
dec hl
bit 0,b
jr nz,suma4 ; subrutina_impar
jr z,resta5 ; subrutina par
suma4 add a,4
jp fin
resta5 sub a,5
fin djnz pista
ret
He encontrado una zona aparentemente libre al final de la ROM1, al menos si no se usa la versión para el +3e:
Código: Seleccionar todo
IF garry
m07c9 defm "K free", 13, 0
m07d1 defm "No files found", 13, 0
merase defm "Erase ", 0
myn defm " ? (Y/N)", 0
defs 28
defb $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
defb $ff,$ff,$ff
ELSE
defb $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
defb $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
defb $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
defb $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
defb $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
defb $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
defb $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
defb $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
defb $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
defb $ff,$ff,$ff,$ff,$ff,$ff
IF v41
IF spanish
defb $8e
ELSE
defb $12
ENDIF
ELSE
IF spanish
defb $3c
ELSE
defb $72
ENDIF
ENDIF
ENDIF
Código: Seleccionar todo
IF garry
m07c9 defm "K free", 13, 0
m07d1 defm "No files found", 13, 0
merase defm "Erase ", 0
myn defm " ? (Y/N)", 0
defs 28
defb $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
defb $ff,$ff,$ff
ELSE
defb $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
defb $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
defb $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
defb $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
defb $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
defb $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
defb $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
IF profmt
defb $ff,$ff,$ff,$ff,$ff,$ff
ELSE
defb $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
defb $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
defb $ff,$ff,$ff,$ff,$ff,$ff
ENDIF
IF v41
IF spanish
defb $8e
ELSE
defb $12
ENDIF
ELSE
IF spanish
defb $3c
ELSE
defb $72
ENDIF
ENDIF
ENDIF
Un saludo.