Para comprobar que los cálculos son idénticos he metido, en una de las versiones de esta rutina, una llamada a PRINT_FP para que vaya imprimiendo el valor de cada elemento del vector Y en pantalla a medida que se va calculando. Pedirle que imprima un número en punto fltoante es una tarea que consume bastante tiempo, como podreis ver.
El programa (sensiblemente más largo que su versión en BASIC, claro está) es éste:
Código: Seleccionar todo
;Bucle SAXPY en ensamblador usando el
;calculador de la ROM
;(C)2012 Miguel Angel Rodriguez Jodar (mcleod_ideafix)
;GPL licensed.
N equ 100
STACK_NUM equ 33b4h
STK_STORE equ 2ab6h
STK_FETCH equ 2bf1h
PRINT_FP equ 2de3h
DEBUG equ 0 ;1 para imprimir vector Y por pantalla
org 50000
di
ld a,253
ld i,a
im 2 ; poner cronometro
ld ix,X
ld iy,Y
ld b,1
ld de,5
BucleRellena ld a,N
sub b
ld (ix+0),0
ld (ix+1),0
ld (ix+2),b ;x(i)=i
ld (ix+3),0
ld (ix+4),0
ld (iy+0),0
ld (iy+1),0
ld (iy+2),a ;y(i)=N-i
ld (iy+3),0
ld (iy+4),0
add ix,de
add iy,de
inc b
ld a,b
cp N+1
jr nz,BucleRellena
ld b,N
ld ix,X
ld iy,Y
ld hl,0
ld (FRAMES),hl ; cronometro a 0
ei ; Comienza a medir el tiempo ahora!
BucSAXPY push bc
push iy
pop hl
call STACK_NUM ; y(i) -> stack
ld a,130 ;
ld e,72 ; Estos 5 numeros son
ld d,245 ; el valor 3.14 codificado
ld c,194 ; en coma flotante del Spectrum
ld b,143 ;
call STK_STORE ; 3.14 (a) -> stack
push ix
pop hl
call STACK_NUM ; x(i) -> stack
rst 28h ; calculador de la ROM
db 04h ; multiplica: a*x(i) -> stack
db 0fh ; suma: a*x(i)+y(i) -> stack
IF DEBUG
db 31h ; dup: una copia para imprimirla
ENDIF
db 38h ; fin calculos
call STK_FETCH ; recuperar resultado del stack
ld (iy+0),a
ld (iy+1),e
ld (iy+2),d
ld (iy+3),c
ld (iy+4),b ; y se guarda en y(i)
ld de,5
add ix,de
add iy,de
IF DEBUG
push iy
ld iy,5c3ah
call PRINT_FP
ld a,32
rst 10h
pop iy
ENDIF
pop bc
djnz BucSAXPY
ld bc,(FRAMES)
im 1
ret
X ds N*5
Y ds N*5
FRAMES dw 0
org 65023
dw NuevaIM2
NuevaIM2 push hl
ld hl,(FRAMES)
inc hl
ld (FRAMES),hl
pop hl
ei
reti
end
La versión con DEBUG=0 (sin impresión en pantalla), está en el fichero "saxpy_rom_noprint.sna". La rutina se llama con PRINT USR 50000 y devuelve como resultado el número de retrazos que ha tardado la rutina (un retrazo = 1/50 s). En el snapshot basta con ejecutar con RUN.
La versión con DEBUG=1 imprime en pantalla a medida que se calcula Y. Esta en el fichero "saxpy_rom_print.sna". Ahí vereis que también está la versión en BASIC. Ejecutando con RUN sale esta versión (mucho más lenta por culpa de los PRINT's). El último valor que sale en realidad es el tiempo en segundos medido. Haciendo PRINT 0.02*USR 50000 se ejecutará la versión en C/M, también imprimiendo valores en pantalla (que deben ser idénticos a la versión BASIC) y por último, el tiempo empleado.
Para los que no quieran ejecutar los snapshosts, diré que la versión en C/M sin impresión, tarda 0.28 segundos, frente a la que hice en BASIC, que recordemos tardaba 1.94 segundos. La versión C/M con impresión tarda 1.38 segundos, frente a su correspondiente en BASIC, que tarda 3.6 segundos.