Capítol 5: El sistema operatiu Commodore-64 en llenguatge ensamblador

Capitol 5 El Sistema Operatiu Commodore 64 En Llenguatge Ensamblador



5.1 Introducció

El sistema operatiu de l'ordinador Commodore-64 ve amb l'ordinador en memòria de només lectura (ROM). El nombre d'ubicacions de bytes de memòria per al Commodore-64 oscil·la entre $ 0000 i $ FFFF (és a dir, 000016 a FFFF16, que és de 010 a 65.53510). El sistema operatiu és de $E000 a $FFFF (és a dir, de 57.34410 a 65.53610).

Per què estudiar el sistema operatiu Commodore-64
Per què estudiar el sistema operatiu Commodore-64 avui quan era un sistema operatiu d'un ordinador que es va llançar el 1982? Bé, l'ordinador Commodore-64 utilitza la unitat de processament central 6510, que és una actualització (encara que no és una gran actualització) del 6502 µP.







El 6502 µP encara s'està produint avui en gran nombre; ja no és per a ordinadors domèstics o d'oficina sinó per a aparells (dispositius) elèctrics i electrònics. El 6502 µP també és senzill d'entendre i operar en comparació amb els altres microprocessadors de la seva època. Com a resultat d'aquests, és un dels millors (si no el millor) microprocessador que s'utilitza per ensenyar el llenguatge assemblador.



El 65C02 µP, encara de la classe de microprocessador 6502, té 66 instruccions de llenguatge ensamblador, que fins i tot es poden aprendre de memòria. Els microprocessadors moderns tenen moltes instruccions en llenguatge ensamblador i no es poden aprendre de memòria. Cada µP té el seu propi llenguatge ensamblador. Qualsevol sistema operatiu, ja sigui nou o antic, és de llenguatge assemblador. Amb això, el llenguatge assemblador 6502 és bo per ensenyar el sistema operatiu per a principiants. Després d'aprendre un sistema operatiu, com el del Commodore-64, es pot aprendre fàcilment un sistema operatiu modern utilitzant-lo com a base.



Aquesta no és només l'opinió de l'autor (jo mateix). És una tendència creixent al món. Cada cop s'estan escrivint més articles a Internet per millorar el sistema operatiu Commodore-64 per fer-lo semblar a un sistema operatiu modern. Els sistemes operatius moderns s'expliquen al capítol posterior al següent.





Nota : El sistema operatiu Commodore-64 (Kernal) encara funciona bé amb dispositius d'entrada i sortida moderns (no tots).

Ordinador de vuit bits
En un microordinador de vuit bits com el Commodore 64, la informació s'emmagatzema, es transfereix i es manipula en forma de codis binaris de vuit bits.



Mapa de memòria
Un mapa de memòria és una escala que divideix el rang complet de memòria en rangs més petits de diferents mides i mostra què (subrutina i/o variable) pertany a quin rang. Una variable és una etiqueta que correspon a una adreça de memòria determinada que té un valor. Les etiquetes també s'utilitzen per identificar l'inici de les subrutines. Però en aquest cas, es coneixen com els noms de les subrutines. Una subrutina es pot denominar simplement una rutina.

El mapa de memòria (disposició) del capítol anterior no està prou detallat. És bastant senzill. El mapa de memòria de l'ordinador Commodore-64 es pot mostrar amb tres nivells de detalls. Quan es mostra al nivell intermedi, l'ordinador Commodore-64 té diferents mapes de memòria. El mapa de memòria predeterminat de l'ordinador Commodore-64 al nivell intermedi és:


Fig. 5.11 Mapa de memòria Commodore-64

En aquells dies, hi havia un llenguatge informàtic popular anomenat BASIC. Molts usuaris d'ordinadors necessitaven conèixer algunes ordres mínimes del llenguatge BASIC, com ara carregar un programa des del disquet (disc) a la memòria, executar (executar) un programa a la memòria i sortir (tancar) un programa. Quan el programa BASIC s'està executant, l'usuari ha d'introduir les dades, línia per línia. No és com avui quan una aplicació (una sèrie de programes formen una aplicació) s'escriu en un llenguatge d'alt nivell amb finestres i l'usuari només ha d'encabir les diferents dades en llocs especialitzats d'una finestra. En alguns casos, utilitzem el ratolí per seleccionar les dades preordenades. BASIC era un llenguatge d'alt nivell en aquell moment, però s'acosta força al llenguatge assemblador.

Tingueu en compte que BASIC ocupa la major part de la memòria al mapa de memòria predeterminat. BASIC té ordres (instruccions) que s'executen pel que es coneix com a intèrpret BASIC. De fet, l'intèrpret BASIC es troba a la ROM des de la ubicació $A000 fins a $BFFF (inclòs), que suposadament és una àrea RAM. Això és 8 Kbytes és bastant gran en aquell moment! En realitat es troba a la ROM en aquest lloc de tota la memòria. Té la mateixa mida que el sistema operatiu des de $E000 fins a $FFFF (inclosos). Els programes escrits en BASIC també es col·loquen entre $0200 i $BFFF.

La memòria RAM del programa de llenguatge ensamblador d'usuari és de $C000 a $CFFF, només 4 Kbytes de 64 Kbytes. Aleshores, per què utilitzem o aprenem el llenguatge ensamblador? Els sistemes operatius nous i antics són de llenguatges assemblador. El sistema operatiu del Commodore-64 està en ROM, des de $E000 fins a $FFFF. Està escrit en el llenguatge assemblador 65C02 µP (6510 µP). Consta de subrutines. El programa d'usuari en llenguatge ensamblador necessita cridar aquestes subrutines per poder interactuar amb els perifèrics (dispositius d'entrada i sortida). La comprensió del sistema operatiu Commodore-64 en llenguatge assemblador permet a l'estudiant entendre els sistemes operatius ràpidament, d'una manera molt menys tediosa. De nou, en aquells dies, molts programes d'usuari per al Commodore-64 estaven escrits en BASIC i no en llenguatge assemblador. Els llenguatges de muntatge en aquells dies eren més utilitzats pels mateixos programadors amb finalitats tècniques.

El Kernal, escrit com a K-e-r-n-a-l, és el sistema operatiu del Commodore-64. Ve amb l'ordinador Commodore-64 en ROM i no en disc (o disquet). El Kernal consta de subrutines. Per accedir als perifèrics, el programa d'usuari en llenguatge assemblador (llenguatge màquina) ha d'utilitzar aquestes subrutines. El nucli no s'ha de confondre amb el nucli que s'escriu com a K-e-r-n-e-l dels sistemes operatius moderns, tot i que són gairebé la mateixa cosa.

L'àrea de memòria des de $C000 (49,15210) fins a $CFFF (6324810) de 4 Kbytes10 de memòria és RAM o ROM. Quan és RAM, s'utilitza per accedir als perifèrics. Quan és ROM, s'utilitza per imprimir els caràcters a la pantalla (monitor). Això vol dir que els caràcters s'estan imprimint a la pantalla o s'accedeix als perifèrics mitjançant l'ús d'aquesta part de la memòria. Hi ha un banc de ROM (ROM de caràcters) a la unitat del sistema (placa base) que s'activa i surt de tot l'espai de memòria per aconseguir-ho. És possible que l'usuari no noti el canvi.

L'àrea de memòria des de $ 0100 (256 10 ) fins a $01FF (511 10 ) és la pila. L'utilitzen tant el sistema operatiu com els programes d'usuari. El paper de la pila es va explicar al capítol anterior d'aquest curs de carrera en línia. L'àrea de la memòria des de $ 0000 (0 10 ) fins a $00FF (255 10 ) és utilitzat pel sistema operatiu. S'hi assignen molts punters.

Taula de salt del nucli
Kernal té rutines que són cridades pel programa d'usuari. A mesura que van sortir noves versions del sistema operatiu, les adreces d'aquestes rutines van canviar. Això vol dir que els programes d'usuari ja no podrien funcionar amb les noves versions del sistema operatiu. Això no va passar perquè el Commodore-64 va proporcionar una taula de salt. La taula de salts és una llista de 39 entrades. Cada entrada de la taula té tres adreces (excepte els darrers 6 bytes) que mai van canviar fins i tot amb el canvi de versió del sistema operatiu.

La primera adreça d'una entrada té una instrucció JSR. Les dues adreces següents consisteixen en un punter de dos bytes. Aquest punter de dos bytes és l'adreça (o adreça nova) d'una rutina real que encara es troba a la ROM del sistema operatiu. El contingut del punter podria canviar amb les noves versions del sistema operatiu, però les tres adreces per a cada entrada de taula de salt no canvien mai. Per exemple, considereu les adreces $FF81, $FF82 i $FF83. Aquestes tres adreces són per a la rutina per inicialitzar els circuits de pantalla i teclat (registres) de la placa base. L'adreça $FF81 sempre té el codi operatiu (un byte) de JSR. Les adreces $FF82 i $FF83 tenen l'adreça antiga o nova de la subrutina (encara a la ROM del sistema operatiu) per fer la inicialització. En un moment, les adreces $FF82 i $FF83 tenien el contingut (adreça) de $FF5B que podria canviar amb la següent versió del sistema operatiu. Tanmateix, les adreces $FF81, $FF82 i $FF83 de la taula de salt mai canvien.

Per a cada entrada de tres adreces, la primera adreça amb JSR té una etiqueta (nom). L'etiqueta de $FF81 és PCINT. PCINT no canvia mai. Per tant, per inicialitzar els registres de pantalla i teclat, el programador només pot escriure 'JSR PCINT' que funciona per a totes les versions del sistema operatiu Commodore-64. La ubicació (adreça d'inici) de la subrutina real, per exemple, $FF5B, podria canviar amb el temps amb diferents sistemes operatius. Sí, hi ha almenys dues instruccions JSR implicades en el programa d'usuari que utilitza el sistema operatiu ROM. Al programa d'usuari, hi ha una instrucció JSR que salta a una entrada a la taula de salts. Amb l'excepció de les últimes sis adreces de la taula de salt, la primera adreça d'una entrada de la taula de salt té una instrucció JSR. Al Kernal, algunes subrutines poden cridar a les altres subrutines.

La taula de salt del nucli comença des de $FF81 (inclosos) pujant en grups de tres, excepte els darrers sis bytes que són tres punters amb adreces de bytes més baixes: $FFFA, $FFFC i $FFFE. Totes les rutines del sistema operatiu ROM són codis reutilitzables. Per tant, l'usuari no ha de reescriure-les.

Diagrama de blocs de la unitat del sistema Commodore-64
El diagrama següent és més detallat que el del capítol anterior:


Fig. 5.12 Diagrama de blocs de la unitat del sistema Commodore_64

