Está en la página 1de 95
oe, ess se wa ee pM ihn? i Wes i SU oe ES OS ‘ ai . igo a aqu ok a0), Prat am a Toon ee h oRote so ein, os cS act TH Raat iat a) ‘40 WEE oo et Whee ‘000! 20 See wut ENO, xa! AD eee os we oe? 8, OE x ce aor AONE, rea echt ok 2 rsa, ee of ree nea a cia aie oe De oS oh FR Ei Sco we i‘ Cc . = ey uk Hae, Ferg 2 ane aie ws at ue yy pose cpl Neant seue OV Eom) a1 Wey 19) “ane ree ce, w cE eh AAD Cee, WH a eS Sha on See x2 se eae ca Ss Seo Gia use CNV Enea Fence corn OOF a eRe G ets wee, AIO) eNeg Meus, care yt ARB 1 Eanes Ecittt Wont Raut ste ae vy 99 8 es Se EA SG. 0 Ns uta Obey ee \ en Vie oases aes Tah ee “erxrhon . Te" Bae 3p Yc Nee oe oa 50 Cee ep) oee Est a ost + COs Oren wv eth a gee “tae ie eye, Brae aes, ee rs 08, a Si R a Sa ar e 2 Mee ane an 7, ia ma a Ae C€ : o ererol ¥, ‘ s oe Fs WAG a ant at hee ie ae Cisst ie, saa Q asia eee 4! 0 WO et, 0 a oh Date a © Of, oat TE Se aes A eee SPREE no ae, oUt | SUPLEMENTO ORIC-ATNOS (Diccionario, FUNCT, ete.) .. ++ 77 Preventeci6n see ee ee ee ee eee cSdigo whquina: introduccién, instrucciones, traduc- cién, registros internos, tablas, ejeuplos.. 1+ +s Estructura del pusic: el prygruma, lineas, to es, variables, sus tipos ¥ estructura, eee ee eee Interprotacién: funcionasilanto y organigramas de 1a se~ cuencia principal, de la introduccién por terlada, de Je insercién de lineas, interpretacién, ejecucién y ta~ bla de direcciones . . + + Interrupeiones: qué son, us tipos, un programa ejen plo de su uso: un reloj independiente dei tuncionamien~ to normal del ordenador, eee eee eee ee ee Cassette: reconondaciones, funcionamiento, codificacién de los ficheros, rutinas de verifirarifn, manejo de £i- cheros, identificacién, direcciones de rutines . . +. ss Sonido: estructura y funcienamiento del generador de 90 nido, registros, uso desde gl cédigo miquina. .... . Direcciones: extensa tabla que contiene las direccio- nee de las principales variahles internas, y de las ruti- nas de la RON, con indicaciones sobre las mismas . . «+ + Aplicaciones: rutinas prestas a su utilizacién Programa utilitario para la carga de lag rutinas .. . . mntrada de expresiones en un INPUT + +--+ ee tee ee RESTORE a un nfimero de linea. see eee ee ee ee Impresién de caracteres gigantes .... . i Verificacién de 1a lectura desde cassette... . 4+. 4 + Conversién a binario (uno 0 dos bytes)... ee eee Cémo tener dos programas Basic en memoria... 21. eee Combinacién de varias rutinas. s+. ++ ee pee ee Errores: tabla de tipos y dipeceiones. © es se ee ee Control: tabla de los caracteres de control: su uso y aplicaciones, como activarlos directanente.. +... ++ Recetario de consulta para Ja preparacién do cue propias rutinas en cédigo miquings see ee ee ee ee ee Bnore de 1.984 Copyright: Ramon Cererola i Nacia Provence, 513-515, 5! Dareelona-25 Teléfono: (93)348.15.97 4a aL 16 29 32 42 47 HE @ OL 62 64 66 67 68 69 3 a 94 PRESENTACTION: B1 ORIC-1 constituye un equipo con una relecién prestaciones/precio realnente interesante, que ha permitido @ michos iniciarse en el apasionante mundo de 1a inform&tica. Cuando uno ha conseguido, superando 1a insuficiencia del ma mal, Leger a un cierto conocimiento del Lenguaje Dasic, se da una idea de las grandes posibilidades de 1a niquina. Sin embargo, incluso cuando se llega a dominar el Basic, queda por descubrir otro apasionante mundo que subyace en las entraiias del microprocesador (este miniscule “coraz6n" que da vida al ORIC). Se trata del codigo maquina Este lenguaje, rodeado miches veces de un cierto misterio, permite unas posi- bilidades que multiplican 1a potencia del equipo: por una parte, la velocidad de ejecucién puede miltiplicarse en ocasiones hasta por un factor de cien, por otra parte, con este nétodo es posible realizar cosas que serian imposi— bles de otro modo, ast, por ejemplo, en 1a pagina 30 se encontraré una breve rutina que permite hacer aparecer on 1a linea roservada superior (aquella en la que habituelsen— te aparecen los mensajes "Saving" y "Loading”) una indicacién horaria, con las horas, minutos y segundos. Bllo no tendrie nada de particular, si no fuera porque el funcionamiento de este reloj no interfiere en absoluto el normal de le maquina. Asi, podenos seguir escribiendo programas, ejecutindolos, modifickndolos, etc. y el reloj sigue funcionando independientenente. Este es solo un ejemplo. En el libro se encontrarén otras rutinas, siompre presentadas de modo yuo su introduccién sea fcil, sin necesidad de concci- mientos especiales, y con métodos de comprobacién para verificar la correcta introduccién de los datos. El Libro est& pensado de modo que pueda resultar “itil, tanto @ los que, cono- codores del Basic, deseen iniciarse en el cédigo miyuina, como a los que, com nocedores ya de éste fltimo, estén interesedos en cdno aplicarlo al ORIC, : aprovechando les rutinas de le ROM. A este fin, a partir de una introduccién general, se paca a describir le es~ tructura del Basic del ORIC-1, el funcionamiento general de 1a 104, como se interpretan las sentencias del Basic, como funciona el cassette y el gencra~ dor de sonido, etc. El libro se completa con una tabla de direcciones ditiles, ejemplos de rutinas y@ preparadas, y un recetario pare preparar fécilmente uno mismo sus propias rutinas. Espero que este libro pueda cubrir 1a laguna informativa que sobre el tena existe y pueda proporcionar al lector nuevas satisfacciones con su ORIC. ! We procurado evitar los erreres, y repasar las rutinac una vez mecanografia~ das. No obstante, supongo que se habrén deslizado ulgunos errores (espero que pocos). Agradeceré, pues, cualquier comentario qua permitirs corregirlos en sucesivas edicions \ CODIGO MAQUINA Exiote un recelo generalizado entre quienes han dado sus primeros pasos con el Basic, a la hora de introducirse en 1a programacién en cbdigo maquina. Se conentan y reconocen sus induddbles ventajas, pero wn cierto hiiite de sisterio impide ou utilizecién. Ello es debido a una serie de factores: ~ por una parte, la falta de manuales de iniciacién simples y accesibles (existen, eso si, espesos y conpletos tratados, usualmente en inglés, pero poco aptos para quien pretende iniciarse en ol tema). ~ falta, en el ORIC-1, de un editor que permita introducir fScilmente las instrucciones en cédigo naquina, intercalarlas, euprinirlas, modificarias, ete. como puede hacerse con 10s progranas asic. | = dificulted en 1a depuracién de erreres, ye que un fallo en un prograna en cbdigo n&quina puede ecarrear bloqueos imprevietos. = falta de informacién sobre las rutinas de 1a ROM y el funcionamiento de 10 misma, do modo que puodan ser utilizadas en nuestros programas en codigo maquina. Los anteriores problenas son subsanables: asi, por 1o que respecta a le falta de informacién, este libro pretende aportar bastantes detos al respecto (a la espera de que el fabricante 1a complete), en cuanto a ir falta de editor, ea piezan @ existir algunos progranas utilitarios en cassette, y yo mismo puedo facilitar a quien 1o desee un completo ensanblador, y 1a depuracién de erro~ res se simplifica preparando los programas en bloques mcdulares (1a llanada progranacién estructurada) fo Por filtimo, para tratar de paliar la falta de manuales de iriciacién, en el presente capitulo voy a dar las nociones generales que permitan a cualquiera, si no un conocimiento a fondo del tema, imposible en tan carte aspacio, si por 10 menos 1a comprensién suficiente para poder iniciar los prineros expe rimentos, y entender el funcionamiento de las rutinas. i ost& formade por una Empernrenos dicionda que ua prograna en e6dige mau sucosién do 1ineas, cada linea conteniendo una sola instruccién. Cada linea esth ropresontade on la menoria de 1a miquina por un conjunte de uno tree bytes. E1 primer byte constituye el cédigo de 1a instruccién; los otros dos, si existen, constituyen el operands sobre el que se nplica la inetruceién. BI primer byte (el correspondiente @ 1a inatmucedén), indica a1 mieroprooces~ dor el nfimero de bytes que foran 1a linea, pues no existe ningiin tipo de se- peracién entro Iineas, ni nunoracién do lee miemae. Las operaciones que realizan lee distintas instrucciones con muy simples, pe— re comprenderlas, conviene conocer le estructura general del microprocesador- El mieroprocesador posee una serie de registros de memoria internos, @ saber: - el registro 4, 0 acumlador, que es el usado comunmente para las operaciones aritméticds o légicas. wlos registros X e Y, usados generalmente como indice (referencia a partir del origen de una tubla). = el registro de estado P, que contiene una serie de indicadores (flegs) que nos determinan e1 estado del microprocesador en un momento dado. ~ el puntero 5 d@ stack, que nos sciiala 1a filtima posicién de memoria utilize— do para conservar las direcciones de retorno de los suvprogranas. = 01 contador do programa rc, que contiene 1a direccién de memoria donde se encuentra la instruccién que se esth leyendo 0 ejecutando. 7 Excepto este &1timo, que es de dos bytes (16 bits), los restantes solo son de un byte (8 bits), por 10 quo el m&ximo valor que pueden cuntener es 255, en | decimal. Por contra, el contador de programa puede llegar a 65535, por 10 que 1a maxina cantidad de menoria que es capaz do direccionar es de 64 K (los 48 de RAM y los 16 de ROM). Recordemos que 1 K vale 1924 bytes. Peel alten reer Gorges, za), con las siguientes funciones: | at ea tslvbxtsfotptzicl ™ : - S (signo): se pone @ 1 cuando el resultado de la filtima operacién ha sido negative (se entiende por negativo todo byte superior o igual a 128). - V (overflow): se pone a uno cuando el resultado de la Giltima operacién ha oxcedide 1a capacided (pasa de 255)- - B (break): se pone a uno al producirse una interrupeién (DRI). i - D (decimal): se pone a uno para ejecutar las operaciones en decimal (de lo contrario o¢ realizan on binario). |- 1 (interrupciones): cuando est& puesto a uno, las interrupciones no estén autorizadas. I 2 (cere): ae pone a uno cuando cl resultado de 1a Gitina éperacién co un i nimero nulo. |- c (carry): arrastre en les operaciones de suma de varius bytes. i El microprocesador 6592 admite un total de 56 instrucciones distintas, que podemos clasificar en varios tipos: ; ~ 16 instrucciones de traslado de bytes. ~ 26 instruceiones de operaciones entre bytes. ~ 15 inotruceiones de saltos. sada para "borrar" - una {iltima instruccién que no hace nada, 1a llamada NOP, instrucciones erroneas. Todas les invtruceiones son repregentadas mediante abreviaturas (mnembnicos) de sus nombres ingleses, y todas son de tres letras. Tenganos en cuenta, no i obstante, que este nombre de la instruccién es solo el quo le damos para ma- yor facilidad de utilizacién por nuestra parte, pero que en el interior de la néquina, a cada instruccién le corresponde un cierto valor del byte, que po~ donos obtener mediante unas teblae adecuadas. Instrucciones de traslado de bytes: LDA page el contenido de una posicién de memoria al registro A. Lx {dem a1 registro x. Lpy idem ai registro Y. © _. “ake iene (! STA pasa el valor del registro A a une posicién de menoria. STX idem del registro x. sty {den del registro ¥. TAX pasa ol contenide dol registre A al registro x. - tay {dem al registro Y. : TKA paca ol contenido del registro X al registro A. TYA {dom del registro ¥. srpcee e TSX paca el contenido del registro S al registro X. x ‘i “ graces) H TXS viceversa. PHA paea el contenide del registro A al stack. Incremente 5. th - PLA recupera del stack un valor y lo pasa a A. Decrementa S. es PHP pasa el contenido del registro P al stack. Incrementa S lel Instrucciones de operaciones entre bytes: > Ave ADC ADC suma el contenido de A al de una posicién de momoria, con arrastri SBC {dem para 1a resta. (WEINC increnenta en una unidad une posicién de menorie. INK {den e1 registro x. uy {den el registro Y. DECDEC decrementa en una unidad el contenido de una posicién de menoria. vex idem el registro x. vey iden el registro Y. scene ar CHPCMP compara el contenido de A con el do una posicién de memoria. [A-1)NjZ5C jel SIM ¢ : crx fdom el registro x. : cry dom el registro Y. -{®DAND ealiza e1 AND légico de A con una posicién de memoria. ORA Adem 1a funcién on. BOR {den el OR exclusivo. BIT comprueba el signo del valor de una posicién de monoria. ASL desplaza a 1a izquierda los bite de una posicién de menoria. ROL idem, con entrada a través del carry. E Usk {don'a le dorecha. ROR edn, con entrada del carry. 4TCSEC pono a uno el bit Carry. SED {dem el bit Decinal. SUTSEI {dom o1 bit Taterrunt. st CLCCLC. pone a coro ol bit Carry, cip {dem el bit Decinal. {den el bit interrupt. {don el bit overflow. - Inatrucciones de saltos Bec salta si el carry osté a coro. sEpne feem et bit rer BPL {dom el bit Signo. sve {dom el bit Uvertiow. BCS salta ‘si el bit Carry esté a uno. vey Tdem el bit Zero. BNI idem el bit Signo. BYS idem e1 bit Overflov. Mf IMP salta incondicionalmente. JSR salts @ une subrutina. | prs vuelve de une subrutina. DRC selta a subrutina de interrupcién. ‘IseT RTI vuelve de una subrutina de interrupcién. © . Como hemos indicado, reprosentanos cada instruccién, en ol interior do la mo- moria de le séquina, por un cierto valor del byte. Como quiera que solo hay 56 instrucciones, mientras que 4 un byte podenos darle 256 valores distintos significa que ‘podemos asignar mis de un valor a le misma instruccién. {Por qua hacenos esto? Para compranderia, vanos a ver el ejemple de una de las instrucciones née corrientenente utilizadas, LDA (que pasa un cierto valor al registro acumulador A). Este instruceién eucle utilisarse para pasar el contenido de una povicién de memoria determinada el acumlador A. Suponganos que se trate de 1a posicién do memoria 49999 (en hexadecimal ¥9C49) (* ver nota a pie do pagina). Repre- sentarenos 1a instruccién mediante LDA $9C4, y direnos que el direcciona~ mionto (forma do dofinir la direccién del operando) ea abzoluto, ya que noo indica la direccién de donde debenos leer el byte, codificado sobre dos by- toa Bn exte cave, 1a traducedén de la instruccién (aegin le tables) es $AD, ¥ @ continuacién deberenos poner los dos bytes que forman 1a direccién pero, aten~ edén!, on orden inverco al habitual, eo decir, primero cl ¥4f (el de peoo ba— jo) y luego $ 9C (el de peso alto), B1 conjunto se introduciré, puos, en le Wenorte de le miyulue wediente Le suceviéu de lov Lees Lyles £AD,249,89C. B2* tos tres bytes forman el auténtico cédigo miquina. Pero sucede a menudo que utilizamos lag direcciones de 1a parte baja de 1a me~ morla, de J @ 255, que constituyen lo que we lama le pagina cero, porque el primer byte de la direceién es nulo. En este caso, este byte nulo constitui~ rie une prdide de nenoria inuecesaria, por lo que se ople por dare la L truccién LDA una traduccién distinta: $45, que indica al microprocesador que se trata do una direccién codificada sobre un solo byte. asi, por ejemplo, LDA $49 90 traduciria por los bytes $15,249. Fopezanos a ver 1a conveniencia de enplear un programa utilitaric que nos rea~ lice la conversién de los simbolus que nosotros utilizamos (el liamado lengue— Je de ensanblaje) al auténtico cdigo miquine, eviténdonos tener que consultar continuamente las tablas para cada instruccién y modo de direccionamiento. Adenia, ostos programas utilitarios (los ensanbladores) tienen miltiples von~ tajas, que se irén viendo posteriormente. yuede también suceder, que en lugar de querer leer el contenido de una posi~ cién de menoria, deveenos introducir un valor concreto en el acumulador. En este caso colocarenos el valor a introducir justo a continuacién del cédigo de 1a instruccién, por lo que @ este modo de direccionamiento le 1lamaren0s inmediato. En este caso, el cédigo correspondiente @ LDA es £A9- de direccionamiento lo sefialanos con el simbolo x. Asi, para introducir el valor $49 en A, harenos LDA #84, lo que se traduce por los bytes ¥A9,849. Obsérvense les diferencias con el caso anterior. Pero la instruccién LDA posede todavia otros cinco tipos de direccionamiento mis sofisticados, cuya utilidad radica en la lectura de tablas al ser utili~ aden dentro de un bucle, y que describizcs a continuacion, nirocctonantonto (eladesade por x1 1a direcesén de donde debentos leer ol ve~ or que peserenos a A dobe obtonerse sunundo el contenido de X al valor que sigue @ la instruccién JNA, y loyendo el contonido de Ja diroccién reeultan~ toy y 1a siguiente, . (GA) EE SiON UA se mumtn Sn chante de (Crd we [ee Bs ss IS (#) Nota: Bn cédigo m&quina es usual representur los valores hexadecimales mediante el cigno ¥. El oigne # eo reserva para el direccionasicnto in— mediato, que se describe en esta misma pigina. otencro DEAR OD Ciypig.ecto ~¥) (paro) Direccionamiente postindexade por Y: 1a direccién de donde leerenow et Valor @ pasar a A se obtendré sumando el contenido de Y a 1a direccién contenida en el byte efialado por el valor que sigue @LDAy,y el Siguienter i staat (npsornn - ) fle fe eatabirs fle bea Direccionamiento indexadd por X: 1a direceién de dondé tonsi”el valor para A se obtendré eumando 1a direccién absolute goatéida on los dos bytes siguien— too a 1DA, aks el contenido del regigtro X. SEwis: op sik 51x =PH,/ Ares ¥ rho SHE RizeegLgnanionto eas on re cea etyeneer ine eet ert eniecre te eed Direccionamiento indexado por X, en pgina cero: en un colo byte. ($85) Estos cinco tipos de direccionamiento’se representan, reepectivamente, me- diante: LDA ()X) LDA (n),¥ LDARyX —-LDAnyY LDA 4X. y en cada caso, 1a instruccién LDA se traduce por un cierto valor que indica el tipo de direccionamiento. Las instrucciones que, como L.A, admiten estos tipos de direccionamiento, son las siguientes (con sus correspondientes traducciones, para que 1a tabla sea de utilided ie la escritura de rutinas) 2B peace haces a Hodes ¥ antes de seguir estudiand nuevas inetruccionos, vamos @ realizar nucetra primera rutina méquina con lo ya conocido, para ver 1a forma practica de Lle~ varlo a cabo (1a rutina, légicamente, cerS my eimple). ierdo Supongamos que quorencs colocar una letra A on ol extromo superior iry do 1a pantalla (en 1a linea reservada normalnente para los mensajes del cas- tte). Ello significa que dobemoa colocar el valor #41 (que es cl cédigo ASCII para 1a letra A) on ol primer byte de 1a zona de Ja pantalla (que en modo TEXT 02 gnD89 (0 #8000) Para ello deberemos primero colocar en el registro A el valor #41, y después pasar el contenido de A a le posicién de memoria citada, es decir: $A9,41 LDA Hf41 —scargamog el valor de la letra Ae AcuM/LADOR $90,$49,$8B STA gBB8f 10 pasamos a 1a pantalla Ahora bien, ‘falta una instruccién’ que, una ver hocho 10 autertor, nos retorue a1 control por teclado (0, en su caso, al prograna que haya Llenado 1a ruting). Fata inatruceién aa normalmanta RTS (rotorna de subrutina) . Si aliadimos esta instruccién, y luego a 1a izquierda de cada 1{nea anotamos loa valores da los bytes correspondientes, segiin las (ablas, obtendrLanos: Bag 4d ; LDA H¥41 ¥8D $89 SBBI= STA gBB8g 869 La rutina ocuparfi pues, seis bytes, que podemos colova: a partir de la direc~ cién $49, que es 1a zona habitualmente reservada para los poquefios progra~ mas en cbdigo méquina escritos por el usuario. Una musiera de entrar estos valores, seria utilizando seis veces 1a instruccién POKE, para lo que pre- vianpnte, deberiaaos traducir @ valores decimales los anteriores, obteniendo: i) $0), gad dee tes 169 » % + YL, 128, 187 4/96 y ahora podenos hacer: POKE #499,169 Sere! POXE #492,65 POKE #492,141 POKE #493,128 POKE #494,187 POKE #495,96 RIS Ya tenemos la rutina en su sitio. Para poder utilizarle, recurriremos « le instruccién CALL #499 y veremos como aparece la A en el sitio anunciado. Evi- dentenente, el Gnico interés de esta rutina ea servir de ejmpla de como puede procederse. Vemos una vez més, 1a conveniencia del prugrana ensanblador, que nos avita largaa secnancias da POKES, lentas y sonetidas n errores. No todas las instruccionas admiten tantos tipos de direceionamiento como LDA, jaf tenemos la siguiente tabla: iii freee pomrer ogy y bastantes,de las instruecionea tienen una traduccién fija, bien porque no vequieren operando 0 porque s6lo admiten un tipo de direccionamiento: y ya para completar las 56 instrucciones, nos quedan solo dos casos especia~ les. ‘Se trata de BIT, que adnite direccionaniento absviuto ($20) 0 en picine cero ($24); y de JMP absoluto (¥4C) © andirecto (¥6C) con la tabla completa de traducciones, vamos aver cémo puede utilizarse el @ireccionamiento indexado. Para ello, suponganos que queremos hacer una ru~ tana que lene los primeros 16 lugares de 1a linea revervada superior de 1a pantalla con letras "A". Podriamos repetir el proceso descrito en 1a prine~ ra rutina que habienos preparado, tantas vecos com letras querunos poner. Sin embargo, vemos que ello resultaria largo y monétono Podesos hacerlo de modo née sinple. pn lugar de colocar en 1s instruccién Ja direccién absoluta donde queremos colocar le "A" (es decir STA ¥BB8#), utili~ zaremos el direccionamiento indexado por X, asi: STA $BB89,X. Antes de empe- zar, pondremos a cero el registro X, mediante 1.DX #@, con lo que colocaremos le A en la-direccién correspondiente a le suma de ¥BB8 mis e1 contenido de X que era cere. Necho esto, incrementanos el valor de X, mediante INX, y comparanos el valor do X con 16, para ver si hemos llegado al final. De no scr asi, volvemos al principio del bucle. La rutina, junto con los valores de los bytes a colocar (traduceién a cédigo méquina) queda asi: : 145) a9 B41 LDA #34 seargamos en A el cardcter 302 $08 LOX 4p iponemos e1 indice X a cero $90 $84 ¥BB lazo STA $NBE,X ;pasanos Aa la pantalla BEB INX jincrementamos X sd $18 crx $16 jeomparanos X con 16 $00 FB BNE Lazo i no es igual, volvenos arriba volvenos al Nasic 460 RTS Aunquo en 1a rutina hemos undo una etéqueta ("luz") purn suber donde dobfa= mos volver, ésta solo tiene utilidad como referencia, y no tiene traduccién en cédigo miquina. Después de 1a instruccién de salto (en este caso, BNE), dobemos inclyir le distancia, en bytes, hasta donde «uerenos ir (miximo, 127 bytes) ©, si debemos volver para atrés, 256 monos dicha dietancia! Asi, conc en nuestro ejemplo, dobemes volver 8 byte atro, colecamoa 256 me nos 8 igual, 248 bytes ($F8 en hexadecimal). Vemos, pues, otro motivo de le convenioncia de un programa eneanblader que noo evite cvtos céloulos. © una vez sabenos qué bytes debonos introducir en 1a memoria, podrfamos utili~ zar el sistema de ir POKFando los correspondientes vulures en las sucesivas direcciones a partir de la que hayanos escogide com. principio de la rutina. Ello resulteria tedioso, Es mejor preparar un pequeno yrograma de Basic que vaya leyendo los valores de una serie de DATA, por ejeuplo: 1g FOR D = #499 TO p4gc 2 READ B+ POKE D,B 39 NEXT : END 19h DATA #A9,#41,4A2, 409,49, 484 , #8, HES eB, H1G,#DP a8, 160 Una voz ejecutado, ya tenemos la rutina on ou sitio, y pedonoe utilizarla, haciendo CALL #499. Con estos pequeiios ejemplos, sélo pretendo haber dado una cierta iniciacién a lo que es ol obdigo maquina, obmo ec preparan lae rutinas y e6mo oe cole— can en 1a memoria de le miquina. £1 lector interesado puede prosecuir el estudio en los Libros quo tratan el toma, pero on realidad, 1a mejor menor do aprender es practicar pequeiios ejemplos como los comentados, introduciendo paulatinanente nuevae inotrucciones, ver loa resultadec, estudiar les distin tas rutines incluidas en este libro, enalizando eu funcionamiento, etc. También, para poder aprovechar al méximo les posibilidades que 1a prograna~ cién en cédigo m&quina nos ofrece, conviene conocer la cetructura de la mi— quina, organizacién de los programas Basic y de las variables, cémo la mi— quine ejecuta les instrucciones Dasic, 1a dircecién de lae rutinas de 1a PON nhs iitiles, ete. Esto, acompaiado de ejemplos concretos, es lo que voy des- eribiendo en el resto del Libro. Si alguien prefiere ix directo a las aplicacioues, el final envuntreré una serie de aplicaciones prestes para su uso (coulo subrutinas de nuestros pro gremas en Basic). Aunque estén descritas de modo que puedan ver ulilizadas sin haber lefdo el resto del libro, su funcionaniente sdlo podré ser coupren— dido después de dicha 1ectura. Antes de continuar, una sencilla aplicacién. |.as direcciones $36 y $307 controlan el tiempo que tarda en leerse el tablero. Normalnente contienen el valor 1¢999 que corresponde a los microsegundos que transcurren entre dos lecturas (19 milisegundos) . Podenos acelerar 1a ejecucién de un prograna disminuyendo el nfinero de lec~ turae del tablero (aumentando €1 tiempo entre ellas). Podéis comprobarlo crononetrando un programa de prueba y haciendo DOXE #396,65535 y repitiendo el crononetraje. En estes condiciones, la escritura resulta mis lenta. i En el otro extremo, podéis acelerar 1a velocidad de escritura haciendo DOKE #386,3990 y comprobando la velocidad de repeticién de lay teclas. Con— viene no bajar mucho de este valor, pues puede bloquearse le miquina (2496 suele ser el, limite). Estas manipulaciones alteran la duracién de los WAIT. Asi pues, si un pro~ arama no requiere introducciones por teclado, podenos acelerarlo incluyendo al principle dol mismo 10KE 93¥0,05535, y al Fined POH WIJ, Lhd. @® be sin ESTRUCTURA DEL BASIC Bl apéndice A del manuel nos indica que el cpecio de menoria entre las di~ receiones $590 y S975F (8 $BIFF si ejecutamos e) conando CRAB), esté desti- nado a los programas del usuario, pero no nos especifica como est distribud da esta zona, ni como se representan en 1a tisna las variebles, y el propio prograna de Basic. De hecho, 1a distribucién es variable, en funcién de las necesidades de ca~ da momento. Las distintas rutinas se encargan de aduptar esta distribucién a ja longitud del programa, niimero y tipo de las variables, etc. Filo obliga a disponer en elgfn lugar unas referencias que nos indiquen dén- do eupieze y termina cada zona. -'stas referencias son unos punteros (grupos de dos bytes consecutivos) situados en pagina cero, el primer byte de los cuales constituye los ocho bits de peso bajo de le direccién referenciada, y el segundo los ocho bits de peso alto. Con el fin de abreviar, reprasenta~ remos el puntero fornado por dos bytes (por ejemplo, #9A-$98), por e610 1a diraccién dal primero de ellos, entre paréntesis (en miestro ejemplo (¥9A)) + La distribucién general es la siguiente: $50t Strings Jummen Prograna 4 a (89) (39) (398) ($a) (gaa) (86) Bl principio del programa de basic hebitualnente eaté en 1a direccién #591, ya que ol byte anterior (direceién $59) contiene un cero necesario para 1a correcta interpretacién del prograna. Pate es pues, el valor coitenido en el puntero (894), de inicio del prograna de Nasic. Normalnente, este pun~ tero no sufre alteracién durante el funcionsmiento norsial EL puntero (#9C) contione 1a direceién ciyuiente al Gitine byte del progre= ua de Basic, que es, @ ou vez, el primero ocupade por lev variables norma les, no dimensionadas (por ejemplo: A, N$%, 23%, etc.). Por ou parte, las variebles dinensionades ocupan 1 zona inmediata posterior a las anteriores, y el priner byte'de las misnas esth marcada por el conte~ nido del puntero (49). Bl primer byte posterior a los ocupstdes por las va~ riables dimensionadas, est& marcado por e1 contenido del puntero (SAB), ¥ aqui empioza una zona Libre, cuya longitud va variando durante ol curso de 1a ejecaién, segin In utilizacifn ae veriables. El HINEM, direecién @ partir de 1a cudl no puede pasar el Basic (utilizable, por ejemplo, para rutinas en cbdigo miquina), viene fijado por el contenido del puntero ($46), y do elif para atrés ae aitéan los strings, o tires al- fabSticas, el principio do las cuales es marcado por el contenido del pun- tero ($A2). ” A medida que se van ocupando las distintas zonas, los punters ($A) y ($A2) 20 van acercando, hasta que, al juitarwe, ee produce el siguiente Lenbmeno: ~ en primer’ lugar, #e produce una limpieza de los espacios que ya no son ne~ cesarios, para abrir espacio libre, = si e1 espacio asi obtonido no ee suficiente para 1a aplicacién que debia dérsele, oe produce el mensaje "Out of metory error", y 1a detencién de le ejecucién. Cuando ejecutanos un HINEN, toda lu zona de strings se desplaza, si el espa~ cio libre es suficiente para ello, y con é1; los punteros ($A2) y ($Av). Por cierto, uno de los "bugs" (errores de disefio) del ORIC-1, consiste en qua, en al momento de conectar la miyuina, los punteros (¥A2) y ($46) son inicializados incorrectamente, a los valores $OFFF y $9FOP, respectivanente. Ello provoca que los strings entran en le zona de menoria habilitada para le pantalla ($8889 a YBFDF), y que las variables pueden invadir Ta zona del gene— rador de caracteres (gn4gf a $BB7F). Para evitarlo, es una practica muy con- Veniente que siempre que conectanos 1a miquina enpecemos ejecatando wn TINEN 49899, asi como incluir esta misma instruccién al principio de todos nues~ tree programas, pare mayor seguridad. Cuando al iniciar 1e ejecucién de vm programa se produce el borrada sa tod las variables (0 al ejecutar el conando CLEAR), en realidad lo “nico que su- cede o9 que loa punteroe ec deeplazan. Asi, los punterce (¢9F) y (#Af), se colocan en coincidencia con el (89C), y el (#42) en coincidencia con el (#46). También venoe que hey quo distinguir ontre 1s monoria ceupada por un progra- ma, y que nos vendré dada por DEBK(¥9C) ~ DEE<(H9A), do 1e monoria que nece~ aite para eu ojecuedén, que es 1a suna de 1a ocupadn por el programa mis Ta ocupada por todas las variables y strings. Debido al fenémeno de limpieza antes descrito, un programa que requiera 12K para au ejecucién, normalnente “rodark" mio rfpide con 4fK dieponiblee hasta el HIME, que si 8610 dispone de los 12% imprescindibles (pues no se harén tan frecuentes los procesos de limpieza). Vista le distribucién yeuerel, pasenos @ couentar el contenide de cada zones Empezaremos con el programa propiasente dicho. La zona de programa contiene las distintas 1ineas de Basic, segin la siguien- te disposici6 = dos octetos iniciales, el contenido de los cuales es 1a direceién de co- mienzo de la linea siguiente, = dos octetos mis que contionen e1 nfimero de 1fnea exprosado en binariv (en ambos casos, el primer byte es el de peso bajo), = 1a secuencia de inatrucciones, en 1a que los nonbres de las variables, los nimeros, las tiras alfabéticas y los comentarios son representados por sus cbdigos ASCII (de ¥2% a $7F), mientras que Jas palebras reservaday del Da- sic son abreviadas @ un solo byte, 1lanado token (de #8 @ $F7), 10 que ehorra espacio en la menoria y tiempo de ejecucién, = un octeto milo que sefiata e1 fin de 1m 14nea La iltima linea va seguida de otros dos bytes milos. La tabla de cédigos de rograna (caractoros ASCIT y tokent), 0% In wiguionta: low bytes do un) TABLA DE BYTES: (de $29 a $7D: caracteres ASCII; de 484 a YF7: tokens palabras reservadas) ! oo i115 : 8/9 }AlB]C EJF Ci) fx fe], [- f a}o[{:]: |< j= 2 H I J{[K {Lim oO xiv izilein{a ite Rtalgleteta|nlo He, fed) eg es) ee | ee | Cea Aum eva |r| noc) cryie |e eee 198] B Pero [eorr [nvese|nen| reo [reore | por [ecor [Pure [toars|ooxe ferrem [unm [ror louise [ioemr 144 [9 Jrexr[osra fineur| om [ous [eeao eer [coro] eun | ur feesime| cos lerran| een [ren] axe 160 feeuense| TEXT JuiRes [51007 lexmope| ZAP | Prris |sound|mvsic | ray |cveser| cuewoy|Oeaw | crocce [rarseen| Free. 16 [CHAR |PareR} ine |sroP | oo [weir Icroan|csave |DFF |ooKe |Pemr|conr |risT |reae | Ger [oan 192] 4 |wew rae} ro fen |sec( | @ avrolecse frac |nor |sree} + | - | w | / 208 t Jano} or | > = < [son] int | ass | use [eee [eos [wexd} & | sar |enp un fexp | cos | sin [ran [arn freen focex |ioc | ven [stag [vac | asc feneg | er freve 2H 240) ravse [evs |scan foomr lierrs feveung ance | Go. al aal| COmAPDA) $276 | pteeaue-p 3299 PUNTERos) Iniclo 4A Tinae ae La siguiente zone 1a ocupan las variables no dimensionadas (nunéricas y aif béticas). Cada una ocupa siete octctos de memoria, de los cuales los dos pri meroo son los cédigos ASCII de Lor dog princros caracteres dei nombre de 1a variable. Si el nombre solo tiene un caracter, el segundo es nulo. I'n el caso de las variables alfabéticas y enteras, los caracteres ¥ y % no son con~ siderados como formando parte del nombre de 1a variable. En su lugar, se po- siciona el correspondiente bit de peso alto del primer 0 segundo caracter- Los cinco octetos restanies tionen una estructura distinta, secin se trate de una variable numérica o alfabéticas ~ en eo caso de una vuriabie nunérica, estos cinco octetos contienen ei velory en binerio y punto flotente, de la variable, i niga, El primer dcteto contiene el exponente, aumentado en $89. En el caso ex- cepeional que ol valor da 1a variahle sea f, 01 exponenta tanhifn 10 as. 1.0 mantiaa occupa Jon cuatro byloe reetantes (Jor do pouw alte, prtamro) Como que 01 primer bit, en punto flotante, eorla siompre uno, le aproveche= wos pera éontener el signo (J = positivo, 1 = negative). - © Como que e1 exponente erté furmude por viele Lily (el octave determina el si¢ no), el nimero mis grande que podemos representer es 21127, es decir, 1a can~ tidad 1,791411835 x 19738. Por olre parle, como que el niero ms grande que podenos representar con los 32 bits de le mantisa es 2f32 - 1 = 4294967295, le precisién nornalmente obtenida en leo c&lcules ea de unas 9 cifras decimales- Eu cambio, en el caso de una variable alfabética, le catructura de 1s {iltimos bytes es distinta. En efecto, el primero de los cinco bytes nos in~ (string), que puede ser, por tanto de g a 255 dice lw longitud de le tir caractere: Loe dos octetos siguientes indican la direcoién donde realmente empieze el string, que puede ser, dentsv del propiu programa de Desic, of le variable se ha creado alli, o en 1a zona de strings, ei ha habido que modificarle, 0 hacer alguna operacién con ella. Finalmente, los dos octetos siguientes no tienen ninguna utilidad, y suelen ser nulog. El esquema de cada tipo de variable, es, pues: numérices; alfabéticas: ee ee _ nombre exp. uantisa nombre long. direc. Pasonos a la siguiente zona, 1a de las variables dimensionadas. Son las te— blas y, como antes, pueden ser nunéricas o altabéticas. in este caso, 1 Jongitud ocupade. por una variuble depende de su tipo y'su dimensién. Las variables dimensionadas nunéricas de punto flotante ccupan un niimero de octetos igual a 5 + 2a + 5b, donde "a" es cl nimero de dimensiones y "b" el niimero total de elementos. Asi, por ejemplo, si hacemos DIN A(3,5,2) el espacio ocupado seré de 5 + 2x3 + 5x(4x6x3) = 371 octetos. Recordemos que A(3) tiene cuatro elementos, ya que existe también 4(g). Su estructura es: 1) dos octetos que contienen el nombre de 1a varinble, segin e1 mismo sistene que en el caco de las variables no dimensionade: 2) dos octetos més que: indicen e1 niimero de bytes ocupados por 1a tebla {en nuestro caso, 371). 3) un octeto que indica e1 nimero de dimensiones (en el ejemplo, 3). 4) tantos bloques de dos octetos como dimensiones haya, conteniendo cada bloque el niinero de elementos dle 1a respectiva dinensién, empezando por 1a que esté mie a le derecha. 5) tantos bloques de cinco octetos couo elementos contiene 1a tabla, Fstos bloquos contienen los ve~ lores de las variables, con 1a nisna estructura descrita anteriormente. Al dimensionar la tabla, los valores se ponen todos a coro. El orden de las variables seria, en nuestro ejemplo: A(S,0,8), A(1,068)+ M2,G2G)¢ (BGA), A(DrLs6)s ACLsLIG), M214), ACGs1,8), ABZ), ete Si ee trata de una tabla de valores enteroz, cads elemento ocupa solamente dos bytes, lo que representa un considerable ahorro de menoria. Si se trata de tablas de valores alfabéticos, su ocupacién es 5 + 2a + 3b, siondo a y b lov mismos valores anterioros. Ahora bien, huy que considerar que, en este caso, tal ocupacién so refiere exclusivamente a los punteros, ya que las tiras alfabéticas propiumonte dichas estén en otras zonas. © La estructura en este caso es; 1) los dos octetor del nombre de 1a variable. 2) los dos octetos de ocupacién de 1a tabla, el octeto del nimero de dimensio- 0 en el cago nee, y los bloquee del niimero de elementos do cada dimeneién, o de las variables numéricas. 3) después, tantos bloques de tres octetos cons elementos haya. En cada blogue, ¢1 primer ccteto indice Ie lonitud de le tira alfabtica, y los dos octetos siguientes 1a direccién de conienzo de le miona. Inicialmente eota sona ce puesta a cero. Tablas nunéricaa: oo 0.0 ooo. wo identificador _n? elementos contenido de los elementos Tablas alfubéticas: cm .m o.00.1 SS identificador n? elementos punteros a los strings Cuando en ol programa se busca el valor de una variable, 1a bfisqueda empieza por el principio de 1a respectiva zona (por ejemplo, si se trata de una va~ riable no dimensionada, le bisqueda empezar en la direccién indicada por el puntero ($9C)). Obvianente, cuantas mis variables de aquél tipo haya, y cuanto mie atrés se encuentre situada la que buscamos, mis tiempo tardart 1« bisqueda. Por te motivo, sien un programa so utilizan muchos variables dietintas, con~ viene crear primero las que vayamos a utilizar mis frecuentenente, pues de este modo 1a yolocidad de ejcucién aunentar’. Tara creer una variable, basta incluir en las primeras lineas del programa una instruccién del tipo A= 3, si querenos inicializarla a un velor concre— to, o simplemente DIN A. Recordemos que la instruccién DIM admite variables miltiples, por ejemplo, DIM A, B, C, etc. Otro método para aumentar 1a velocidad de ejecucién a base de disminuir el niimero de variables, consiste en aprovechar el mismo nombre de variable pa- ra otros usos cuando ya no so necesita el valor anterior. le todos modos, esta prictica se presta a confusiones, por lo que no es my recomendable. INTERPRETACION Como todos 1oe micro-erdensdoree do tu tipo, ol CRIC-1 e2 una abquina nontada alrededor de un micro-procesador (en este caso, el 65/2). El dinico lenguaje que un micro-procesador es capaz de "entender" y ejecutar es el cédigo m&qui- na. Aaf pues, para que el ORIC-1 pueda ejecutar sentencias y programas en Basic, es neceoario un programa (en oédigo m&quina) que tradurca lao secuen- cias de instrucciones Basic a sus equivalentes en cédigo miquina. Este programa, que realiza la traduccién o “interpretacién", esté escrito en la ROM (© EPROM, sogiin modelo), y ocupa las posiciones de memoria desde ¥COIS hasta $FFFF, utilizando también la parte de IAM entre $949 y SA3FF. El conocimiento de la estructura y funcionamiento del programa intérprete tie ue un doble interés: = por una parte, nox proporciuuaré informacién, no 3610 sobre el ORIC=1, sino sobre la estructura general de un micro-ordenador; = por otra, nos permitir& aprovechar para nuestros propios programas las sub~ sulinay incluidus en 1a ROM, entender 1o que hace en realidad cada instruc~ eign del Basic, enmendar los bugs y, en general, obtener e1 m&ximo rendi- miento de la maquina. Bn el presente capitulo vamos 4 deveribir, por 1 menos en au parte princi~ pal, 1a estructura del prograna intérprete. ara ello incluiremos diversos Gingranay de flujo que hagen mis conprensibies las oxplicaciones. Empezaremos por el momento en que conectamos e1 ORIC-1 a la red. kn este mo- mento, un circuito especial de RESET envia al microprocesador una sefial de anterrupcién que hace que 18 ejecucién enpiece en 1a direccién ¥F420 (punto de arranque en frio). Por cierto, en algunos modelos, si 1a aparicién del voltaje no es suficieate~ mente brusca, no se produce Ja sefial de RESET, y el aparato presenta dificul~ tades de arranque. Para evitarlo, hay dos soluciones: - la primera, conectar el alimentador a 1a red antes de conectarlo al ORIC~1; = 1a segunda, disponer entre el alimentador y el ORIC-1, un pequesio interrup- tor. Este sistema tiene 1a ventaja adicional de permitir efectuar en todo momento un RESET total en casos de bloqueo profundo (que puede producirse al trabajar en cédigo miquina, si cometenos algin error). En 1a direccién $F42D antes citada empieza 1a fase de inicializacion goueral. En esta fase se procede a: = inicializar el stack, el registro de estado y algunas direcciones de PAN empleadas pare saltos; = comprober e1 estado de 1a memoria RAM, colocando ciertos valores en la mis~ ma y leyéndolos @ continuacién, asi como comprobar la existencia de 16x 6 48 K (segin versién); ~ inicializar los periféricos (VIA, circutto de sonido); ~ inictulizar toda una serie de registros en lus primeray piginus de memoria RAM; ~ limpiar le pantalla e imprimir el mensaje, "Copyright: - inicializar el generador de caracter Finalizada esta fase, se produce un salto @ la direccién $c4n5, que es donde empieza el 1azo principal del programa intérprete (ver "Secuencia principal del interpretador"). ani, en primer lugar, se produce Ja impresién del mensaje "Ready". A resaltar que, en lugar de llamar directgnente a 1a rutina de impresién ($CBED), so pro duce un JSR $1A, donde hey un JNP SCBBD (incluido en 1a fase de inicializa~ edn). at ne WA vere. $n Dado que siempre que finaliza un programa (o la ejecucién de una linea entra- da directamente por tecledo), se pasa por este punto, tanto si ha sido por fi nalizacién normal, por Control C, o por deteccién de error; podenos, alteran~ do los valores contenidos a partir de #1A, obtener varios efectos, por ejen- plo: = que aparezca otro mensaje, on lugar de "Ready" (por ejemplo: "Listo"). ~ que, en caso de error, el programa no se detenga, sino que continue en al~ gin lugar previamente determinado (simulacién de ON ERROR GOTO), aunque ar- tes habré aparecido ya el mensaje de error. = establecer algin sistema de proteccién de progranas, incluyendo en este 1u= gar un JMP $F42D, Asi, si alguien interrumpe por cualquier medio el pro~ erema, para leerlo o copiarlo, se ejecutar& inmediatemente una inicializa- eign general que lo borrark, junto con todo el contenido de 1a menoria. Para ello basta incluir cond primera instruceién del prograna 1a siguien- te: DOKE #1B,8F42D. Después del monsaje "Ready", pasamos @ 1a espera de In introducesén de una Linea por teclado (rutina $C5A2, que estudierenos n&s adelante). Hecho esto, el puntero del intéeprete (que sigue las inatruccianes @ nadida que les vamon Jeyendo) se coloca al principio de 1a linea intreducida, y leomos el primer carketer de 1a misma. Si es un byte mulo (caso de una linea vacfa), volvenos a esperar una nueva entrada de linea. En caso contrerio, conrobemos si e} primer caracter de Ja nea era un nimero 0 no. Si os un nimoro, 1a Mnoa va dostinads « vor ineortada en el pregrana de Davic actual, y se produciré un salto a $C4z3. De lo contreric, se produciré 1a tokenizacién (conversién de los caracterce que fornan lor nombres de lae ine— trucciones dp Basic © cédigos que les sinbolizan con un solo byte, ahorrando emoria y tiompo de cjecucién), y un salto a CBDD, donde se produce le in~ terpretacién y ejecucién de lar sentencias incluides on le Iince. © grasp (rotve iaterpostoe) cans sever fis scac7 $eyer Puntero inktrprete ol primipio Wineo SECUENCIA PRINCIPAL DEL INTERPRETADOR Jee gccer® TSR B2e SB. TSR S2FL Sete. Isr g2re LDA 4836 LDY #8C3 JSR $1A Ls $2F1 gsr gc5a2 Sesare str ISR TAX BEO (scac TPES LDX 43°F ! we . se ‘ @ Insercién linea t ; toute ses. fenes~ (tran, bre teat fo ‘ @ goucr, cerunde flyE5 E1y 426 eae 2 Nivlgacsey @ Interpretacién linea (ol termine. retoma a $cu8s, corrando ef ble principal) era ~ Estudiemos ahora cémo se produce la introduccién de la linea por tecledo. Di ganos antes que ol objeto de ln misma ox pasur lor caractoroe intreducidor 6 una zona de nenoria en pfgina cere, concretanente @ partir de la direccién 435, seguida de un byte nulo, para sefialar al final. La rutine empieza en ¥C5A2, y en priner Ingar pone # core el registro X, que es el que se va utilizando durante le introduccién como eventa del nimero de caractares entradas. Faperanos 1a pulsacién da una tocla. Si es Cantrol A, capiamos de te posi= cién actual del cursor en pantalle el carécter que contenga. Luego se proce~ de a ln inprosién dol cardetor, 0 ejecueién dol correspondionte ebdige de cox trol, segiin el caso. Se comprueban algunos casos especieles (vor diagram "Introduccién Jno por teclado"), y eo pasa ol cardeter lofde a 1a correcpondicnte pocicién ex el buffer de teclado (1a zona antes mencionada a partir de $35). Comprobenos Iuego que no se haya superade la longitud mAxinn, y volvence a loer una nuom va tecle. El proceso se repite haste que la tecla pulsada es Return, en cuyo caso se afiade el nulo de fin de Linea, se posiciona o} puntere a1 principio do Is misma, y retornanos a 1a rutina llamante. Bl proceso do tokenizacién va loyendo 1a Linea carfcter por carfcter. A cada rueve carketer, comprucha si existe coineidencia entre 1a secuencia de arse teres que enpieza en el recién lefdo, y los nowbres de palabras reservades dol Basic, inclufdoe on una tabla que empieza en fOPEA. Si ee produce 1a coincidencia, lo cecuencia de caracteres es jsuatituida por un dinico byte que contiene un cédigo ("token") de Ja instruccién. De este modo, durante 1a ejecucién de un programa, coda inetrucesén de tlavic en) zaré por un token, que nos conducirf a le correspondiente rutina en cédigo nfquine. Bota ey le causu de algunos urrures que we preducen en veastoner y que, uno no cae en ello, pueden ser de diffcil localizucibn. En efecto, si queromos escribir una Linea de Rasic que content lo viquienter 19 IF M= FORN=G TIEN ++. y la escribimos junta, sin espacios de separacién, al ser tokenizodu, le Variable F y le palabia reservade OR furmmeGn lu polebin FOR, que vera in terpretada como un error de sintaxis. Para evitarlo, hay que ostudiar cada cavo, fn este, puede soluciana'se 5u~ tercalundo un espacio entre la F y el OK, © bien intercambiando Jas dos con— diciones, con lo que resultaria: 16 IF N=GORM=F THEN. ‘Entrada line ‘por Feclode INTRODUCCION LINEA FOR TECLADO BAL LOX ado rman AG Ise feary” cue abl Bye ¢D wy $265 : Loa 4.12, poses ane Waser ene at bars ees $e, Loa 239 fez ee See decl2., : 60) ssa fe Fimprecibn en pono Go geeveitn Contd) Contrat X73 Foo canicler al buffer de teclacto Supongamos que 1a linea que acabanos de introducir en el buffer iba precedida de un némero. En este caso se deduce que la linea va destinada a ser inser— tada dentro dol programa de Basic actualnente residente en 1a menoria KAN. La rutina que realiza tal funcién empieza en la direccién #C4E}. En priner lugar, la auceaién de caracteros que fornan el nimero de linea (colocados @ partir de $35) deben ser transformados @ su valor binaric, sobre dos bytes, y pasados a las direcciones $33-$34. Esta tarea 1a desenpefia 1a sub-rutina BCAQ8. Por cierto, que esta rutina admite como miximo nimero de linea 63999. Ello ne hace asi porqna durante 1a ejecucién de un programa de asic, el nénero do linea es salvado en las posicio:or ZA8-ZA9. Si en lugar de un programa, la ejecucién es de una linea entrada directemente por teclado, para distinguirlo cargamos el valor $FF en la direccién $A9 (byte de peso alto del nimero de linea). Si al nfimero de linea fuera, por ejemplo, 65496, e1 byte de peso al~ to adquiriria este mismo valor, prestdndose a una falsa interpretacién. A continuacién se produce la tokenizacién del resto de la linea, segin la rutina #0604, ya conantada. Al final, 1a longitud de 1a linea se coloct en Ja direccién #26, para los posteriores c&lculos de variacién de lov punteros. Luego se busca a partir del principio del programa de Bavic para buscar una inea que contenga el mismo niimere’que In que acabamos de crear. Si existe, procedenos a su eliminacién, recopiando el resto del programe a partir del final de la linea anterior. Ello obliga variar 1 puntero dol final del Basic, y reciloular les links. es decir, los dos byter inicials de cada linea que contienen 1a direccién de conienzo de 1a siguiente. ata fi1tina funeién ex encomendarin a 1a subrutina $C56F. Estos cambios obligan, por Gitino, a borrar les variables, canbiando los punteros quo scilaleban las zonas que ocupaban (suhrutina ¥C733)- Si 1a nueva linea co nula (eo 01 cao cuando eimplonento introducimos un ni mero de linea y pulsamos la tecla Return), hemos finalivalo el proceso de in werciSns En ease eontraric, se abre un nuove espacio on 0 programa do fiasic corriendo el resto del programa tantos lugares coo indigue la direccién 26, y modificando de nuove el puntore de fin de Basic. La Linea ee recopiada en exte espacio recién abierto, y nuovenente se repite el proceso de recaleulado y modificacién de los links, borrado de las varia~ bles y modificacién de los puntoro: Terminede e1 proceso, se produce el retorno a la direceién #407, on 1a co- euencia principal del interpretador. Cono que este punto de retorno es pos~ terior al fragmonto de rutina en que ec produce la inpreeién del mensaje "Ready", este no se produce en tal caso. Debido a todos los cambios introducidos, y el borrado de les variables, un prograna de Dasic interrumpido en el que ve haya modificeds alguna Linea, no puede ser continuado. En efecto, 1a rutina $C733 coloca af 1a direccién GAD. Al efectuar CONT, se comprueba esta direccién, y sives nule, se produ ce un salto @ rutina de error, con inpresién del monsaje "Can't continue". © Seues, Insereién Binge Fase nim. Umea a Integro 935-34 Presnso-* I] INSERCION LINEA EN PROGRAMA Retorna a ba secvencia pin~ cipok. Mensaje “Out of memory” ‘y.eaboena re @ la secvencia Rehace punters} principal. Retena 0 fa Secvencia principal 1) Sila 1fnea que hemoa introducide por teclade no cupicza con un niimero de 1f- nea, se entiende que va dostinada a eu ejecucién innediata (como hemos visto en el estudio de le secuencia principal del interpretador). En wsty caso, se produce un salto a la direccién ¢CODD, donde empieza el pro— ceso de ejecucién de las secuenc: de instrucciones en Basic. En realidad, esta rutina sirve lo mismo para la ejecucién de les lineas entrades directa~ mente por teclado, que para le ejecueién de un programa previanente introdu~ cido en ls memoria (luego veremos cémo), kn primer lugar, se compruoba 31 estemos en modo TRON, comprobando el bit de peso alto de la direceién $2F4 (que es el que conserva este estado), y, en cago ufirmativo, se provede # 1 impresién del niimere de linen entre parén— tesis rectos, A continuacién, se procede a 1a lecture del primer cerécter de 1a instruc cién, y e1 salts @ la subrutina que ejecutara 1a instrucesén propsamente di~ cha. Esta subrutina (SC8FE), por su inportancia especifics, ser& estudiade Andependientenente. Terminada 1a ejecucién de la instruceién, se lee el teclado para conprobar si ontretanto se ha pulsado el Control C. En caso afirmativo, saltaremos @ $0942, para proceder @ la finalizacién del proceso. be 10 contrario, continuanos saivendo los punteros. Leenios el siguiente ca- rheter para comprobar si se trata del nulo del final de linea, Si no es asi, comprobamos que sea ol cerdcter dos puntos (":") que separa una de otra las distintas instrucciones. De no ser asi, saltariamos a Ja rutina de error. Si efectivamente, eraeste el carécter, volvenos a $C8DD para seguir con 1a siguiente instruccién. Si hablamos encontrado e1 mulo de fin de Lines, conprobance si se trate del final de prograna (Leyendo ol byte posterior al siguiente, y viendo si es tenbién nulo), En este caso, saltamos a $C958 para procder a 1a final cdén (retorno a la secuencia principal). Si no hab{anca Megado al final del prograsa, locnios el nimoro de linen, 10 guardamos en $A8-$A9, corremos el puntero el principio de la primera instruc— cién de 1e nueva Mnea y seguimos el proceso. Como en los anteriores casos, el proceso se sigue mejor si similtineanente se ve repasando en el diagrana “Interpretacién de las sentencies de Basic". En modo ejecucién directa, el modo TRON queda autonéticamonte desactivado, pare eviter que en le primera parte do 1a rutina se produjera 1a inpresién de un némero sin sentido, En caso de que 1a interrupcién del programa haye sido provocada mediante un Control C, antes del retorno a la secuencia principel se produce 1a impre~ sién dal mensaje "Broak". Remarquemas que le qua aefiala ol fin de un programa do Nanic, e# quo ol byte de peso alte del link siguiente sea nulo (en efecto, 18 siguiente Iinca no puede estar'en plgina core). © INTERPRETACION DE LAS SENTENCIAS DE RASTC ‘Se salvan fos punteros prime mencaje ‘Syntax error” Etirmtnns del skal la direccién de re forse y vuelve a $oues Antes de ver como se produce la ejecucién de una instruccién, vamos « repasar un par de cunceptos, que nos seyén Gtiles luego para una mejor comrensiou. E1 primero de olios es 1m estructura del propio program de Basic. Este es~ th formado por una sucosién de lineas. Cada linea empieza por un grupo de cuatro bytes que 1a identifican: los dos primeros nos seralan 1a direccién de comienzo de la siguiente linea del programa, mientras que los dos siguien— tes constituyen el nimero de le linea, ‘A continuaci6n vienen 1a9 instrucciones, separadas por el carficter dos pun— tos, para terminar 1e linea con un byte nulo. Al final del programa, el segundo byte de 1o que constituiria el identificador de una eventual siguien— te 1fmea es nulo también para indicar este fin (este byte es el final del programa). Asimismo, antes del primer byte de la primera linea, debe haber tanbién un nulo, por necosidades del programa de interpretacién. Cada instruccién empieza por el token que le identifica, y sigue con los pardmetros sobro los cuales se aplica, por tanto, cuando leenos el priner byte de una instruccién de Basic, leemos dicho token. llay, sin enbargo, una excepcién a esta norma: es el caso del token correspondiente a LET, que no es necesario en el Basic del ORIC-1. El interpretador entiende en dicho caso (cuando el primer byte de la ins~ truccién no corresponde a un token) que se trata de un LET. En cambio, en otros ordenadores, el LET es necesario para distinguir la asignacién de un valor a una variable (LET A = 3), de una simple comparacién légica (IF A = 3)- Bl otro punto a considerar es 1a estructura del stack del 6592. Ceda ver que se produce el salto a una subrutina (JSR), 1a direccién del Gltimo byte del JSR os oubida al stack (que ocupa de $IFF hacia $19), ecupando dos bytes. Al término de 1a subrutina, el encontrar RIS, se coge del stack In direceién alli almacenada, ae le incrementa uno, y se coloca en el contador de progra~ reanudindose 1a ejecucién desde allf, F1 control del iiltimo byte del stack se lleva a cabo de foraa automitica en el registro Stack Fointer. bebe tenerse también en cuenta que ol stack es utilizade @ menudo nara el pase de parémetros entre rutinas, o para guardar los datos dle los buclos, © los resultados intermedioy de f6rmules complojas. Hechas estes consideraciones, pasemos ya a ver el funcicnaniento de la ruti~ Ra que ejecuta una instruccién de Basic, y que empieza en ¥C8FE. Se conprueba primero si el primer carécter corresponde @ un byte nulo, en cuyo caso retornamos sin hacar nada. Luege comprobamos si se trata de un token, de lo contrario saltamos directamente a 1a subrutina correspandiante a Ja inatruceién Ler. A continuacién buscamos, on una table que ompicza en $CM6, 1a direceién de Ja correspondiente subrutina (menos uno, por lo antes comentade), y La subi~ mos al stack. Finalmente, leomes ol siguiente earketer, y al encontrar el RIS, se produciré un “retorno" a la direccién colocad: en la pila, que seré 1a do comienzo de 1a subrutina on eédigo miquina correependierte a 1a ine truccién de Basic. BIECUCION DE UNA INSTRUCCION Leemas de la tobla $906 fa direecin. y la eubimes af Back Ejecueidn LET Lee Siguiente carccter y “relorna” o la subrutina correspondiente ol token INSTRUCCIO® "RUN" Macia variables Pontero al inicio. AL ratorno, prosequimes la gjecuciéin dente del programa BASIC. (é'she #8 considerodo como una prolongacin de ta tinea que 4 slate. inlerpretumde). Cada subrutina en cddigo maquina dete, pues, leer los parémetros, ejecutar so- bre los mignos las operaciones correapondientes, y retornur con el puntero del intérprete corrido al primer byte siguiente a1 final de 1a instruccién (que sera, habitualmente, el carfcter dos puntos, o el nulo de fin de linea). Todo 1o explicado hasta ahore es valido para 1a ejecucién de ine trucci ones entradas directuente por teclado, ero, como se inicia le ejecucién de un pro- grana? Simplemente, cuando encontramos la instruccién fUN, por el mecanismo que acebanos de describir, se produce un salto a ¥C980. A11i se conprucba si e1 RUN va seguido de un nimero de linea, en cuyo caso la misma es buscada y el puntoro del intérprete posicionade en el principio de la misma, |'n caso contraria se posiciana en al principio del Rasic. inar los retornos innecesarios yy A continuacién se limpia el stack, para eli al oncontrar el RTS, continuaré 1a interpretacién como +i siguiéramos on la Linea de Basic, pero ya desde el prograna. estos efectos, podemos imasi~ nar que un programa de Basic constituye una prolonyacién de la Iinea ertrada por el teclado que contiene el RUN. Las rutinas de interpretacién y ejecu- cién son las mismas. Mirando la tabla ¥c¥6 (y afiadiéndo uno a los valores encontrados), hallare- mos las direccionos de todas las rvtinax correspondientes a las instrueciones del Basic, que son: #0941 YP gcoas | corr forE4 nee CEA | NORMAL gocac J ‘rRow gocer } vaorr ficgno | PoP fngcé fF PLor #DA16 ff PULL $0937 f LoRus #8 # avgac | Doxs go9Pa ) RUPSAT 8c 9 SDA16 | UNTIL gceai | FoR gow ff govea | List 30832 fF Lerine wy $90 | gcwoc ff NEXT 5 gcaoa f DATA we $92 ¥ gocco ¥ INPUT spore # DIM we $94 | SccoA f CLS i sScCFD | READ 150 $96 9 gcad2 | LET gc953 f| coro ise £98 | gcoee | ron | seaze IF 54 39a | gcoir | RESTORE $0996 | GosuL 16 9c | dogwo | RETURN fond. f Rew 458 gow | S095 | WIMEM gu974 f crap 160 20 | d2994 | RELEASE gagag | roar sez $a2 | SEQBB f} HIRES BP415 J sHOOr 16y fa4 | BF418 | BAPLODS SF41B I ZaP vec $a6 | drqi2 | Pxne izBa9 | som $5889 | musrc 820889 | PLAY #e87D | cunsir e070 | cURMOV 87D 4 DRAW va70 Ff ciacus go87D | Parra i ges | PILL BE8TD | CHAR 0889 | PAPER (Bub89 PNK pease F stor ¥ca78 fon gosoD f WALT BBTAA f CLOAD geTDB ff cSavis go4oi | Dur Bn804 | PoKR aaa iis 192 CO Ello nos permite llamar lag rutinas desde el cédigo mMquina (por ejemplo, po- denos comprobar que la direccién de IiRES es KEIN, hacienda CALL. #EOLB. Debemos, sin enbargo, hacer algunas aclaraciones: = La tabla solo llega haste el token $Cl, ya que @ partir del #C2 no corres~ ponden a instruccionas, sino a aperadores, y parte de otras instruccionee, y son nanejados diferentenente. ; Puede parecer extraiio que haya coincidencias en 1a tabla imés de una ins~ trucedén con la misma direccién). F110 ea dehido a dos ceusas, segin los casos: a) En al casa da tam parejas PULL-UNTH. y bOP trate on realidad de la miswa inatruccién, con dos noubres distinter. >) Ba 01 caso de 1os grupos SOUND-MUSIC-ILAY PAVER-TNK y CURSET-CURHOV= ~DRAW-CIRCLE-PATTERN-FILL-CHAR, 0 trata de rutinas que por convenien~ cias de programacién hun eido agrupadas (en concreto, para eprovechur el mismo proceso de lectura de pardmetros, y por ciertas similitudes entre las aisnas). En este caso, para desviar Ja ejecucién al junto correcto, nos valenos del hecho que e lu entrada de 1a subrutina el registro y contiene un valor igual a dos veces la diferencia entre g8f y el token de Ja ins- URN, £4jémonea que oe truceién. - Las rutinas que no requieren parémetros pueden ser Llamadas wediante JSR (0 desde el Basic, mediante CALL), por ejemplo CLS, HIRES, PING, etc. Son necesarias de todos modos, alyunce preeauciones especiales. Asi, CLEAR (y otras), requieren que a la entrada el registro de estado tena e1 indicador 7 en set, ya que empieza con un INE ¥C164, que va a iTS. Podemos evitarlo entrando on la direccién siguiente. - Por otra parte, las rutinas que requieren parémetros no pueden ser 11) das de esta forma, ya que intentarian leerlos a partir de la posicién ac~ tual del puntero del intérprete (fin de la inetruceién CALL). N&s adelan— te veremos la forma de utilizarlas. En la mayoria de los casos, si queremos utilizar una de estas rutinas J19- nindola desde el cddigo miyuinn, reeulta nds ventajovo saltar Le fave de lectura de pardmetros, a veces la m&s lenta, e introducir sus valores di- rectanente en los lugares adecuados (véase, a titulo de ejenplo, Ja scccién dodicada a1 generador de sonido) « En este caso hay que cuidar que los valores sean vélidos, pues no hubré ue~ teccién de errores, a menos que expresamente la preveancs. INTERRUPCIONES Nornalnente, 1a ejecucién de une rutina procede de modo continuo, de una ins- trucei6n a la siguiente, con log eventuales saitos provocades por los . ranch En ecasiones, sin embargo, conviene interrupir este proceso ya y los Jumps. A este fin, el ra llevar @ cabo otras tareas, como 1a lectura del teclady microprocesador 6592 dispone de una serie de dispovitivee de interrupeién. dsl, cuando a1 correspondiente terminal de} 05/2 1lega una sefiul 0 "denanda" de interrupeién, el contenido del contador de prograna y del registro de es~ tado aon salvados en el stack, y 1a ejecucién desviada a una rutine especial (rutina de interrupeién), finalizada la cual (al encontrar 1a instruccién RIT) se retorna el prograaa interrumpida, Las rutinas de interrupcién suelen’ empezar salvando el contenido de los regis- tros internos, para restaurarlos antes del retorno al prograna principal. 41 recibir 1a denanda de interrupcién, el microprocesador toma 1a direceién donde debe continuar del contenido de ciertas posiciones ("vectores"), situades al final de le nom. Hay tres tipos de interrupcién, que estudiamos acto sequido: 1) RESET GENERAL (arranque en frio). La demanda de interrupeién 1a produce un circuito especial que se activa en el momento de conecter le miquina. E1 vector correspondiente se encuentra en las posicivues YFFFC-/FFFD, ¥ contiene 1a direccién ¥F42D. La rutina que enpicza en ¥F42D provocn Ja inicializacién general, proce diendo a una comprobacién de 1a menoria, y colocacién de los valores nece: varios en la pégina cero, generador de caracteres, pantalla, ete. 2) RESET PARCIAL (arranque en caliente). Se produce cuando pulsamos e] bo— tén situado en la parte inferior do is migtine. trovoca una reiniciali~ zacién parcial, sin borrer los progranas ni las variables. Una particularidad de oate interrupcién es que ol vector, situado en las direcciones ¥FFFA-SFFFD, contione e1 valor ¥22i, situade en KAN. Por oa te motivo, podemos modificar el efecto de esta interrupcién, canbiando el contenido de $220-$22C~J22n (que originalmente contiene un INP #PdW). Asi, por ejemplo, podemos inhibir el efecto de 1a pulsacién del citado botén, simplenente haciendo VOKE 4970,04, To que puede sor Keil para ciertos procesos de proteccién de progranas. bastarf hacer FOCE #220,76. Para reataurar ol funcianamianto normal, 3) INTERRIPCTON POR EL VIA. Fl VIA (6522 Versatile Interface Adapter) es ol circuito encargado de comunicar el microprocevador con los periféricos (teclado, cassette, impresora, pantalla). Conticne un tomporizador quey cada centésima de segundo, envia una demanda de inter:upeién al micropro~ conndor. En este caso el vector esti en #FFFE-¥FFTF y coutiene lu direccién $228, también modificable, por tanto. Un funcionamiento normal, esta interrup= cién proyoca 1a lectura del teclado, entre otras funcionos 103 @ ver un ejemplo de 1a utilidad de poder modificar Ja rutina de interrup rvirh para comprobar quo, en ebdigo miquina, 7 posible v cién, lo que nos efectuar cosas que seriun imposibles desde el asic. En efecta, mediante un programa Basie, podenas realizar sn indicador harario, que muestre permanentemente 1a hora actual, en ol formato deseado. Ahora bien, ello exige que mientras esth en marcha eate programa, na podemos realizar a= tros trabajos con el ORIC-1. Pues bien, la rutina que llevaremos a cabo permitird simultancamente continuar el funcionamiente normal, y acl podremos preparar programa, ejecutarlos, ote. mientras el reloj sigue funcionando. Con el fin de que sca totalmente compa- ‘ible con e2te funcionamicnte normal, haremos quo le indicacién horaria 4p rezca en la linea reservada superior (aquella en la que normalmente aparecen loo meneajee Loading y Saving)+ A continuacién doy wn programa de Nasic que, el cjecntarl., 2c encergard de introducir la rutina en cédigo miquina. tna ver ejecutade, el programa puede ser borrado, pues solo sive para cargar Ja rutine. AB = "20 CANSA9Z4ADD4BDAIPZOCZADZAZAPOWSFAA2dB4EB2HDICPASED AGEAA292292F" Ad = Ag + "PBACPICADSCESFOADG21 4BBA4EAIE AEDS FOAALPTE SZBBB DB2BBDDS704999BD" Ag = Ag + "AF G49D82BBCA1PHC6BAA682846930 3913932303038 3030 3A3A3A36343A 363490" FOR I = 1 TO LEN (Ag) STEP 2 A= 8400 + (I= 1)/2 1B = VAL(H" 4 mvs (4f,1,2)) POKE A,B + NEX? S = Gt FORD = 0409 TO #45E S = S + DEEK (D) + NEXT IFS¢> 1264179 THEN PRINT "Error escri;tura" Pe Una vez copiado, haced RUN. Si aparece Ready, todo ha ido bien. > antes If, By Yh. "echo esto, es aparece el mensaje de error, repasad las i aconsejable salvar la rutine miuina haciendo: CSAVE "RELOZ", ANY, EMISE Ahora ya podenos utilizarin. Tara ollo, suponganos quo wveremoy que et re~ oj empiece @ las 15:35:09. tintonces eseribirenos lu sentencia: CALL 4498,28:35298 AL puloor el Return, el reloj se poo en marcha. $i querenes que Lunerone 6o~ mo cronémetro, hacemos CAIL #499,0:00:49. Le rutine puede ser Uenada desde el teclado 0 desde un progruma, pero a sentencia que 1a llana debe ser 1a Gi- tima de 1a linea. El reloj llega hasta 99:59:59 y luogo vuelve a empezar en MP:US:F. Todu aque~ Lio que inhiba las interrupciones, pararé el reloj, asi al funcionar el casset~ te, el reloj se detiene (adends, 10s mensajee alteran Ja indicnedén horaria) « Tanbién las instruceiones de impresién producen algunos retrases en el reloj, Lo que hace que no sea miy exact, pero de todos modo conserva su utilidad como denostracién, 0 en algunos programs do jucco- . La rutina en Lenguaje de ensumblaje eg 1a siguiente: 490 20 CA FH reall JSR sRACA inhibimos 1as interrupeiones 493 AQ 24 LDA 824 405 Ad 94 wy ida 4 “gr 8b 29. 92 sta $229 canbiamos e1 vector interrupeién 40a 66 2a 92 sty 22a 4fD 42 49 LOX 964 ‘ dar 85 OF 94 meee } soteianizencs contedor 412 26 04 BB JSR $8804 desinhibimos interrupciones 415 26 D9 OF gsr CFD9 saltamos 1a coma 41B 45 Bg LDA 4A Ad BA LY nicest aa mn escribinos #1 horario inieial 41E 20 2F FB JSR gr82r 42. 4c gp cA gMP Jcapd saltanos al final de 1a linea 424 98 int PEP salvanos el registro de estado 425 CH SF p4 Dic f45F 42a 48 PHA 42B 8A KA salvamos registros 420 48 PHA 4ep ay 64 WA aapoudey $A SH EY ctctnsennn of canter 432-82 OT LDK 47 434 PH A? BR leg INC gand2,x —— la indicnetén hora} 437 BD 82 BB LDA $BB82,x 43A DD 57 4 cur £45754 43D 96 99 BOC sorx si hemos superado el mixino para 43F BD AF 94 LDA $44P,X Pesta cifra, increnentamos 18 in~ 442 9D 82 BB STA #BB82,X | mediata « la izquierda 445 CA DEK 446 16 EC BPL llag 448 68 sorx PLA 449 AK TAX anoe lee regivtroe 44a 68 PLA 448 28 sorp PLP 44c 4c 93 Bo sup £803 y vamos 2 le rutina normal 44P 36 36 3A 36 36 3A 36 39 cifras mininas 457 3A 3A 38 36 3A 3A 36 3A cifras mixinas 45F Op contador De $400 a $423 es 1a parte que se ejecuta cuando 1lamanos 1a rutina, al po- ner el horario inicial. De $424 a $448 es 1a parte que se ejecute cade con~ selo, manque GLO ends nonin we coubia Tn baudiene thn boewrin. Finalmente, de $44F @ $45F son los distintos valores utilirados por 1a ruti~ © CASSETTE E1 interfase para cassette contenido en ef UNIC=1 constituye un método sen~ cillo y econémico (y adomis, hasta Ja Ilegada de los discos, el dinico) para Ja valvaguurda de programus y ficheros, gta simplicsdad parece pagarse a costa de algunos inconvenientes, No obstante, si alguno de ellos puede ser cierto, 1a mayorfa pueden subsanarse con un adecuado conveimiento de su fun cionamiento. E1 presente capitulo pretende doscribir este funcionaniento, y presonter una serie de rutinas de utilidad (verificacién, identificacién, etc.), asi como los elenentos para poder construir facilnente uno mismo lo yutine que preci~ se pura ou caso particular. Antes de pasar, sin embargo, al estudio del software, recordaré los consejos nds corrientes sobre 1a utilizacién del magnet$fono: ~ ai se va a adquirir uno exclusivo pare esta misién, conviene probar verios modelos antes de decidir cufl adquirir. fn general, Jos modelos mis sen~ cillos suelen dar mejores resultados que los de clevada calidad. También pueden encontrarse, en tiendas especialivadas, modelos especiales pare or~ denador personal. - el cabezal debe mantenerse siempre limpio y bien alineado, Puede compro— barse escuchando una cinta de audio y comprobando la nitidez de los agudos. - Conviene que el altavoz incorporata quede desconectado al colocer el en~ chufe de conexién al ORIC-1 (el sonido de un fichero en cassette no resul— ta excesivamente agradable). = Debe tantearse el volumen hasta obtener 1a mixima fiabilidad. tuede empe- zarse ajusténdolo a los dos tercios del recorrido, ‘i existe control de tono, se colocar al mixiro de agudos. ~ Las conexiones deben ser #élidas, y los conductores alejados de cables eléctricos. - Deben emplearse cintas de audio de buena calidad, que no se atasquen (el sistena es especialmente sensible a las fluctuaciones de velocidad). Pasenos ahora a ver cono esth representado fisicamente un prograna en le cinta del cassette. Puesto que un programa es una sucesién de tytes. y un byte esth compuesto de bits, empezarenos viendo cémo representamos un bit. Como que en una cinta mugnética podenos crabar imaultvos, seré esta In forma en que representomos un bit. Cada impulso dura 2/8 microsegundos, y esté seguido de un espacio hasta el préximo impulso., Fste espacio dura otros 298 microsogundoy fore ee hij of Le descripeién anterior es vGlida pare grabactén a 1a velocidad ripiaa. tn @1 caso do 1a velocidad Jenta, el siatea es distinto. Cada bit contiene 4 u 6 impulsos de distinta durecién, segin ve trate de un 1 6 ung. A la Jectura, comparamos el nfimero de inpulsos con G, y asi eliminanos un cierto poreentaje de erreres, aumentando 1a fiapiiicad. Observemos que en e1 caso de una grabacién continuada de bits 4 (a veloci~ dad répida), el porfodo 03 de 2x248 = 416 microsegundos, 10 que equivale a una frecuencia de 249 Hz, por ello decimos que 1a velocidad es de 24/ bau dios (bits/segundo). Sin oubargo, si se trata de ceros, el periodo ex un Sf % mis leryo, y la Velocidad de tranamisién menor, Podenos conprobarlo con el wiguicnte expo rimento: En primer lugar, hagamos FOR A = #599 TO #5FFF : TOE A,@ : NEXT para crear una zona de menoria de 4K con todos los bits nulos. Después hagam CSAVE "", ANS(9,EASFFF y cronometrenos el tiempo que dure el mensaje "Sa~ ving". Veremos que es de unos 31 segundos. Ahora enpezaremos haciendo FOR A= a5#if TO gSPFF : POSE A,255 : NEXT. pax ra llenar la misma zona de nemoria con bits todos 1. Si repetinos 1a misma prucbe, veremos que ol "Saving" dura aliora solo unos 24 segundos. No obstante, si dividimos los 24 segundos entre los 4x1924 bytes, veremos que nos da un tiempo para cada byte de unos 586) microsegundos, bastante si perior @ lo que resultaria de 1a sucesién de 8 bits (8x41 = 3328). En efecto, el ORIC-1 no graba solamente los ocho bite componentes, sino W bit inicial nulo, luego los ocho hits eapezando por el de posn mis hijo, luego un bit de paridad, y finalmente tres bils con valor 1. tn total 13 bits, segin el siguicnte esquem YVeamos finalnente 1a estructura del fichero completo. Consta, por este or~ den, de: = 259 bytes $16, que constituyen ol tono inicial, que eirve, durante 1a gra— bacién, para ajustar el control automitico de voluwen, y, durante Is Ieetu ra, para permitir la sincronizacién del proceso (saber dénde empieza el primer bit de cada byte). = un byte $24, que sefala el final del ton, y puede ser utilizado cono iden tificader del tipo de fichero. = 9 bytes que contiguen los puuteros de lay direvciones inicial y finel, 1a indicacién de si es cédigo maquina o Basic, y si se trate de un progrens de ejecucién autonitica. = el nombre de programa, en cOdigo ASCII, Seguido de un byte nulo que sena— 1a el fin del nombre. - el contenido del fichero propiamente dicho, byte a byte. EL comando CSAVE efectua lo siguiente: - coloca los punteros de inicio y fin del Basic en los de inicio y fin de fichero, como valores por defecto. - lee 109 pardmetros: nombre del programa, eventuales direcciones de inicio y fin, euto-load, velocidad de grabacién; y los colocu en Jos Ingares adem cuados. = bloquea el teclado y prepara el circuito de interfaso para activa ol relé de control remoto del cassette = enviamos los 259 bytes #16, e1 byte $24, los punteros, el nombre @1 pro- grama, y todos los bytes del misno. = dovolvemos e1 control al teclado y, si estabanos en programa, volvenos & Je ejecucién del mismo (pero si era ejecucién directa por teclado, se da por finalizada 1a linea, aunque contuviera mis inetrucciones, Ello se hace eel porque la rutina altera el buffer de teclado). 254 dyles aby Lyte Feo ae Tono sincroniz. ‘punteros “nose ruto | bytes fichere ca ee ease Bee Bl comando CLOAD, por su parte, actua as: = colocamos 1 puntero de inicio del Basic como puntero inicial del fichero por defecto. ~ leemos los parémetros, y los pasamos a las direcciones adecuadas. = bloqueamos el teclado, y preparamos el circuito para la lectura, activando el rei. - escribimos el mensaje "Searchin = dutentamos sincrouizar el tono iuicial. ~ esperamos un byte con valor $24+ = leemos dei cassette los y bytes siguientes, y los colocamos en los punte= ros (de $66 a 25). = leemos el nombre del programa, y lo pasamos a partir de $49, seguido de un nulo. = comprobanos 1a coincidencia del nombre con el que habianos colocade & par- tir de $35. Si no se produce, volvenos a enpezar. escribimos "Loading" nombre del programa. ~ leemos del cassette cada byte, y lo vamos pasando a la memoria, incremen- tando el puntero, hasta llegar al final. ~ Si era auto-load, saltamos a ejecucién a partir del principio del programa. ~ en caso contrario, volvemos al control por teclado (si estibamos ejecutan do un programa, no retornamos al mismo). Al final del capitulo concretaré, pare el lector interesado en ello, las di- recciones de las distintas rutinas y punteros. No obstante, antes describiré algunas aplicaciones de todo 1o anterior. Bn ocasiones escribimos programas Basic que contienen subrutinas en cédigo niguina. Resultaria interesante poder salvar en un {nico fichero en cassette anbas partes (Basic y miquina). Pues bién, si 1a parte en cédigo maquina no excede 250 bytes, hay un método my simple para lograrlo. Escribimos 1a parte en eSdigo miquina en 1a zona f4jif ~ <4kF. Cuando quera~ mos salvar el programa, haremos: CSAVE "nombre" ,A#4é$. De este modo se sal~ varé desde $499 hasta el final del Basic (valor final por defecto). Para recuperar el programa, podrenos hacer un CLOAN "nonbre” totalmente normal. Un fichere en cassette siempre va a parar a la miawa direccién an que asta~ ba cuando se cred, aunque on el CLOAD especifiquemos una diroccién distinta. Nay un efecto marginal de la instruccién CLOAD que debemos tener en cuenta porque puede causarnos problemas. Se trata de que despuas de un CLOAN, el puntero de final del Basic se posiciona al final dol fichero leido. Si este fichero ora efectivanente un programa Davie, todo eo correcto, porey y abi radica el problena, si era una rutina en cédigo miquina, 1a alteracién del punter dy fin de Basic puede provocar errores de ejecucién. Ash, si ol puntere vv colove despuGy del MINIM, cualquier intunto de ejecu- tar el programa, o afladir alguna linea, se resolveré en la aparicién del wongaje “OUT OF NBNORY ERROR" « Si, on cambio, e1 puntero queda por debaJo del principio dol Basic (cusy fre~ cuonte cuando leemos rutinas que henos escrito a partir de $499), las varia~ Dies plancharfn las 1inens del Basic, con restltados imprevisibies. Para evitarlo, podemos hacer dos cosa: ~ Si honos de leer una parte en Basic y otra on niquina, leerenos primero esta Gltima y luego el Basic. Asi el puntero queda finaimente en ol lugar adecuado. = Si ol prograna Basic ya existe, y queremos leer una rutina en aéquina, podenos hacer:PRINT DEEK (#9C), luego CLOAD » y después DOKE @9C, valor. De este modo se reataura el puntero. Rocordence que eatas tres sentencias no pueden ser incluidas en una sole Linea, pues 1a ejecucién se detiene después del CLOAD. Bn ocasiones, durante la lectura de un fichero en cassette, se produce un error de lectura de un byte. Si el error es en un cardcter o instruccién, veremos un cambio en tel lugar, Sin embargo, si el error se produce en los bytes inieiales de una linea, que contienen 1a direccién de 1a siguiente, suele ocurrir que aparecen al listar el programa una sucesién de l¢tras U. En este caso, podemos rehacer las uniones interlineas mediante le ejecucién do CALL $C56F. 0 OP OHTA Y ya que hablamos de errores de lectura, quizhs el principal problene de 18 salvacién de progranas en caysotte estriba en el hecho de no disponer do un sistema de verificacién que permita conocer i le lectura se ba efectuado correctanente 0 no. Fllo seria my interesante, pues nos permitirsa trabajar tranquilamente @ 2499 baudios, con el consigniente confort. Pues bien, a continnacién des~ cribiré una pequefia rutin que cumple esta funcién, fécil de incorporar a todos nuestros programas (#410 ocupa 56 bytes), y que permite trabajar con una seguridad total. Se trata de una rutina que, inmediatamente después de la lectura, imprime un checksum dol programa Bavic lofdo. Nos baste comprobar quo sea el mismo que habrenos anotado on e1 momento do 1a grabacién para estar seyuroe quo 1a Lectura ha sido correcta (0 repetirla, en cado contrario). Le rutina en of, on cddigo akquina, ocupa de #408 hasta S4FP, Tara erearla por primera vez, escribiremos el eiguiente programa hasic: © Ap AY = "A2948673AGI9847284708471988818657985 7999P2E671A 20 3C8DAG2E673B1" 24 AZ = AZ + "72DPECCADPF49BAAA5TI2PCLEPAIZC2P4DCCASTIAGTBACCIES" 39 FOR I = 1 TO LEN (AS) STEP 2 49 A= #4C8 + (I - 1)/2 + B= VAL ("#" + MIDS (A¥,T,2)) 59 POKE A,B + NEXT 6 S = 9 : FOR D = #4C8 TO #4FF STEP 2 78S = S + DBEK (D) + NEXT 89 IF S<> 916324 THEN PRINT "Error escritura, Repasa Ag” Una vez escrito, hacéis RUN. Si todo va normal, ya tenéis la rutina en cbdigo maquina en su lugar. Conviene que la salvéis haciendo: CSAVE "VERIF", ANAC8, ExdTF, S Bn lo eucesivo, cuando queréis salvar un programa en Basic, leersis prime Fo 1a cinta con el "VERIF", y luego salvaréis el prograna Basic junto con la rutina haciendo: CSAVE "nombro", Av4C8, AUTO. Al mismo tiempo, hacéis CALL #4C8 y anothis en la tapa del cassette las doo cantidades quo eparezcan. Fs0 e0 todo. Cuando luego ledis el programa, al terminar le lectura, aparecerén las mis mas cantidades, si la lectura ha sido correcta. Para los interesados en 1a rutina, #u contenido, on lenguaje de ensamblaje, eg el siguiente: LOX #4 SIX $73 sbyte de peso alto del puntero LY 4 sty $72 sbyte de peso bajo del puntero sty $70 yte de peso bajo de le suma sty $72 sbyte de peso alto de la suma YA DEY jdireccién iniciel $4rF euna CLC Ave $70 jincrementanos suma STA $78 BCC salto INC $71 salto LIX #3 5X contador de bytes seguidos nulos dir IN }increnentamos puntero BNE lect INC $73 lect LDA ($72),¥ jleemos contenido byte BNE suna DEX BNE dir YA TAK LDA $73 JSR $B9CL jimprimimos G1tima direccién LDA #44 gsr» gccap LDA $71 LOX $79 amp gEdc1 s4uprinimoy 01 checksum no henos acabado, siguiente direccién imprimimos una coma @ seh apn” El programa cargador no tiene otra misién que introducir facilmente le rutina en cbdigo afquina y, por tanto, una vez ejecutado puede ser borrado. 1 leer "VERIF" desde el cassette, recordar lo dicho sobre 1a alteracién del puntero final del Basic. Las rutinas de la ROM que escriben los mensajes "Searching", "Saving" y "Loa~ ding", no tienen en cuenta comprobar si la miquina est& en modo HIRES, e im— prinen el mensaje en una posicién fija de le menoria, Si estamos en IIRES, Cone que esta posicién corresponde al interior do la pantalla, en lugar del mensaje, apareco una fina iinea horizontal punteada (hacia los dos tercios desde la parte superior de la pantalla). Es corriente en muchas aplicaciones la actualizacién de ficheros en cassette. La programacién de un trabajo de oste tiyo se enfrenta (on el ORIC=1) con dos problemas principales: ~ no existe una instruccién eapecifica para salvar (0 leer) ficheros de datos numéricos o alfabéticos. Solo podemos salvar programas en Rasic o fragmen— tos de memoria concretados por sus direcciones inicial y final. = si dontro de un programa se incluye una instruceién de lectura de un fiche ro en cassette (CLOAD), la ejecucién del programa se interrumpe inmediate— mente después de efectuada 1a lectura. Vanos a ver 1a manera de subsanar-aubos inconmunientes. Es factible crear rutinas en eddigo miquina que permitan salvar y leer te- blas nunéricas 0 alfabéticas (en la revista del ORTC aparecié une para ta~ blas numéricas). No obstante, muchas veces resulta mis simple lo siguiente: ‘Si queremos, por ejemplo, salvar la tabla Ag(I), para loc valores de I= #6 hasta I = 99, suponiendo que la longitud media de cada string sea de unos dioz caracteres, ello quiero decir que necesitamos una zona de nenoria libre da 19 x 11 = 119 bytes (@1 onceavo byte sirve para marcar el final del string). Conviene dejar un margen do seguridad. Reservaremos, encima del INEM, una zona suficiente para ubicar estos 11/8 hytas. Par njenpto, hactendo HINEN 49608 tendremos nie que 10 que nos hace falta. Entonces traspasaremos a esta zona la tabla, haciendo: 1p D = 4999p 15 FORT = 9 10 99 2 AB = AB(I) 25 FOR .T 1 TO LEN(AS) 38 © = ASC(MIDS(AS,I,2)) 35 POKE DC +D= D4 ago NexT' 45 TOKE DP sD DAD 59 NeXT 55 TOKE De Bvidentemente, los nfimeroe de linea pueden ser cualeequicra, y las instruccio~ nes pueden ser agrupadas en menos Lineas (Jas he dispuesto aqui asi simplemen- te pare una sejor comprensién). Una vez transforuada asi la tabla, podemos salvarla en un fichero de cassette simplemente haciendo: CSAVE "nombre", AN9#¢¢, ED Cuando queramos recuperar la tabla, primero-copiamos el fichero,, mediante: ombre" CLOAD * y luego transformamos e1 fichero a la tabla original, mediante 1a rutina in~ versa, por ejemplo: Wg F=-1:D= agg 15 REPEAT 28 FeF+l:rg= 25 REPEAT 6 K = PEEK (D) 35 Tp K THEN FE = PY + CHES (K) o D=D+L 45 uNttL K =o 50 AS(F) = FS 55 UNTIL FY =" Coma antes, los nfimeros de nea pueden ser variados, y lae inetrucciones con— densadas (pero cuidade con el IF de Ja linea 35). Esta rutina requiere que se haya dimensionada praviamante A¥(1g), un elemento mis que los necesarios. Subsiete ol segundo probleme que hab{anos menotonade, ea decir, al hacer ol CLOAD so interrumpe 1a ejecucién del programa. Para solventarlo, 1a manera nés simple coneiete en redactar una poquefia ru~ tna on miquina, que podenoe incluir on una Mfnoa do REM. Bes 596 os rup 597 28 DQ CF JSR $CPD9 = jsaltanos 1a coma 5A 26 25 BT JSR B5725 jleewos Low par&outroy 59D 28 CA EG JSR $B6CA — jpreparamoe e] VIA 519 28 AS B4 JSR B4AB jleemos Tichero 513 20 94 EB JSR $884 — jdevolvemos control al teclado 516 28 PLP 517 RTS Para incluirla en el programa Basic, hacemos que la primera 1inea sea: 9 REM ABCDEFGHIJKLINOPOR (1inea de REM con 18 caracteres) y luego, mediante POKEs, introducimos a partir de la direccién $596, los bytes Gocimares: 8) 32, 217, QT, 32, 37 251) 32, Me, LM, 32, 168, 2B, Jz, 4y 232, 49, 96. Es decir: POKE #596,8 : POKE #597,32 : ete. Cuando dentro del programa Basic queramos leer el fichero, en lugar de CLOAD haremos: CALL #596, "nombre" (,S para velocidad lenta), y se produciré la Jectura normal, pero retornando el control al programa Basic, al terminar. Si queremos comprobar 1a correcta introducedén de la rutina, podemos hacer: S=@ 1 FOR D = #596 TO #517 STEP 2: S = S + DEEX(D) : NEXT : PRINT S 1 resultado a obtenor debe ser 27389). En ocasiones puede resultar interesante poder saber qué contiene una cassette, sin necesidad de tenor quo leer el correspondiente fichero. Para ello podemos valernos de la siguiente rutina, que lee solo el cabezal del fichero, y nos imprime en la pantalla ol nombre del citado fichero, y las direcciones de prin cipio y fin del mismo. Primero daré un prograna de Basic pare introducir le rutina: Xx IDENT 3% Ww As 9932CA 999856748 29C AEG 299 6E62A3ARECI24DBF9A 292 IPEGISSD" “6 15 AB = AS + "CADPF82930E6F905954 9BBDIPOIS4SaNbARABADAOAMAAOMENCRY 2h AB = AB + "A92C2B12CCA5HPAOSF2PCIEPAGAC2P12CCA562AG612ICLEPACFFE TIS" 25 FOR I = 1 70 LEN(AS) STEP 2 3B A = 4499 + (I~ 1)/2 + B= VAL( 35 POKE A,B: NEXT 49 S= 91 FOR D = #499 TO #451 STEP 2 45° S = S + DERK(D) + NEXT 5@ IF S<> 1294634 THEN PRINT "Error. Repasa Ag" "+ MIDB(A$,T,2)) Una vex ejecutado el programa, puede ser borrado, Para salvar 1a rutine en nfquina hacer CSAVE "INRNT", Asdgp, Ba45i. Cuando quaranos identificar wn fichero en cassette, harewoo CALL 4498 (ol co velocidad lente) 0 CALL #493 (si es velocidad répida), y pondremos en mar cha In cinta. Al encontrar el principio del fichcro, oc imprimirén en le pan talla el nombre del prograna, 1a direceién del primer byte y 1a del fitino. La rutina, en longuaje de ensanbleje, e como sigue: fai ell lento LDA #3 svelocidad lente tie | DIT (zap LDA #$);velocidad sfpida 3 STA $67 PUP JSR gB6CA JSR $8696 ini JSR $B639 CMP #824 — jeomprobanos oi e9 el snicsaL BNE ini 94 no, leemoe el siguiente LIX #9 punt JSR $£639 jleemos los punteros STA $5D,x sy los pasamos a pdgina cero DEX BNE punt nomb JSR $8639 j1eemos cardcter BER salto si @8 nulo, saltanoe STA $49,X 510 pasamos a pigina cero INK BNE nob salto STA $49,x JSR $E8$4 ;devolvemos control al teclado PLP “LDA ¥849 — jpuntero nombre, peso bajo Dy af ipuntero nombre, peso alto JSR $CBED jimprimimos nombre LDA By "JSR $CC12 j4mprimimos 10 coma ( LDA 6p Hinicio, peso alto LOX $5F jinicio, peso bajo JSR $EfC1 sAmprimlmos direccién LDA #', JSR C012 jimprimimoa 1a com LDA $62 jfinel, peso alto nx #61 inal, poso hajo JSR $B9CL jimprimimgs direcedén IMP $B7FF jvolvemos @ espera teclado Coma vemos, podemos conatruir mitinas @ medida pare cada necosidad. Para £o— cilitar esta tarea, a continuacién deseribo las direcciones de mayor utilidad relatives al cassette: en pigina coro: 935-848 nombre del fichero a buscar, seguido de un mulo #49-#5) nombre dal ficharo encontrado, seguido de un mule $5F-¥6f direccién inicio fichero $61-¥62 direceién final fichero 863 auto-loed #64 ebdigo maquina en le ROM: #E4A8 ee un Lichero completo desde el cassette. Exige preparacién previa del VIA, y los parknetros en phgina core. $£53E rutina que retorna al Basic on caso de error durante una lec tura de un fichero en cassette. #8554 incrementa el puntero para la lectura y posiciona carry. #8563 borra ol moneaje do 1a linea rocorvada cuperior. ¥£56B — escribe 1 nombre dol programa on la linea reservade. 98576 eweribe un mensaje on 1a linea reservada euperior. #8578 salva un fichero‘completo en cassette. 3B5C6 salva un byte on casectte. $B5F3 salva un bit en cassette. #8638 loo un byte doado el cacactte y 1o pasa a far. $E65E lee un bit desde el cassette. #2696 oinoreniza el tono inicial. #86BA scribe on el cassette el tono inicial. ¥B6CA inhibe interrupeionce y prepara ol VIA pare el trabajo con el cassette. ¥56PS — comprueba 1a coincidencia del nombre buscado con el del fi- chero encontrado. #5725 lee los parfmetros para el CLOAD y el CSAVE. $B7AA —rutina CLOAD. H7DBrutina CSAVB. $5894 desirihibe interrupciones, devolviendo el control al teclado. BL timer 1 del VIA es el que se encarga de producir los inpulsos de 2/8 micro~ segundos, para couforvar o coulrolar los impulsus « través del bit 7 dol Port B Podenos adapter ol programa de Lectura de tables para valores nunéri- c02, ,mediante las inatrucciones STRA y VAL« Note © esr ates ath WE o SONIDO En algunos microordenadores 09 e1 propio microprocesador el que se encarga de Ja produccdén del sonido. Ello implica que, mientras tanto, 1a unidad central queda imposibilitada para ejecuter otras tareas, lo que representa un inconve~ niente para programas de juegos y aplicaciones similares. El ORIC-1, en cambio, dispone de un circuito independiente especielizado on le generacién del sonido. De este modo, una vez que el microprocesador ha envia~ do les érdenes adecuadas a dicho circuito, queda libre para otras tareas, como gestion de la pantalla, célculos, 0, simplemente, preparacién de los datos pa- ra el préximo sonido a producir. Adem&s, el generador de sonido contenido en el ORIC~1 dispone de una serie de posibilidades que le permiten obtener conbinaciones de sonido my elaboradas, ya que dispone de tres generadores de tono, un generador de ruido, un genera— dor de envolventes preprogranadas, y tres canales de amplificacién independien tes. Su esquema es el siguiente: Dsalida Como vemos, dispone de 14 registros de control, numerados de J a D (on hexad cimal), La,misién de cada uno de ellos es: Hegistro Contenido Perfodo'cunal 1, peso bajo Periodo canal 1, peso alto veriodo canal 2, peso bajo Perfodo canal 2, peso alto Ferfodo canal 3; peso bajo Perfodo canal 3, peso alto “Coloracién" del ruido Control autorizacién canales Volumen canal} Volumen canal 2 Volumen canal 3 Perfodo envolvente, poso bejo Periodo envolvente, peso alto Tipo envolvente Cou rwordueunna ‘Vamos a concretar 1a utilizacién de cada registr ~ Rogistros $5: perfodo de cada canal, expresado en microsegundos. Recuérde~ 80 que e1 periodo es el inverso de 1a frecuencia. Asi, por ejemplo, el maxi mo perfodo posible, $FFFF (en decimal: 65535), corresponderé a una frecuen~ cla a L ———L— = isn 0065535 Evidentemente, no es necesario egpecificar el period de aquellos canales que no vayanos a utilizar. ~ Registro 6: sus cinco bits de peso bajo determinan 1a "coloracién”, 0 tono principal del ruido. El valor corresponde al ruido mis agudo, y el valor 31 al mds grave Los tres bits restantes no son tomados en consideracién, asi las instruccio- nes: SOUND 4,9,7 y SOUND 4,32,7 son equivalentes. ~ Registro 7: sus 6 bits de peso bajo determinan qué canales quedan activos para el tono y cudles para el ruido. Su estructura es: xx RW Donde H, roprovonta oi bicquso dol canal "i" para el rvido, ¥ 7, 10 miaso para el tono. Asi, por ejemplo, 0f deecamoe que por e1 canal 2 page un tono, por el canal 2 tanto tono como ruido, y por el canal 3 nada, el valor a incluir en el re~ gintro 7 sork, on binario: “ P91p1199 (en decimal, 44). = Rogistroe 8-A1 volumon do cada canal, dela 15. Si en lugar de un voluwen conatante, deseanos que el sonido evolucione eiguiendo una de les envolven— teo preprogramadas, dobenos introducir wl velur 16 (an hexadecimal: $19). Registros D-C: perfodo de 1a envelvente, en milisegundos. A resalter que se entiende por perfodo el conjunto de dos rampas; asi, si especificamos tun valor de 10000, las diatintas envolventes sexhi: t © D segundos perfodo = Registro D: sus cuatro bits de peso bajo determinan el tipo de envolvente, Uy eutre les preprogramadas, segin el cédigo indicade en la figura superior. Obsérvese que este cédigo es distinto del utilizado en las sentencias del BASIC, Yenos, pues, que culocunds lus valores adecuados en los divlintos registros del circuito generador de sonido podremos obtener todos los efectos sonoros do que este es capaz, con lux venlajas de wayor rapides y cuutrol totel que el cédigo m&quina nos proporciona. Ahora bien, estos registros no fornan parte de la memoria, y no son, por ten- to, directamente accesibles. Para modificer los wisuoy ey preciso pasar por el circuito de interface VIA 6522. Ello resulta, no obstante, muy sencillo, ya que en la RON existe una rutina especifica que cumple esta misién. Se trata de 1a que empieza en 1a direc— cién de memoria $7535, y exige a le entrada el nlimero de registro en A y el contenido que queremos incluir en 61 en x. Asi, por ejemplo, #i queremos que el volumen del canal 1 (registro 8) sea 5+ harenos + WK #5 svalor a pasar LDA #8 jniimero de registro JSR $F535 jse efectua el trespaso Cuando desepmos alterar todos o 1a mayoria de los registros del circuito de sonido, resulta més oficiente utilizer 1a rutina $FA6C , en lugar de repetir catoree veces el proceso antorior~ La rutina $FAGC pasa a los registros del Y al D los valores contenidos en 14 bytes de memoria consecutivos. Para indicar a 1a rutina de dénde debe leer tos bytes, debemos introducir ei X © Y, respoctivanente, loa bytes do peso bajo y alto del puntero ai inicio de ie table. Ejemplo: PAB5 Fy 280 |mA9e wate vane aig PAeC||, | Lan SIRE” Bote sistena es ol que utilizan los dos clice del teclado,’y 158 ‘comandos *7= PING, SHOOT y EXPLODE, segin los siguientes datos: gomando rutina table reg: @ 123456789 ABED PING = FA8S-—FASD 18 00 00 00 00 00 00 3F 10 00 00 00 OF 00 SHOOT FASB FAA3 00 09 00 00 00 00 OF 07 10 10 10 00 08 00 EXPLODE FABL FAB 00 00 00 00 00 00 1F OF 10 10 10 00 18 00 clic FAFA FBO2 LP 00 00 00 00 00 00 3E 10 00 00 1F 00 00 elec FBI. FDIS 2P 00 00 00 00 00 00 35 10 00 00 1F 00 00 Bn contraposicién a les anteriores, el comando ZAT 02 algo ngs complejo, ya que requiere un desplazamiento continuo de la frecuencia. Para ello, empie— za utilizando 1a rutina ¥PA6C para inicializar todos los regiotroe, y lucge emplea 1a rutina $F535 dentro de un bucle para producir por el canal 1 todos os perfodos desde 1 hasta 111, succeivamente, con una breve pausa en cada uno de ellos. Los comandos SOUND, MUSIC y PLAY proceden a leer los par4metros, comprobar su validez, y pasarlos a log registros adecuados, previa modificacién, #L procede. Asf, ol cédigo de volumen J se transform on 16, y el cédigo de en volvente 3 se transfurma en 6, etc. Igualmente, 01 cbaigo de nota (en 61 comando MUSIC) debe ser pasado a periode para su introduccién en el registro correspondiente. Vara ello nos valesos dy una table que empieza en $FC44 (bytes de peso alto) y S#UD1 (peso bajo). Los valores asi obtenidos son vélidos pare 1a octava f. Para les otras oc vavas se divide por 2 tantas veces como indica el niimero de octeva. wo poe FA# SOL SOLW LA LAW 7 8 9 w un a2 Nota! Cédigo ORIC 1 Perfodo hexa 0777 O70B O66 0647 O5EC 0597 0547 O4FB 0483 0470 0430 O3F4 fd. decimal 1911 1803 1702 1607 1516 1431 1351 1275 1203 1136 1072 1012 Sustituir los comandos SOUND y PLAY por sus equivatentes en cédigo mfquina Tesulta simple valiéndose de lo dascrito hasta ahora. Sin onbargo, para ob- tener el MUSIC, resulta mis adecuado utilizar 1a siguiente secuencia LDA tt nfimero de canal eee sea STA $2B1 LDA # yolumen (0 J para envolvonte) STA $257 LDX # cédigo nota (formato BASIC) LoY # nfimero de octava JSR SFCIF No hay que olvidarse de eutorizar el canal seleccionado, mediante el adecuado ‘valor on el ‘registro 7. © joo Pmpleando 1a secuencia anterior, resulta faci) pensar en una rutina que repro~ duzca fragmentos msicales contenidos en una tabla, a razén de un byte por no— ta(por ejemplo, 4 bits para la longitud de le note, y otros cuatro pare el to~ no), , De esto modo, 1a ocupacién do memoria ee minima. El-acceso directo a los registros del circuito generador de eonido permite, por ejemplo: modificar gucesivamente el volumen de cada canal, para lograr tipos de envol ventes distintos de los preprogramados, independientes de uno a otro canal, © superpuestos unos a otros. modificar de modo continuo 1a frecuencia, produciendo efectos de tipo sire- na, 0 al estilo del comando ZAP. Para los interesados en estudiar Jas rutinas SOUND, MUSIC y PLAY, todas eupie~ zan en $E889. All1{ la rutina lee los pardémetros, pasando sus valores a la di- recoién $2B1 y sucesivas (dos bytes para cada parémetro), y busca en 1a table #E84E la direccién real de la rutina especifica, que en realidad contiene un salto a otra direccién, segin el siguiente esquoma: én galta a comando direc sounD $F41E #FB26 Music F424 #PBFE PLAY raz. #FBB6 Aqui se produce el pase de los pardmetros a los oportunos registros, valiéndo— se de las subrutinas antes explicad Si durante ol proceso se detecta algin tipo de error en los parénetros, el byte $2E9 es puesto a 1, para sefialarlo al retorno. Gran parte del tiempo de ejecucién de estos comandos se destina al cAlculo de los parémetros (conversién de caracteres ASCII a valores binarios) y verifica~ eign de los mianos, por 1o que el cddigo miquina permite una gran velocidad. Nota: Anteriormente, el dibujar los gréficos de las envolventes, 10 he hecho segin 50 indica en el manuel del fabricante del ORIC-1. No obstante, por 10 monos en 18 versién que poseo, #e aprecian doe variantes: = 10 primera se halla en 1a envolvente nimero 4, que en lugar de empezar en el valle (punto bajo) de la envolvente, lo hace en la cresta. La evolucién posterior ee 1a indicada. = 1a segunda, més importante, en 1a envolvonto nimoro 5, que empieza tanbién en la cresta, para ir disminuyendo hasta ( al logar al semiperiodo, monen- to en que de golpe asciende al maxino, donde se estabiliza. Otra nota: Podenos anular e1 tono produeido por un canal, sin alterar el registro 7, simplouente introduciendo un # en el registro coriespondiente al volusen del canal en cuestién, Recordenos que, pare el contro} por en~ volvente, el valor a introducir era $19 (en decimal: 16). DIRECCTONES eficiencia en nuestros programas en efdigo waquint, se Para lograr 1a miximna er la RON, evitendo requiere utilizer al mixino lac subrutinas ya conten duplicidades innocceariae, avi como 1a meniymlacién de les punteras y pardme~ tros contenidos en las primeras paginas de memoria, y utili.ados por las ru~ tinas de le KON. Bllo preciea, do una parte, un cenoeimiente general de Ja ertructura dal sis jegiin se ha descrito en todo lo anterior, y por otra, el conocimionto tema, Rete es al especkfico de 1a ubicacién do las distintes rutinas y pardmotroe. objeto del presente capitulo. Evidentemente, una descripcién exhaustiva de todas lay rutinas, con sus pun~ tov de vulzada, requeriulentes y resultados eacaps # les posibilidades del Por ello me limiteré a detallar law caracteristicas nas presente cuaderno. 2 Stiles, asi couo algunos de los parémetros importantes de les rutines 1 nis usados, con sus aplicaciones usuales. } ser considerada més bien como una guia pe Una vez hallada, 1a La relacién resultante debe, pue ra una why r&pida biequeda de 1a direccién necesarie. rutina debe ser estudiada, medjarie su desensamblado, para ver si se ajusta a Lo que necesitumus, y cumy debewoy utilizaria, Las direcciones estén ordenadas, per 1o que empezanos por los parfmetros de las primeras péginae de le memoria, para seguir con la NOW, a partir de £CpN#: gC-$D: — puntero usualmente empleado para la lectura de mensajes. $12-$13: puntero a la direccién de principio de 1a linea de pantalla en que ge encuentra actualmente el cursor. $1A-Z1C: contiene un JMP $CBED, y es usada por la secuencia principal del antérprete para 1a impresién del mensaje "ieady", niimaro da érden de 1a Linea de Rasic buscada por un GOTO. Aparente mente, au dinica utilidad seria servir para un eventual VENUNDER puntero a la direccién actual del cursor en 1a pantalla. contione un JMP a 1a direccién donde hayamos definide le instruccifin usr. 24-25: bytes utilizados para buscar el fin de una linea o de una tira al~ fabatica dentro de una linea. #261 utilizado como contador de la tabla de nonbres de instruccionos, para coloular el token corrcopondionte a lac miomac, durante el pro= cose de tokenizacién. s2T: usado para distinguir si estamos dimensionando una variable, o cal~ oulando ou valor. alfabética, y se 928: contiene el valor $FF si la variable buscada pone & cory un cusu cuntrurio. $29: contiene el valor $84 si 1a variable buscada ev entera (dos bytes), y cero en caso contrario. © fponinen g2cr B2E: Bere $39: $31: 893-8345 $35-884r #91-893: 89A-¥9B + #9C-B9D: g9B-S9P: FAG-BAL: BAD-GAB: BA6-ZA7: $AR-HAG: sus dos primeros bits sirven para fijar si estamos dentro de un READ, un GET 0 un INIUT. el bit de peso alto determina el Control 0 (anula momentineamen~ te la impresién en la pantalla). utilizado on luz provesus de lecture y everilura de un Lyte en ua fichero de cassette, para alnacenar el byte a pesar al cassette. Lieva 1a cuenta del nimero de caracteres inpresos en 1a Linea ac~ tual por 1a impresora (erréneanente inicializado a 13, al princi: pio do cada linea). nimero de caracteres por linea de 1a impresora. acumulador integro (dos bytes). También destinade a contener el niimero de linea al introducir por teclado una. buffer de entrada del teclado. Destinado a contener los caracteres que se van entrando. Fn 61 se lleva a cabo la tokenizacién. Jas instrucciones CLOAD y CSAVE utilizan, como vemos a continuaci6n, este zona. Suele constituir la zona de pigina cero utilizable por las rutinas del usuario en cédigo maquina, con un minimo de precauciones. 1 del fichero en cassette. direccién inici direccién final del fichero en cassette. marca la caracteristica de autorload (ejecucién automitica al fina~ : Hrticigscotent ad. Lizar La Lectura). {Eien nuvo-ore gs peer due reermt.cs sefiala que el fichero es en cddigo m&quina, }s1 19s bayC7prerraan.es mac seiiala que 1a ¢rabacién (0 le Lectura), deve cfectuerre @ veloci~ dad lente, de Wf baudios. $220%/' puntero que apunte a $91, 394, etc., vegin cual sea el GLtimo pu tero utilizado para salvar una yurieble. punleros de una variable alfabética (longitud y direccsén inicial) eda+ Supt las necesidales, se euplean tanbiés actualmente consid Jas direcciones siguientes. puntero hacia 1a direccién del primer byte del programs Basic re~ sidente en la memoria. (WICIALMENTE [28() puntero al primer byte ocupado por las variekles no dimensionad del programa de Basic. (INDICA TAMBIEN EL FINAL DEL BASIC) puntero al primer byte ocupado por las variables dineneionacas puntero al primer byte de la zona libre entre las variables dimen sionadas y 1a zona de strings. puntero al primer byte ocupado por los strings. puntero al primer byte después de los ocupados por los strings, es decir, puntero al HIMEM. wrunte Ie ejecucién de un prograna Nagic, coutiene el valor det niimero de 1fnea en curso. Si se trata de ejecucién directa por te~ elado, el byte contenido en %A9 vale ¥ ® ATMOS/ ORIC-L SACHZAD: eag-ZB1: $B2-$B3: : #04-BB5: #B6-$B7 + scenscrs 300-405: se9-$E11 #82: i #80: SE9-BEA: $1GP-Z1FF: $208: sagen $213: B22, 8228-$22A: s2en-ge20: : 8261-3262: 8263-264: $268: 1 $269: ! B2bA2 ' s26ar #26: * y26o-¥26 $27e k2bP: utilizado pare salvar ol puntero del intérprete, y tanbién pora Undicar ei se han producide modificacionee en el prograna Pasic antes de un intento dg continuacién. puntore de los DATA. usado provisionalmente para le lecture de un DATA. contienen os dos primeros caracterea de 1a variable buccada- Los bits de peso alto nos indican el tipo de variable. puntero a la direcoién de comienzo de 1a variable. puntero # Ju dirvevitu iniciel de une Inca de programe + acunulador de punto flotante. también utilizado en ocasiones para salver el puntero de} intér- prete. inicio de 1a rutina quo lee el careter siguiente al apuntado por el puntero del intérprete. Adem. pere lee el carkcter actval. puntero del intérprete de asic. pila (stack). De $1FF para abajo c-ntiene las direccior torne y los pardnetros que ve pasan entre rutinas. Te iy pare arriba es utilizado para contener valores a imprimir, de re- mientras nantenenos pulsada une tecla, este byte contiene un valor que depende de 1a tecla puleada (no es el codigo ASCII). el bit de peso alto determina e1 modo minéecula contiene 1a miscare del PATTERN. coutivny un 1, of le menoria es de 16K, un oi ex dw 48K. contiene el vector a 1a direccién de 1a rutina de interrupciés por'el VIA, cada centésina de segundo (1ectura del teclado). contiene el vector a la direcci6n de interrupeién en caso de un Reset parcial (pulsacién del botén situado en 1a parte inferior de 1a néquina). puntero pare salter @ la ejecucién del correspondiente careter de control. usedo cono valor intermedio para muitiplicer por 4 et minero de Linoa, durente el eéleulo de la direecién vie ge 1a en Je pantalla. posicién vertical del cursor, a partir de @. posicién horizontal del cursor, a partir de YJ. byte cuyos ocho bits determinan ¢1 estado de} teclado (ver el apur: tado correspandiente que detalla la funcifn de ceca bit). atribute TAPER. atribute INK. puntero @ la direccién de principio de 10 pantalla. niimero de linens de 1a pantalla. ® 9276-$277: contador de interrupciones. { 5 1 $209: woulrola el estado de le pentalle (HIRES, GRAD, ete.) : $201-$2C2: puntero a la direccién de donde no se puede pasar por el conando GRAB. . i $2F: ebdigo ASCII de la Gitina tecla pulsada, wks 389. ! $28: a partir de aqui se colocan los parfnetros para las rutinas musi~ cales y de alta resolucién. “gard: el bit de peso alto indica impresién en la impresora. De lo con— trario, le impresién es por 1a pantalla. : #24: el bit de peso alto determina el modo TRON. $2F9-¥2F6: vector a la direccién de ejecucién de 1a instruccién "! $2r7: usado por 1a shscara de impresién do los atributos. $288: valor retornado por una expresién. A ‘i a , $2FC-$2FD: vector a la direccién de ejecucién de la instruccién "&( 3308: registro de salida del port 8 det VIA. 301: registro de snlida dat port A dal VIA, con reconocimionte de recep— cién. registro de sentido de los datos del port B del VIA. registro de sentido de los datos del port A del VIA. 9394-9395: temporizador 1 del VIA. $396-4397: registro latch del teuporizador 1 del VIA. $398-8399: temporizador 2 del VIA. #30a. rogistre do desplazamiento en serie del VIA. 9398s registro de control auxiliar del VIA. #30c: registro de control periférico del VIA. $3: registro de estado de interrupciones del VIA. #90: registro de autorizacién de interrupoionee dol VIA. #30r: registro de salida del port A, sin acuse de recepcién, del VIA. #0996: inicio de 1a tabla de direcciones de las rutinas en cddigo mfquina correspondientes @ les distintas inotruceionce dol Baeic. | segecs inicio de la tabla de direcciones de ejecucién y grados de priori~ | dad de los operadores +, ~, x, /, 1, AND y OR. CREA: Anicio de 1a tabla de los nombres do lao dietintae palabras reser vadas del Basic. Para sefialar el final de cada palabre, el filtino byte tiene el LiL de peso alto puesto a 1. (1M0F 124) i‘ | feades indedo do 1a tabla de mensajes de error. $C3F8: _rutina que abre espacio dentro de un programa de Basic, pare poder Angertar en 81 una nueva 1inen. ¥c43Br --rutina que comprueba si hay espacio bastante bajo el stack para _ ‘poder llevar a cabo el c&lculo de una expresién, y almacenar alli Jog datos necesarios para los valores intermedios. : | sc485: | | seams: | 1 SC4E3: | 3c56F: \ SCOEB: $C719 $0738: #0765: 80773: sc824: #0832: scB41: SCBAD: gcann: SCORE: rutina general de error. Interrumpe 1a ejecucién en curso, anunciando un mongaje do errer, quo lco de la table ¥C2AC. EL reyistro Xe le entrada debe contener la distancia desde ¥C2AC hasta el primer caréc~ ter del mensaje. Cada meneuje termina con un ccsécter que tiene el bit de peso alto a uno. Este es el punto por el que se entra Abn yeneral. secuencia principal del Basic una vez acabada le fase de iniciali rutina que intercala una M{nea de Basic entrada por teclado, dentro del programs en curso. rutina que recalcula y modifica los links de un programa de Basic. después de haber sido éste modificado. También puede ser fitil cuan- do por un error de lectura aparecen al listar e} wrocrema una serie ,de letras U (hacer CALL #C50F). 6 tambien: g ? g [RETRN entrada de una if{nea de asic por teciado. rutina que lee la tecla pulsada y, si ve trataba de Control 0, pori- ciona los correspondientes bits del registro 26 para senalario. xutina que tokeniza 1a nea de pasic presente en ei buffer de teclu~ do, dejando en ol registro Y 1a longitud final de la misma. rutina correspondiente @ "EDIT". rutina que busca, @ partir del principio del programa de Basic, una Linea cuyo niimero corresponda con el que layanos puesto en los bytes 633-834. Al retorno, el puntero ¥CE-~SCF contiene lu direccién del primer byte de 1a linea buscada, y $1D-11 e1 nimero de orden de 1a Linea dentro del progrena, £1 carry se pone @ set si 1a liexios encon- trado, y a clear en caso contrerio. rutina similar @ le anterior, pero en Ingar de iniciar 1a biequeda por el principio del programa, ec ompicza a partir de la direscién contenide en A (peso bajo), X (peso alto), que debe ser la innedinta ne tn este caso, el puntero Y1D sta encontrar anterior a) primer byte de une 14m -#1E es incrementado en el nimero de 1ineas ealtadas Ix 1a buseada, rating "NEW". ruting "CLEAR". Leva el puntero del intérprete al byte anterior al primero del pro~ grana de asic. rutin "LIST". muting "LIST". iting “LPKINIs muting "FoR". interpretador del Basic. Este ex el punto por dunde se entra ol eje- curar el comando FUN. interpretador del Rasic. ato = el pinto por donde se entrn pare ejecuciéa de una Linea entrada directanente por teclado. que empieza on el byte rutina que ejecuta una instruceién de Pa apuntado por el puntero del intérprete, que acabanos de leer. @ sCORD: SCADA scab: scalc: #CA3E: SCAGL: #CA66: SCA78: sCA98: gcaD2: gCBO1: gonors SCBED: #COA: sccgD: scc1ps goci2: decap: scc6D: gec89: evsc: sCCBRs rutina "RESTORE". rutina que lee el teclado y comprueba si hemos pulsado Control C para detener la ejecucién de una linea o programa de Nasic. rutina "STOP". rutina "END". rutina "CONT". rutina "RON. rutina "GOSUB". rutina "GOTO rutina "POP" y "RETURN" (equivalentes). rutina "DATA". muting que ineramenta a1 pantera del intérprete en el niimera de bytas indicado por el registro Y. rutina que busca el fin de un DATA, 0 de una linea de Basic, segin 1a entrada sea en este punto o en ¥CAIF. rutina "IF", rutine "REM", rutina que busca un ELSE © el final de 1a linea de Basic. rutina "OR". rutina que convierte un nimero expresado por sus caracteres ASCII @ integro sobre dos bytes, 1lev&ndolo a ¥33-¥34. keta rutina es nis répida que la general, pero solo trabaja en la gana J~63999. rutine "LET", rutina "PRINT". rutine quo salts a una nuova 1nea. rutina que imprime un mensaje que empieza en la direcoién apuntada por el puntero formado por los registros A, Y y termina con un byte mio. rutina "CLS". En realidad, imprine el carécter gc. rutina que inprime un espacio. rutina que inprime un interrogante. mutina general de impresibn del carketer cnyo chdiga ests contenido en Aa le entrada. Sirve también para ejecutar los caracteres de control, y tene on cuenta les dobles elturas, columnas reservadas, etc. subrutina do le anterior quo también imprime el carfcter contenido en A, pero menos general. contiene el mensaje "PRINTER ERRO} rutina "1", rutina "THON", rutina "TROFF". | { t 1 | sccRA: seccg: scCrD: soDg3¢ scegc: SCETTE SCRA: SCF Ta: $CFO9e scrD3: ‘SCFE4: SCRFO: sDpF2: SDPFC: 90186: s02ig: BD3FD: gD4g1e $0419: SD4EB: SDIFAt rutina "GET", rutina "INPUT". rutina "READ". muting que 160 (del Leclado © de ui proguaue) uu valor y Lo aoigna @ tuna variable, Ee una subrutina de GET y de INFUT. rutina "NEXT". ! ' rutina que culcule el velor de una expresién que empieza en el lugar apuntado por el intérprete de Basic, y pasa su resultado a ecumla~ dor de punto flotante. subrutina de la anterior que calcula la expresién, pero sin proceder @ los tests de error al final. rutina que calcula el valor del siguiente nimerv o variable apuntady por el puntero del intérprete (no el conjunto de la expresién). rutina que apunte y salta la tira alfabética contenida a partir de a poaieién actual del puntero del intérprete. lee el carécter apuntado por el puntero del intérprete, comprueba aque ea el cesendo, i 10 ea, Jo saita, y 94 no, va a un mensaje co error. Segiin cual sea el punto de entrada, el car&cter buscado e: gcrD3: ")* scrv6: "(" BCFD9: *. SCFDB: e1 contenido en A rutinas "INVERSE" y "NORMAL". Van directamente a error. Se supone que carresponden a rutinas que en un principio se planearon, pero que luego no se incluyeron en el proyecto definitivo. rutina que busca el valor de una variable. rutina "DIN". rutina que busca una variable © la crea, posicionando los registros $28, $29, $B4, 925, $BO y SBT. mutina que compmishn que el carketer lefda san una letra A-7 y posi- ciona el carry @ set en tal caso, y @ clear en caso contrario. rutina que pasa el valor del acumlador de punto flotante a integro, retornando su valor en los bytes $03~Z04. rutina que pasa él velor del registro ¥ el acumilador de punto flo~ tanto. ‘rutina "DEF". rutine que comprueba que estenos ejecutando un programa y, on caso contrario, salte « error. rutina que busca espacio on la zona de strings. rutina que, @ partir de la direccién contenida en los bytes ty Vy busca 1a longitud de une tira alfabStica, poedcionande Loe punters (02) y ($01) al principio de"la tira y ($88) al byte siguiente al final. El regietre gh9 contondré 1a Lonyitud. © e06r7t D715: $D89D: gp852: $D85B: D867: D894: s089D: gp8acr gp609: $0937: 30965: #0996: spgcé: SDOFA: #DALG: gDE73: $DF22¢ SDFCFs segci: spol SEAAB: #25931 BE512: ges2i: SBS3Er $0554 rutina quo coloca una tira alfabética en 1a zona de strings. rutine que retorna al acumileder A el nfimero de caracteres de une ti- ra alfabética. rutina que calcula el valor de una éxpresiéa como integro un byte, y lo lleva simult&neamente al registro X y a $D4. posiciona el puntero del intérprete en el valor contenido en el pun— tero (#66) que suele ser el final de una tira alfabética rutina que lee los parémetros para el POKE (responsable de que el segundo parémetro del POKE no pueda ser un valor hexadecimal, ya que conserva el primer parémetro en ¥33-34, que son utilizados para le convereién de un valor hexadecimal. rutina que pasa el acumlador de punto flotante a integro sobre dos bytes, llevindolo » $33~$34. rutina "POK rutina "WAIT". rutine "DOSE". Fulinu que pase el valor del integre formade por los registres A ¢ ¥ fal acumuledor de punto flotante. rutina "LORES". rutina que calcula le direccién del primer byte de une Linea de pan- talla a partir del ninero do linea, colocedo previanente en el acumi~ lador, y devolviendo 1e direccién en ¥1r-$2g- rutina que lee los parémetros X e Y para una posicién en pantalla. muting *PLOT". muting "REPEAT". rutinas "PULL" y "UNTIL" (equivalentes). rutina que lee lea cinco octetas a partir del apuntado por A, ¥ y Los pasa al acumulador de punto flotante (lee una varieble). rutina que pasa el integro contenido en #D1,8D2 al acumuiador de pun~ to flotante. rutin que calcula el valor de un nfimero expresado en ASCII. rutina que imprine un {ntegro’ contenido en Los registros A y x. mutina que pasa el valor dal acnmlador de punto flotante @ su expre~ sign en caracteres ASCII @ partir de #191, terminado en un nulo. rutina que lee un fichero desde el cassette. mensaje “Sourching" (2/mA Searching TESTS :CHLAF EG CA: CAL EAAG:chtaret) monsaje "Loading". nensije "File error. Load aborted". rutina de error durante 1e Lectura de un fichero en cassette. inorementa el puntero empleado para 1a lectura de un fichero en casset— te y posiciona el carry si hemos acabado. © $8563: ge56re $B576r ‘E578 SESBC gE5C6: SE5F3: BE639 S$BO5E: ge67D: 9B696: sEOBA: SEOCA: BERD: $8725: E790: $ETAS: SETAAt SETDB: EB ya SEBgD: $8513: $PB48: SE84E: | $8866: rutin quo borra ol mensaje que pudiera haber en 1a nea reservada superior de 1e pantalla. muting que eseribe a1 nombre del progrena en la ines reservada su~ perior de 1a pantalla. : rutina que escribe un mensaje en la linea reservada superior. rutinn que salva un fichero on cassette. : mensaje "Saving". muting que salva un byte en el fichero de cassette. rutina que salva un bit en el fichero de cassette. rutina que lee un byte desde un fichero en cacaette. E1 byte leide va construyendo en el registro $2F. rutina que lee un bit desde un fichero en cassette. eubruting para la lectura de un bit. Cuenta el tiempo desde 1a ante~ rior rampa hasta la siguiente, y 1o compara con 512 microsegundos, po sicionando el carry on coneccucnoia (recordomos que cl tiempo seria de 416 microsegundos para un bit 1, y de 624 para un g). rutina que lee el tono previo do un fichero de cassette, utilizin— dolo para sincronizar la sucesién de bits rutina que escribe al principio de un fichero en cassette el tono previo de eincronizacién, formade de 259 bytes #16. inhibe las interrupciones por teclado, preparando el circuito de in- terfase VIA para la lectura del cassette. rutiua que comprueba 1a coincidencia del nombre leido en un fichero de cassette con el que busckbamos. subrutina de CLOAD y CSAVE que lee los pardmetros necesarios. suline que calcula el valor de 1a expresién siguiente, lo pasa a Antegro dos bytes y 1o coloca en $33-#34- ebdigos de !, £, A, S, AUTO utilizados por la rutina de lectura de parfmetros para lectura y grabacién de ficheros en cassette. rutina "CLOAD". rutina "CSAVE". desinhibe las interrupciones, finalizundy unw uperacién cou el cas— jotte, y retornando a interrupciones por teclado. irutina "CALL". calcula 1a exprosién hexadecim#l ASCIT que enpieva en el byte siguien~ te al apuntado por el puntero del intérprete (que seré nornalnente el cardcter =), yo pasa a ¥33-$34+ i6n hexadecimal. rutina que calcula une expré inicio de 1s table de direcciones de ejecucién de, por este orden, SOUND, MUSIC) PLAY, CURSE, CUIMOV, DRAW, CIRCLE, PATTERN, FILL, CHARy PAPER @ INK. tabla del nimero do parfmetros necesarios para lus mismas funcionos. @ / nantes $E8721 SERTD: 8B889: 8995: $E95B: BESTA: $5994: $EQAQ: BEQBBY FEA24: ‘SEAGL: SEASE: $EAD9: ERG3: SEBS: SEBDO: SECEG: ¥ECI5: ECAP: Sepp: sng: $EDTO: BEDF6: SEEFF: SF p2Ds FBT: 8FH93+ 1 prgase tabla que indica cuéles de 1as anteriores instrucciones admiten valo— res negativos como parametros entrada comin da CURSET, CURMOV, DRAW, CIRCLE, PATTERN, FILL y CHAR. entrada comin de SOUND, MUSIC, PLAY, PAPER © INK. rutina que retorma a A el cédigo ASCII de 1e diltina tecle pulsade. rutina HIMEN. rutin GRAD. rutin RELEASE. rutina TEXT, rutina HIRES. fragmento destinado e ser copiado a partir de la direccién $E2, duran- te la fase de inicializactén general. en caso de encontrar un FLSE © un conenterio, salte al fin rutina que de programa, y posiciona el Carry segin se trate de ua ui- do 1a 1fne. mero. posiciona el carry a clear si el carfcter contenido en A es un nfimero (cédigos ASCII de $30 a $39), y pone el 7ero @ set si era ":" 0 un nulo (fin de instruccién o fin de linea). | fragmento de 1a fase de inicializacién general. mensaje “Rytes freat. monsaje "Oric extended basic..." empieza une table do JMP. rutina que resta el contenido de ($2/4,x) menos (f299,Y) y retorna 1 ORA de los dos bytes. suma ($299,X) ads (8299,x) dejando el resultado en (8299,X)- rutina que resta uno al puntero ($269,X). Anhibe lay interrupciones del VIA (desactiva el tecledo). rutina de interrupeién cada centésima de segundo rutina que vacia las direcciones $272 a $277, conservando A, X, Y- rutina CURSET. Requiere le posicién X en el registro X; Je posicién ¥ en el registro ¥, y el color del cursor (fondo, frente.+.) on el registro g212. rutina que transforma el pardmetro de coordenada horizontal del modo alta resolucién (colocado previamente on ¥C-#D) a ninero de byte den= tro de 1a Linea (que queda en $C-¥D) y niimero de bit dentro del byte (en $5-$F). Resulta til cuando queranos hacer una divieign de valo~ rea sobre dos bytes. Consorva A, X e Y. (Dividendo en #C-$D, divi- sor en $240-$201, el cociente queda en #C-4n y el resto en SE-4F). rutina CURSET. rutina DRAW. rutina PATTERN. rutina CHAR. gr25g1 8F2641 SP4gor 8F5351 $PSB3: #F5D31 BPoR2: SPSFC: SPOS2: SPOOF: BF615+ ‘SPOLB: eP624: SP6311 arora sP677: 8P6D3: sr6rs FFTOG $P729: SET73Ft SFTACE er62r+ rutin que verifica el valor de un pardmetro pare les rutinas musica les o de alta resolucién. Comprueba que el contenido de f29f,X-~291,X sea mayor que cero pero menor que A, y posiciona el carry, segin el resultado de 1a cosprobacténs perecida a 1a anterior, pero adenis‘adnite el valor cero. principio de una tabla de JMP. rutina que pasa el contenido del registro x al registro del circuito generador de sonido indicado por el contenido de A. principio de le table que hay que sumar a la direccién $F5F2 pera ob- tener 1a direccién de la subrutina correspondiente a un carécter de control. Ancrementa el puntero del cursor de 1a pantalla. rutina pare el coutrel H (retrocede un lugar). rutina para el control K (sube un lugar). rutina para el control I (adelanta un lugar). rutina para el control J (desciende un lugar). pio de 1a Lines actual de rutina para el control H (vuelve al pri Je pantalla). rutina para ol control ¥ (vaca 1a 1fnea actual en pantalla). rutina para el contrel L (vaca 1a pantalla). rutina para el control * (retorna el cursor el principio de le pan talle, sin linpiar este). mousaje "CAPS". mensaje " _" (cuatro espacios, para borrar el CAPS). rutina que vacia una linea de 1a pantalla. transforma el nimero de linea a direccién inicial de la misma, retor nando el valor en los registros A e Y. multiplica el valor de A por 4 y coloca el resultado en #263-$264. rutina que imprime (0 no) el mensaje CAPS en la parte superior dere~ cha, segin el estado actual del teclado. rutina que imprime el caracter contenido en X (subrutina de ¥CC12). idem car&cter contenido en A. Futina quo coloca un mensaje en 1a 1fnea superior de 1a pantalia. Los registros A e Y deben contener la direccién del primer caracter del mensaje (que debe terminar con un byte nulo), mientras que el registro X debe contener 1a distancie desde el primer byte de le Pantelle hasta el lugar donde se debe empezar e imprimir el mensaje. bloque destinado a ser copiade en les direcciones $228 y sucesivas duratite la inicializacién general. rutina de inicializacién general. mensaje "Nomory error", rutina de inicializacién de los periféricos. rutina de inicializacién del teclado y los colores pantalla. @ #969: srOTF: roc: SPODD: PAG: SFA49: SFAFAr SEBL ‘$FBBO: SFBFE: $eC45: sFC52: SFCTO? SFPRAS SPFFC: SPRFR: Nota: rutina de inicializacién del VIA durante el reset general. rutina que inicializa 1a pantalla. rutina que comprueba #1 tipo de memoria y ou correceién. subrutina para lo comprobacién de 1a memoria. otra subrutina para la comprobacién de la memoria. fs la responsa- blo do que on 1a sona libre de la memoria apare can lov cédigos #55+ comprueba 1a memoria, dejando pasar un cierto intervalo entre le es eritura y la lectura, para comprobar el correcto refresco de 1e AM dinknica, rutina que produce un retardo de unos 8 miligecundos. rutina que provéca un retardo variable, en funcién del valor que coutenga el xegielro X # 1a entrada (entre 1,5 y unos 3/9 mseg.)+ produce el PING. produce el SHOOT. produce el EXPLODE. produce un clic del teclado. produce el otro clic. rutina PLAY. rutina MUSIC. tabla que nos da e1 perfodo correspondiente a cada nota musical (bytes de peso alto). dem. los bytes de peso bajo. generador de caracteres (destinado a ser copiado en I:AM). vector para al reset parcial. Contiene la dizeceiin £22, en RAM, lo que permite desviarla, vector para el reset general. Contiene 1a direcesén $7420. vector para 1a interrupeién para el VIA. Contien 1a direceién $228, on RAM, por lo que también puede ser desviada. Las dircecionce detalladag oon viJidas para lav versiones a la venta en olmercado en el momento de preparar el presente cuaderno. No ob: tanto, entra dentro de 1o posible que, en cl affn de realizar cicrtas nmejoras, eventuales nuevas versiones presenten modificaciones en al~ gin punto. Si el ordenador se ha adquirido con posterioridad a enero de 1984, deber& comprobarse este punto, realizando un checksum de la ROM, asi: S= Gt FOR A = #0999 TO wFPFF STEP 2.1 5 = § + DEEK(A) : NEXT : 7S da, on mi m&quina, el valor: 245258461. © ; pprmncyersotemee APLICACTONES Ba ote capitulo vance @ ver algunos ejemplos de la utilidad do ineluir en un programa de Basic subrutinas en cédigo méquina. Procureré asimismo que las aqui incluides puedan cer de aplicactén mio" menos general, breves y segu- Fas, con el fin de que el lector pueda adeptarins sus propics programas. Antes, sin embargo, de pasar a los ejemplos concretos, vey « dar algunas in- dicaciones genorales. Acoatumbro a colecer cotas subrutinas en ebdige miquina juste antes del prin cipio del programa Basic, es decir, de modo que el filtimo byte de le subruti~ na goa ol do la direccién #4FF- Recordemos, en efecto, que el programa Wusic empieza en la direccién $591, y que debe ir precedido de un byte nulo, que ocupa 1s direccién 3549. Le venlaja de ubrar de exte mdy oy lu posibitidud de vaivur conjuntamente ex un solo Fichero de cassette tonto 1a subrutina como el prograna, Para ello, ef el nombre del prograna ea NOMBRE, y 1a direceién de inicio do 1a subrutiae $49 (por ejemplo), bastard hacer: CSAVE "NOMBRE" ,Audeg El problema que suele presentarse a quien no posee un prograna ensamblador, 0 un utiliturio parecidv, es la introduccién de 1a rutina. Para subsanar este Anconveniente, a continuacién daré un pequefio programa en Basic que sorvird pare carger cualquiera de las rutinay de este cupitulo y que, ademis, contie— ne un proceso de verificacién para conprobar la correcta introduccién de los Gatos, xllo evita sorpresas inesperadas (en cddigo miquina cualquier error puede provocer el bloqueo de le riquina u otres comportanientos andmilos). El programa es ¢1 siguient 10 HIMEN #9809 + F = #4FF 29 INPUT "Direceton inieial" yr 30 IF 1S THEN PRINT "Error datos" : PING : GOTO 29 50 meuT LIF B= Para introducir una subrutina en cédigo mfquina, hacer RUN y responder @ la pregunta "Direccién inital?" introductendo 1a del primer byte de 1e eubru- tina (no olvidar @1 signo # para indicar les direcciones hexadecimales). Después el programa va preguntando uno por uno los conteridos de todos los bytes de 1a cubrutina (oi los intreducts en decimal, no !ace falta el signe 4) hasta 1 ditimo, después del cual, os pediré 1a suma de comprobacién, 0 “checkoun", que facilite con cada subrutina, a fin de dotectar cualquier exror de introduccién, que obligaria a volver a repetir el proceso. Finalizada con éxito la introduccién, podéis eliminar el programa Nasic con um NEW (es sconvejable que Jo calvéis antes en cassette, para futuras ocasio- nes), y pasbis a escribir el verdadero programa de Rasic. tlecho esto, podéis salvar 01 conjunto segin comenté antes y ya, siempre que quesdis utilizerto, o@ bastard un CLOAD "NOMBRE" normal, para recuperar conjuntamente Basic y cé- Aigo whquina. Saipan Entrada de expresiones en un INIUT. En ocesiones, interesaria poder entrar una expresién elyebréica, o una Linea completa de Basic, en respuesta a un INPUT ejecvtado dentro de un programa. Por ejemplo, en los programas de dibujo de {raficas, es necesario detener el programa, crear una linea de Hasic con la Suncién a rep:o:entar (con el ade~ cuado nimero de linea), y reenprender el programa con el PUN n? de Linea ne~ ‘Yodo ello resulta poco préctico, y sujeto a errores, conplicando el proceso do utilizacién del prorana, Vamos a ver como una sencilla subrutina en cb- digo mhquina nos resuelve el problema, Voy a empezar dando la "recete" para introducir el programa, y luego comenta- ré su funcionamiento. [fn primer lugar, mediante el procrama auxiliar descri- to en la introduccién del capitulo, vamos a crear la subrutina. [ara ello, después del RUN, entramos como direccién inicial 18 W4D8, y a continuscién los siguientes valores: 165234, 725165 233, T2p 32,1025 197,134, 233,132,234, 32 220 pH, 20 204 321 198,162,181, 53,24, 6,157,412, 5,232, 248, 246, 1f64 133,233, 14,133,234,90. Finalmente, como checksum, el valor 695196, y 9i aparece el lleady, es que to- do ha ido bion, vino, mis atenci6n 30 pr6xiim ver. Ya poderios hacer NEW, e introducir el siguiente program: gcoros, TAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARARAAAAANAARAAAAAAAAAAAAADRARARAARA 2RETURN 5 POR D = #59C TO 4558 : POKE D,32: NEXT : ? "Entra la funcion Y=f(X)" : CALL #48 1P WIRES + CURSET 29,19,3 : DRAW G,184,1 : CURSET 2H,199,3 : DRAW 260,841 15. M = 26 : N= 199: CURSET M,N,3 : FOR P - 24 TO 229 2X =P - 2: GOSUB 1: C= INT(IGs - ¥) 25 IF Q<@ THEN Q- 9 30 IF > 199 THEN Q = 199 35 IF M= P AND N =. THEN NEXT 4 DRAW P-M,Q-Ny1 : M 45 INPUT "Otra funcion" 5¢ IP R¥>"O" THEN 5 Q + NEXT Observaciones: ~ las Lineas J y 1 deben ser introdueidas tal cual, ein ningiin espacio inter medio. ~ 1a Mnea 1 debe constar de, exactanente, 77 caracteres "A" (dos Lineas com pletas de 38 caructeres, y ol iitino, que evtard Justy debajo del primcre) + = on le linea 59, 01 cardcter entre conillas es 1a letra 0, no el nfimero G. Utdlizactén: = Hacer RUN. La miquina te pide le funcién @ representer, Introduce, por ejemplo: Y = 89 K SIN(X/3) * SIN(X/38). | Pucdeo utilirar le toola DELETE en caso necesario. Termina 1a introduccién con RETURN. = FD programa prea a INES, dibmja low ajen, y luego In curvy dendo ¥ is hasta X = 249, y para unos valores de y entre -99 y +199. |.a curva es di- bujada mediante trazo continuo, no por puntos, y el prograna ost protegido contra valores de Y que se solgan de la pantalla. vce = AL acabur lu grafic, el programa pregunta si duseas representar otra fun= cién. En caso afiraativo, responde S, 0 SI (observa que tanbién conprende YES, © OUI). En caso negetivo N, O NU (0 NON). Si has respondico que si, el proceso se repite. Para los interesados en ello, 1a rutina en cédigo miguina es 1a siguiente: $4D8 LDA SEA bee 29 salvanos el puntero del intérprete en el stack 5 THA entr JSR gc5a2 entrada Mnea en el buffer de teclado SX $89 ay si 10 1fnea era nula, esperamos otra DEO ontr JSR $C6A tokenizamos 1a Linea presente en el buffer ix as inicializanos fntice para 1a copia lazo LDA 935)X leenos caricter del buffer pea fin ai era el milo finil, sal tance STA 350C,x Jo colocenos en 1a 1inea 1 del programa Basic 1x auaontanos indice BNE Lazo pasanos al siguiente carécter fin PLA srs $09 recaperanos puntero antes de retornar ai asic STA $EA RTs RESTORE a un niimero de linea. En el ORIC-1, cuando ejecutamos un RESTORE, el puntero dle los PATA vuelve al principio del programa de Basic, de modo que el siguiente READ leerd el primer DATA contenido en el programa. Sin enbargo, ciertas versiones de Rasic disponen de un VESTORE n, que permite colocar el puntero de los TATA en el ninero de Linea especificado en la sen~ tencia RESTORE, de modo que el siguiente READ lea el primer PATA que se en- cuentre después de la Linea n. Si queremos disponer en algiin programa de esta fuincién, jodenos crearla con Ja adecuada subrutina. Para ello. enpezareuos, como sieapre, empleando nues~ tro programa auxiliar de entrada de rutinas en cédigo miquina. In esta oca~ sién, 1a direccién de comienzo es 1a adr4, y los valores de los bytes: 324157231 1654154, 166,155,532, 232,198,176,3, 76,241, 2/1165, 246,233 1, 1334116165 5247, 253 W135 9171596 EL checksum vale ahora 544744. Si no ha habido errores, hacer KIN, Para mostrar céno se puede utilivar en-un programa la nueva instruceién, es~ cribir el eiguionto program: 19 DOKE “w2P5,4464 24 REPEAT : INPUT “Numero de Linea"jL i! L : READ Ax 39 2 "He leido le " 5 Ag : PULL © 49° DATA linea 4g 59 DATA linea 5¢ 199 DATA linea 199 259 DATA linea 259 365 DATA linea 365 laced RUN. B1 programa og pregunta qué linea desedis leer, y a continuacién os indice lu inex leldu. comproberéis que el VATA leido Serf sienpre 01 pri- mero que haya empezendo en la linea especificada. Ast, por ejemplo, si indichis 1a linea 2f, el DATA Lefdo serd el do 12 Linca 4Y." Si Ja Linea especsticada no existe, aparece el mensaje UNDEP'D STATEMENT ERROR. El prograna no 9e detione hasta que no lo interrumpiis con Control C. La rutina es la siguiente: $4E4 JSR $ZET9D — Leewos 1a expresién y calculamos su valor LDA $94 Lx $93 JSR $C6EB —buacamas In direcesén do in Minos espocifiesds BCS salto si 1a hemos encontrado, saltanos IMP $C9F1 an caso contrario, vanos a rutina de error salto LDA $CE spc al STA $36 restamos uno a 1a direceién halladz, y colocenos Loa gor cote velor en el puntero de Los PATA (4f-YIN1) SBC ep sta go1 RTs retorno al fasic Observaréis que, para mayor comodidad al llamar la rutina, utilizamos la inatruceién "1", Tara ello, al principio del programa, definimoe le migma en la direccién de inicio de 1a subrutina (linea 19 DO'E 42P5,44R4)« Hecho esto, basta hacer | n para restaurar el puntero a la linea ny Impresién de caracteres gigantes Cuando se desee imprimir eu 1a pantalla caracteres ocho veces mayores que Jo hubitual, por ejemplo para Uiluloy, juegos, anuncius, ele. puede emplear~ se la siguiente rutina, que se utiliza con la misma simplicidad que 1a fun- cién PLOT. Para ello, utilizaremos como siempre nuestro programa auxilier y entrare~ mos los siguientes valores, a partir de la direccién $488 (que en el OKIC se entra come #408): 32, 156, 217, 32, 217, Q¢7, 32. 13, 210, UJ, 7149, 227, 2. 138. Izy 248, 249, 160, G, 177, 12, 162, 6, 172, 248, 2, I, I, 1, 72, 14d, 3, 169, 16f, 44, 169, 32, 145. 31, 4, 200. 192. 44. 176. 4, 202. 248. 236, 169, 49, 24, W1, 31, 133, 31, 144, 2, 234, 32, 2W, 12, 25, 2, 230, 13, 286, 227, 2, 16, 243, 96. Por Giltimo, e1 checksum debe valer 718931. #i todo la ido bien. Para utilizar la rutina mis cémodamente, conviene definir la instruccién mediante DOKE #2F5,n4b8. leche evto, pars imprimir, por ejemplo, el ceric: ter A (de cédigo 65) de modo que el margen superior izquierdo esté en 1a co- jumna 15 y 1a fila 8 haremos: 115,8,05 Pata demostrar las posibilidades de 1a rutina, probad e1 siguiente programa de Basic que permite escribir directamente por teclado curacteres gigantes @ medida que los vamos tecleando: 19 DOKE #2F5,44B8 + POKE #26A,2 2g CLS: Aga" " : REPEAT 38 GET KS + A¥ ~ RIGHTS(AS,5) + KE 49 X=1: FORC=1106 541 X,19,aSC(MIDS(AS,C,2)) 6 X=X4 6: NEXT 7$ UNTIL kK = CHRE(3) Para interrumpir el programa basta hacer Control C. Le tira alfabética en la 1fnea 24 est& formada por seis espacios. 1a rutina desensanblada es: plotg gsr 0996 jlee los parénetros colume-file gsr gcrD9 Slee y celta 1 come Jsr gp8¢D jealcula la expresién a valor integre Ly 67 sty $263 jdoble uso: contador y base tabia TXA JSR SFORE jealcule puntero al primer byte carécter arrib Loy ag LDA ($C),Y jee el byte de} dibujo de) carketer DK go Loy g2r8 jposicién horizontal ASL A ASL A SLA jleewoy bit PHA BCC den : LDA e165 sbloque en video inverao BIT [dou LDA #32] STA ($1F),Y¥ — jcolocamos bloque PLA ny sincrenentenos colunne cry wag jcouprobamos si salinos de pantalla wes fin DEX BNE bucle jrepetinos seis veces fin LDA #49 cue ADC SLF STA IF jincrementanos puntero al inicio de Linea BCC salto ’ INC gag salto INC gC }inerenentanos puntero al dibujo 5 NG 1uogo INC $D luego DEC $2E3 jlo repotimos ocho veces bPL arrib nts jretornamos al basic \ Verificacién de la lectura desde cassette. ‘A poco que queranos efectuar un trabajo de cierta importancia con el cassette noe veremce en ie necesidad de incorporar algin tipo de rutina para 1a veri— ficacién de 1a lectura. Es por ello que, aunque en el capitulo dedicado al caosette ya he inclufde una de tales rutinas, alediré aqui otra. Eata presenta con roepecto a 1a anterior Ia ventaja de ver utilirable tanbién para rutinas en cédigo maquina y todo tipo de ficheros, a diferencia de aque~ lla, aolo utilisable pare programas en facie. Ademio, reculta més corta, 1o que 1a hace por ello mismo mds fiable. Como contrapartida a estas ventajas estd el hecho de un use algo mis comple~ Jo, que detaiaré postertornente. bupezerenos por introducir ia rutina con ayuda de nuostre programa auxiliars A partir do la direccién inicial 44DA, los valores de los bytes son: 165, 95, 164, 96, 133, 51, 132, 52, 169, Hy 17H, 168, 24, 97, 51, 144, 1, 248, 72, 32, 84, 229, 194, 144, 243, 17%, 152, 32, 193, 224, 76, 214, 231, 32) 75, 231s 249, 218. El checksum final deber& ser 624393. Si todo ha ido bien, ya tenemos 1a ru~ tina dispuesta. En su forma actual, sirve para checksumar programas Basic, segiin el siguiente proceso: Introducimos el programa de Basic que queranos salvar, y hacemos: CALL #4PB, RADA, EDEEK(#9C) obtendremes un valor entre J y 65535, que deberenos anotar en 1a tapa del cas~ sette, pues constituye el checksum del programa. Ahora podemoe salvar el pro~ grama mediante 1a sentenci CSAVE "nombre", AB4DA, AUTO “aiiadiend# ,5 si lo queremos a velocidad Jenta, 3 todo. AL leer el programa, con un CLOAD normal, debenos obtener el mismo checksum anotado en Je tapa (0 de lo contrario, repetir Ja lectura). Para ntilizarle con ritinas en cédigo m&quina u otro tipo de ficheros, debere~ nos trasledar 1a rutina de verificacién de modo que quede situada antes del principio del fichero « enlvar. Avi, el principin do 1a rutina de verifica~ cién deber& situarse 38 bytes antes del principio del ficlero propianente di- cho. Para obtener ol checksum, deberenos hacer: CALL manu, Achsum, Efinfichero endo menu le direccién de inicio del fichero real meno: 5 bytes, y chsum la direccién de inioie del fichoro real menoa 38 bytes, tlacha asia y nuotada al checksum, para salvar el conjunto, hareno |) CSAVE “nombre”, Achsum, Efinfichero, AUTO rh totalmente normal. El posterior CLOAD de ensamblaje, comentada, es 1a siguients La rutina en lenguaj chaum LDA §5F ure \ colocanos 1a direceién iniciel en el puntero sty $34 LDA up \ TAX inictalizanos a cero los regis tres TAY sume "CLC ADC (833X) | uuamos ef contenido del byte leido pec next iy next PHA st e554 } couprobanos si henos liecade at fina? PLA RCC muna et no, volvencs & sumer el siguiente byte TAK 1A i inprininos on 1a pantalla e1 chectsun JSR gBgcu SMP $2706 ratornanos al Rasie por teclado manu JSR $E740 _—Leenoe las direceiones de inicio y fin REQ cham -—aaltanoa al principio de 1a zutina Aprovecharé 1a ocasién para comenter un hecho que podria ver motivo de dudas al chocksumer programas de Basic. Cuando salvanos un programa de hasic en cassette, el filtimo byte inclufdo on el fichero de cassette no es el itino del prograea de Basic, sino el siguiente a este (que es el primero destinade @ las variables). Por este motivo, dos progranes de Nasic exactanente igualos pueden dar valo~ res distintos para el checkeun, segin el valor que tuviera el byte excedente Para comprobarlo, dado un cierto programa, hagamos: PPKE DEEK(#9C), y calculemos el checksum. duage haganoa “ POKE DEEK(¥9C), 2 y repitamos el célculo del checksum. Comprobarenos que el checksum habré variado (aumentado en una unidad). Simi~ larnente, podenos probar dando otros valores y para cada caso #a obtendré un checksum distinto. Por este motivo, conviene calcular el checkeum inmediata~ monto antes de oalvar el fichoro, oin realizar ninguna otra operacién inter media que pudiera alterar ol byte final. También es reconondable, cono garantie suplementaria, comprobar el checksum, innediatamente después de salvade ol fichero, para asegurarnos que no ha varia do por cualquier causa. Finalmente, como ejemplo de los valores a utilizar on el caso de rutinas en ebdigo miquina, para ol "ORICNON", quo ompicea en ¥AS#G y termina on 4D1SS, Jes sentencids serian: wcflculo del checksum: CALL BATFB, AWATDA, EWDI8¢ para salvario: SAVE "ORICON", ABATDA, D¥D1E, AUTO Conversién a binario. La siguiente rutina permite imprimir en 1a pantalla el equivalento binario de un nfimero. En realidad presento dos versiones de 1a misma rutina: la primera para niimeros hasta 255 (ocho bits), y 1a segunda hasta 65535 (dieciseis bits). Para la primera versién, la direccién inicial es ¥4EF, y los bytes: 32, 13, 216, 169, 8, 169, 24, 6, 212, 42, 32, 18, 2f4, 136, 298, 245, 96. Bl checksum vale 293916. Una vez entrada le rutina, definiremos el comando mediante DOKE #2P5,44mF. Hecho esto, para convertir, por ejemplo, el numero 7} a binario, basta harer 173 y Aparece: P1pP1gA1 Si el nimoro es mayor que 255, aparecerd el mensaje Illegal Cuantity Frror. La parte fraccionaria, ei existe, seri ignorada. Para obtener una tabla de equivalentes binarios, podéis hacer: FOR N= § TO 255 : PRINT Ny ¢ 1 N+ PRINT = NEXT La rutina en lenguaje de ensamblaje, comentada, es la siguiente: JSR $089D _—jealoula la expresién que sigue al | y 1a pasa a ivalor integro sobre un byte colocdndolo en $04 Loy #8 jutilizado para conter los ocho bits bit LDA #318 este valor, al afiadirle un bit por la derecha see convertiré en el cddigo ASCIT de 9 6 1 ASL $04 ipasa el bit de peso alto al carry ROL A sy del carry a 1a derecha del acumulador JSR gccl2 —jimprime el valor resultante en el acunuledor DEY jeontanos los bite BNE bit j#i no henoe acabado, volvemos al siguiente ~4RIS jretornamos al asic Segunda versién: direccién inicial wd. Yalores de los bytes: 32, 157, 231, 16, 16, 169, 24, 6, 51, 38, 52, 42, 32, 18, 24, 138, 298, 243, 96. Checkoum: 219919. Para definir ol comando: DOSE ¥2F5,W4ED. Le utilizacién somejante al caso anterior: FOF LLLIPGIP1LLIGAGS JSR $8790 jealcula la expresién que sigue al ! y la pasa a syalor integro doa bytes en $33 #34 Loy #16 jeontador de los 16 bits bit LDA #18 jeomo en la anterior rutina ASL $33 jel resto es similar al caso anterior, solo que ol ROL $34 ibit de peso alto de #33 entra por 1a derecha del ROL A WI, y lo In dzquierde de bite, pana al seomilador JSR gcc12 DEY BNE bit + RTS Chino tener dos programas Rasic en memo1 Sucede que en ocasiones querencs simultanear el uso de dos distintos progrenas de Basic. Por ejemplo cuando preparamos un programa, y para ello utilizenos otro da tipo utilitario. Si los programas son algo larjos, el proceso de lec~ tura desde ol cassette se hace pronto mondtono y tedicso. Sin embargo, 1a memoria del ORIC-1 48 K es suficiente para poder contener si: multéneanente dos programas de longitud normal. kn efecto, restendo las z0- nas ocupadas por el sistema para sug variables internas, caracteres y panta~ lia, aun nos quedan unos 49 K. La mayorfa de los programas de uso corriente caben en 26K, por lo que resulta posible partir en dos la zona “itil. Ee Lo que realize 1a siguiente rutina, que permite guardar J programa exis tenta, en sina zone por ancina del IIIMEM, de donde se recupern eunnda wuplve a hacer falta. Para ello es necesario que el IIIMEN este situado en #40i¥ 0 menos (de lo contrario, al llamar la rutina, se produce un mensaje de error). Pero enpecenos por introducir 1a rutina. 1a direccién inicial ea wéiit y los valores de los bytes: ‘ 165 1675 244 18 144 53 765 1315196) 169 yf 199 1765193 178, GY, 9 199,171 169, 781133 4179416, 1,1625725177 41765724177 »178 145,176,194 145,178, 200, 208, 2435230517723 179 24216, 236, 325131 41975 24 165 145 9195 4241954196 5105 5 146,195, 9,133,157 ,324515199, 76,255,231. El chocksum vale 1239577. Una vez le rutina en su sitio, introducimos el primero de los dos programas de Basic en 1a memoria (por teclado 0 por. cag~ sette, por los precedimientos normales). leche este, haconos HINEN (abhi y luego DOKE #4EGY,9 (esto sd1o es necesario la primera vez). tego hacenos caLt {iB con 10 que e1 prograna de Naric quedaré guardado en tine zona encima dol /IINEM (ai hacenos un J.1ST, no arareceré nada). Potoaios ahora inteogucir el segundo programa, nornalnente. Tete segundo prograna serd el que quedarh activo, pudiends ejecuterio, Listerlo, nodificerlo, ete. normalnente Bn cualquier momento podenos intercanbiar anbos programas simplemente hacien- do otra vez CALL #4BB (1a rutina tarda algo menos de un segundo en intercom biar 1a zona “activa” con la zona "de reserva"), Couo efecto adicional, la rutina borra todas las variables, sara evitar que las utilizadas por un pro- grana pueden alterar los resultados del otro. La zona “activa” ocupe de #591 a HADFF y 1a "de reserva" de y4bf1 a H9OIF. LDA SAT eemos el byte de peso alto del IINEN CNP #g4E © comparamos con $4F BCC salto jai el NIMEM es inferior, saltenos INP $0483 ide lo contrario, vamos a mensaje de error salto LDA #6 STA $09 + STA gB2 LDA 45 STA $81 jeolocamos $584 en el puntero ($09) LDA #34E STA $33 seolocanos #4E9P en el puntero ($82) Loy #1 s¥ eg el indice dentro de 1a pagina @ . paracrine I i Lox 9848. 5x e9 el contador de paginas @ copier leazo LDA (BY) ,¥ jleomos un byte de la zona activa PHA slo ealvamos en el stack LDA (#B2),¥ jleemoe un byte de la zona de reserva STA ($B9),¥ 10 pasamos a 1a zona activa PLA irecuperancs el otro byte STA ($B2),¥ sy Jo pasanos a Ja zona de reserva Ny Hnorenentanos Indice BNE lazo jaeguimos hasta el fin de le pagina INC $01 jincrewentamey puutero “ae Live” INC $33 sincrementamos puntero "reserva’’ DEX lecremontamos contador de piginas BPL lazo jseguimos hasta acabar las paginas ust $056r jbuscanos {in de prograna cic wee LDA 391 ADC 42 STA g9c LDA $92 ADC 49 STA $9 chacemos puntero fin de programa JSR $C733 jborramos zona de variables INP. $ETRP jretornanos al intérprete Combinacién de varias mtii Todas las rutinas se han preparado de siodo que acaben en ti4FF. Ello inpide usar mis de una al mismo tiempo, ya que se solaparian uutuamente. Podemos evitarlo, trasladindolas a otra zona (1a mas usual es de #4ff en ade~ lente). Para ello, supuesto que tenemos una de estas rutinas que empieza en la direccién "inicio" y queremos pasarla a una zona que empiece en la direc~ ¢ién "destino", podemos hace: * I = ihieio : F = destino : FOR D = I 70 #4FF : TO-E F,PEEC(D) + Fer +i exp Légicamente, 94 antes 1a rutina se liemaba mediante 1a instruceién CALL inicio, ahora deber& serlo mediante CALL destino. De este modo, podemos colocar todas Jas rutinas en 1a zona de Wig a WA, pu~ diendo ser utilizadas simultdneamente. Otra zona converiente es de n97M) & ‘¥97FF, supuesto que el IHIMEM haya sido colocado por debajo de exta zona. ERRORES En el curso de las distintas rutinas, se procede e una serie de comprobacio~ nes, por ejemplo, si los pardmelros estén dentro de la gama de valores vili~ dos, © si el modo do funcionamiento en curso es el adecuadu, etc. De encontrarse alguna condicién de error, 1a ejecucién se desvia hacia una rulina que para el programm eu curso, restaura una serie de registros en p&~ gina cero, imprime un mensaje de errpr, y retorna a la espera de nuevas ins~ trucciones por teclado. Podemos hacer que muestras propias rutinas en cédigo maquina lleven @ cabo Jas verificaciones necesarias para evitar bloqueos imprevistos, y se desvien @ las rutinas de error antes citadas, indicando el mensaje adecuado. La forma general de llamar ¢ 1a rutina de error consiste en cargar el regis~ tro X con el valor adecuado (ver tabla), y saltar a ¥C485. Sin embargo, pera 1a mayoria de tipos de error, existen direcciones de momoria en 1a I'M a las que podenos wouter. |igectamente sin necesidad de inicializar x. PST ee] NEXT WITHOUT FOR - SYNTAX #cre4 RETURN WITHOUT GosUB #C9RE OUT OF DATA - ILLEGAL QUANTITY Sp2ng OVERFLOW aAvuep OUT OF NENORY 80483 UNDEF'D STATEMENT #COFL BAD SUBSRIPT #p29D REDIN'D ARAY - DIVISTON BY ZRRO ADEs ILLEGAL DIRECT spa1e DISP / TYPE MISNATCH SDAT2-FCRB6 STRING TOO LONG #06c7 FORMIT.A TOO COMPLEX #0536 CAN'T CONTINUR - UNDEF 'D FUNCTION ¥pg21 BAD UNTIL ¥DAZ2 Ejemplo: para sefialar un error "ILLEGAL QUANTITY" podenos hacer, mediante 1a rutina general: LDX #935 JNP $C485 0 bien, simplemente: JIMP #n2ng. Fn CONTROL El ORIC-1 utilize, como la mayoria de ordenadores, el cédigo ASCII para repre~ sentar los diferentes caracteres. En este eSdigo, cada letra mayfscula o mi~ niscula, los nimeros, signos do puntuacién,'el espacio y caracteres especiales tienen una representacién especifica mediante un cSdigo de siete bite. Como que un byte tiene ocho bits, el octavo, de peso alto, queda libre para usos especiales, Asi, por ejemplo, al representar un mensaje en eddigo mi~ quina, este bit suele utilizarse para marcar el fin del mensaje. También, en Je impresién en la pantalla, sirve para representar que aquel caracter debe ser representado en video invertido (en los colores complenentarios) « Los siete bits permiten representar cantidades del # al 127. Sin embargo, 9610 los cédigos del 32 01 126 se utilizan para representar caracteres. V1 resto, del $ al 31 y el 127, al ser "imprimidos" mediante el PRINT 0 su equi- valente en maquina, 1a rutina ¥CC12, en lugar de imprimir un cardcter, ejecu- tan ciertas funciones de control. Asi por ejemplo, si hacemos PRINT CIRS(13), © bien, en miquina: LDA #13, JSR $CC12, se produciré un retorno del cursor al principio de la linea actual en la pantalla, Todos los caracteres de control pueden lograrse por el método antes descrito, pero hay algunos que, por su uso mis frecuente, disponen de teclas especiales en el propio teclado del ORIC-1. Asi, las teclas de las cuatro flechas co- rrasponden a los caracteres de cédigos 8 a ll. Para al resto, disponemos de un sistema nis cémodo que el PRINT CHNS(n). Consiste en a pulsacién de Ja tecla do Control y, sinultincamente, otra fecla cualquiera. Un efecto, el resultado de pulsar la tecla de Control es que los dos bits de peso alto dol cédigo de 1a tecla jutlvada son nt @. Asf, Control D equivale a TRINT cun#(4), ya que Ja letra D tiene of eb- “digo ASCIL 68, es decir P1PPA19 en binario. AL poner a cere los dos prine~ ros bits, so transform en Uf9GB19H, 0 sen, el cerfeter de cbdigo 4. Les caractoroe do control de utilidad en 1a m&quina de base son: Efecto obtenide: Copia en el buffer de teolade ¢} carkoter contonide en la posicién actual del cursor, si no es atributo Detiene 1a ejecucién do un programa Pasa @ la inpresién on doble altura, o 3 cancels, si ya estibamos en este modo de improsién Anula lo9 clics del teclado, o los retorna si ya . estaban inhibidos Produce el FING Desplaza 0) cursor a In izyuierds ( Pesplura el cursor € la derecha (+) Dosplaza el cursor becia ubajo (+) ® Desplaza el cursor hacia arriba (+) Retorna el cursor al principio de Je panteda, borréndola Retorna al principiea de la Mnen aetual do le pantalla, sin borrarla (RETURN) Borra 1a linea actual de Ja pantalla Anula nonenténeanente 1a improsién de los carace teres en la pantalla. |. improsién suele retor- par al terninar 1a instruceién on curso. Determina inpresién por la impresora Anula le aparicién del cursor en Ja pantalla, o Jo reterna, si no aparecia Anula le impresién en Ja pontalle de modo cefini- tivo, haste move puleaeién de Control & Intercambia 1 node mayhaculas-mingseulss Termina 1a introduecién de 1a line actual en el buffer, anulandola FSCAPR. FI siguiente carketer serf interpretado como un atributo. Autoriza impresién en 1a coluona protegida, hasta quo vuelve @ pulsarse otra vez Devuelve el cursor al principio de 1a pantal borrarla DELETE. Anula filtino cordeter introduces de Bepocial interés suelen rovestir en algunas rutinas los vactores relatives @ Jas interrupeiones, 2 saber: 0228 ©0244 ~—sINTFS salta a la rutina de tratamiento de interrupeién por VIA 0222 © 0247-=sNMIJP salta a la rutina do tratamiento de le NNT 0230 © 024A_—sINTSL retorne de 1a rutina de tratamiente de interrapedén uso de nstos vec La xutina de reloj y la que usa 1a tecla FUNCT son ejenple tores, Je queda la posibi~ y en todo caso Cuando uno se cansa de ver sicupre el misuo tipo de letras, lided de redefinir loz caracteres. feta ee una tarea tediosa, Limitada a la mattiz 6x8, que no permite excesivas filigranas. Sin oabéfge, una manera ffeil de canbiar el tipo de letra puede ser 1a ejecu- cién del siguiente programa: Ag TEXT 29 FOR A = #3599 TO #BTFF 3 B= PEEK (A) 49 IF (B AND #38) = #29 THEN POXE A,B OR #19 59 NEXT : PING Recordenos que cuando queramos volver al tipo de letra inicial, nes bactaré hacer CALL #F8D$ (0 bien CALL "F895 en el ORIC~1). Otra difererfcia entre las dos versiones del ORIC es 1a numeracién de las co Jumias de la pantalla de baja resolucién, que empieza en lu segunda columne fen el ORIC-1, y en le primera en el ORIC~Atmos (con lo que llega a 36 en Ie primera versi6n, y a 39 on le segunda). Hay que tenerlo presente al convertir algunos programas en fasie que utilicen grfficos, LA TECLA “FUNCT” Uno de 108 hechos que més comentarios suscité yu desde 1m 1Legada de las pri- meres infornaciones gréficas sobre el nuevo ORIC~Atmor, fue la existencia de una tecla marcada con "FUNCT" en el extremo inferior derecho del teclado, ast como su posible utilidad. La aparicién del manual no aclaré aucho las cosas, pues e:: e1 mismo ni siquie~ ra se cita dicha tecla. {Cul es, pues, su misién? Segin parece, se trata de una tecla de "reserva", prevista por loz constructo~ res para futuras versiones del ORIC que incorporarén este misno teclads, y en la tecla FUNCT tendré un cometido especifico. prevé que detorminados programas de Tansoft la utilicen, asi cono os que e1 misuo usuario pueda preparar, para funciones especiales, general mente desde e1 cédigo maquina, aunque tanbién es accesible desde el Basic. La manera mis simple de detectar la pulsacién de esta tecla es leyendo el con~ tenido de 1a direccién de nenoria 4299. Esta direccién es le que detecta la pulsacién de las teclas CTRL y SHIFT. Mientras ninguna de estas teclas A pulsada, su contenido vale $38, pero durante la pulsacién de una de ellas su contenido se modifica a los valores: = puleande 1a tecle CTRL, ot obtiene ¥A2 = pulsando la tecla SILIFT izquierda — $A4 = puloando 1a teela SiIIPT dorecha wa pulsando 1a nueva tecla FUNCT BAS Bn todos los casos, el valor #38 retorna al dejar de julsar 1a tecla. 19 de destacar el hecho de que ambas teclas “IITFT no cstin interconectadas, sino que corresponden ‘efectivanente a teclas diferenciadas, 1o que puede ser utilizado e las adecuadas rutinas. 4 Une interesante uplivacién de Ie ulilizecién de 1a tecla FUNCT 1 conscituye la rutina que se describe a continuacién. Se trata de une corta (183 bytes) Futina en c6digo wéguina, eeplazada en lex posiciones de menuria desde ¥4y9 hasta $486, que redefine el teclade de modo que cuando 1a tecla FUNCT se nan- tiene pulsada, al pulsar ginulthneanente cualquier otra tecia, aparece direc tamente el nombre completo de una instruccién del Pasic. edie De este modo, el trabajo de copiar largos programas se ve considerablenente simplificado. Para facilitar su utilizacién, las principsles instrucciones han sido asignadas a le inicial correspondiente (por ejemplo: F = FOR, G = GOTO, K = REPEAT, L = LIST, I = INPUT, etc+), © 91 esta se hallaba ya ocupada, @ otra letra caracteristica ( X = EXPLODE, Y = PLAY, 0 = POKR, S = GOSUR, ete-), oa algin signo que sea facilmente recordable (asi, las flechas izquierda y derecha corresponden @ LEFTS y RIGHTS)+ Las teclas conservan 1a facultad de repeticién, y se niegan a continuar cuando liegamos al final de la linea, para evitar la pérdida total de la misma. Lvi- dentenente, si no pulsance FUNCT, el teclado funciona cone de costunbre. Para poder introducir ffcilmente 1a rutina, he preparado un programa cargador dutoverificante en Vlasic, que sirve a esto flu, y on ol wiguente: ®

También podría gustarte