Pseudo-Random Numbers ROM Zone Finder
Descripción del contenido de la página
Utilidad escrita en Sinclair BASIC para la Sinclair ZX Spectrum que busca en la ROM una zona de 256 octetos con el mayor número de octetos diferentes.
Este programa busca en la ROM de la ZX Spectrum la zona de 256 octetos que contiene el mayor número de octetos diferentes, con el objeto de utilizarla después en una rutina en ensamblador de Z80 para generar números seudo-aleatorios, como parte del perfeccionamiento de un jueguecito de «marcianos» llamado Alien-A.
Lo cierto es que, en lugar de buscar una zona así en la ROM, es más fácil hacerla uno mismo dentro del programa. Pero en ocasiones 256 octetos de memoria pueden ser un tesoro que no hay que desperdiciar.
Terminé el programa más por diversión que por su utilidad real. Para que el programa termine su tarea necesita mucho tiempo, varias horas, de modo que es aconsejable ejecutarlo en un emulador de ZX Spectrum con el máximo de velocidad que nuestra computadora permita.
Pero si la velocidad de ejecución es un problema, hay alternativa: Al día siguiente de escribir este programa escribí una versión mucho más rápida escrita y compilada con ZX BASIC.
Pantallazos
Pantalla de presentación:
Varios momentos de la búsqueda del mejor rango (cada línea horizontal de puntos representa un rango analizado; los puntos de cada línea se dibujan cuando en el rango está presente el octeto correspondiente a esa coordenada X; la zona de la pantalla donde se dibujan las líneas se borra cada vez que se llena):
Código fuente
10 REM Pseudo-Random Number ROM Zone Finder
20 REM Copyright (C) 2010 Marcos Cruz
30 REM http://programandala.net
40:
50 REM License:
60 REM http://programandala.net/license
70:
80 REM 2010-04-08 First version.
90:
100 REM -----------------------
110 REM Init
120:
130 REM System variables:
140 LET S POSN=23688
150:
160 REM Functions:
170 DEF FN l()=24-PEEK (S POSN+1): REM current line
180:
190 REM Constants:
200 LET first=0: REM first ROM block address to be examined
210 LET last=16384-255: REM last ROM block address to be examined
220 LET maxY=176: REM max y graph coord in the Spectrum
230 LET titlePaper=6: REM yellow
240 DIM l$(32): REM screen wide blank string
250:
260 REM -----------------------
270 REM Screen
280:
290 PAPER 7: INK 0: BRIGHT 0: FLASH 0: INVERSE 0: OVER 0
300 CLS
310 BORDER titlePaper
320 PRINT INVERSE 1;"Pseudo-Random Numbers"'"ROM Zone Finder"
330 PRINT "(C) 2010 Marcos Cruz"
340 PRINT "http://programandala.net"
350 FOR n=0 TO FN l()
360 PRINT AT n,0; OVER 1; INK 8; PAPER titlePaper;l$;
370 NEXT n
380 LET workLine=FN l()+1
390 PRINT AT workLine,0;
400:
410 REM -----------------------
420 REM About
430:
440 PRINT "This program searches for a 256-"'"byte zone in the ZX Spectrum ROM"'"with the highest number of"'"different values, in order"'"to be used as a lookup table in"'"a pseudo-random number generator"'"routine in Z80 assembler."
450 PRINT '"It was written mainly for fun."
460 PRINT '"It's distributed under the terms"'"of the Programandala License:"'"http://programandala.net/license"
470 PRINT '"Press any key to start."
480 PAUSE 0
490:
500 REM -----------------------
510 REM Explore
520:
530 LET count=0
540 LET maxCount=0
550 LET bestZone=0
560 GO SUB 790
570 FOR a=first TO last
580 PRINT AT workLine,15;a;"-";a+255
590 FOR b=0 TO 255
600 LET n=PEEK (a+b)
610 IF NOT POINT (n,y) THEN PLOT n,y: LET count=count+1
620 NEXT b
630 IF count>maxCount THEN LET maxCount=count: LET bestZone=a: GO SUB 870
640 LET count=0
650 LET y=y-1
660 IF y<0 THEN GO SUB 790: GO SUB 870
670 NEXT a
680:
690 REM -----------------------
700 REM Result
710:
720 GO SUB 930
730 PRINT "Finished."
740 PRINT "Best range found: ";bestZone;"-";bestZone+255
750 PRINT "Different values: ";maxCount
760 STOP
770:
780 REM -----------------------
790 REM Subroutine: Clear the exploring screen
800:
810 GO SUB 930
820 PRINT "Current range:"
830 LET y=maxY-8*(FN l()+1)-2
840 RETURN
850:
860 REM -----------------------
870 REM Subroutine: Best range so far
880:
890 PRINT AT workLine+1,0;"Best so far: ";bestZone;"-";bestZone+255;" (";maxCount;")"
900 RETURN
910:
920 REM -----------------------
930 REM Subroutine: Clear the working space
940:
950 FOR i=21 TO workLine STEP -1
960 PRINT AT i,0;l$;
970 NEXT i
980 PRINT AT workLine,0;
990 RETURN
1000:
1010 REM -----------------------
1020 REM Save the program
1030:
1040 SAVE "PRNRZF" LINE 10