La ROM i la RAM es mostren com un bloc aquí. Aquí es mostra el xip d'interfície de vídeo (IC) per gestionar la informació a la pantalla, que no es mostrava al capítol anterior. El bloc únic per a dispositius d'entrada/sortida, que es mostra al capítol anterior, es mostra aquí com a dos blocs: CIA #1 i CIA #2. CIA són les sigles de Complex Interface Adapter. Cadascun té dos ports paral·lels de vuit bits (que no s'han de confondre amb els ports externs d'una superfície vertical de la unitat del sistema) anomenats port A i port B. En aquesta situació, els CIA estan connectats a cinc dispositius externs. Els dispositius són el teclat, el joystick, la unitat de disc/impressora i un mòdem. La impressora està connectada a la part posterior de la unitat de disc. També hi ha un circuit de dispositiu d'interfície de so i un circuit de matriu lògica programable que no es mostren.

Tot i així, hi ha una ROM de caràcters que es pot intercanviar amb les dues CIA quan s'envia un personatge a la pantalla i no es mostra al diagrama de blocs.

Les adreces RAM de $D000 a $DFFF per a circuits d'entrada/sortida en absència de caràcters ROM tenen el següent mapa de memòria detallat:

Taula 5.11
Mapa de memòria detallat de $D000 a $DFFF
Interval de subadreces Circuit Mida (bytes)
D000 – D3FF VIC (controlador d'interfície de vídeo (xip)) 1K
D400 - D7FF SID (circuit de so) 1K
D800 – DBFF RAM de color 1K Nibbles
DC00 – DCFF CIA #1 (teclat, joystick) 256
DD00 – DDFF CIA #2 (bus sèrie, port d'usuari/RS-232) 256
DE00 – DEF Obriu la ranura d'E/S #1 256
DF00 – DFFF Obriu la ranura d'E/S #2 256

5.2 Els dos adaptadors d'interfície complexos

Hi ha dos circuits integrats (CI) concrets a la unitat del sistema Commodore-64, i cadascun d'ells s'anomena adaptador d'interfície complexa. Aquests dos xips s'utilitzen per connectar el teclat i altres perifèrics amb el microprocessador. Amb l'excepció del VIC i la pantalla, tots els senyals d'entrada/sortida entre el microprocessador i els perifèrics passen per aquests dos CI. Amb el Commodore-64, no hi ha comunicació directa entre la memòria i cap perifèric. La comunicació entre la memòria i qualsevol perifèric passa per l'acumulador del microprocessador, i un d'aquests són els adaptadors CIA (IC). Els IC s'anomenen CIA #1 i CIA #2. CIA són les sigles de Complex Interface Adapter.

Cada CIA té 16 registres. Amb l'excepció dels registres de temporitzador/comptador de la CIA, cada registre té 8 bits d'ample i té una adreça de memòria. Les adreces de registre de memòria per a CIA #1 són de $DC00 (56320 10 ) a $DC0F (56335 10 ). Les adreces de registre de memòria per a CIA #2 són de $DD00 (56576 10 ) a $DD0F (56591 10 ). Tot i que aquests registres no es troben a la memòria dels CI, formen part de la memòria. Al mapa de memòria intermèdia, l'àrea d'E/S de $D000 a $DFFF inclou les adreces CIA de $DC00 a $DC0F i de $DD00 a $DD0F. La major part de l'àrea de memòria RAM d'E/S de $D000 a $DFFF es pot intercanviar amb el banc de memòria de la ROM de caràcters per a caràcters de pantalla. És per això que quan els personatges s'envien a la pantalla, els perifèrics no poden funcionar; tot i que és possible que l'usuari no ho noti ja que l'intercanvi d'anada i tornada és ràpid.

Hi ha dos registres a la CIA #1 anomenats Port A i Port B. Les seves adreces són $DC00 i $DC01, respectivament. També hi ha dos registres a la CIA #2 anomenats Port A i Port B. Per descomptat, les seves adreces són diferents; són $DD00 i $DD01, respectivament.

El port A o el port B de qualsevol CIA és un port paral·lel. Això significa que pot enviar les dades al perifèric en vuit bits alhora o rebre les dades del microprocessador en vuit bits alhora.

Associat al port A o al port B hi ha un registre de direcció de dades (DDR). El registre de direcció de dades per al port A de CIA #1 (DDRA1) es troba a la ubicació del byte de memòria de $DC02. El registre de direcció de dades per al port B de CIA #1 (DDRB1) es troba a la ubicació del byte de memòria de $DC03. El registre de direcció de dades per al port A de CIA #2 (DDRA2) es troba a la ubicació del byte de memòria de $DD02. El registre de direcció de dades per al port B de CIA #2 (DDRB2) es troba a la ubicació del byte de memòria de $DD03.

Ara, cada bit del port A o del port B es pot establir mitjançant el registre de direcció de dades corresponent perquè sigui l'entrada o la sortida. L'entrada significa que la informació va des del perifèric al microprocessador a través d'una CIA. La sortida significa que la informació va des del microprocessador al perifèric a través d'una CIA.

Si s'ha d'introduir una cel·la d'un port (registre), el bit corresponent al registre de direcció de dades és 0. Si s'ha de sortir una cel·la d'un port (registre), el bit corresponent al registre de direcció de dades és 1. En la majoria dels casos, tots els 8 bits d'un port estan programats per ser d'entrada o de sortida. Quan l'ordinador està encès, el port A es programa per a la sortida i el port B per a l'entrada. El codi següent fa que el port CIA #1 A com a sortida i el port CIA #1 B com a entrada:

LDA #$FF
STA DDRA1 ; $DC00 està dirigit per $DC02
LDA #$00
STA DDRB1 ; $DC01 està dirigit per $DC03

DDRA1 és l'etiqueta (nom de la variable) per a la ubicació dels bytes de memòria de $DC02 i DDRB1 és l'etiqueta (nom de la variable) per a la ubicació dels bytes de memòria de $DC03. La primera instrucció carrega 11111111 a l'acumulador de µP. La segona instrucció copia això al registre de direcció de dades del port A de la CIA núm. 1. La tercera instrucció carrega 00000000 a l'acumulador de µP. La quarta instrucció copia això al registre de direcció de dades del port B de la CIA núm. 1. Aquest codi es troba en una de les subrutines del sistema operatiu que fa aquesta inicialització a l'encesa de l'ordinador.

Cada CIA té una línia de sol·licitud de servei d'interrupció al microprocessador. El de la CIA #1 va al IRQ pin del µP. El de la CIA #2 va al NMI pin del µP. Recorda que NMI té una prioritat més alta que IRQ .

5.3 Programació en llenguatge ensamblador del teclat

Només hi ha tres interrupcions possibles per al Commodore-64: IRQ , BRK i NMI . El punter de la taula de salt per IRQ es troba a les adreces $FFFE i $FFFF de la ROM (sistema operatiu) que correspon a una subrutina encara al sistema operatiu (ROM). El punter de la taula de salt per a BRK es troba a les adreces $FFFC i $FFFD del sistema operatiu que correspon a una subrutina encara al sistema operatiu (ROM). El punter de la taula de salt per NMI es troba a les adreces $FFFA i $FFFB del sistema operatiu que correspon a una subrutina encara al sistema operatiu (ROM). Per al IRQ , en realitat hi ha dues subrutines. Per tant, la interrupció de programari BRK (instrucció) té el seu propi punter de taula de salt. El punter de la taula de salt per IRQ condueix al codi que decideix si s'activa la interrupció de maquinari o la interrupció de programari. Si és la interrupció de maquinari, la rutina per IRQ es diu. Si és la interrupció de programari (BRK), es crida la rutina per a BRK. En una de les versions del sistema operatiu, la subrutina per IRQ està a $EA31 i la subrutina per a BRK és a $FE66. Aquestes adreces estan per sota de $FF81, de manera que no són entrades de taula de salt i podrien canviar amb la versió del sistema operatiu. Hi ha tres rutines d'interès en aquest tema: la que comprova si es prem una tecla o un BRK, la que està a $FE43, i la que també pot canviar amb la versió del SO.

L'ordinador Commodore-64 és com una màquina d'escriure enorme (cap amunt) en aparença sense la secció d'impressió (capçal i paper). El teclat està connectat a la CIA #1. El CIA #1 escaneja el teclat cada 1/60 de segon pel seu compte sense cap interferència de programació, per defecte. Així, cada 1/60 de segon, la CIA #1 envia un IRQ al µP. Només n'hi ha un IRQ pin al µP que només prové de la CIA #1. L'únic pin d'entrada de NMI del µP, que és diferent de IRQ , prové només de la CIA #2 (consulteu la il·lustració següent). BRK és en realitat una instrucció de llenguatge ensamblador que es codifica en un programa d'usuari.

Així, cada 1/60 de segon, el IRQ s'anomena la rutina a la qual apunten $FFFE i $FFFF. La rutina comprova si es prem una tecla o es troba la instrucció BRK. Si es prem una tecla, s'anomena la rutina per gestionar la premsa de tecla. Si és una instrucció BRK, s'anomena la rutina per gestionar BRK. Si no és cap, no passa res. Cap dels dos pot passar, però la CIA #1 envia IRQ al µP cada 1/60 de segon.

La cua del teclat, també coneguda com a memòria intermèdia del teclat, és un rang d'ubicacions de bytes de RAM des de $ 0277 fins a $ 0280, ambdós inclosos; 1010 bytes en total. Aquest és un buffer First-in-First-Out. Això vol dir que el primer personatge que arriba és el primer que marxa. Un caràcter d'Europa occidental ocupa un byte.

Així, mentre que el programa no consumeix cap caràcter quan es prem una tecla, el codi de la tecla entra a aquesta memòria intermèdia (cua). La memòria intermèdia es continua omplint fins que hi hagi deu caràcters. No es registra cap caràcter que es preme després del desè caràcter. S'ignora fins que s'obté (consumeix) almenys un caràcter de la cua. La taula de salt té una entrada per a una subrutina que obté el primer caràcter de la cua al microprocessador. Això vol dir que pren el primer caràcter que entra a la cua i el posa a l'acumulador de µP. La subrutina de la taula de salt per fer-ho s'anomena GETIN (per a Get-In). El primer byte per a l'entrada de tres bytes a la taula de salt s'etiqueta com a GETIN (adreça $FFE4). Els dos bytes següents són el punter (adreça) que apunta a la rutina real a la ROM (SO). És responsabilitat del programador anomenar aquesta rutina. En cas contrari, la memòria intermèdia del teclat romandrà plena i totes les tecles premudes recentment seran ignorades. El valor que entra a l'acumulador és el valor ASCII de la clau corresponent.

Com entren els codis clau a la cua en primer lloc? Hi ha una rutina de taula de salt anomenada SCNCKEY (per a la clau d'exploració). Aquesta rutina es pot cridar tant per programari com per maquinari. En aquest cas, s'anomena per un circuit electrònic (físic) del microprocessador quan el senyal elèctric IRQ és baixa. Com es fa exactament això no s'aborda en aquest curs de carrera en línia.

El codi per obtenir el primer codi de tecla de la memòria intermèdia del teclat a l'acumulador A és només una línia:

GETIN

Si la memòria intermèdia del teclat està buida, es col·loca $00 a l'acumulador. Recordeu que el codi ASCII de zero no és $00; és de $30. $00 significa nul. En un programa, pot haver-hi un punt en què el programa hagi d'esperar que premeu una tecla. El codi per a això és:

ESPEREU JSR GETIN
CMP #$00
ESPERA LA GRANOTA

A la primera línia, 'WAIT' és una etiqueta que identifica l'adreça RAM on es posa (escriu) la instrucció JSR. GETIN també és una adreça. És l'adreça del primer dels tres bytes corresponents de la taula de salt. L'entrada GETIN, així com totes les entrades de la taula de salt (excepte les tres darreres), consta de tres bytes. El primer byte de l'entrada és la instrucció JSR. Els dos bytes següents són l'adreça del cos de la subrutina GETIN real que encara es troba a la ROM (SO) però per sota de la taula de salt. Per tant, l'entrada diu saltar a la subrutina GETIN. Si la cua del teclat no està buida, GETIN posa el codi de clau ASCII de la cua First-In-First-Out a l'acumulador. Si la cua està buida, es col·loca Null ($00) a l'acumulador.

La segona instrucció compara el valor de l'acumulador amb $00. Si és $00, vol dir que la cua del teclat està buida i la instrucció CMP envia 1 a la marca Z del registre d'estat del processador (simplement anomenat registre d'estat). Si el valor d'A no és $00, la instrucció CMP envia 0 a la marca Z del registre d'estat.

La tercera instrucció que és 'BEQ WAIT' envia el programa de nou a la primera instrucció si la bandera Z del registre d'estat és 1. La primera, segona i tercera instruccions s'executen repetidament en ordre fins que es prem una tecla del teclat. . Si mai es prem una tecla, el cicle es repeteix indefinidament. Normalment, un segment de codi com aquest s'escriu amb un segment de codi de temporització que surt del bucle després d'un temps si mai no es prem una tecla (consulteu la discussió següent).

Nota : El teclat és el dispositiu d'entrada predeterminat i la pantalla és el dispositiu de sortida predeterminat.

5.4 Canal, número de dispositiu i número de fitxer lògic

Els perifèrics que fa servir aquest capítol per explicar el sistema operatiu Commodore-64 són el teclat, la pantalla (monitor), la unitat de disc amb disquet, la impressora i el mòdem que es connecta a través de la interfície RS-232C. Perquè la comunicació es produeixi entre aquests dispositius i la unitat del sistema (microprocessador i memòria), s'ha d'establir un canal.

Un canal consta d'una memòria intermèdia, un número de dispositiu, un número de fitxer lògic i, opcionalment, una adreça secundària. L'explicació d'aquests termes és la següent:

Un buffer
Observeu de l'apartat anterior que quan es prem una tecla, el seu codi ha d'anar a una ubicació de bytes a la RAM d'una sèrie de deu ubicacions consecutives. Aquesta sèrie de deu ubicacions és la memòria intermèdia del teclat. Cada dispositiu d'entrada o sortida (perifèric) té una sèrie d'ubicacions consecutives a la memòria RAM anomenada memòria intermèdia.

Número de dispositiu
Amb el Commodore-64, qualsevol perifèric es dóna amb un número de dispositiu. La taula següent mostra els diferents dispositius i els seus números:

Taula 5.41
Números de dispositiu Commodore 64 i els seus dispositius
Número Dispositiu
0 Teclat
1 Unitat de cinta
2 Interfície RS 232C per, per exemple, un mòdem
3 Pantalla
4 Impressora #1
5 Impressora #2
6 Traçador #1
7 Traçador #2
8 Unitat de disc
9
¦
¦
¦
30
Des de 8 (inclosos) fins a 22 dispositius d'emmagatzematge més

Hi ha dos tipus de ports per a un ordinador. Un tipus és extern, a la superfície vertical de la unitat del sistema. L'altre tipus és intern. Aquest port intern és un registre. Commodore-64 té quatre ports interns: port A i port B per a CIA 1 i port A i port B per a CIA 2. Hi ha un port extern per al Commodore-64 que s'anomena port sèrie. Els dispositius amb el número 3 cap amunt estan connectats al port sèrie. Estan connectats en cadena (un que està connectat darrere de l'altre), cadascun dels quals és identificable pel seu número de dispositiu. Els dispositius amb el número 8 cap amunt són generalment els dispositius d'emmagatzematge.

Nota : el dispositiu d'entrada predeterminat és el teclat amb el número de dispositiu 0. El dispositiu de sortida predeterminat és la pantalla amb el número de dispositiu 3.

Número de fitxer lògic
Un número de fitxer lògic és un número donat per a un dispositiu (perifèric) en l'ordre en què s'obren per accedir-hi. Van de 010 a 255 10 .

Adreça secundària
Imagineu que dos fitxers (o més d'un fitxer) s'obren al disc. Per diferenciar aquests dos fitxers, s'utilitzen les adreces secundàries. Les adreces secundàries són números que varien d'un dispositiu a un altre. El significat de 3 com a adreça secundària per a una impressora és diferent del significat de 3 com a adreça secundària per a una unitat de disc. El significat depèn de característiques com quan s'obre un fitxer per llegir-lo o quan s'obre un fitxer per escriure. Els possibles nombres secundaris són de 0 10 a 15 10 per a cada dispositiu. Per a molts dispositius, el número 15 s'utilitza per enviar ordres.

Nota : el número del dispositiu també es coneix com a adreça del dispositiu i el número secundari també es coneix com a adreça secundària.

Identificació d'un objectiu perifèric
Per al mapa de memòria Commodore predeterminat, les adreces de memòria de $ 0200 a $ 02FF (pàgina 2) són utilitzades únicament pel sistema operatiu en ROM (Kernal) i no pel sistema operatiu més el llenguatge BASIC. Tot i que BASIC encara pot utilitzar les ubicacions mitjançant el sistema operatiu ROM.

El mòdem i la impressora són dos objectius perifèrics diferents. Si s'obren dos fitxers des del disc, són dos objectius diferents. Amb el mapa de memòria predeterminat, hi ha tres taules consecutives (llistes) que es poden veure com una taula gran. Aquestes tres taules contenen la relació entre els números de fitxer lògic, els números de dispositiu i les adreces secundàries. Amb això, un canal específic o un objectiu d'entrada/sortida esdevé identificable. Les tres taules s'anomenen taules de fitxers. Les adreces de RAM i què tenen són:

$0259 — $0262: Taula amb etiqueta, LAT, de fins a deu números de fitxer lògics actius.
$0263 — $026C: Taula amb etiqueta, FAT, de fins a deu números de dispositiu corresponents.
$026D — $0276: Taula amb etiqueta, SAT, de deu adreces secundàries corresponents.

Aquí, '—' significa 'a', i un número pren un byte.

El lector pot preguntar: 'Per què no s'inclou la memòria intermèdia de cada dispositiu per identificar un canal?' Bé, la resposta és que amb el commodore-64, cada dispositiu extern (perifèric) té una sèrie fixa de bytes a la memòria RAM (mapa de memòria). Sense cap canal obert, les seves posicions encara hi són dins de la memòria. La memòria intermèdia per al teclat, per exemple, es fixen de $ 0277 a $ 0280 (inclosos) per al mapa de memòria predeterminat.

Les subrutines Kernal SETLFS i SETNAM
SETLFS i SETNAM són rutines Kernal. Un canal es pot veure com un fitxer lògic. Perquè s'obri un canal, s'han de produir el número de fitxer lògic, el número de dispositiu i una adreça secundària opcional. També pot ser necessari un nom de fitxer opcional (text). La rutina SETLFS configura el número de fitxer lògic, el número de dispositiu i una adreça secundària opcional. Aquests números es posen a les seves respectives taules. La rutina SETNAM estableix un nom de cadena per al fitxer que pot ser obligatori per a un canal i opcional per a un altre canal. Consisteix en un punter (adreça de dos bytes) a la memòria. El punter apunta al començament de la cadena (nom) que pot estar en un altre lloc de la memòria. El nom de la cadena comença amb un byte que té la longitud de la cadena, seguit del text (nom). El nom té un màxim de setze bytes (longitud).

Per trucar a la rutina SETLFS, el programa d'usuari ha de saltar (JSR) a l'adreça $FFBA de la taula de salt del sistema operatiu a la ROM per al mapa de memòria predeterminat. Recordeu que, a excepció dels darrers sis bytes de la taula de salt, cada entrada consta de tres bytes. El primer byte és la instrucció JSR, que després salta a la subrutina, comença a l'adreça dels dos bytes següents. Per trucar a la rutina SETNAM, el programa d'usuari ha de saltar (JSR) a l'adreça $FFBD de la taula de salt del sistema operatiu a la ROM. L'ús d'aquestes dues rutines es mostra a la discussió següent.

5.5 Obrir un canal, obrir un fitxer lògic, tancar un fitxer lògic i tancar tots els canals d'E/S

Un canal consta d'un buffer de memòria, un número de fitxer lògic, un número de dispositiu (adreça del dispositiu) i una adreça secundària opcional (un número). Un fitxer lògic (una abstracció) que s'identifica amb un número de fitxer lògic pot referir-se a un perifèric com una impressora, un mòdem, una unitat de disc, etc. Cadascun d'aquests diferents dispositius hauria de tenir números de fitxer lògics diferents. Hi ha molts fitxers al disc. Un fitxer lògic també pot fer referència a un fitxer concret del disc. Aquest fitxer en particular també té un número de fitxer lògic que és diferent dels dels perifèrics com ara la impressora o el mòdem. El programador dóna el número de fitxer lògic. Pot ser qualsevol nombre des del 010 ($00) fins al 25510 ($FF).

La rutina OS SETLFS
La rutina OS SETLFS a la qual s'accedeix saltant (JSR) a la taula de salt de la ROM del sistema operatiu a $FFBA configura el canal. Ha de posar el número de fitxer lògic a la taula de fitxers que és LAT ($0259 — $0262). Ha de posar el número de dispositiu corresponent a la taula de fitxers que és FAT ($0263 — $026C). Si l'accés al fitxer (dispositiu) necessita un número secundari, cal posar l'adreça secundària corresponent (número) a la taula de fitxers que és SAT ($026D — $0276).

Per funcionar, la subrutina SETLFS necessita obtenir el número de fitxer lògic de l'acumulador µP; necessita obtenir el número de dispositiu del registre µP X. Si ho necessita el canal, ha d'obtenir l'adreça secundària del registre µP Y.

El programador decideix el número de fitxer lògic. Els números de fitxer lògics que fan referència a diferents dispositius són diferents. Ara, abans de trucar a la rutina SETLFS, el programador hauria de posar el número del fitxer lògic a l'acumulador µP. El número de dispositiu es llegeix des d'una taula (document) com a la taula 5.41. El programador també hauria de posar el número de dispositiu al registre µP X. El proveïdor d'un dispositiu com ara una impressora, una unitat de disc, etc. proporciona les possibles adreces secundàries i els seus significats per al dispositiu. Si el canal necessita una adreça secundària, el programador l'ha d'obtenir del document que es subministra amb el dispositiu (perifèric). Si l'adreça secundària (número) és necessària, el programador l'ha de posar al registre µP Y abans de trucar a la subrutina SETLFS. Si no hi ha necessitat d'una adreça secundària, el programador ha de posar el número $FF al registre µP Y abans de trucar a la subrutina SETLFS.

La subrutina SETLFS es crida sense cap argument. Els seus arguments ja es troben als tres registres del 6502 µP. Després de posar els números adequats als registres, la rutina es crida al programa simplement amb el següent en una línia separada:

JSR CONJUNTS

La rutina posa els diferents números adequadament a les seves taules de fitxers.

La rutina OS SETNAM
S'accedeix a la rutina OS SETNAM fent un salt (JSR) a la taula de salt de la ROM del sistema operatiu a $FFBD. No totes les destinacions tenen noms de fitxer. Per a aquells que tenen destinacions (com els fitxers del disc), s'hauria de configurar el nom del fitxer. Suposem que el nom del fitxer és 'mydocum' que consta de 7 bytes sense cometes. Suposem que aquest nom es troba a les ubicacions de $C101 a $C107 (inclosos) i la longitud de $07 és a la ubicació de $C100. L'adreça inicial dels caràcters de cadena és $C101. El byte inferior de l'adreça inicial és $01 i el byte superior és $C1.

Abans de trucar a la rutina SETNAM, el programador ha de posar el número $07 (longitud de la cadena) a l'acumulador µP. El byte inferior de l'adreça inicial de la cadena de $01 es posa al registre µP X. El byte més alt de l'adreça inicial de la cadena de $C1 es posa al registre µP Y. La subrutina s'anomena simplement amb el següent:

JSR SETNAM

La rutina SETNAM associa els valors dels tres registres amb el canal. Els valors no cal que romanguin als registres després d'això. Si el canal no necessita un nom de fitxer, el programador ha de posar $00 a l'acumulador µP. En aquest cas, s'ignoren els valors que es troben als registres X i Y.

La rutina OS OPEN
S'accedeix a la rutina OS OPEN saltant (JSR) a la taula de salt de la ROM del sistema operatiu a $FFC0. Aquesta rutina utilitza el número de fitxer lògic, el número de dispositiu (i la memòria intermèdia), una possible adreça secundària i un possible nom de fitxer, per proporcionar una connexió entre l'ordinador Commodore i el fitxer del dispositiu extern o el propi dispositiu extern.

Aquesta rutina, com totes les altres rutines Commodore OS ROM, no té cap argument. Tot i que utilitza els registres µP, cap dels registres s'havia de carregar prèviament amb arguments (valors) per a això. Per codificar-lo, només cal que escriviu el següent després de cridar a SETLFS i SETNAM:

JSR OBERT

Es poden produir errors amb la rutina OPEN. Per exemple, és possible que no es trobi el fitxer per llegir-lo. Quan es produeix un error, la rutina falla i posa el número d'error corresponent a l'acumulador µP i estableix la bandera de transport (a 1) del registre d'estat µP. La taula següent proporciona els números d'error i el seu significat:

Taula 5.51
Números d'error del nucli i els seus significats per a la rutina OPEN ROM OS
Número d'error Descripció Exemple
1 MOLTS FITXES OBRIR quan ja s'obren deu fitxers
2 FITXER OBERT OBERT 1,3: OBERT 1,4
3 FITXER NO OBERT IMPRIMIR#5 sense OBRIR
4 ARXIU NO TROBAT CÀRREGA “NONEXISTENF”,8
5 DISPOSITIU NO PRESENT OBERT 11,11: IMPRIMIR#11
6 NO ENTRAR FITXER OBRE 'SEQ,S,W': GET#8,X$
7 NO SORTIR FITXER OBRIR 1,0: IMPRIMIR#1
8 FALTA NOM DE FITXER CÀRREGA “”,8
9 ILLEGAL DEVICE NO. CARREGAR “PROGRAMA”,3

Aquesta taula es presenta d'una manera que és probable que el lector vegi en molts altres llocs.

La rutina OS CHKIN
S'accedeix a la rutina OS CHKIN fent un salt (JSR) a la taula de salt de la ROM del sistema operatiu a $FFC6. Després d'obrir un fitxer (fitxer lògic), s'ha de decidir si l'obertura és d'entrada o sortida. La rutina CHKIN fa que l'obertura sigui un canal d'entrada. Aquesta rutina ha de llegir el número de fitxer lògic del registre µP X. Per tant, el programador ha de posar el número de fitxer lògic al registre X abans de trucar a aquesta rutina. S'anomena simplement com:

JSR CHKIN

La rutina OS CHKOUT
S'accedeix a la rutina OS CHKOUT saltant (JSR) a la taula de salt de la ROM del sistema operatiu a $FFC9. Després d'obrir un fitxer (fitxer lògic), s'ha de decidir si l'obertura és d'entrada o sortida. La rutina CHKOUT fa que l'obertura sigui un canal de sortida. Aquesta rutina ha de llegir el número de fitxer lògic del registre µP X. Per tant, el programador ha de posar el número de fitxer lògic al registre X abans de trucar a aquesta rutina. S'anomena simplement com:

JSR CHKOUT

La rutina OS CLOSE
S'accedeix a la rutina OS CLOSE fent un salt (JSR) a la taula de salt de la ROM del sistema operatiu a $FFC3. Després d'obrir un fitxer lògic i transmetre els bytes, el fitxer lògic s'ha de tancar. Tancar el fitxer lògic allibera la memòria intermèdia de la unitat del sistema perquè l'utilitzi algun altre fitxer lògic que encara s'ha d'obrir. També s'eliminen els paràmetres corresponents a les tres taules de fitxers. La ubicació de la RAM per al nombre de fitxers oberts es redueix en 1.

Quan l'ordinador està encès, hi ha un restabliment de maquinari per al microprocessador i altres xips principals (circuits integrats) a la placa base. Això és seguit per la inicialització d'algunes ubicacions de memòria RAM i alguns registres en alguns xips de la placa base. En el procés d'inicialització, la ubicació de la memòria de bytes de l'adreça $0098 a la pàgina zero es dóna amb l'etiqueta NFILES o LDTND, depenent de la versió del sistema operatiu. Mentre l'ordinador està funcionant, aquesta ubicació d'un byte de 8 bits conté el nombre de fitxers lògics que s'obren i l'índex d'adreces inicials de les tres taules de fitxers consecutives. En altres paraules, aquest byte té el nombre de fitxers oberts que es disminueix en 1 quan es tanca el fitxer lògic. Quan es tanca el fitxer lògic, l'accés al dispositiu terminal (destinació) o al fitxer real del disc ja no és possible.

Per tancar un fitxer lògic, el programador ha de posar el número de fitxer lògic a l'acumulador µP. Aquest és el mateix número de fitxer lògic que s'utilitza per obrir el fitxer. La rutina CLOSE ho necessita per tancar aquest fitxer en particular. Igual que altres rutines ROM del sistema operatiu, la rutina CLOSE no pren un argument, encara que el valor que s'utilitza des de l'acumulador és una mica un argument. La línia d'instrucció del llenguatge ensamblador és simplement:

JSR TANCAR

Les subrutines (rutines) del llenguatge assemblador 6502 personalitzades o predefinides no prenen arguments. Tanmateix, els arguments vénen de manera informal posant els valors que utilitzarà la subrutina als registres del microprocessador.

La rutina CLRCHN
S'accedeix a la rutina OS CLRCHN fent un salt (JSR) a la taula de salt de la ROM del sistema operatiu a $FFCC. CLRCHN significa CLeaR Channel. Quan es tanca un fitxer lògic, se suprimeixen els seus paràmetres de número de fitxer lògic, número de dispositiu i possible adreça secundària. Per tant, s'esborra el canal del fitxer lògic.

El manual diu que la rutina OS CLRCHN esborra tots els canals oberts i restaura els números de dispositiu predeterminats i altres valors predeterminats. Això vol dir que es pot canviar el número de dispositiu d'un perifèric? Bé, no del tot. Durant la inicialització del sistema operatiu, la ubicació del byte de l'adreça $0099 s'indica amb l'etiqueta DFLTI per contenir el número de dispositiu d'entrada actual quan l'ordinador està funcionant. El commodore-64 només pot accedir a un perifèric alhora. Durant la inicialització del sistema operatiu, la ubicació del byte de l'adreça $009A es dóna amb l'etiqueta DFLTO per contenir el número de dispositiu de sortida actual quan l'ordinador està funcionant.

Quan es crida a la subrutina CLRCHN, estableix la variable DFLTI a 0 ($00), que és el número de dispositiu d'entrada predeterminat (teclat). Estableix la variable DFLTO a 3 ($03), que és el número de dispositiu de sortida predeterminat (pantalla). Altres variables del número de dispositiu es restableixen de la mateixa manera. Aquest és el significat de restablir (o restaurar) els dispositius d'entrada/sortida a la normalitat (valors per defecte).

El manual del Commodore-64 diu que després de cridar la rutina CLRCHN, els fitxers lògics oberts romanen oberts i encara podrien transmetre els bytes (dades). Això vol dir que la rutina CLRCHN no elimina les entrades corresponents a les taules de fitxers. El nom CLRCHN és força ambigu pel seu significat.

5.6 Enviament del personatge a la pantalla

El circuit integrat principal (IC) per gestionar la visualització de caràcters i gràfics a la pantalla s'anomena Video Interface Controller (xip) que s'abreuja com VIC al Commodore-64 (en realitat VIC II per a VIC versió 2). Perquè una informació (valors) vagi a la pantalla, ha de passar per VIC II abans d'arribar a la pantalla.

La pantalla consta de 25 files i 40 columnes de cel·les de caràcters. Això fa 40 x 25 = 1000 caràcters que es poden mostrar a la pantalla. El VIC II llegeix les corresponents ubicacions de bytes consecutives de memòria RAM de 1000 per als caràcters. Aquestes 1000 ubicacions juntes es coneix com a memòria de pantalla. El que entra en aquestes 1000 ubicacions són els codis de caràcters. Per al Commodore-64, els codis de caràcters són diferents dels codis ASCII.

Un codi de caràcters no és un patró de caràcters. També hi ha el que es coneix com a ROM de caràcters. La ROM de caràcters consta de tot tipus de patrons de caràcters, alguns dels quals corresponen als patrons de caràcters del teclat. La ROM de caràcters és diferent de la memòria de la pantalla. Quan s'ha de mostrar un caràcter a la pantalla, el codi de caràcter s'envia a una posició entre les 1000 posicions de la memòria de la pantalla. A partir d'aquí, es selecciona el patró corresponent de la ROM de caràcters que s'ha de mostrar a la pantalla. L'elecció del patró correcte a la ROM de caràcters a partir d'un codi de caràcters la fa VIC II (maquinari).

Moltes ubicacions de memòria entre $D000 i $DFFF tenen dos propòsits: s'utilitzen per gestionar les operacions d'entrada/sortida diferents de la pantalla o s'utilitzen com a ROM de caràcters per a la pantalla. Es tracta de dos blocs de memòria. Un és RAM i l'altre és ROM per a ROM de caràcters. L'intercanvi dels bancs per gestionar l'entrada/sortida o els patrons de caràcters (ROM de caràcters) es fa mitjançant programari (rutina del sistema operatiu en ROM de $F000 a $FFFF).

Nota : El VIC té registres que s'adrecen amb adreces de l'espai de memòria dins del rang de $D000 i $DFFF.

La rutina CHHROUT
S'accedeix a la rutina OS CHROUT fent un salt (JSR) a la taula de salt de la ROM del sistema operatiu a $FFD2. Aquesta rutina, quan es crida, agafa el byte que el programador ha posat a l'acumulador µP i s'imprimeix a la pantalla on es troba el cursor. El segment de codi per imprimir el caràcter 'E', per exemple, és:

LDA #$05
CRUT

El 0516 no és el codi ASCII per a 'E'. El Commodore-64 té els seus propis codis de caràcters per a la pantalla on $05 significa 'E'. El número #$05 es col·loca a la memòria de la pantalla abans que VIC l'enviï a la pantalla. Aquestes dues línies de codificació haurien de venir després de configurar el canal, obrir el fitxer lògic i cridar la rutina CHKOUT per a la sortida. El codi complet és:

; Configura el canal
LDA #$40 ; número de fitxer lògic
LDX #$03 ; el número de dispositiu per a la pantalla és de 03 $
LDY #$FF ; sense adreça secundària
JSR SETLFS ; configurar el canal adequat
; no SETNAM ja que la pantalla no necessita un nom
;
; Obre el fitxer lògic
JSR OBERT
; Estableix el canal per a la sortida
LDX #$40 ; número de fitxer lògic
JSR CHKOUT
;
; Sortida de caràcters a la pantalla
LDA #$05
JSR CHROUT
; Tanca el fitxer lògic
LDA #$40
JSR TANCAR

L'obertura s'ha de tancar abans que s'executi un altre programa. Suposem que l'usuari de l'ordinador escriu un caràcter al teclat quan s'espera. El programa següent imprimeix un caràcter des del teclat a la pantalla:

; Configura el canal
LDA #$40 ; número de fitxer lògic
LDX #$03 ; el número de dispositiu per a la pantalla és de 03 $
LDY #$FF ; sense adreça secundària
JSR SETLFS ; configurar el canal adequat
; no SETNAM ja que la pantalla no necessita un nom
;
; Obre el fitxer lògic
JSR OBERT
; Estableix el canal per a la sortida
LDX #$40 ; número de fitxer lògic
JSR CHKOUT
;
; Introduïu caràcters des del teclat
ESPERA JSR GETIN ; posa $00 a A si la cua del teclat està buida
CMP #$00 ; Si $00 van anar a A, llavors Z és 1 amb la comparació
BEQ WAIT ; GETIN de la cua de nou si 0 anava a l'acumulador
BNE PRNSCRN ; aneu a PRNSCRN si Z és 0, perquè A ja no té $00
; Sortida de caràcters a la pantalla
PRNSCRN JSR CHROUT ; envia el caràcter en A a la pantalla
; Tanca el fitxer lògic
LDA #$40
JSR TANCAR

Nota : WAIT i PRNSCRN són les etiquetes que identifiquen les adreces. El byte del teclat que arriba a l'acumulador µP és un codi ASCII. El codi corresponent que Commodore-64 ha d'enviar a la pantalla ha de ser diferent. Això no es té en compte al programa anterior per simplicitat.

5.7 Enviament i recepció de bytes per a la unitat de disc

Hi ha dos adaptadors d'interfície complexos a la unitat del sistema (placa base) de Commodore-64 anomenats VIA #1 i CIA #2. Cada CIA té dos ports paral·lels que s'anomenen Port A i Port B. Hi ha un port extern a la superfície vertical de la part posterior de la unitat del sistema Commodre-64 que s'anomena port sèrie. Aquest port té 6 pins, un dels quals és per a dades. Les dades entren o surten de la unitat del sistema en sèrie, un bit a la vegada.

Vuit bits paral·lels del port intern A de la CIA #2, per exemple, poden sortir de la unitat del sistema a través del port sèrie extern després de ser convertits a les dades en sèrie mitjançant un registre de desplaçament a la CIA. Les dades en sèrie de vuit bits del port sèrie extern poden entrar al port intern A de la CIA #2 després de ser convertides a les dades paral·leles mitjançant un registre de canvi a la CIA.

La unitat del sistema Commodore-64 (unitat base) utilitza una unitat de disc externa amb un disquet. Es pot connectar una impressora a aquesta unitat de disc de manera en cadena (connectant dispositius en sèrie com una cadena). El cable de dades de la unitat de disc està connectat al port sèrie extern de la unitat del sistema Commodore-64. Això vol dir que una impressora en cadena també està connectada al mateix port sèrie. Aquests dos dispositius s'identifiquen amb dos números de dispositiu diferents (normalment 8 i 4, respectivament).

L'enviament o la recepció de dades per a la unitat de disc segueix el mateix procediment que s'ha descrit anteriorment. Això és:

  • Establir el nom del fitxer lògic (número) que és el mateix que el del fitxer de disc real mitjançant la rutina SETNAM.
  • Obrint el fitxer lògic mitjançant la rutina OPEN.
  • Decidir si és d'entrada o sortida mitjançant la rutina CHKOUT o CHKIN.
  • Enviament o recepció de dades mitjançant la instrucció STA i/o LDA.
  • Tancant el fitxer lògic mitjançant la rutina CLOSE.

El fitxer lògic s'ha de tancar. Tancar el fitxer lògic tanca efectivament aquest canal en particular. Quan es configura el canal per a la unitat de disc, el programador decideix el número de fitxer lògic. És un nombre entre $00 i $FF (inclosos). No hauria de ser un número que ja s'hagi escollit per a cap altre dispositiu (o fitxer real). El número de dispositiu és 8 si només hi ha una unitat de disc. L'adreça secundària (número) s'obté del manual de la unitat de disc. El programa següent utilitza 2. El programa escriu la lletra “E” (ASCII) en un fitxer del disc anomenat “mydoc.doc”. Se suposa que aquest nom comença a l'adreça de memòria de $C101. Per tant, el byte inferior de $01 ha d'estar al registre X i el byte superior de $C1 ha d'estar al registre Y abans que es cridi la rutina SETNAM. El registre A també hauria de tenir el número $09 abans de cridar la rutina SETNAM.

; Configura el canal
LDA #$40 ; número de fitxer lògic
LDX #$08 ; número de dispositiu per a la primera unitat de disc
LDY #$02 ; adreça secundària
JSR SETLFS ; configurar el canal adequat
;
; El fitxer de la unitat de disc necessita un nom (ja a la memòria)
LDA #$09
LDX #$01
LDY#$C1
JSR SETNAM
; Obre el fitxer lògic
JSR OBERT
; Estableix el canal per a la sortida
LDX #$40 ; número de fitxer lògic
JSR CHKOUT ;per escriure
;
; Sortida de caràcters al disc
LDA #$45
JSR CHROUT
; Tanca el fitxer lògic
LDA #$40
JSR TANCAR

Per llegir un byte del disc al registre µP Y, repetiu el programa anterior amb els canvis següents: En lloc de “JSR CHKOUT ; per escriure”, utilitzeu “JSR CHKIN ; per llegir”. Substituïu el segment de codi per “; Sortida de caràcters al disc” amb el següent:

; Introduïu caràcters des del disc
JSR CHRIS

S'accedeix a la rutina OS CHRIN fent un salt (JSR) a la taula de salt de la ROM del sistema operatiu a $FFCF. Aquesta rutina, quan es truca, obté un byte d'un canal que ja està configurat com a canal d'entrada i el posa al registre µP A. La rutina del sistema operatiu GETIN ROM també es pot utilitzar en lloc de CHRIN.

Enviament d'un byte a la impressora
L'enviament d'un byte a la impressora es fa de manera similar a l'enviament d'un byte a un fitxer del disc.

5.8 La rutina OS SAVE

S'accedeix a la rutina OS SAVE fent un salt (JSR) a la taula de salt de la ROM del sistema operatiu a $FFD8. La rutina OS SAVE a la ROM desa (bolca) una secció de la memòria al disc com a fitxer (amb un nom). S'ha de conèixer l'adreça inicial de la secció a la memòria. També s'ha de conèixer l'adreça final de la secció. El byte inferior de l'adreça inicial es col·loca a la pàgina zero de la memòria RAM a l'adreça $002B. El byte més alt de l'adreça inicial es col·loca a la següent ubicació de memòria del byte a l'adreça $002C. A la pàgina zero, l'etiqueta TXTTAB fa referència a aquestes dues adreces, tot i que TXTTAB en realitat significa l'adreça $002B. El byte inferior de l'adreça final es col·loca al registre µP X. El byte més alt de l'adreça final més 1 es col·loca al registre µP Y. El registre µP A pren el valor de $2B per a TXTTAB ($002B). Amb això, la rutina SAVE es pot cridar amb el següent:

JSR DESA

La secció de la memòria a desar pot ser un programa en llenguatge assemblador o un document. Un exemple de document pot ser una carta o un assaig. Per utilitzar la rutina de desar, cal seguir el procediment següent:

  • Configureu el canal mitjançant la rutina SETLFS.
  • Establiu el nom del fitxer lògic (número) que és el mateix que el del fitxer de disc real mitjançant la rutina SETNAM.
  • Obriu el fitxer lògic mitjançant la rutina OPEN.
  • Feu que sigui un fitxer per a la sortida utilitzant CHKOUT.
  • El codi per desar el fitxer va aquí que acaba amb 'JSR SAVE'.
  • Tanqueu el fitxer lògic mitjançant la rutina CLOSE.

El programa següent desa un fitxer que comença des de les ubicacions de memòria de $C101 a $C200:

; Configura el canal
LDA #$40 ; número de fitxer lògic
LDX #$08 ; número de dispositiu per a la primera unitat de disc
LDY #$02 ; adreça secundària
JSR SETLFS ; configurar el canal adequat
;
; Nom del fitxer a la unitat de disc (ja a la memòria a $C301)
LDA #$09 ; longitud del nom del fitxer
LDX #$01
LDY#$C3
JSR SETNAM
; Obre el fitxer lògic
JSR OBERT
; Estableix el canal per a la sortida
LDX #$40 ; número de fitxer lògic
JSR CHKOUT ; per escriure
;
; Fitxer de sortida al disc
LDA #$01
STA $ 2B ; TXTTAB
LDA #$C1
STA $ 2C
LDX #$00
LDY #$C2
LDA #$2B
JSR DESA
; Tanca el fitxer lògic
LDA #$40
JSR TANCAR

Tingueu en compte que aquest és un programa que desa una altra secció de la memòria (no la secció del programa) al disc (disquet per a Commodore-64).

5.9 La rutina OS LOAD

S'accedeix a la rutina OS LOAD fent un salt (JSR) a la taula de salt de la ROM del sistema operatiu a $FFD5. Quan una secció (àrea gran) de la memòria es desa al disc, es desa amb una capçalera que té l'adreça inicial de la secció a la memòria. La subrutina OS LOAD carrega els bytes d'un fitxer a la memòria. Amb aquesta operació LOAD, el valor de l'acumulador ha de ser 010 ($00). Perquè l'operació LOAD llegeixi l'adreça inicial a la capçalera del fitxer del disc i posi els bytes del fitxer a la RAM a partir d'aquesta adreça, l'adreça secundària per al canal ha de ser 1 o 2 (el programa següent utilitza 2). Aquesta rutina retorna l'adreça més 1 de la ubicació RAM més alta que es carrega. Això vol dir que el byte baix de l'última adreça del fitxer en RAM més 1 es posa al registre µP X, i el byte alt de l'última adreça del fitxer en RAM més 1 es posa al registre µP Y.

Si la càrrega no té èxit, el registre µP A conté el número d'error (possiblement 4, 5, 8 o 9). També s'estableix la bandera C del registre d'estat del microprocessador (fet 1). Si la càrrega té èxit, l'últim valor del registre A no és important.

Ara, en el capítol anterior d'aquest curs de carrera en línia, la primera instrucció del programa de llenguatge assemblador es troba a l'adreça de la RAM on va començar el programa. No ha de ser així. Això vol dir que la primera instrucció d'un programa no ha d'estar al començament del programa a la memòria RAM. La instrucció d'inici d'un programa pot estar en qualsevol lloc del fitxer a la memòria RAM. Es recomana al programador que etiqueti la instrucció del llenguatge ensamblador amb START. Amb això, després de carregar el programa, es torna a executar (executar) amb la següent instrucció de llenguatge ensamblador:

JSR INICI

'JSR START' es troba al programa de llenguatge ensamblador que carrega el programa que s'ha d'executar. Un llenguatge ensamblador que carrega un altre fitxer de llenguatge ensamblador i executa el fitxer carregat té el procediment de codi següent:

  • Configureu el canal mitjançant la rutina SETLFS.
  • Establiu el nom del fitxer lògic (número) que és el mateix que el del fitxer de disc real mitjançant la rutina SETNAM.
  • Obriu el fitxer lògic mitjançant la rutina OPEN.
  • Feu que sigui el fitxer d'entrada mitjançant el CHKIN.
  • El codi per carregar el fitxer va aquí i acaba amb 'JSR LOAD'.
  • Tanqueu el fitxer lògic mitjançant la rutina CLOSE.

El programa següent carrega un fitxer del disc i l'executa:

; Configura el canal
LDA #$40 ; número de fitxer lògic
LDX #$08 ; número de dispositiu per a la primera unitat de disc
LDY #$02 ; adreça secundària
JSR SETLFS ; configurar el canal adequat
;
; Nom del fitxer a la unitat de disc (ja a la memòria a $C301)
LDA #$09 ; longitud del nom del fitxer
LDX #$01
LDY#$C3
JSR SETNAM
; Obre el fitxer lògic
JSR OBERT
; Estableix el canal d'entrada
LDX #$40 ; número de fitxer lògic
JSR CHKIN ; per llegir
;
; Fitxer d'entrada des del disc
LDA #$00
CÀRREGA JSR
; Tanca el fitxer lògic
LDA #$40
JSR TANCAR
; Inicieu el programa carregat
JSR INICI

5.10 El mòdem i l'estàndard RS-232

El mòdem és un dispositiu (perifèric) que converteix els bits de l'ordinador en els corresponents senyals elèctrics d'àudio per ser transmesos a través de la línia telefònica. A l'extrem receptor, hi ha un mòdem abans que un ordinador receptor. Aquest segon mòdem converteix els senyals d'àudio elèctrics en bits per a l'ordinador receptor.

Cal connectar un mòdem a un ordinador a un port extern (a la superfície vertical de l'ordinador). L'estàndard RS-232 es refereix a un tipus particular de connector que connecta un mòdem a l'ordinador (en el passat). En altres paraules, molts ordinadors en el passat tenien un port extern que era un connector RS-232 o un connector compatible RS-232.

La unitat del sistema Commodore-64 (ordinador) té un port extern a la seva superfície vertical posterior que s'anomena port d'usuari. Aquest port d'usuari és compatible amb RS-232. S'hi pot connectar un dispositiu mòdem. El Commodore-64 es comunica amb un mòdem a través d'aquest port d'usuari. El sistema operatiu ROM del Commodore-64 té subrutines per comunicar-se amb un mòdem anomenat rutines RS-232. Aquestes rutines tenen entrades a la taula de salts.

Velocitat de transmissió
El byte de vuit bits de l'ordinador es converteix en una sèrie de vuit bits abans de ser enviat al mòdem. El contrari es fa des del mòdem a l'ordinador. La velocitat de transmissió és el nombre de bits que es transmeten per segon, en sèrie.

Fons de la memòria
El terme 'Fond de memòria' no es refereix a la ubicació dels bytes de memòria de l'adreça $0000. Es refereix a la ubicació de RAM més baixa on l'usuari pot començar a posar les seves dades i programes. Per defecte, és de 0800 $. Recordeu de la discussió anterior que moltes de les ubicacions entre $0800 i $BFFF són utilitzades pel llenguatge informàtic BASIC i els seus programadors (usuaris). Només queden les ubicacions d'adreces de $C000 a $CFFF per utilitzar-les per als programes i les dades del llenguatge ensamblador; això són 4 Kbytes dels 64 Kbytes de memòria.

Cim de la Memòria
En aquells dies, quan els clients compraven els ordinadors Commodore-64, alguns no venien amb totes les ubicacions de memòria. Aquests ordinadors tenien ROM amb el seu sistema operatiu des de $E000 fins a $FFFF. Tenien RAM des de $ 0000 fins a un límit, que no és $ DFFF, al costat de $ E000. El límit era inferior a $DFFF i aquest límit s'anomena 'Top of Memory'. Per tant, la part superior de la memòria no fa referència a la ubicació $FFFF.

Commodore-64 Buffers per a comunicació RS-232
Buffer de transmissió
El buffer per a la transmissió RS-232 (sortida) pren 256 bytes des de la part superior de la memòria cap avall. El punter d'aquest buffer de transmissió s'etiqueta com a ROBUF. Aquest punter es troba a la pàgina zero amb les adreces $00F9 seguides de $00FA. En realitat, ROBUF identifica $00F9. Per tant, si l'adreça per a l'inici de la memòria intermèdia és $BE00, el byte inferior de $BE00, que és $00, es troba a la ubicació $00F9 i el byte superior de $BE00, que és $BE, es troba a la ubicació $00FA. ubicació.

Buffer de recepció
El buffer per rebre els bytes RS-232 (entrada) pren 256 bytes des de la part inferior del buffer de transmissió. El punter d'aquest buffer de recepció s'etiqueta com a RIBUF. Aquest punter es troba a la pàgina zero amb les adreces $00F7 seguides de $00F8. RIBUF identifica realment $00F7. Així, si l'adreça per a l'inici de la memòria intermèdia és $BF00, el byte inferior de $BF00, que és $00, es troba a la ubicació $00F7 i el byte superior de $BF00, que és $BF, es troba a la ubicació $00F8. ubicació. Per tant, s'utilitzen 512 bytes de la part superior de la memòria com a memòria intermèdia total RS-232.

Canal RS-232
Quan un mòdem està connectat al port d'usuari (extern), la comunicació amb el mòdem és només comunicació RS-232. El procediment per tenir un canal RS-232 complet és gairebé el mateix que en la discussió anterior, però amb una diferència important: el nom del fitxer és un codi i no una cadena a la memòria. El codi $0610 és una bona opció. Significa una velocitat de transmissió de 300 bits/s i alguns altres paràmetres tècnics. A més, no hi ha cap adreça secundària. Tingueu en compte que el número de dispositiu és 2. El procediment per configurar un canal RS-232 complet és:

  • Configuració del canal mitjançant la rutina SETLFS.
  • Establiment del nom del fitxer lògic, $0610.
  • Obrint el fitxer lògic mitjançant la rutina OPEN.
  • Fer-lo el fitxer per a la sortida mitjançant CHKOUT o el fitxer per a l'entrada mitjançant CHKIN.
  • Enviament dels bytes únics amb CHROUT o rebent els bytes únics amb GETIN.
  • Tancant el fitxer lògic mitjançant la rutina CLOSE.

S'accedeix a la rutina OS GETIN fent un salt (JSR) a la taula de salt de la ROM del sistema operatiu a $FFE4. Aquesta rutina, quan es crida, agafa el byte que s'envia a la memòria intermèdia del receptor i el posa (retorna) a l'acumulador µP.

El programa següent envia el byte 'E' (ASCII) al mòdem que està connectat al port compatible RS-232 de l'usuari:

; Configura el canal
LDA #$40 ; número de fitxer lògic
LDX #$02 ; número de dispositiu per a RS-232
LDY #$FF ; sense adreça secundària
JSR SETLFS ; configurar el canal adequat
;
; El nom per a RS-232 és un codi, p. $0610
LDA #$02 ; La longitud del codi és de 2 bytes
LDX #$10
LDY#$06
JSR SETNAM
;
; Obre el fitxer lògic
JSR OBERT
; Estableix el canal per a la sortida
LDX #$40 ; número de fitxer lògic
JSR CHKOUT
;
; Sortida de caràcters a RS-232, p. mòdem
LDA #$45
JSR CHROUT
; Tanca el fitxer lògic
LDA #$40
JSR TANCAR

Per rebre un byte, el codi és molt semblant, excepte que 'JSR CHKOUT' es substitueix per 'JSR CHKIN' i:

LDA #$45
JSR CHROUT

es substitueix per 'JSR GETIN' i el resultat es col·loca al registre A.

L'enviament o la recepció contínua de bytes es realitza mitjançant un bucle per a l'enviament o la recepció del segment de codi, respectivament.

Tingueu en compte que l'entrada i la sortida amb el Commodore són similars en la majoria dels seus casos, excepte pel teclat, on algunes de les rutines no les crida el programador, però sí que les crida el sistema operatiu.

5.11 Recompte i cronometratge

Considereu la seqüència de compte enrere que és:

2, 1, 0

Això és el compte enrere del 2 al 0. Ara, considereu la seqüència del compte enrere que es repeteix:

2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0

Aquest és el compte enrere que es repeteix de la mateixa seqüència. La seqüència es repeteix quatre vegades. Quatre vegades significa que el temps és 4. Dins d'una seqüència s'està comptant. Repetir la mateixa seqüència és cronometratge.

Hi ha dos adaptadors d'interfície complexos a la unitat del sistema del Commodore-64. Cada CIA té dos circuits de comptador/temporitzador anomenats Timer A (TA) i Timer B (TB). El circuit de recompte no és diferent del circuit de temporització. El comptador o temporitzador del Commodore-64 fa referència al mateix. De fet, qualsevol d'ells es refereix essencialment a un registre de 16 bits que sempre compta enrere fins a 0 als polsos del rellotge del sistema. Es poden establir diferents valors al registre de 16 bits. Com més gran sigui el valor, més temps es trigarà a comptar fins a zero. Cada vegada que un dels temporitzadors passa de zero, el IRQ El senyal d'interrupció s'envia al microprocessador. Quan el recompte baixa més enllà de zero, s'anomena desbordament inferior.

Depenent de com es programi el circuit del temporitzador, un temporitzador pot funcionar en mode d'una sola vegada o en mode continu. Amb la il·lustració anterior, el mode únic significa 'fer 2, 1, 0' i aturar-se mentre els polsos del rellotge continuen. El mode continu és com '2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, etc.'. que continua amb els polsos del rellotge. Això vol dir que quan passa de zero, si no es dóna cap instrucció, la seqüència de compte enrere es repeteix. El nombre més gran sol ser molt més gran que 2.

Es genera el temporitzador A (TA) de la CIA #1 IRQ a intervals regulars (durades) per fer servei al teclat. De fet, això és cada 1/60 de segon per defecte. IRQ s'envia al microprocessador cada 1/60 de segon. És només quan IRQ s'envia que un programa pot llegir un valor de clau de la cua del teclat (búfer). Recordeu que el microprocessador només té un pin per al IRQ senyal. El microprocessador també té només un pin per al NMI senyal. El senyal ¯NMI al microprocessador sempre prové de la CIA #2.

El registre del temporitzador de 16 bits té dues adreces de memòria: una per al byte inferior i una altra per al byte superior. Cada CIA té dos circuits de temporitzadors. Les dues CIA són idèntiques. Per a CIA #1, les adreces dels dos temporitzadors són: DC04 i DC05 per a TA i DC06 i DC07 per a TB. Per a CIA #2, les adreces dels dos temporitzadors són: DD04 i DD05 per a TA i DD06 i DD07 per a TB.

Suposem que el número 25510 s'ha d'enviar al temporitzador TA de la CIA #2 per fer el compte enrere. 25510 = 00000000111111112 està en setze bits. 00000000111111112 = $000FFF està en hexadecimal. En aquest cas, $FF s'envia al registre a l'adreça $DD04, i $00 s'envia al registre a l'adreça $DD05 - little endianness. El següent segment de codi envia el número al registre:

LDA #$FF
ESTAT $DD04
LDA #$00
ESTUDI $DD05

Tot i que els registres d'una CIA tenen adreces RAM, es troben físicament a la CIA i la CIA és un IC separat de la RAM o la ROM.

Això no és tot! Quan al temporitzador se li ha donat un número per fer el compte enrere, com amb el codi anterior, el compte enrere no comença. El compte enrere comença quan s'ha enviat un byte de vuit bits al registre de control corresponent per al temporitzador. El primer bit d'aquest byte per al registre de control indica si el compte enrere ha de començar o no. Un valor de 0 per a aquest primer bit significa aturar el compte enrere, mentre que un valor d'1 significa començar el compte enrere. A més, el byte ha d'indicar si el compte enrere és en mode d'un sol cop (un cop) o en mode d'execució lliure (mode continu). El mode d'un sol cop fa el compte enrere i s'atura quan el valor del registre del temporitzador passa a zero. Amb el mode de marxa lliure, el compte enrere es repeteix després d'arribar al 0. El quart bit (índex 3) del byte que s'envia al registre de control indica el mode: 0 significa mode de funcionament lliure i 1 significa mode d'un sol cop.

Un nombre adequat per començar a comptar en mode d'un cop és 000010012 = 09 $ en hexadecimal. Un nombre adequat per començar a comptar en mode d'execució lliure és 000000012 = $01 en hexadecimal. Cada registre de temporitzador té el seu propi registre de control. A la CIA #1, el registre de control del temporitzador A té l'adreça RAM de DC0E16 i el registre de control del temporitzador B té l'adreça RAM de DC0F16. A la CIA #2, el registre de control del temporitzador A té l'adreça RAM de DD0E16 i el registre de control del temporitzador B té l'adreça RAM de DD0F16. Per començar a comptar enrere el nombre de setze bits a TA de CIA #2, en mode d'un sol cop, utilitzeu el codi següent:

LDA #$09
STA $DD0E

Per començar a comptar enrere el nombre de setze bits a TA de CIA #2, en mode d'execució lliure, utilitzeu el codi següent:

LDA #$01
STA $DD0E

5.12 El IRQ i NMI Sol·licituds

El microprocessador 6502 té el IRQ i NMI línies (pins). Tant la CIA #1 com la CIA #2 tenen cadascun IRQ pin per al microprocessador. El IRQ el pin de la CIA #2 està connectat a NMI pin del µP. El IRQ el pin de la CIA #1 està connectat a IRQ pin del µP. Aquestes són les úniques dues línies d'interrupció que connecten el microprocessador. Doncs el IRQ el pin de la CIA #2 és el NMI font i també es pot veure com la línia ¯NMI.

La CIA #1 té cinc possibles fonts immediates de generació IRQ senyal per a µP. La CIA #2 té la mateixa estructura que la CIA #1. Per tant, la CIA #2 té les mateixes cinc possibles fonts immediates de generar el senyal d'interrupció aquesta vegada que és el NMI senyal. Recordeu que quan el µP rep el NMI senyal, si està manipulant el IRQ sol·licitud, la suspèn i la gestiona NMI petició. Quan acabi de manipular el NMI sol·licitud, després reprèn la gestió de la IRQ petició.

CIA #1 normalment està connectat externament al teclat i a un dispositiu de joc com un joystick. El teclat utilitza més el port A del CIA #1 que el port B. El dispositiu del joc utilitza més el port CIA #1 B que el seu port A. El CIA #2 normalment està connectat externament a la unitat de disc (encadenat a la impressora) i el mòdem. La unitat de disc utilitza més el port A del CIA #2 (encara que a través del port sèrie extern) que el port B. El mòdem (RS-232) utilitza més el port CIA #2 B que el seu port A.

Amb tot això, com sap la unitat del sistema què causa el? IRQ o NMI interrompre? CIA #1 i CIA #2 tenen cinc fonts immediates d'interrupció. Si el senyal d'interrupció al µP és NMI , la font és una de les cinc fonts immediates de la CIA #2. Si el senyal d'interrupció al µP és IRQ , la font és una de les cinc fonts immediates de la CIA #1.

La següent pregunta és: 'Com diferencia la unitat del sistema entre les cinc fonts immediates de cada CIA?' Cada CIA té un registre de vuit bits que s'anomena Registre de control d'interrupcions (ICR). L'ICR dóna servei als dos ports de la CIA. La taula següent mostra els significats dels vuit bits del registre de control d'interrupcions, començant pel bit 0:

Taula 5.13
Registre de control d'interrupcions
Índex de bits Significat
0 Establit (fet 1) per sota del temporitzador A
1 Establit per desbordament inferior del temporitzador B
2 Estableix quan el rellotge de l'hora del dia és igual a l'alarma
3 S'estableix quan el port sèrie està ple
4 Definit per dispositiu extern
5 No utilitzat (fet 0)
6 No utilitzat (fet 0)
7 S'estableix quan s'estableix qualsevol dels cinc primers bits

Com es pot veure a la taula, cadascuna de les fonts immediates està representada per un dels cinc primers bits. Així, quan es rep el senyal d'interrupció al µP, s'ha d'executar el codi per llegir el contingut del registre de control d'interrupció per conèixer la font exacta de la interrupció. L'adreça RAM de l'ICR de la CIA #1 és DC0D16. L'adreça RAM de l'ICR de la CIA #2 és DD0D16. Per llegir (retornar) el contingut de l'ICR de CIA #1 a l'acumulador µP, escriviu la següent instrucció:

LDA$DC0D

Per llegir (retornar) el contingut de l'ICR de CIA #2 a l'acumulador µP, escriviu la següent instrucció:

LDA $DD0D

5.13 Programa de fons impulsat per interrupcions

El teclat normalment interromp el microprocessador cada 1/60 de segon. Imagineu que un programa s'està executant i arriba a la posició d'esperar una tecla del teclat abans de poder continuar amb els segments de codi següents. Suposem que si no es prem cap tecla des del teclat, el programa només fa un petit bucle, esperant una tecla. Imagineu que el programa s'està executant i només esperava una tecla del teclat just després d'emetre la interrupció del teclat. En aquest punt, tot l'ordinador s'atura indirectament i no fa res més que el bucle d'espera. Imagineu que es prem una tecla del teclat just abans del següent número de la següent interrupció del teclat. Això vol dir que l'ordinador no ha fet res durant aproximadament una seixantena part de segon! Això és molt de temps perquè un ordinador no faci res, fins i tot en els temps del Commodore-64. L'ordinador podria haver estat fent una altra cosa en aquest temps (durada). Hi ha moltes durades d'aquest tipus en un programa.

Es pot escriure un segon programa perquè funcioni amb aquestes durades 'inactius'. Es diu que aquest programa funciona en segon pla del programa principal (o primer). Una manera senzilla de fer-ho és forçar el maneig d'interrupcions BRK modificades quan s'espera una tecla del teclat.

Apuntador per a la instrucció BRK
A les ubicacions consecutives de la RAM de les adreces $0316 i $0317 hi ha el punter (vector) per a la rutina d'instruccions BRK real. El punter predeterminat es posa allà quan el sistema operatiu encès l'ordinador a la ROM. Aquest punter predeterminat és una adreça que encara apunta al controlador d'instruccions BRK predeterminat a la ROM del sistema operatiu. El punter és una adreça de 16 bits. El byte inferior del punter es col·loca a la ubicació del byte de l'adreça $0306, i el byte més alt del punter es col·loca a la ubicació del byte $0317.

Es pot escriure un segon programa de manera que quan el sistema està 'inactiu', el sistema executa alguns codis del segon programa. Això vol dir que el segon programa ha d'estar format per subrutines. Quan el sistema està 'inactiu' que està esperant una tecla del teclat, s'executa una següent subrutina per al segon programa. La interacció humana amb l'ordinador és lenta en comparació amb el funcionament de la unitat del sistema.

És fàcil resoldre aquest problema: cada cop que l'ordinador hagi d'esperar una tecla del teclat, inseriu una instrucció BRK al codi i substituïu el punter a $0316 (i $0317) pel punter de la següent subrutina de la segona ( programa personalitzat). D'aquesta manera, ambdós programes s'executarien en una durada que no és molt més llarga que la del programa principal que s'executa sol.

5.14 Muntatge i compilació

L'assemblador substitueix totes les etiquetes per adreces. Un programa de llenguatge assemblador s'escriu normalment per començar en una adreça determinada. El resultat de l'assemblador (després del muntatge) s'anomena 'codi objecte' amb tot en binari. Aquest resultat és el fitxer executable si el fitxer és un programa i no un document. Un document no és executable.

Una aplicació consta de més d'un programa (llenguatge ensamblador). Normalment hi ha un programa principal. La situació aquí no s'ha de confondre amb la situació dels programes de fons basats en interrupcions. Tots els programes aquí són programes en primer pla, però n'hi ha un primer o principal.

Es necessita un compilador en lloc de l'assemblador quan hi ha més d'un programa en primer pla. El compilador reuneix cadascun dels programes en un codi objecte. Tanmateix, hi hauria un problema: alguns dels segments de codi es superposaran perquè els programes probablement estan escrits per persones diferents. La solució del compilador és desplaçar tots els programes superposats excepte el primer a l'espai de memòria, de manera que els programes no es superposen. Ara, quan es tracta d'emmagatzemar variables, algunes adreces de variables encara es superposarien. La solució aquí és substituir les adreces superposades per les adreces noves (excepte el primer programa) perquè ja no es superposin. D'aquesta manera, els diferents programes s'ajustaran a les diferents porcions (àrees) de la memòria.

Amb tot això, és possible que una rutina d'un programa cridi una rutina d'un altre programa. Per tant, el compilador fa l'enllaç. L'enllaç es refereix a tenir l'adreça inicial d'una subrutina en un programa i després cridar-la en un altre programa; tots dos formen part de l'aplicació. Ambdós programes han d'utilitzar la mateixa adreça per a això. El resultat final és un codi objecte gran amb tot en binari (bits).

5.15 Desar, carregar i executar un programa

Un llenguatge assemblador s'escriu normalment en algun programa editor (que es pot proporcionar amb el programa assemblador). El programa editor indica on comença i acaba el programa a la memòria (RAM). La rutina Kernal SAVE del sistema operatiu ROM del Commodore-64 pot desar un programa a la memòria al disc. Només bolca la secció (bloc) de la memòria que pot contenir la seva crida d'instruccions al disc. S'aconsella tenir la instrucció de crida a SAVE, separada del programa que s'està desant, de manera que quan el programa es carregui a la memòria des del disc, no es torni a desar quan s'executi. Carregar un programa en llenguatge assemblador des del disc és un tipus de repte diferent perquè un programa no pot carregar-se per si mateix.

Un programa no pot carregar-se des del disc fins on comença i acaba a la memòria RAM. En aquells temps, el Commodore-64 es subministrava normalment amb un intèrpret BASIC per executar els programes de llenguatge BASIC. Quan la màquina (ordinador) està engegada, s'instal·la amb l'indicador d'ordres: PREPARAT. A partir d'aquí, les ordres o instruccions BASIC es poden escriure prement la tecla 'Enter' després d'escriure. L'ordre BASIC (instrucció) per carregar un fitxer és:

CARREGA 'nom del fitxer',8,1

L'ordre comença amb la paraula reservada BASIC que és LOAD. Això és seguit per un espai i després el nom del fitxer entre cometes dobles. Va seguit el número de dispositiu 8 que va precedit per una coma. L'adreça secundària del disc, que és 1, va seguida d'una coma. Amb aquest fitxer, l'adreça inicial del programa de llenguatge ensamblador es troba a la capçalera del fitxer del disc. Quan el BASIC acaba de carregar el programa, es retorna l'última adreça RAM més 1 del programa. La paraula 'retornat' aquí significa que el byte inferior de l'última adreça més 1 es posa al registre µP X, i el byte superior de l'última adreça més 1 es posa al registre µP Y.

Després de carregar el programa, s'ha d'executar (executar). L'usuari del programa ha de conèixer l'adreça d'inici per a l'execució a la memòria. De nou, aquí cal un altre programa BASIC. És l'ordre SYS. Després d'executar l'ordre SYS, el programa de llenguatge ensamblador s'executarà (i s'aturarà). Durant l'execució, si es necessita alguna entrada des del teclat, el programa de llenguatge ensamblador ho hauria d'indicar a l'usuari. Després que l'usuari introdueixi les dades al teclat i prem la tecla 'Enter', el programa de llenguatge ensamblador continuarà executant-se utilitzant l'entrada del teclat sense interferències de l'intèrpret BASIC.

Suposant que l'inici de l'adreça RAM d'execució (execució) per al programa de llenguatge ensamblador és C12316, C123 es converteix a la base deu abans d'utilitzar-la amb l'ordre SYS. La conversió de C12316 a base deu és la següent:

Per tant, l'ordre BASIC SYS és:

SYS 49443

5.16 Arrencada per a Commodore-64

L'arrencada del Commodore-64 consta de dues fases: la fase de restabliment del maquinari i la fase d'inicialització del sistema operatiu. El sistema operatiu és el Kernal en ROM (i no en un disc). Hi ha una línia de reinici (de fet RES ) que es connecta a un pin a 6502 µP, i al mateix nom de pin en totes les naus especials com la CIA 1, CIA 2 i VIC II. En la fase de restabliment, a causa d'aquesta línia, tots els registres del µP i dels xips especials es reinicien a 0 (fer zero per cada bit). A continuació, pel maquinari del microprocessador, el punter de pila i el registre d'estat del processador es donen amb els seus valors inicials al microprocessador. A continuació, es dóna el comptador del programa amb el valor (adreça) a les ubicacions $FFFC i $FFFD. Recordeu que el comptador del programa conté l'adreça de la següent instrucció. El contingut (adreça) que es manté aquí és per a la subrutina que comença la inicialització del programari. Fins ara, tot el fa el maquinari del microprocessador. En aquesta fase no es toca tota la memòria. Aleshores comença la següent fase d'inicialització.

La inicialització es fa mitjançant algunes rutines del sistema operatiu ROM. La inicialització significa donar els valors inicials o predeterminats a alguns registres en els xips especials. La inicialització comença donant els valors inicials o predeterminats a alguns registres en els xips especials. IRQ , per exemple, ha de començar a emetre cada 1/60 de segon. Per tant, el seu temporitzador corresponent a la CIA #1 s'ha de configurar al valor predeterminat.

A continuació, el Kernal realitza una prova de RAM. Comprova cada ubicació enviant un byte a la ubicació i tornant a llegir-lo. Si hi ha una diferència, almenys aquesta ubicació és dolenta. Kernal també identifica la part superior de la memòria i la part inferior de la memòria i estableix els punters corresponents a la pàgina 2. Si la part superior de la memòria és $DFFF, $FF es posa a la ubicació $0283 i $DF es posa a la ubicació $0284 bytes. Tant $0283 com $0284 tenen l'etiqueta HIRAM. Si la part inferior de la memòria és de $0800, $00 es posa a la ubicació $0281 i $08 es posa a la ubicació $0282. Tant $0281 com $0282 tenen l'etiqueta LORAM. La prova de memòria RAM comença en realitat des de $ 0300 fins a la part superior de la memòria (RAM).

Finalment, els vectors d'entrada/sortida (punters) s'estableixen als seus valors per defecte. La prova de memòria RAM comença en realitat des de $ 0300 fins a la part superior de la memòria (RAM). Això vol dir que la pàgina 0, la pàgina 1 i la pàgina 2 estan inicialitzades. La pàgina 0, en particular, té molts punters ROM del sistema operatiu i la pàgina 2 té molts punters BASIC. Aquests indicadors s'anomenen variables. Recordeu que la pàgina 1 és la pila. Els punters s'anomenen variables perquè tenen noms (etiquetes). En aquesta etapa, la memòria de la pantalla s'esborra per a la pantalla (monitor). Això significa enviar el codi de 20 $ per a l'espai (que passa a ser el mateix que ASCII 20 $) a les ubicacions de la pantalla de 1000 RAM. Per últim, el Kernal inicia l'intèrpret BASIC per mostrar l'indicador d'ordres BASIC que està LLES a la part superior del monitor (pantalla).

5.17 Problemes

Es recomana al lector que resolgui tots els problemes d'un capítol abans de passar al capítol següent.

  1. Escriu un codi de llenguatge ensamblador que faci que tots els bits del port CIA #2 A com a sortida i el port CIA #2 B com a entrada.
  2. Escriu un codi d'idioma ensamblador 6502 que espera una tecla del teclat fins que es prem.
  3. Escriu un programa de llenguatge ensamblador 6502 que enviï el caràcter 'E' a la pantalla del Commodore-64.
  4. Escriu un programa de llenguatge ensamblador 6502 que prengui un caràcter del teclat i l'enviï a la pantalla del Commodore-64, ignorant el codi de la tecla i el temps.
  5. Escriu un programa de llenguatge ensamblador 6502 que rebi un byte del disquet Commodore-64.
  6. Escriu un programa de llenguatge assemblador 6502 que desi un fitxer al disquet Commodore-64.
  7. Escriu un programa en llenguatge assemblador 6502 que carregui un fitxer de programa des del disquet Commodore-64 i l'iniciï.
  8. Escriu un programa de llenguatge ensamblador 6502 que enviï el byte 'E' (ASCII) al mòdem que està connectat al port compatible RS-232 de l'usuari del Commodore-64.
  9. Explica com es fan el recompte i el cronometratge a l'ordinador Commodore-64.
  10. Expliqueu com la unitat del sistema Commodore-64 pot identificar 10 fonts diferents de sol·licituds d'interrupció immediata, incloses les sol·licituds d'interrupció no emmascarables.
  11. Expliqueu com es pot executar un programa en segon pla amb un programa en primer pla a l'ordinador Commodore-64.
  12. Expliqueu breument com es poden compilar els programes en llenguatge assemblador en una aplicació per a l'ordinador Commodore-64.
  13. Expliqueu breument el procés d'arrencada de l'ordinador Commodore-64.