Boriel escribió:Las rutinas de Santi (sromero) y mcleod están puestas con ciertas modificaciones para que funcionen con el compilador, pero aparecen mencionados en el fuente Espero que no les importe.
Claro que no, hombre.
Un saludo!
Moderador: Sir Cilve Sinclair
Boriel escribió:Las rutinas de Santi (sromero) y mcleod están puestas con ciertas modificaciones para que funcionen con el compilador, pero aparecen mencionados en el fuente Espero que no les importe.
Boriel escribió:
- Optimizaciones varias (a nivel semántico y de código intermedio). Esas que nunca he tenido tiempo de hacer.
Código: Seleccionar todo
ld a, h
or l
or d
or e
ret z ; Returns 0 (EQ) if HL == DE == NULL
ld a, h
or l
ld a, -1
ret z ; Returns -1 if HL is NULL and DE is not NULL
ld a, d
or e
ld a, 1
ret z ; Returns +1 if HL is not NULL and DE is NULL
Código: Seleccionar todo
ld a, h
or l
jr z,__HLZERO
ld a, d
or e
ld a, 1
ret z ; Returns +1 if HL is not NULL and DE is NULL
[...]
__HLZERO: ld a, d
or e
ret z ; Returns 0 (EQ) if HL == DE == NULL
ld a, -1
ret ; Returns -1 if HL is NULL and DE is not NULL
Código: Seleccionar todo
xor a
sbc hl, bc ; Carry if len(b$) > len(a$)
jr z, __EQULEN ; Jump if they have the same length
sbc a, a ; A = -1 if len(b$) > len(a$), 0 otherwise
jr nz, __PRESERVEBC
add hl, bc ; Restore HL (original length)
ld b, h ; len(b$) <= len(a$)
ld c, l ; so BC = hl
__PRESERVEBC:
neg ; A = 1 if len(b$) > len(a$), 0 otherwise
add a, a ; A = A * 2 so (2 or 0)
dec a ; A = 1 if len(b$) > len(a$), -1 otherwise
__EQULEN:
pop hl ; Recovers A$ pointer
push af ; Saves A in A' for later (Value to return if strings reach the end)
Código: Seleccionar todo
sbc hl, bc ; Carry if len(b$) > len(a$)
jr z, __EQULEN ; Jump if they have the same length
sbc a, a ; A = -1 if len(b$) > len(a$), 0 otherwise
jr nz, __PRESERVEBC
add hl, bc ; Restore HL (original length)
ld b, h ; len(b$) <= len(a$)
ld c, l ; so BC = hl
__PRESERVEBC:
neg ; A = 1 if len(b$) > len(a$), 0 otherwise
add a, a ; A = A * 2 so (2 or 0)
__EQULEN:
dec a ; A = 1 if len(b$) > len(a$), -1 if len(b$) < len(a$), 0 if len(b$) == len(a$)
pop hl ; Recovers A$ pointer
push af ; Saves A in A' for later (Value to return if strings reach the end)
Código: Seleccionar todo
__PRGRAPH0:
ld l, a
ld h, 0 ; HL = A (accumulator)
add hl, hl
add hl, hl
add hl, hl ; HL = a * 8
Código: Seleccionar todo
__PRGRAPH0:
add a, a
ld l, a
ld h, 0 ; HL = a * 2 (accumulator)
add hl, hl
add hl, hl ; HL = a * 8
Metalbrain escribió:Hablando de optimizaciones, he visto un par en la rutina __STRCMP (en library-asm\string.asm ):
aquí...:
...estás comprobando dos veces si HL es o no nulo, y se puede usar un pequeño salto para bifurcar al comprobar por primera vez, algo así:Código: Seleccionar todo
ld a, h
or l
jr z,__HLZERO
ld a, d
or e
ld a, 1
ret z ; Returns +1 if HL is not NULL and DE is NULL
[...]
__HLZERO:
ld a, d
or e
ret z ; Returns 0 (EQ) if HL == DE == NULL
ld a, -1
ret ; Returns -1 if HL is NULL and DE is not NULL
Debido al salto, la rutina tarda un pelín más si HL vale 0 (12 estados si DE también vale 0, o 3 si no), pero si ese no es el caso (lo cual debería ser lo normal), ganamos 13 estados.
Por otra parte, aquí:Código: Seleccionar todo
xor a
sbc hl, bc ; Carry if len(b$) > len(a$)
jr z, __EQULEN ; Jump if they have the same length
sbc a, a ; A = -1 if len(b$) > len(a$), 0 otherwise
jr nz, __PRESERVEBC
...
sabemos que A vale 1 desde la última vez que le asignamos dicho valor, así que podemos mover la etiqueta __EQULEN un poquito hacia arriba y prescindir del xor a inicial, ganando 1 byte (y 4 estados si no tenemos la misma longitud en las cadenas). Quedaría así:
Boriel escribió:En cualquier caso, en __HLZERO también se puede sustituir LD A, D por OR D y nos ahorramos 3 estados creo.
Boriel escribió:pensé en su momento que INC/DEC tb. afectaban al CARRY, pero veo que no.
Metalbrain escribió:Otra optimización más, esta vez en __PRINTCHAR (en library-asm\print.asm)
Aquí:Código: Seleccionar todo
__PRGRAPH0:
ld l, a
ld h, 0 ; HL = A (accumulator)
add hl, hl
add hl, hl
add hl, hl ; HL = a * 8
llegamos siembre con A<80h, así que lo podemos cambiar por:Código: Seleccionar todo
__PRGRAPH0:
add a, a
ld l, a
ld h, 0 ; HL = a * 2 (accumulator)
add hl, hl
add hl, hl ; HL = a * 8
ganando 7 estados.
juanjo escribió:Finalmente, echo en falta la instruccion load de basic, para cargar pantallas y bloques de datos. Estaba previsto esto, Boriel?
juanjo escribió:Me esta picando mucho esto, he empezado a hacer un juego de naves. Pero los graficos udg no me bastan, alguien tiene algun link a rutinas de sprites que tengan precision de pixel? O de hacer scroll de fondo tambien.
Código: Seleccionar todo
print 8 shr 2
>2
Código: Seleccionar todo
10 LET a = 5: LET b = 2
20 IF a AND b THEN PRINT "HOLA"
Código: Seleccionar todo
PRINT 5 & 7
>5
Código: Seleccionar todo
PRINT 5 .and. 7
>5
Código: Seleccionar todo
PRINT 5 bitand 7
>5
Código: Seleccionar todo
PRINT 5 bin and 7: REM Demasiado "largo"
>5
juanjo escribió:Respecto a los operadores, yo prefiero simbolos por separado como & para el and bit a bit, pero igual si que es mas facil de recordar la opcion de los puntos.
Tengo un lio con los arrays, se declaran con el numero de elementos 'dim a(n)' y se referencian con a(0) hasta a(n-1) ? Es que segun veo en el snake.bas, se declaran con n-1 en el tamaño
Código: Seleccionar todo
DIM a(1 TO 5) ' Ojo, no se puede usar "n". No hay arrays dinámicos. N tiene que ser un número
Código: Seleccionar todo
DIM a(5): REM Es lo mismo que DIM a(0 TO 5)
juanjo escribió:Ok gracias, solo es que me liaba porque creia que dim a(10) tenia 10 elementos y no 11
sromero escribió:juanjo escribió:Ok gracias, solo es que me liaba porque creia que dim a(10) tenia 10 elementos y no 11
¿?
No sé si Boriel se ha rallado, pero DIM A(10) debería tener DIEZ elementos (no 11) de 0 a 9... ¿no?
Usuarios navegando por este Foro: Bing [Bot] y 33 invitados