Spectrum +3: pro-format en ROM

Todo sobre la creación, diseño y programación de nuevo software para
nuestro Spectrum

Moderador: Sir Cilve Sinclair

Responder
zx_spectrum_plus3
Jack The Nipper
Mensajes: 185
Registrado: Mar Abr 17, 2007 12:32 pm

Spectrum +3: pro-format en ROM

Mensaje por zx_spectrum_plus3 » Vie Nov 06, 2015 9:48 am

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. ¿Me podéis ayudar?


Un saludo.

zx_spectrum_plus3
Jack The Nipper
Mensajes: 185
Registrado: Mar Abr 17, 2007 12:32 pm

Re: Spectrum +3: pro-format en ROM

Mensaje por zx_spectrum_plus3 » Lun Nov 09, 2015 1:31 pm

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).

zx_spectrum_plus3
Jack The Nipper
Mensajes: 185
Registrado: Mar Abr 17, 2007 12:32 pm

Re: Spectrum +3: pro-format en ROM

Mensaje por zx_spectrum_plus3 » Mar Nov 10, 2015 1:40 pm

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, así que si nadie sugiere nada, tendré que dar zanjado este tema.


Saludos.

Responder

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 10 invitados