rutina custom loader

Soporte técnico sobre los lanzamientos de MojonTwins y comentarios sobre los güegos. Ofrecemos soporte técnico con Fourspriter, te ayudamos con ZX Basic o Z88DK, te damos pistas some cómo saltarse un bicho y cosas así.

Moderador: na_th_an

Avatar de Usuario
astromarinecorps
Mensajes: 28
Registrado: Sab, 15 Feb 2014, 17:52

rutina custom loader

Mensajepor astromarinecorps » Sab, 15 Feb 2014, 19:47

hola:

recientemente me he vuelto a enganchar al spectrum, tras descubrir la churrera y acabarme los amores de brunilda, perdonad si la pregunta no es muy correcta en este foro, pero sé que aquí hay gente cualificada, tengo una espina clavada desde hace años y quiero sacarmela antes de pasar a la otra vida, quisiera hacer una rutina para cambiar los colores de carga habituales del spectrum, he encontrado una lista con todos los custom loaders y algunos de ellos estan destripados pero en emsamblador y no entiendo nada. Mi sueño seria un pequeño cargador en el que se pudieran incluir 4 variables customizables, 2 para cada color de carga y que despues incluyera un simple load""screen$, para ver como carga una pantalla con los colores configurados por mi, me conformo con eso, por ahora no quiero carga turbo o algo complicado como bleepload. Llevo desde el año 2000 intentando esto, tras guardar mi zx y mi ultima microhobby con la portada de los lemmings en 1992 y volver a retomarlo con la salida de los emuladores.

muchas gracias.
Avatar de Usuario
na_th_an
Mensajes: 26413
Registrado: Vie, 09 Ene 2009, 12:18

Re: rutina custom loader

Mensajepor na_th_an » Sab, 15 Feb 2014, 20:26

Lo más sencillo para esto es coger la rutina de la ROM, copiarla en RAM, y cambiar donde se establecen los colores... Pero para cualquier cosa de estas, es necesario saber un poco de ensamblador.

Yo no tengo mucha idea de estos manejes, pero Zup en Zona de pruebas y Antonio Villena, habitual del mismo foro y que también se pasa por aquí, seguro que pueden ayudarte.
Como diría Rorshach: "Urm..."
antoniovillena
Mensajes: 494
Registrado: Jue, 24 Oct 2013, 15:52

Re: rutina custom loader

Mensajepor antoniovillena » Sab, 15 Feb 2014, 20:50

