JOYSTICKS Y SPECTRUM Todas las 8-bits de los 80 en su mayoria tenian conectores para mandos de juego, permitiendo con eso precisamente jugar con la maquina. Desde las consolas de juegos como el Atari 2600, hasta el Apple II y el C=64, entre otros. Pero el ZX Spectrum, resultó ser una curiosa excepcion, al igual que su antecesor el ZX81, el Spectrum carecia de tomas para conectar siquiera un joystick. Habia que comprarse una interfase para poder disfrutar de los mandos de juego. Reuno aqui todas mis notas sobre como definir funciones para leer joysticks en el Spectrum asi como las funciones equivalentes en otras maquinas 8-bits. Para mi comparacion, he elegido: Atari, Amstrad, Commodore y TS-2068 Atari El Basic de Atari tiene dos funciones para leer los joysticks: STICK (n) donde n = un valor de 0 - 3 mientras los modelos 400 y 800 admitian hasta 4 mandos (0-3) los modelos XL y XE solo admiten 2 (0-1) devuelve un valor dependiendo de la posicion en que está la palanca de juego, siendo los valores: 14 = arri. 10 = arr. izq. 13 = abj. 6 = arr. der. 11 = izq. 5 = abj. der. 7 = der. 9 = abj. izq. 15 - si no se hace ningun movimiento STRIG (n) devuelve 0 cada vez que se pulsa el boton de disparo. Amstrad Locomotive Basic tiene una sola funcion para leer los mandos de juego: JOY (n) donde n = 0 / 1 - para elegir el joystick a usar y devuelve los sigtes valores: bit decimal 0:arr. 1 1:abj. 2 2:izq. 4 3:der. 8 4:disp.2 16 5:disp.1 32 De este modo, si se pulsa el boton de disparo del joystick 1, mientras se mueve la palanca a la izquierda, JOY(0) devolverá 20, que es la suma de 16 + 4. C=64 y Vic-20 Vic-20 tenia un conector para un solo joystick y hay que leer las posiciones 37151 y 37152, que son sus puertos A y B. Antes de leer los puertos deben configurarse pokeando en 37139 a 0 y 37154 como se ve en el ejemplo: A=PEEK(37151):POKE37154,127:B=PEEK(37152):POKE37154,255 (A AND 4)=0 - Arriba - bit 2 (A AND 8)=0 - abajo - " 3 (A AND 16)=0 - Izq. - " 4 (B AND 128)=0 - Der. - " 7 (A and 32) - Disparo - " 5 (A AND 20)=0 - Arr. Izq. (A AND 24)=0 - Abj. Izq. (A AND 4)=0 AND (B AND 128)=0 - Arr. Der. (A AND 8)=0 AND (B AND 128)=0 - Abj. Der. En el caso del C=64, este ofrecia la posibilidad de usar dos mandos, los cuales se leen mediante PEEK a: P1(56321) P2(56320) P1(disp) P2(disp) centrado 255 127 239 111 arr. 254 126 238 110 abj. 253 125 237 109 izq. 251 123 235 107 der. 247 119 231 103 arr. izq. 250 122 234 106 arr. der. 246 118 230 102 abj. izq. 249 121 233 105 abj. der. 245 117 229 101 El joystick del puerto 2 se puede leer tambien del modo sigte: J=PEEK(56320) (J AND 1)=0 - arr. (J AND 2)=0 - abj. (J AND 4)=0 - izq. (J AND 8)=0 - der (J AND 16)=0 - disparo C=128 y Plus/4 A diferencia del C=64 y VIC-20, que debian leer los joysticks mediante la funcion PEEK, los modelos Plus/4 y C=128 si tenian una funcion para leer los mandos: JOY (n) donde n = 1 / 2 - para elegir el joystick a usar y devuelve los sigtes valores: 0 - neutro 1 - arr. 2 - arr. der. 3 - der. 4 - abj. der. 5 - abj. 6 - abj. izq. 7 - izq. 8 - arr. izq. + 128 - cuando se pulsa el boton de disparo. TS-2068 / TC-2068 Ahora, vamos a mencionar la funcion extra con la que TIMEX dotó a su versión TS-2068: STICk (m,n) donde: m = 1 - para leer los movimientos de la planca de juego = 2 - lee si se pulsa el boton de disparo n = 1 - si elegimos el joystick izquierdo = 2 - si usamos el joyst. derecho devuelve 0 - inmovil 1 - arr. 5 - arr. izq. 4 - izq. 6 - abj. izq. 2 - abj. 10 - abj. der. 8 - der. 9 - arr. der. para m = 1 y 1 - si se pulsa el disparo 0 - si no para m = 2 Ahora pasamos a ver cuales son los equivalentes en el ZX Spectrum JOYSTICK KEMPSTON La norma Kempston normalmente permitia conectar un solo joystick al port 31, de modo que su lectura era mediante IN 31. Siendo asi, las funciones STICK y STRIG de Atari o JOY de Amstrad se definen como sigue: DEF FN j()=IN 31 - para leer el joystick DEF FN z()=FN j()>15 - para leer cuando se pulsa el boton de disparo 26 24 25 * * * 10 8 9 \ ^ / \ ¡ / 18 * 2 < - 0 - > 1 * 17 / ! \ / v \ 6 4 5 * * * 22 20 21 disparo = 16 (*) JOYSTICK FULLER La interface Fuller Audio Box, ofrecia además de 3 canales de sonido merced al chip AY 3-8912 (el mismo del TS2068 y el 128k), conectar un solo joystick al puerto 127, de modo que su lectura era mediante IN 127. Ahora, las funciones STICK y STRIG de Atari o JOY de Amstrad se definen como sigue: DEF FN j()= IN 127 - lee el joystick DEF FN z()= FN j() < 128 - lee cuando se pulsa el boton de disparo 122 126 118 * * * 250 254 246 \ ^ / \ ¡ / 123 * 251 < - 255 - > 247 * 119 / ! \ / v \ 249 253 245 * * * 121 125 117 disparo = 127 (*) JOYSTICK SINCLAIR La norma Sinclair permite en cambio conectar dos joystick al Spectrum, resultando: Key Joystick 2 Key Joystick 1 1 izq. 6 izq. 2 der. 7 der. 3 abajo 8 abajo 4 arriba 9 arriba 5 disparo 10 disp. IN 61438 lee joystick 1 IN 63486 lee joystick 2 bit 0 'disp.' bit 4 'disp.' bit 1 'arr.' bit 3 'arr.' bit 2 'abj.' bit 2 'abj.' bit 3 'der.' bit 1 'der.' bit 4 'izq.' bit 0 'izq.' De ese modo la función para leer los joysticks 1 y 2 es: DEF FN j()=IN 61438 - 170 DEF FN j()=IN 63486 - 165 2 18 10 1 2 0 * * * + + + 3 19 11 17 18 16 \ ^ / \ ^ / \ ¡ / \ ¡ / 4 * 5 < - 21 - > 13 * 12 9 + 25 < - 26 - > 24 + 8 / ! \ / ! \ / v \ / v \ 1 17 9 21 22 20 * * * + + + 0 16 8 5 6 4 disparo = 20 (*) disparo = 10 (+) Una mejora es formularla del sigte modo: DEF FN j(x)=IN (61438 +(1998 and x=2))-(170-(5 and x=2) donde x = 1 (joyst 1) y 2 (joyst 2) El dilema estriba ahora en la lectura del botón de disparo, ya que si se usa el mando 1 entonces DEF FN z()=FN j() - 1, pero si se usa el mando 2 tenemos DEF FN z()=FN j() - 16 ya que los valores a leer para strig 1 = 0,2,4,8,10,12,16,18 y 20 y strig 2 = 0,1,2,4,5,6,8,9 y 10 Nota: Los valores a restar de 170 y 165, es debido a que el valor por defecto de los joystick Sinclair es de 191. En la mayoria de emuladores, obtengo 191 en cualquier modelo de Spectrum, pero algunos me devuelven 255 en modo 16k y 48k. EL TECLADO DEL SPECTRUM Para leer todo el teclado del mismo modo en que se leen los joysticks de la norma Sinclair hay que definir la sigte. función: DEF FN k(m,n)=(n= IN (254+256*(255-2^m)-170) donde m = 0: CS - V 1: A - G 2: Q - T 3: 1 - 5 (joyst.Sinclair 2) 4: 6 - 0 (joyst.Sinclair 1) 5: Y - P 6: H - ENTER 7: B - SPACE Donde FN k(4,n) equivale a FN j(1) del ejemplo anterior. siendo n = cualquiera de los valores devueltos por FN j(1) y FN j(2) En emuladores: Real Spectrum acepta solamente las normas Kempston y Sinclair con mandos de PC. Spectaculator usa Kempston, Fuller, Cursor (AGF o Protek) y Sinclair. Klive igual que Spectaculator. EmuZwin lo mismo. x128 en su ultima version alfa, añade a todo lo antes dicho, el DK'Troniks, el TrickStick y los mandos de Timex. FUSE acepta Kempston, Sinclair, cursor, Fuller y mandos de Timex. SpecEmu permite ademas de Sinclair y Cursor, un segundo Kempston a leer en IN 55. ZX32 admite Kempston, Cursor y Sinclair. Z80stealth solo admite Kempston y Sinclair. ZXmak2 solo Kempston. Zesarux varios incluidos mandos para ZX81. Warajevo, solo Kempston, sinclair y Cursor. Igual el Z80 de Lunther. Para cerrar un listado ejemplo originalmente publicado por tu TUMicro #5 como demostracion de las funciones joystick de Atari, pero adaptado para Kempston: 10 REM "JOYSTICK" 20 DEF FN j()=IN 31: DEF FN z()=FN j()>15 30 LET x=40:LET y=20:LET c=0 90 PLOT x,y 100 LET a=FN j() 200 IF a=4 THEN LET y=y-1:GOTO 300 210 IF a=5 THEN LET y=y-1:LET x=x+1:GOTO 300 220 IF a=1 THEN LET x=x+1:GOTO 300 230 IF a=9 THEN LET x=x+1:LET y=y+1:GOTO 300 240 IF a=8 THEN LET y=y+1:GOTO 300 250 IF a=10 THEN LET y=y+1:LET x=x-1:GOTO 300 260 IF a=2 THEN LET x=x-1:GOTO 300 270 IF a=6 THEN LET x=x-1:LET y=y-1 300 IF x>254 THEN LET x=0 310 IF y>174 THEN LET y=0 320 IF x<0 THEN LET x=255 330 IF y<0 THEN LET y=175 400 IF FN z() THEN LET c=c+1 410 IF c=7 THEN LET c=0 420 INK c: GOTO 90 El mismo listado adaptado a la norma Sinclair: 10 REM "JOYSTICK" 20 DEF FN j(x)=IN (61438 +(1998 and x=2))-(170-(5 and x=2) 30 LET x=40:LET y=20:LET c=0 90 PLOT x,y 100 LET a=FN j(1) 110 IF a=17 THEN LET y=y-1:GOTO 300 120 IF a=9 THEN LET y=y-1:LET x=x+1:GOTO 300 130 IF a=13 THEN LET x=x+1:GOTO 300 140 IF a=11 THEN LET x=x+1:LET y=y+1:GOTO 300 150 IF a=19 THEN LET y=y+1:GOTO 300 160 IF a=3 THEN LET y=y+1:LET x=x-1:GOTO 300 170 IF a=5 THEN LET x=x-1:GOTO 300 180 IF a=1 THEN LET x=x-1:LET y=y-1 300 IF x>254 THEN LET x=0 310 IF y>174 THEN LET y=0 320 IF x<0 THEN LET x=255 330 IF y<0 THEN LET y=175 400 IF a=20 THEN LET c=c+1 410 IF c=7 THEN LET c=0 420 INK c: GOTO 90 A manera de apendice he decidido mencionar otras versiones de Basic: Tandy Color C. y Dragon usan la funcion JOYSTK(x), siendo x un valor de 0 a 3 para leer las verticales y horizontales de cada mando de juego. Por ejemplo: A=JOYSTK(0):B=JOYSTK(1), donde A lee el movimiento derecha-izquierda y B lee el movimiento arriba-abajo del mando derecho. Y con PEEK(65280) el boton de disparo. Apple II usa mandos analogicos que lee mediante la funcion PDL(n), donde si n=0 lee la horizontal, n=1 lee la vertical, ambos del mando 1. N=3/4 leen del mando 2. Devuelve valor de 0 a 255, siendo 127=quieto o centrado. PEEK(49249+n) siendo n un valor de 0 a 2, lee el boton de disparo. Laser 200 requiere de la funcion (INP(n)AND31) siendo n=43 para leer el mando izq. y 39 su boton ARM, mientras n=46 y 45 leen el mando der y su boton ARM. PC/GW-Basic posee al igual que Atari, las funciones STICK y STRIG para leer los joysticks y el boton de disparo. Iguales funciones que en MSX Basic. TI99/4 Texas instrment usa la sentencia CALL JOYST (k,x,z) siendo k=1/2 para seleccionar cual mando usar y devolviendo los valores de -4 a 4 en x,z. CALL KEY(k,r,s) permiten leer tanto el teclado como el disparo de los mandos. Acorn Electron requeria de la expansion PLUS1 para podersele conectar mandos. Una vez hecho esto, se podian leer mediante la funcion ADVAL(x) siendo x=1 para horizontal y x=2 para leer la vertical; mientras que el disparo se leia mediante: b= ADVAL(0) AND 3. (c) 2017 zx_if1@hotmail.com