Pregunta

Dado que muchos de los problemas del Proyecto Euler requieren que realice una verificación de divisibilidad varias veces, he estado tratando de encontrar la forma más rápida de realizar esta tarea en ZX81 BASIC.

Hasta ahora he comparado (N / D) con INT (N / D) para verificar si N es divisible por D o no.
He estado pensando en hacer la prueba en código máquina Z80 , todavía no descubrió cómo usar las variables en BASIC en el código de máquina.

¿Cómo se puede lograr?

¿Fue útil?

Solución

No sé si RANDOMIZE USR está disponible en ZX81, pero creo que se puede usar para llamar a rutinas en el ensamblaje. Para pasar argumentos, es posible que necesite usar POKE para establecer algunas ubicaciones de memoria fija antes de ejecutar RANDOMIZE USR.

Recuerdo encontrar una lista de rutinas implementadas en la ROM para admitir el ZX Basic. Estoy seguro de que hay algunos para realizar operaciones flotantes.

Una alternativa al punto flotante es usar matemática de punto fijo. Es mucho más rápido en este tipo de situaciones donde no hay coprocesador matemático.

También puede encontrar más información en los problemas de Sinclair User. Publicaron algunos artículos relacionados con la programación en ZX Spectrum

Otros consejos

Puede hacer esto muy rápido en código de máquina restando repetidamente. Básicamente tiene un procedimiento como:

set accumulator to N
subtract D
if carry flag is set then it is not divisible
if zero flag is set then it is divisible
otherwise repeat subtraction until one of the above occurs

La versión de 8 bits sería algo así como:

DIVISIBLE_TEST:
LD B,10
LD A,100

DIVISIBLE_TEST_LOOP:
SUB B
JR C, $END_DIVISIBLE_TEST
JR Z, $END_DIVISIBLE_TEST
JR $DIVISIBLE_TEST_LOOP

END_DIVISIBLE_TEST:
LD B,A
LD C,0
RET

Ahora, puede llamar desde básico usando USR. Lo que USR devuelve es lo que esté en el par de registros BC, por lo que probablemente desee hacer algo como:

REM poke the memory addresses with the operands to load the registers
POKE X+1, D
POKE X+3, N
LET r = USR X
IF r = 0 THEN GOTO isdivisible
IF r <> 0 THEN GOTO isnotdivisible

Esta es una introducción que escribí a Z80 que debería ayudarlo a resolver esto. Esto lo hará explique las banderas si no está familiarizado con ellas. Hay una carga de más enlaces a cosas buenas de Z80 desde el sitio principal, aunque se centra en Spectrum en lugar de ZX81.

Una versión de 16 bits sería bastante similar pero con operaciones de pares de registros. Si necesita ir más allá de 16 bits, sería un poco más complicado.

La forma de cargar esto depende de usted, pero el método tradicional es utilizar declaraciones de DATOS y POKE. ¡Sin embargo, es posible que prefiera que un ensamblador descubra el código de máquina por usted!

Su solución existente puede ser lo suficientemente buena. Sustitúyalo solo por algo más rápido si considera que es un cuello de botella en la creación de perfiles.

(Dicho con una cara seria, por supuesto)

Y de todos modos, en el ZX81 puedes cambiar al modo RÁPIDO.

Primero debe colocar los valores en algunas ubicaciones de memoria conocidas. Luego use las mismas ubicaciones desde dentro del ensamblador Z80. No pasa ningún parámetro entre los dos.

Esto se basa en lo que (todavía) recuerdo de ZX Spectrum 48. Buena suerte, pero podría considerar actualizar su hw. ; /

El problema con el código de máquina Z80 es que no tiene operaciones de coma flotante (y no hay un número entero dividido o multiplicado, para el caso). Implementar su propia biblioteca FP en el ensamblador Z80 no es trivial. Por supuesto, puede usar las rutinas BASIC integradas, pero también puede seguir con BASIC.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top