El código en cuestión es éste. Es corto, no muy complicado de entender y está muy localizado. Puedes hacer un copiado a RAM y parchear como dice na_th_an pero tampoco ocupa demasiado como para que sea un problema.
$this->bbcode_second_pass_code('', '
;; SA/LD-RET
L053F: PUSH AF ; preserve accumulator throughout.
LD A,($5C48) ; fetch border colour from BORDCR.
AND $38 ; mask off paper bits.
RRCA ; rotate
RRCA ; to the
RRCA ; range 0-7.

OUT ($FE),A ; change the border colour.

LD A,$7F ; read from port address $7FFE the
IN A,($FE) ; row with the space key at outside.

RRA ; test for space key pressed.
EI ; enable interrupts
JR C,L0554 ; forward to SA/LD-END if not


;; REPORT-Da
L0552: RST 08H ; ERROR-1
DEFB $0C ; Error Report: BREAK - CONT repeats

; ---

;; SA/LD-END
L0554: POP AF ; restore the accumulator.
RET ; return.

; ------------------------------------
; Load header or block of information
; ------------------------------------
; This routine is used to load bytes and on entry A is set to $00 for a
; header or to $FF for data. IX points to the start of receiving location
; and DE holds the length of bytes to be loaded. If, on entry the carry flag
; is set then data is loaded, if reset then it is verified.

;; LD-BYTES
L0556: INC D ; reset the zero flag without disturbing carry.
EX AF,AF' ; preserve entry flags.
DEC D ; restore high byte of length.

DI ; disable interrupts

LD A,$0F ; make the border white and mic off.
OUT ($FE),A ; output to port.

LD HL,L053F ; Address: SA/LD-RET
PUSH HL ; is saved on stack as terminating routine.

; the reading of the EAR bit (D6) will always be preceded by a test of the
; space key (D0), so store the initial post-test state.

IN A,($FE) ; read the ear state - bit 6.
RRA ; rotate to bit 5.
AND $20 ; isolate this bit.
OR $02 ; combine with red border colour.
LD C,A ; and store initial state long-term in C.
CP A ; set the zero flag.

;

;; LD-BREAK
L056B: RET NZ ; return if at any time space is pressed.

;; LD-START
L056C: CALL L05E7 ; routine LD-EDGE-1
JR NC,L056B ; back to LD-BREAK with time out and no
; edge present on tape.

; but continue when a transition is found on tape.

LD HL,$0415 ; set up 16-bit outer loop counter for
; approx 1 second delay.

;; LD-WAIT
L0574: DJNZ L0574 ; self loop to LD-WAIT (for 256 times)

DEC HL ; decrease outer loop counter.
LD A,H ; test for
OR L ; zero.
JR NZ,L0574 ; back to LD-WAIT, if not zero, with zero in B.

; continue after delay with H holding zero and B also.
; sample 256 edges to check that we are in the middle of a lead-in section.

CALL L05E3 ; routine LD-EDGE-2
JR NC,L056B ; back to LD-BREAK
; if no edges at all.

;; LD-LEADER
L0580: LD B,$9C ; set timing value.
CALL L05E3 ; routine LD-EDGE-2
JR NC,L056B ; back to LD-BREAK if time-out

LD A,$C6 ; two edges must be spaced apart.
CP B ; compare
JR NC,L056C ; back to LD-START if too close together for a
; lead-in.

INC H ; proceed to test 256 edged sample.
JR NZ,L0580 ; back to LD-LEADER while more to do.

; sample indicates we are in the middle of a two or five second lead-in.
; Now test every edge looking for the terminal sync signal.

;; LD-SYNC
L058F: LD B,$C9 ; initial timing value in B.
CALL L05E7 ; routine LD-EDGE-1
JR NC,L056B ; back to LD-BREAK with time-out.

LD A,B ; fetch augmented timing value from B.
CP $D4 ; compare
JR NC,L058F ; back to LD-SYNC if gap too big, that is,
; a normal lead-in edge gap.

; but a short gap will be the sync pulse.
; in which case another edge should appear before B rises to $FF

CALL L05E7 ; routine LD-EDGE-1
RET NC ; return with time-out.

; proceed when the sync at the end of the lead-in is found.
; We are about to load data so change the border colours.

LD A,C ; fetch long-term mask from C
XOR $03 ; and make blue/yellow.

LD C,A ; store the new long-term byte.

LD H,$00 ; set up parity byte as zero.
LD B,$B0 ; timing.
JR L05C8 ; forward to LD-MARKER
; the loop mid entry point with the alternate
; zero flag reset to indicate first byte
; is discarded.

; --------------
; the loading loop loads each byte and is entered at the mid point.

;; LD-LOOP
L05A9: EX AF,AF' ; restore entry flags and type in A.
JR NZ,L05B3 ; forward to LD-FLAG if awaiting initial flag
; which is to be discarded.

JR NC,L05BD ; forward to LD-VERIFY if not to be loaded.

LD (IX+$00),L ; place loaded byte at memory location.
JR L05C2 ; forward to LD-NEXT

; ---

;; LD-FLAG
L05B3: RL C ; preserve carry (verify) flag in long-term
; state byte. Bit 7 can be lost.

XOR L ; compare type in A with first byte in L.
RET NZ ; return if no match e.g. CODE vs. DATA.

; continue when data type matches.

LD A,C ; fetch byte with stored carry
RRA ; rotate it to carry flag again
LD C,A ; restore long-term port state.

INC DE ; increment length ??
JR L05C4 ; forward to LD-DEC.
; but why not to location after ?

; ---
; for verification the byte read from tape is compared with that in memory.

;; LD-VERIFY
L05BD: LD A,(IX+$00) ; fetch byte from memory.
XOR L ; compare with that on tape
RET NZ ; return if not zero.

;; LD-NEXT
L05C2: INC IX ; increment byte pointer.

;; LD-DEC
L05C4: DEC DE ; decrement length.
EX AF,AF' ; store the flags.
LD B,$B2 ; timing.

; when starting to read 8 bits the receiving byte is marked with bit at right.
; when this is rotated out again then 8 bits have been read.

;; LD-MARKER
L05C8: LD L,$01 ; initialize as %00000001

;; LD-8-BITS
L05CA: CALL L05E3 ; routine LD-EDGE-2 increments B relative to
; gap between 2 edges.
RET NC ; return with time-out.

LD A,$CB ; the comparison byte.
CP B ; compare to incremented value of B.
; if B is higher then bit on tape was set.
; if <= then bit on tape is reset.

RL L ; rotate the carry bit into L.

LD B,$B0 ; reset the B timer byte.
JP NC,L05CA ; JUMP back to LD-8-BITS

; when carry set then marker bit has been passed out and byte is complete.

LD A,H ; fetch the running parity byte.
XOR L ; include the new byte.
LD H,A ; and store back in parity register.

LD A,D ; check length of
OR E ; expected bytes.
JR NZ,L05A9 ; back to LD-LOOP
; while there are more.

; when all bytes loaded then parity byte should be zero.

LD A,H ; fetch parity byte.
CP $01 ; set carry if zero.
RET ; return
; in no carry then error as checksum disagrees.

; -------------------------
; Check signal being loaded
; -------------------------
; An edge is a transition from one mic state to another.
; More specifically a change in bit 6 of value input from port $FE.
; Graphically it is a change of border colour, say, blue to yellow.
; The first entry point looks for two adjacent edges. The second entry point
; is used to find a single edge.
; The B register holds a count, up to 256, within which the edge (or edges)
; must be found. The gap between two edges will be more for a '1' than a '0'
; so the value of B denotes the state of the bit (two edges) read from tape.

; ->

;; LD-EDGE-2
L05E3: CALL L05E7 ; call routine LD-EDGE-1 below.
RET NC ; return if space pressed or time-out.
; else continue and look for another adjacent
; edge which together represent a bit on the
; tape.

; ->
; this entry point is used to find a single edge from above but also
; when detecting a read-in signal on the tape.

;; LD-EDGE-1
L05E7: LD A,$16 ; a delay value of twenty two.

;; LD-DELAY
L05E9: DEC A ; decrement counter
JR NZ,L05E9 ; loop back to LD-DELAY 22 times.

AND A ; clear carry.

;; LD-SAMPLE
L05ED: INC B ; increment the time-out counter.
RET Z ; return with failure when $FF passed.

LD A,$7F ; prepare to read keyboard and EAR port
IN A,($FE) ; row $7FFE. bit 6 is EAR, bit 0 is SPACE key.
RRA ; test outer key the space. (bit 6 moves to 5)
RET NC ; return if space pressed. >>>

XOR C ; compare with initial long-term state.
AND $20 ; isolate bit 5
JR Z,L05ED ; back to LD-SAMPLE if no edge.

; but an edge, a transition of the EAR bit, has been found so switch the
; long-term comparison byte containing both border colour and EAR bit.

LD A,C ; fetch comparison value.
CPL ; switch the bits
LD C,A ; and put back in C for long-term.

AND $07 ; isolate new colour bits.
OR $08 ; set bit 3 - MIC off.
OUT ($FE),A ; send to port to effect the change of colour.

SCF ; set carry flag signaling edge found within
; time allowed.
RET ; return.
')

Para tunear los colores. Al principio se fijan en rojo/cyan con esta instrucción:
$this->bbcode_second_pass_code('', '
OR $02 ; combine with red border colour.
LD C,A ; and store initial state long-term in C.
')

La propia rutina LD-EDGE-1 invierte los colores complementándolos con 7, al ser colores primarios también se obtiene el complementario real. Así que en una primera fase se van alternando el 2 y el 5 (rojo y cyan). Si te das cuenta siempre suman 7.

Luego una vez encontrados los pulsos de sincronismo pasamos a azul/amarillo con esa instrucción
$this->bbcode_second_pass_code('', '
LD A,C ; fetch long-term mask from C
XOR $03 ; and make blue/yellow.
LD C,A ; store the new long-term byte.
')

En todo momento el color actual se guarda en el registro C, en los 3 bits más bajos. Al hacer un XOR con 3, si el último valor era rojo (2) se convierte en azul (1) y si era cyan (5) se convierte en amarillo (6).

Así que bueno, siempre que se alternen colores complementarios el cambio es muy sencillo. Si lo que quieres son colores no complementarios tendrías que irte a la parte del código que cambia el borde, que es esta:

$this->bbcode_second_pass_code('', '
LD A,C ; fetch comparison value.
CPL ; switch the bits
LD C,A ; and put back in C for long-term.
AND $07 ; isolate new colour bits.
OR $08 ; set bit 3 - MIC off.
OUT ($FE),A ; send to port to effect the change of colour.
')

Y cambiarla por algo como esto:
$this->bbcode_second_pass_code('', '
LD A,C ; fetch comparison value.
CPL ; switch the bits
LD C,A ; and put back in C for long-term.
rrca
ld a, 1+8 ; azul
jr c, etiq
ld a, 2+8 ; rojo
etiq OUT ($FE),A ; send to port to effect the change of colour.
')

Que alterna colores no complementarios como el azul y el rojo (tienes que sumar 8 al código de color), pero ten en cuenta que esto está en la rutina LD-EDGE-1. Tendrías que crearte otra rutina idéntica pero con otros colores para distinguir el tono guía del resto de la carga.
Avatar de Usuario
astromarinecorps
Mensajes: 28
Registrado: Sab, 15 Feb 2014, 17:52

Re: rutina custom loader

Mensajepor astromarinecorps » Sab, 15 Feb 2014, 22:54

agradezco mucho vuestras respuestas, la rutina no la acabo de entender muy bien, a lo mejor lo hubiera conseguido haciendo pruebas cambiando las cosas que me habeis comentado pero no he sido capaz ni de encontrar un emsamblador z80 para windows y pegar el codigo de esta rutina para hacer dichas pruebas... :ayayay:
antoniovillena
Mensajes: 494
Registrado: Jue, 24 Oct 2013, 15:52

Re: rutina custom loader

Mensajepor antoniovillena » Dom, 16 Feb 2014, 00:15

Busca "ensamblador z80 para windows" en google, seguro que te aparece alguno.
Avatar de Usuario
astromarinecorps
Mensajes: 28
Registrado: Sab, 15 Feb 2014, 17:52

Re: rutina custom loader

Mensajepor astromarinecorps » Dom, 16 Feb 2014, 00:42

he conseguido copier la rutina original en un z80 emsambler y me ha generado unos ficheros que no tengo ni idea de que hacer con ellos... :oops:
Adjuntos
carga.jpg
carga.jpg (400.04 KiB) Visto 7221 veces
Avatar de Usuario
na_th_an
Mensajes: 26413
Registrado: Vie, 09 Ene 2009, 12:18

Re: rutina custom loader

Mensajepor na_th_an » Dom, 16 Feb 2014, 00:59

Te vale cualquiera. Yo uso pasmo. Ejecutas pasmo archivo.asm archivo.bin y te generará un archivo.bin que puedes cargar en la RAM de tu emulador. Por ejemplo, en spectaculator basta con arrastrarlo sobre la ventana del emulador e introducir en qué dirección quieres que lo almacene (que será, por lo general, la que salga en el ORG).
Como diría Rorshach: "Urm..."
Avatar de Usuario
astromarinecorps
Mensajes: 28
Registrado: Sab, 15 Feb 2014, 17:52

Re: rutina custom loader

Mensajepor astromarinecorps » Dom, 16 Feb 2014, 01:08

creo que algo he hecho mal, no se porque tengo 2 ficheros asm, ni que es ese starup...
Adjuntos
carga.jpg
carga.jpg (144.4 KiB) Visto 7216 veces
antoniovillena
Mensajes: 494
Registrado: Jue, 24 Oct 2013, 15:52

Re: rutina custom loader

Mensajepor antoniovillena » Dom, 16 Feb 2014, 01:31

Ok, primero prueba a ensamblar algo limpio. El código que te he pasado debería cargar sin problemas. Luego le vamos añadiendo cosas como un cargador pero de momento solo ensambla.
antoniovillena
Mensajes: 494
Registrado: Jue, 24 Oct 2013, 15:52

Re: rutina custom loader

Mensajepor antoniovillena » Dom, 16 Feb 2014, 01:34

De camino bájate esta herramienta porque luego la vas a necesitar para crear un archivo .TAP

http://retrolandia.net/foro/showthread.php?tid=51

Volver a “Ayuda”

¿Quién está conectado?

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