Spectrum +3: pro-format en ROM

Aquí solo proyectos que incluyan el código fuente

Moderador: Fundadores

Reglas del Foro
Si no se incluyen los fuentes, se debe usar el foro de proyectos de software generales
Responder
Avatar de Usuario
javier2112
Demonio tercer orden
Demonio tercer orden
Mensajes: 886
Registrado: 30 Oct 2014, 12:36
Ubicación: Málaga
Has thanked: 11 times
Been thanked: 13 times

Spectrum +3: pro-format en ROM

Mensaje por javier2112 »

Hola.

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
Pese a mis pequeños conocimientos y aún menor experiencia en esto, creo que he localizado la parte clave del asunto. Es esta:

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
En ella se prepara un área de memoria con, entre otra información, la numeración de los sectores. Ahora es cuando solicito ayuda para saber cómo modificar la rutina y para que forme parte de la ROM.

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
Suponiendo que esto sea correcto, ahora "sólo" quedaría ver de dónde se obtienen los bytes que se están usando de más (16).

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
Lo que he hecho es añadir compilación condicional para mi caso, reduciendo 16 bytes en esa zona:

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
Lo he probado en un emulador y el +3 arranca como si fuera un +2A pero no acaba de funcionar correctamente, por lo que es evidente que el S.O. usa esa parte de la memoria (pese a no estar etiquetada) y no encuentro espacio libre, o al menos yo no sé cómo arreglarmelas para ahorrar esos 16 bytes que necesito.


Un saludo.
Visita mi hilo de ventas:
viewtopic.php?t=4789
Avatar de Usuario
javu61 !Sinclair QL
Fundador
Fundador
Mensajes: 2175
Registrado: 30 Mar 2013, 11:58
Ubicación: Valencia
Been thanked: 76 times
Contactar:

Re: Spectrum +3: pro-format en ROM

Mensaje por javu61 »

El interleave no es 4/5, el interleave que usa es 1, lo que se cuenta es cuantos sectores se salta entre dos consecutivos, contando que el disco es circular por lo que siempre el primero y el último son consecutivos. Al salta sectores, da tiempo de procesar los datos recien leidos antes de que alcances el siguiente sector, y así la lectura es mas uniforme. En estos discos son posibles tres:

Interleave 0: 1-2-3-4-5-6-7-8-9-1-2-3-4-5-6-7-8-9-1-2-3-4-5-6-7-8-9-1-2-3-4-5-6-7-8-9....
Interleave 1: 1-6-2-7-3-8-4-9-5-1-6-2-7-3-8-4-9-5-1-6-2-7-3-8-4-9-5-1-6-2-7-3-8-4-9-5....
Interleave 3: 1-8-6-4-2-9-7-5-3-1-8-6-4-2-9-7-5-3-1-8-6-4-2-9-7-5-3-1-8-6-4-2-9-7-5-3....

El resto no pues o no son divisibles enteros o son superiores a la mitad del nro de sectores. No se demasiado de la como meter cosas en la ROM del +3, pero por aquí si hay gente que sabe algo mas de como hacerlo.
Larga vida y prosperidad \\//_
Avatar de Usuario
sinclair200 España
Moderador
Moderador
Mensajes: 9993
Registrado: 28 Mar 2014, 18:25
Ubicación: Madrid
Has thanked: 8 times
Been thanked: 177 times

Re: Spectrum +3: pro-format en ROM

Mensaje por sinclair200 »

Esa utilidad, de Microhoby como todas las demás hace siglos que me la teclee línea a línea, y todavía hoy las sigo utilizando en el +3, y es verdad que el formato Data le da al disco del +3 5K de mas que el formato +3, yo creo que Alan Sugar les obligó a sus curritos a mejorar ese formateo del CPC para diferenciarlo del +3 y que pareciera mejor maquina que el +3 que lo consideraba una maquina de juegos solo, mientras que su CPC pretendía que fuese una maquina mas seria.
Aunque para mi el Spectrum, no tiene nada que envidiar al CPC, desde que DR creo un CP/M para el, se puso ya a la altura del Amstrad, corriendo bajo ese sistema operativo, programas y utilidades creadas para el CPC e incluso para el PCW salvando claro está las columnas de pantalla que en el +3 eran inferiores....
Con lo cual si se pudiera incorporar esa rutina a las Rom del +3e seria una pasada.
De hecho todos habreís comprobado que si un disco de 3,5 en la unidad B la formatea el +3, le adjudica 173K igual que a la unidad A, pero es lo que el pobre tiene en su ROM, y no sabe hacer otra cosa.
Yo con mi disquetera B comprada en Microsat venia acompañada de un disco con una rutina que permitia al +3 formatear a 710K, los discos de 3.5" y lo mejor, luego el +3 leia sin problemas toda esa cantidad de espacio grabado en el disquete.
Resumiendo se podrían hacer diabluras en esa posible ROM modificada, a ver esos monstruos de la programación que tenemos por aquí le dan unas pocas vueltas al tarro..... :D
Imagen
Z80 INSIDE.........
WANTED:…………. CPC 6128 british
Avatar de Usuario
javier2112
Demonio tercer orden
Demonio tercer orden
Mensajes: 886
Registrado: 30 Oct 2014, 12:36
Ubicación: Málaga
Has thanked: 11 times
Been thanked: 13 times

Re: Spectrum +3: pro-format en ROM

Mensaje por javier2112 »

javu61 escribió:El interleave no es 4/5, el interleave que usa es 1,
(...)
Bueno, quizá no sea afortunado usar la palabra interleave. Yo lo que quiero dar a entender es la numeración lógica de los sectorores físicos consecutivos.
SI los sectores físicos van del 0 al 8, la nueración que hay que asignarles es 1,6,2,7,3,8,4, 9 y 5. Por tanto, la nueración logica variará unas veces sumando 5 al anterior y otras restando 4, y eso es lo que hace precisamente la rutina modificada que he hecho:

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
Bueno, en realidad lo hace al revés puesto que empieza por el último sector y termina por el primero, así que a veces suma 4 y otras resta 5.
javu61 escribió: (...)
No se demasiado de la como meter cosas en la ROM del +3, pero por aquí si hay gente que sabe algo mas de como hacerlo.
Bueno, eso es lo que he explicado antes: se cogen los fuentes que hay en emuscriptoria y búscate el ensamblador cruzado sjasmplus. Se modifica lo que quieras y vuelves a generar las roms. El problema es que no veo un hueco donde ponerlo ::?


Saludos.
Última edición por javier2112 el 25 Nov 2015, 09:15, editado 1 vez en total.
Visita mi hilo de ventas:
viewtopic.php?t=4789
Avatar de Usuario
javier2112
Demonio tercer orden
Demonio tercer orden
Mensajes: 886
Registrado: 30 Oct 2014, 12:36
Ubicación: Málaga
Has thanked: 11 times
Been thanked: 13 times

Re: Spectrum +3: pro-format en ROM

Mensaje por javier2112 »

Se me olvidó mencionar que luego está la duda de por qué, en la rutina de MH, la parte alta del byte que se carga en el registro A (para asignar el nº lógico al sector) es 0xC en lugar de 0 que sería lo que se deduce de la explicación, de manera que la numeración lógica de los sectores es:
0xC1, 0xC6, 0xC2, 0xC7, 0xC3, 0xC8, 0xC4, 0xC9 y 0xC5

Parece que debería ser simplemente:
0x01, 0x06, 0x02, 0x07, 0x03, 0x08, 0x04, 0x09 y 0x05.
Visita mi hilo de ventas:
viewtopic.php?t=4789
Responder

Volver a “Proyectos de software abiertos”